码迷,mamicode.com
首页 > 其他好文 > 详细

PE注入

时间:2016-10-11 21:01:59      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:

技术分享
  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             else
337 
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注入

标签:

原文地址:http://www.cnblogs.com/yifi/p/5950622.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!