首页 > 代码库 > PE注入

PE注入

技术分享
  1 // PE注入.cpp : 定义控制台应用程序的入口点。  2 //  3   4 #include "stdafx.h"  5   6 #include <windows.h>  7   8 #include <tlhelp32.h>  9  10 #include <process.h> 11  12 #include <stdio.h> 13  14  15  16 #pragma comment (lib, "winmm.lib") 17  18  19 #pragma comment (lib, "kernel32.lib") 20  21 /*获取进程ID号*/ 22  23 DWORD GetProcessIdByName(LPWSTR name) 24  25 { 26  27     PROCESSENTRY32 pe32; 28  29     HANDLE snapshot = NULL; 30  31     DWORD pid = 0; 32  33  34  35     snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 36  37     if (snapshot != INVALID_HANDLE_VALUE) 38  39     { 40  41         pe32.dwSize = sizeof(PROCESSENTRY32); 42  43         if (Process32First(snapshot, &pe32)) 44  45         { 46  47             do 48  49             { 50  51                 if (!lstrcmp(pe32.szExeFile, name)) 52  53                 { 54  55                     pid = pe32.th32ProcessID; 56  57                     break; 58  59                 } 60  61             } while (Process32Next(snapshot, &pe32)); 62  63         } 64  65         CloseHandle(snapshot); 66  67     } 68  69     return pid; 70  71 } 72  73 extern "C" void mainCRTStartup(); 74 DWORD main(); 75  76 /** 77   78  * 远程进程内存中注入PE 79    80   */ 81  82 HMODULE injectModule(HANDLE proc, LPVOID module) 83  84  85  86 { 87  88  89     DWORD i = 0; 90  91     DWORD_PTR delta = NULL; 92  93     DWORD_PTR olddelta = NULL; 94  95     /* 获取模块PE头 */ 96  97     PIMAGE_NT_HEADERS headers = (PIMAGE_NT_HEADERS)((LPBYTE)module + ((PIMAGE_DOS_HEADER)module)->e_lfanew); 98  99     PIMAGE_DATA_DIRECTORY datadir;100 101 102 103     /* 计算注入代码长度 */104 105     DWORD moduleSize = headers->OptionalHeader.SizeOfImage;106 107     LPVOID distantModuleMemorySpace = NULL;108 109     LPBYTE tmpBuffer = NULL;110 111     BOOL ok = FALSE;112 113     if (headers->Signature != IMAGE_NT_SIGNATURE)114 115         return NULL;116 117     if (IsBadReadPtr(module, moduleSize))118 119         return NULL;120 121     distantModuleMemorySpace = VirtualAllocEx(proc, NULL, moduleSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);122 123     if (distantModuleMemorySpace != NULL)124 125     {126 127         tmpBuffer = (LPBYTE)VirtualAlloc(NULL, moduleSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);128 129         if (tmpBuffer != NULL)130 131         {132 133             RtlCopyMemory(tmpBuffer, module, moduleSize);134 135             datadir = &headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];136 137             if (datadir->Size > 0 && datadir->VirtualAddress > 0)138 139             {140 141                 delta = (DWORD_PTR)((LPBYTE)distantModuleMemorySpace - headers->OptionalHeader.ImageBase);142 143 144 145                 olddelta = (DWORD_PTR)((LPBYTE)module - headers->OptionalHeader.ImageBase);146 147 148 149 150 151                 PIMAGE_BASE_RELOCATION reloc = (PIMAGE_BASE_RELOCATION)(tmpBuffer + datadir->VirtualAddress);152 153 154 155                 while (reloc->VirtualAddress != 0)156 157                 {158 159                     if (reloc->SizeOfBlock >= sizeof(IMAGE_BASE_RELOCATION))160 161                     {162 163                         DWORD relocDescNb = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);164 165 166 167                         LPWORD relocDescList = (LPWORD)((LPBYTE)reloc + sizeof(IMAGE_BASE_RELOCATION));168 169 170 171                         for (i = 0; i < relocDescNb; i++)172 173                         {174 175                             if (relocDescList[i] > 0)176 177                             {178 179                                 DWORD_PTR *p = (DWORD_PTR *)(tmpBuffer + (reloc->VirtualAddress + (0x0FFF & (relocDescList[i]))));180 181 182 183                                 *p -= olddelta;184 185                                 *p += delta;186 187                             }188 189                         }190 191                     }192 193                     reloc = (PIMAGE_BASE_RELOCATION)((LPBYTE)reloc + reloc->SizeOfBlock);194 195                 }196 197 198 199                 tmpBuffer[(DWORD)main - (DWORD)module] = 0x55;200 201 202 203                 ok = WriteProcessMemory(proc, distantModuleMemorySpace, tmpBuffer, moduleSize, NULL);204 205             }206 207             VirtualFree(tmpBuffer, 0, MEM_RELEASE);208 209         }210 211 212 213         if (!ok)214 215 216 217         {218 219 220             VirtualFreeEx(proc, distantModuleMemorySpace, 0, MEM_RELEASE);221 222             distantModuleMemorySpace = NULL;223 224         }225 226     }227 228     return (HMODULE)distantModuleMemorySpace;229 230 }231 232 233 /**234  235  * 获取DEBUG权限236   237   */238 239 BOOL EnableDebugPrivileges(void)240 241 {242 243     HANDLE token;244 245     TOKEN_PRIVILEGES priv;246 247     BOOL ret = FALSE;248 249 250 251     if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token))252 253     {254 255         priv.PrivilegeCount = 1;256 257         priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;258 259 260 261         if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid) != FALSE &&262 263             AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, NULL) != FALSE)264 265         {266 267             ret = TRUE;268 269         }270 271         CloseHandle(token);272 273     }274 275     return ret;276 277 }278 279 BOOL peInjection(DWORD pid, LPTHREAD_START_ROUTINE callRoutine)280 281 {282 283     HANDLE proc, thread;284 285     HMODULE module, injectedModule;286 287 288 289     BOOL result = FALSE;290 291 292 293 294     proc = OpenProcess(PROCESS_CREATE_THREAD |295 296         PROCESS_QUERY_INFORMATION |297 298         PROCESS_VM_OPERATION |299 300         PROCESS_VM_WRITE |301 302         PROCESS_VM_READ,303 304         FALSE,305 306         pid);307 308 309 310     if (proc != NULL)311 312     {313 314         module = GetModuleHandle(NULL);315 316         injectedModule = (HMODULE)injectModule(proc, module);317 318         if (injectedModule != NULL)319 320         {321 322             LPTHREAD_START_ROUTINE remoteThread = (LPTHREAD_START_ROUTINE)((LPBYTE)injectedModule + (DWORD_PTR)((LPBYTE)callRoutine - (LPBYTE)module));323 324             thread = CreateRemoteThread(proc, NULL, 0, remoteThread, NULL, 0, NULL);325 326             if (thread != NULL)327 328             {329 330                 CloseHandle(thread);331 332                 result = TRUE;333 334             }335 336             else337 338             {339 340                 VirtualFreeEx(proc, module, 0, MEM_RELEASE);341 342             }343 344         }345 346         CloseHandle(proc);347 348     }349 350     return result;351 352 }353 354 DWORD WINAPI entryThread(LPVOID param)355 356 {357 358 359 360     DWORD newModuleD = (DWORD)param;361 362 363     MessageBox(NULL, L"Injection success.Now initializing runtime library.", NULL, 0);364 365     //mainCRTStartup();366 367     MessageBox(NULL, L"This will never be called.", NULL, 0);368 369     return 0;370 371 }372 373 void entryPoint()374 375 {376 377     MessageBox(NULL, L"entryPoint", NULL, 0);378 379     EnableDebugPrivileges();380 381 382 383     //peInjection(GetProcessIdByName(L"explorer.exe"), entryThread);384     peInjection( 6384, entryThread);385 386 }387 DWORD main()388 389 {390 391     //MessageBox(NULL, L"In Main ", NULL, 0);392 393     printf("This printf can work because runtime library is now initialized.\n");394     entryPoint();395 396 397 398 399     //(NULL, L"In main end", NULL, 0);400 401     ExitThread(0);402 403     return 0;404 405 }406 407  
View Code

通过此方法可将一个进程的完整镜像完全注入到另外一个进程的内存空间中,从而在一个进程空间中包含了两套不同的代码。与DLL注入相比,PE注入的主要优势是不需要很多文件,只需要MAIN.EXE注入到其他进程并唤起自身代码即可。

PE注入