|
49 | 49 |
|
50 | 50 | #include "MemoryModule.h" |
51 | 51 |
|
| 52 | +typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); |
| 53 | +typedef int (WINAPI *ExeEntryProc)(void); |
| 54 | + |
52 | 55 | typedef struct { |
53 | 56 | PIMAGE_NT_HEADERS headers; |
54 | 57 | unsigned char *codeBase; |
55 | 58 | HCUSTOMMODULE *modules; |
56 | 59 | int numModules; |
57 | 60 | int initialized; |
| 61 | + int isDLL; |
| 62 | + int isRelocated; |
58 | 63 | CustomLoadLibraryFunc loadLibrary; |
59 | 64 | CustomGetProcAddressFunc getProcAddress; |
60 | 65 | CustomFreeLibraryFunc freeLibrary; |
61 | 66 | void *userdata; |
| 67 | + ExeEntryProc exeEntry; |
62 | 68 | } MEMORYMODULE, *PMEMORYMODULE; |
63 | 69 |
|
64 | | -typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); |
65 | | - |
66 | 70 | #define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx] |
67 | 71 |
|
68 | 72 | #ifdef DEBUG_OUTPUT |
@@ -202,11 +206,12 @@ ExecuteTLS(PMEMORYMODULE module) |
202 | 206 | } |
203 | 207 | } |
204 | 208 |
|
205 | | -static void |
| 209 | +static int |
206 | 210 | PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta) |
207 | 211 | { |
208 | 212 | DWORD i; |
209 | 213 | unsigned char *codeBase = module->codeBase; |
| 214 | + int result = 0; |
210 | 215 |
|
211 | 216 | PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_BASERELOC); |
212 | 217 | if (directory->Size > 0) { |
@@ -254,7 +259,9 @@ PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta) |
254 | 259 | // advance to next relocation block |
255 | 260 | relocation = (PIMAGE_BASE_RELOCATION) (((char *) relocation) + relocation->SizeOfBlock); |
256 | 261 | } |
| 262 | + result = 1; |
257 | 263 | } |
| 264 | + return result; |
258 | 265 | } |
259 | 266 |
|
260 | 267 | static int |
@@ -355,7 +362,6 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, |
355 | 362 | PIMAGE_NT_HEADERS old_header; |
356 | 363 | unsigned char *code, *headers; |
357 | 364 | SIZE_T locationDelta; |
358 | | - DllEntryProc DllEntry; |
359 | 365 | BOOL successfull; |
360 | 366 |
|
361 | 367 | dos_header = (PIMAGE_DOS_HEADER)data; |
@@ -410,6 +416,7 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, |
410 | 416 | result->numModules = 0; |
411 | 417 | result->modules = NULL; |
412 | 418 | result->initialized = 0; |
| 419 | + result->isDLL = (old_header->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0; |
413 | 420 | result->loadLibrary = loadLibrary; |
414 | 421 | result->getProcAddress = getProcAddress; |
415 | 422 | result->freeLibrary = freeLibrary; |
@@ -434,7 +441,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, |
434 | 441 | // adjust base address of imported data |
435 | 442 | locationDelta = (SIZE_T)(code - old_header->OptionalHeader.ImageBase); |
436 | 443 | if (locationDelta != 0) { |
437 | | - PerformBaseRelocation(result, locationDelta); |
| 444 | + result->isRelocated = PerformBaseRelocation(result, locationDelta); |
| 445 | + } else { |
| 446 | + result->isRelocated = 1; |
438 | 447 | } |
439 | 448 |
|
440 | 449 | // load required dlls and adjust function table of imports |
@@ -451,14 +460,20 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, |
451 | 460 |
|
452 | 461 | // get entry point of loaded library |
453 | 462 | if (result->headers->OptionalHeader.AddressOfEntryPoint != 0) { |
454 | | - DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); |
455 | | - // notify library about attaching to process |
456 | | - successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); |
457 | | - if (!successfull) { |
458 | | - SetLastError(ERROR_DLL_INIT_FAILED); |
459 | | - goto error; |
| 463 | + if (result->isDLL) { |
| 464 | + DllEntryProc DllEntry = (DllEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); |
| 465 | + // notify library about attaching to process |
| 466 | + successfull = (*DllEntry)((HINSTANCE)code, DLL_PROCESS_ATTACH, 0); |
| 467 | + if (!successfull) { |
| 468 | + SetLastError(ERROR_DLL_INIT_FAILED); |
| 469 | + goto error; |
| 470 | + } |
| 471 | + result->initialized = 1; |
| 472 | + } else { |
| 473 | + result->exeEntry = (ExeEntryProc) (code + result->headers->OptionalHeader.AddressOfEntryPoint); |
460 | 474 | } |
461 | | - result->initialized = 1; |
| 475 | + } else { |
| 476 | + result->exeEntry = NULL; |
462 | 477 | } |
463 | 478 |
|
464 | 479 | return (HMEMORYMODULE)result; |
@@ -549,6 +564,17 @@ void MemoryFreeLibrary(HMEMORYMODULE mod) |
549 | 564 | } |
550 | 565 | } |
551 | 566 |
|
| 567 | +int MemoryCallEntryPoint(HMEMORYMODULE mod) |
| 568 | +{ |
| 569 | + PMEMORYMODULE module = (PMEMORYMODULE)mod; |
| 570 | + |
| 571 | + if (module == NULL || module->isDLL || module->exeEntry == NULL || !module->isRelocated) { |
| 572 | + return -1; |
| 573 | + } |
| 574 | + |
| 575 | + return module->exeEntry(); |
| 576 | +} |
| 577 | + |
552 | 578 | #define DEFAULT_LANGUAGE MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL) |
553 | 579 |
|
554 | 580 | HMEMORYRSRC MemoryFindResource(HMEMORYMODULE module, LPCTSTR name, LPCTSTR type) |
|