Changeset 4116 for zzuf/trunk/src
- Timestamp:
- Dec 12, 2009, 11:20:16 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
zzuf/trunk/src/myfork.c
r4115 r4116 51 51 52 52 #if defined HAVE_WINDOWS_H 53 static int dll_inject(void *, void *); 53 static void rep32(uint8_t *buf, void *addr); 54 static int dll_inject(void *, void *, char const *); 54 55 static intptr_t get_base_address(DWORD); 55 56 static intptr_t get_entry_point_offset(char const *); 56 #endif57 58 #if defined HAVE_WINDOWS_H59 static inline void addcpy(void *buf, void *x)60 {61 memcpy(buf, &x, 4);62 }63 57 #endif 64 58 … … 259 253 260 254 /* Insert the replacement code */ 261 ret = dll_inject(pinfo.hProcess, epaddr );255 ret = dll_inject(pinfo.hProcess, epaddr, SONAME); 262 256 if(ret < 0) 263 257 { … … 278 272 279 273 #if defined HAVE_WINDOWS_H 280 static int dll_inject(void *process, void *epaddr) 281 { 282 uint8_t code1[] = /* LIBZZUF: */ 283 "libzzuf.dll\0" 284 /* OLDEP: */ 285 "_______" 286 /* START: */ 287 "\xb8____" /* mov eax,<libzzuf.dll> */ 288 "\x50" /* push eax */ 289 "\xb8____" /* mov eax,<LoadLibraryA> */ 290 "\xff\xd0" /* call eax */ 291 "\xb8\0\0\0\0" /* mov eax,0 */ 292 "\x50" /* push eax */ 293 "\xb8\x07\0\0\0" /* mov eax,7 */ 294 "\x50" /* push eax */ 295 "\xb8____" /* mov eax,<OLDEP> */ 296 "\x50" /* push eax */ 297 "\xb8____" /* mov eax,<NEWEP> */ 298 "\x50" /* push eax */ 299 "\xb8____" /* mov eax,<GetCurrentProcess> */ 300 "\xff\xd0" /* call eax */ 301 "\x50" /* push eax */ 302 "\xb8____" /* mov eax,<WriteProcessMemory> */ 303 "\xff\xd0" /* call eax */ 304 "\xb8____" /* mov eax,<NEWEP> */ 305 "\xff\xe0"; /* jmp eax */ 306 uint8_t code2[] = /* NEWEP: */ 307 "\xb8____" /* mov eax,<START> */ 308 "\xff\xe0"; /* jmp eax */ 309 void *lib; 274 static void rep32(uint8_t *buf, void *addr) 275 { 276 while(buf++) 277 if (memcmp(buf, "____", 4) == 0) 278 { 279 memcpy(buf, &addr, 4); 280 return; 281 } 282 } 283 284 static int dll_inject(void *process, void *epaddr, char const *lib) 285 { 286 static uint8_t const loader[] = 287 /* Load the injected DLL into memory */ 288 "\xb8____" /* mov %eax, <library_name_address> */ 289 "\x50" /* push %eax */ 290 "\xb8____" /* mov %eax, <LoadLibraryA> */ 291 "\xff\xd0" /* call %eax */ 292 /* Restore the clobbered entry point code using our backup */ 293 "\xb8\0\0\0\0" /* mov %eax,0 */ 294 "\x50" /* push %eax */ 295 "\xb8____" /* mov %eax, <jumper_length> */ 296 "\x50" /* push %eax */ 297 "\xb8____" /* mov %eax, <backuped_entry_point_address> */ 298 "\x50" /* push %eax */ 299 "\xb8____" /* mov %eax, <original_entry_point_address> */ 300 "\x50" /* push %eax */ 301 "\xb8____" /* mov %eax, <GetCurrentProcess> */ 302 "\xff\xd0" /* call %eax */ 303 "\x50" /* push %eax */ 304 "\xb8____" /* mov %eax, <WriteProcessMemory> */ 305 "\xff\xd0" /* call %eax */ 306 /* Jump to the original entry point */ 307 "\xb8____" /* mov %eax, <original_entry_point_address> */ 308 "\xff\xe0"; /* jmp %eax */ 309 310 static uint8_t const jumper[] = 311 /* Jump to the injected loader */ 312 "\xb8____" /* mov eax, <loader_address> */ 313 "\xff\xe0"; /* jmp eax */ 314 315 /* code: 316 * +---------------+--------------------+--------------+-------------+ 317 * | loader | entry point backup | library name | jumper | 318 * | len(loader) | len(jumper) | len(lib) | len(jumper) | 319 * +---------------+--------------------+--------------+-------------+ */ 320 uint8_t code[1024]; 321 322 void *kernel32; 310 323 uint8_t *loaderaddr; 324 size_t liblen, loaderlen, jumperlen; 311 325 DWORD tmp; 312 326 313 /* Backup the old entry-point code */ 314 ReadProcessMemory(process, epaddr, code1 + 0x0c, 7, &tmp); 315 if(tmp != 7) 316 return -1; 317 318 /* Copy the first shell code to a freshly allocated memory area. */ 319 loaderaddr = VirtualAllocEx(process, NULL, sizeof(code1), MEM_COMMIT, 320 PAGE_EXECUTE_READWRITE); 327 liblen = strlen(lib) + 1; 328 loaderlen = sizeof(loader) - 1; 329 jumperlen = sizeof(jumper) - 1; 330 if (loaderlen + jumperlen + liblen > 1024) 331 return -1; 332 333 /* Allocate memory in the child for our injected code */ 334 loaderaddr = VirtualAllocEx(process, NULL, loaderlen + jumperlen + liblen, 335 MEM_COMMIT, PAGE_EXECUTE_READWRITE); 321 336 if(!loaderaddr) 322 337 return -1; 323 338 324 lib = LoadLibrary("kernel32.dll"); 325 if(!lib) 326 return -1; 327 328 addcpy(code1 + 0x14, loaderaddr + 0x00); /* offset for dll string */ 329 addcpy(code1 + 0x1a, GetProcAddress(lib, "LoadLibraryA")); 330 addcpy(code1 + 0x2d, loaderaddr + 0x0c); 331 addcpy(code1 + 0x33, epaddr); 332 addcpy(code1 + 0x39, GetProcAddress(lib, "GetCurrentProcess")); 333 addcpy(code1 + 0x41, GetProcAddress(lib, "WriteProcessMemory")); 334 addcpy(code1 + 0x48, epaddr); 335 FreeLibrary(lib); 336 337 WriteProcessMemory(process, loaderaddr, code1, sizeof(code1), &tmp); 338 if(tmp != sizeof(code1)) 339 return -1; 340 341 /* Copy the second shell code where the old entry point was. */ 342 addcpy(code2 + 0x01, loaderaddr + 12 + 7); 343 WriteProcessMemory(process, epaddr, code2, 7, &tmp); 344 if(tmp != 7) 339 /* Create the first shellcode (jumper). 340 * 341 * The jumper's job is simply to jump at the second shellcode's location. 342 * It is written at the original entry point's location, which will in 343 * turn be restored by the second shellcode. 344 */ 345 memcpy(code + loaderlen + jumperlen + liblen, jumper, jumperlen); 346 rep32(code + loaderlen + jumperlen + liblen, loaderaddr); 347 348 /* Create the second shellcode (loader, backuped entry point, and library 349 * name). 350 * 351 * The loader's job is to load the library by calling LoadLibraryA(), 352 * restore the original entry point using the backup copy, and jump 353 * back to the original entry point as if the process had just started. 354 * 355 * The second shellcode is written at a freshly allocated memory location. 356 */ 357 memcpy(code, loader, loaderlen); 358 memcpy(code + loaderlen + jumperlen, lib, liblen); 359 360 /* Backup the old entry point code */ 361 ReadProcessMemory(process, epaddr, code + loaderlen, 362 jumperlen, &tmp); 363 if(tmp != jumperlen) 364 return -1; 365 366 /* FIXME: the GetProcAddress calls assume the library was loaded at 367 * the same address in the child process. This is wrong since Vista 368 * and its address space randomisation. */ 369 kernel32 = LoadLibrary("kernel32.dll"); 370 if(!kernel32) 371 return -1; 372 373 rep32(code, loaderaddr + loaderlen + jumperlen); 374 rep32(code, GetProcAddress(kernel32, "LoadLibraryA")); 375 rep32(code, (void *)(uintptr_t)jumperlen); 376 rep32(code, loaderaddr + loaderlen); 377 rep32(code, epaddr); 378 rep32(code, GetProcAddress(kernel32, "GetCurrentProcess")); 379 rep32(code, GetProcAddress(kernel32, "WriteProcessMemory")); 380 rep32(code, epaddr); 381 FreeLibrary(kernel32); 382 383 /* Write our shellcodes into the target process */ 384 WriteProcessMemory(process, epaddr, code + loaderlen + jumperlen + liblen, 385 jumperlen, &tmp); 386 if(tmp != jumperlen) 387 return -1; 388 389 WriteProcessMemory(process, loaderaddr, code, 390 loaderlen + jumperlen + liblen, &tmp); 391 if(tmp != loaderlen + jumperlen + liblen) 345 392 return -1; 346 393
Note: See TracChangeset
for help on using the changeset viewer.