0x01
主要功能, 加载一个exe到 一个内存中, 并运行这块内存
0x02
有限制条件, EXE必须具有重定位表, 否则运行失败!!
截图
pid模块还没写完
想把进程移植到指定的 PID中运行!
0x03 关键代码
(有参考价值的代码, 重定位表的修复, 导入表的修复)
006 | #include "DebugTool.h" |
007 | #include "PEOperate.h" |
014 | VOID GetExeOEP( LPVOID pFileBuffer, DWORD &entryPoint) |
016 | PIMAGE_DOS_HEADER pDosHeader = NULL; |
017 | PIMAGE_NT_HEADERS pNTHeader = NULL; |
018 | PIMAGE_FILE_HEADER pPEHeader = NULL; |
019 | PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; |
020 | PIMAGE_SECTION_HEADER pSectionHeader = NULL; |
029 | if (*(( PWORD )pFileBuffer)!=IMAGE_DOS_SIGNATURE) |
031 | printf ( "不是有效的MZ标志\n" ); |
036 | pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; |
039 | printf ( "------------DOS头------------\n" ); |
040 | printf ( "MZ标志: %x\n" ,pDosHeader->e_magic); |
041 | printf ( "PE偏移: %x\n" ,pDosHeader->e_lfanew); |
044 | if (*((PDWORD)(( DWORD )pFileBuffer+pDosHeader->e_lfanew))!=IMAGE_NT_SIGNATURE) |
046 | printf ( "不是有效的PE标志\n" ); |
051 | pNTHeader = (PIMAGE_NT_HEADERS)(( DWORD )pFileBuffer+pDosHeader->e_lfanew); |
054 | printf ( "------------NT头------------\n" ); |
055 | printf ( "Signature: %x\n" ,pNTHeader->Signature); |
056 | pPEHeader = (PIMAGE_FILE_HEADER)((( DWORD )pNTHeader)+4); |
057 | printf ( "------------标准PE头--------\n" ); |
058 | printf ( "Machine: %x\n" ,pPEHeader->Machine); |
059 | printf ( "节的数量: %x\n" ,pPEHeader->NumberOfSections); |
060 | printf ( "SizeOfOptionHeaders: %x\n" ,pPEHeader->SizeOfOptionalHeader); |
063 | pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(( DWORD )pPEHeader+IMAGE_SIZEOF_FILE_HEADER); |
064 | printf ( "------------OPTION_PE头--------\n" ); |
065 | printf ( "Machine: %x \n" ,pOptionHeader->Magic); |
066 | printf ( "OEP: %x \n" ,pOptionHeader->AddressOfEntryPoint); |
067 | printf ( "ImageBase: %x \n" ,pOptionHeader->ImageBase); |
068 | printf ( "SectionAlignment: %x \n" ,pOptionHeader->SectionAlignment); |
069 | printf ( "FileAlignment: %x \n" ,pOptionHeader->FileAlignment); |
070 | printf ( "SizeOfImage: %x \n" ,pOptionHeader->SizeOfImage); |
071 | printf ( "SizeOfHeaders: %x \n" ,pOptionHeader->SizeOfHeaders); |
074 | entryPoint = pOptionHeader->AddressOfEntryPoint; |
082 | BOOL FixImport( LPVOID pFileBuffer, DWORD imagebase) |
090 | PIMAGE_DOS_HEADER pDosHeader = NULL; |
091 | PIMAGE_NT_HEADERS pNTHeader = NULL; |
092 | PIMAGE_FILE_HEADER pPEHeader = NULL; |
093 | PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; |
094 | PIMAGE_SECTION_HEADER pSectionHeader = NULL; |
095 | PIMAGE_SECTION_HEADER pSectionHeader_ADD = NULL; |
096 | PIMAGE_DATA_DIRECTORY pDataDirectory = NULL; |
098 | pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; |
099 | pNTHeader = (PIMAGE_NT_HEADERS)(( DWORD )pFileBuffer+pDosHeader->e_lfanew); |
100 | pPEHeader = (PIMAGE_FILE_HEADER)((( DWORD )pNTHeader)+4); |
101 | pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(( DWORD )pPEHeader+IMAGE_SIZEOF_FILE_HEADER); |
102 | pSectionHeader = (PIMAGE_SECTION_HEADER)(( DWORD )pOptionHeader+pPEHeader->SizeOfOptionalHeader); |
103 | pDataDirectory = pOptionHeader->DataDirectory; |
106 | IMAGE_DATA_DIRECTORY pImportDirectory = pDataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; |
108 | DWORD ImportVirtualAddress = pImportDirectory.VirtualAddress; |
109 | DWORD ImportFoa = RVAToFileOffset(pFileBuffer,ImportVirtualAddress); |
111 | printf ( "ImportVirtualAddress: %x \n" ,ImportVirtualAddress); |
112 | printf ( "Size: %x \n" ,pImportDirectory.Size); |
113 | printf ( "ImportFoa: %x \n" ,ImportFoa); |
118 | PIMAGE_IMPORT_DESCRIPTOR pImp = NULL; |
119 | pImp = (PIMAGE_IMPORT_DESCRIPTOR)(( DWORD )pFileBuffer + ImportVirtualAddress); |
122 | PIMAGE_THUNK_DATA pOrgThunk, pFirstThunk; |
123 | PIMAGE_IMPORT_BY_NAME pImportName; |
125 | OutputDebugStringF( "-----------import table info------------" ); |
127 | while (NULL != pImp->OriginalFirstThunk) { |
128 | pImp->Name += imagebase; |
130 | OutputDebugStringF( "DLL: %s" , pImp->Name); |
133 | HINSTANCE hInstance = LoadLibraryA(( LPCSTR )pImp->Name); |
134 | if (NULL == hInstance) { |
135 | OutputDebugStringF( "Load library %s failed, error: %d\n" , pImp->Name, GetLastError()); |
139 | pOrgThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->OriginalFirstThunk); |
140 | pFirstThunk = (PIMAGE_THUNK_DATA)(imagebase + pImp->FirstThunk); |
142 | while (NULL != *( DWORD *)pOrgThunk) { |
143 | if (pOrgThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32) { |
144 | fpFun = GetProcAddress(hInstance, ( LPCSTR )(pOrgThunk->u1.Ordinal & 0x0000ffff)); |
148 | pImportName = (PIMAGE_IMPORT_BY_NAME)(( DWORD )imagebase + ( DWORD )(pOrgThunk->u1.AddressOfData)); |
149 | fpFun = GetProcAddress(hInstance, ( LPCSTR )pImportName->Name); |
151 | pFirstThunk->u1.Ordinal = ( LONG )fpFun; |
155 | FreeLibrary(hInstance); |
166 | BOOL RelocPemodule( LPVOID pFileBuffer, DWORD reImageBase , int offsetReloc) |
175 | PIMAGE_DOS_HEADER pDosHeader = NULL; |
176 | PIMAGE_NT_HEADERS pNTHeader = NULL; |
177 | PIMAGE_FILE_HEADER pPEHeader = NULL; |
178 | PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL; |
179 | PIMAGE_SECTION_HEADER pSectionHeader = NULL; |
180 | PIMAGE_DATA_DIRECTORY DataDirectory=NULL; |
183 | pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; |
184 | pNTHeader = (PIMAGE_NT_HEADERS)(( DWORD )pFileBuffer+pDosHeader->e_lfanew); |
185 | pPEHeader = (PIMAGE_FILE_HEADER)((( DWORD )pNTHeader)+4); |
186 | pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(( DWORD )pPEHeader+IMAGE_SIZEOF_FILE_HEADER); |
187 | pSectionHeader = (PIMAGE_SECTION_HEADER)(( DWORD )pOptionHeader+pPEHeader->SizeOfOptionalHeader); |
190 | DataDirectory = pOptionHeader->DataDirectory; |
193 | printf ( "IMAGE_DIRECTORY_ENTRY_BASERELOC: Address: %x ,Size: %x \n" ,DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress, |
194 | DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size); |
198 | DWORD FoA = RVAToFileOffset(pFileBuffer,0x2df10); |
200 | DWORD BaseReloc_Directory_Address = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress; |
201 | DWORD BaseReloc_Directory_Size = DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; |
202 | FoA = RVAToFileOffset(pFileBuffer,BaseReloc_Directory_Address); |
206 | PIMAGE_BASE_RELOCATION prelocBase = (PIMAGE_BASE_RELOCATION)(( DWORD )pFileBuffer + BaseReloc_Directory_Address); |
209 | DWORD reloca_addr,count, offset, type; |
211 | while (prelocBase->VirtualAddress!=NULL) |
213 | reloca_addr=prelocBase->VirtualAddress+reImageBase; |
214 | count=(prelocBase->SizeOfBlock- sizeof (IMAGE_BASE_RELOCATION))>>1; |
215 | item= ( WORD *)(( char *)prelocBase+ sizeof (IMAGE_BASE_RELOCATION)); |
216 | for ( int i=0; i<( int )count;i++) |
218 | offset = item[i] & 0x0fff ; |
219 | type = item[i] >> 12 ; |
222 | *( DWORD *)(reloca_addr+offset)+=offsetReloc; |
227 | PDWORD myAddress = (PDWORD)(( DWORD )pFileBuffer + changeFoa); |
228 | *myAddress = *myAddress - 0x10000000 + 0x20000000; |
233 | prelocBase=(PIMAGE_BASE_RELOCATION)(item+count); |
239 | BOOL GetProcessImageInfo( LPSTR szExePath, DWORD &ImageBase, DWORD &ImageSize, DWORD &processId) |
241 | HANDLE hProSnapshot =NULL; |
243 | TCHAR szPath[MAX_PATH]; |
244 | HANDLE hModSnapshot=NULL; |
246 | PROCESSENTRY32 pe32={0}; |
247 | MODULEENTRY32 me32 = {0}; |
248 | hProSnapshot =CreateToolhelp32Snapshot(TH32CS_SNAPALL,0); |
249 | if (hProSnapshot==INVALID_HANDLE_VALUE) |
253 | TCHAR szBaseAddr[10]={0}; |
254 | TCHAR szBaseSize[10]={0}; |
257 | pe32.dwSize = sizeof (pe32); |
258 | BOOL fOk =Process32First(hProSnapshot,&pe32); |
259 | for (; fOk; fOk =Process32Next(hProSnapshot,&pe32),dwIdx++) |
263 | if ( strcmp (szExePath,pe32.szExeFile)==0) |
265 | sprintf (szPID, "%d" ,pe32.th32ProcessID); |
266 | processId = atoi (szPID); |
267 | hModSnapshot =CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,pe32.th32ProcessID); |
268 | if (hModSnapshot !=INVALID_HANDLE_VALUE) |
270 | ZeroMemory(&me32, sizeof (me32)); |
271 | me32.dwSize = sizeof (me32); |
272 | if (Module32First(hModSnapshot, &me32) && pe32.th32ProcessID !=0) |
275 | sprintf (szBaseAddr, "%d" ,me32.modBaseAddr); |
276 | sprintf (szBaseSize, "%d" ,me32.modBaseSize); |
277 | sprintf (szPath, "%s" ,pe32.szExeFile); |
278 | ImageBase = atoi (szBaseAddr); |
279 | ImageSize = atoi (szBaseSize); |
285 | OutputDebugStringF( "GetProcessImageInfo: Error.... " ); |
289 | OutputDebugStringF( "GetProcessImageInfo: Error.... " ); |
294 | OutputDebugStringF( "GetProcessImageInfo: Error.... " ); |
300 | VOID InjectEXE( HWND hwndDlg) |
303 | HWND hEditExePath = GetDlgItem(hwndDlg,IDC_EDIT_EXEPATH); |
304 | TCHAR szExePath[256]={0}; |
305 | GetDlgItemText(hwndDlg,IDC_EDIT_EXEPATH,szExePath,256); |
306 | if (szExePath == NULL) |
308 | MessageBox(0, "Exe路径未填写" , "错误01" ,0); |
311 | OutputDebugStringF( "ExePath: %s " ,szExePath); |
315 | si.cb = sizeof (STARTUPINFO); |
316 | si.lpDesktop=TEXT( "gyarmy" ); |
317 | PROCESS_INFORMATION pi={0}; |
329 | OutputDebugStringF( "Process: %d,%d " ,pi.hProcess,pi.hThread); |
332 | DWORD processImageBase = 0; |
333 | DWORD processImageSize = 0; |
336 | BOOL isInfo = GetProcessImageInfo(szExePath,processImageBase,processImageSize,processId); |
338 | MessageBox(0, "Exe没有获取ImageInfo" , "错误02" ,0); |
341 | OutputDebugStringF( "Process: %08X,%08X , %d" ,processImageBase,processImageSize,processId); |
344 | LPVOID pFileBuffer = NULL; |
345 | pFileBuffer = malloc (processImageSize); |
346 | memset (pFileBuffer,0,processImageSize); |
347 | HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false ,processId); |
348 | OutputDebugStringF( "hProcess: %d" ,( DWORD )hProcess); |
353 | MessageBox(0, "打开Exe进程失败" , "错误03" ,0); |
356 | DWORD dwNumberOfBytesRead; |
357 | BOOL isReadAll = ReadProcessMemory(hProcess,( LPCVOID )processImageBase,pFileBuffer,processImageSize,&dwNumberOfBytesRead); |
360 | MessageBox(0, "读取Exe进程失败" , "错误04" ,0); |
365 | RelocPemodule(pFileBuffer,( DWORD )pFileBuffer,( DWORD )pFileBuffer-processImageBase); |
368 | FixImport(pFileBuffer,( DWORD )pFileBuffer); |
372 | DWORD entrypoint = 0; |
373 | GetExeOEP(pFileBuffer,entrypoint); |
375 | int PEStartpoint = ( int )pFileBuffer+( int )entrypoint; |
376 | OutputDebugStringF( "entrypoint: %08X" ,( DWORD )entrypoint); |
377 | OutputDebugStringF( "PEStartpoint: %08X" ,( DWORD )PEStartpoint); |
380 | TerminateProcess(pi.hProcess,0); |
394 | BOOL CALLBACK MainDialogProc( |
405 | SetDlgItemText(hwndDlg,IDC_EDIT_EXEPATH,TEXT( "back.exe" )); |
410 | EndDialog(hwndDlg,0); |
415 | switch (LOWORD(wParam)) |
417 | case IDC_BUTTON_INJECT: |
434 | int APIENTRY WinMain( HINSTANCE hInstance, |
435 | HINSTANCE hPrevInstance, |
440 | EnableDebugPrivilege(TRUE); |
441 | DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG_MAIN),NULL,MainDialogProc); |
源代码下载:
20180129_01.rar
0则评论给“运行内存中的exe(一)”