44#include < tchar.h>
55#include " rtltype.h"
66#include " ntstatus.h"
7+ #include " Native.h"
78#include < algorithm>
89
910#if _MSC_VER
@@ -134,7 +135,7 @@ static BOOL CheckSize(size_t size, size_t expected) {
134135 return TRUE ;
135136}
136137
137- static BOOL CopySections (const unsigned char * data, size_t size, PMEMORYMODULE module ) {
138+ static BOOL CopySections (const unsigned char * data, PMEMORYMODULE module ) {
138139 LPBYTE codeBase = module ->codeBase ;
139140 LPVOID dest;
140141 PIMAGE_NT_HEADERS headers = GetImageNtHeaders (module );
@@ -145,7 +146,12 @@ static BOOL CopySections(const unsigned char* data, size_t size, PMEMORYMODULE m
145146 alloc_size = headers->OptionalHeader .SectionAlignment ;
146147 cp = false ;
147148 if (section->SizeOfRawData ) {
148- if (!CheckSize (size, static_cast <size_t >(section->PointerToRawData ) + section->SizeOfRawData )) return FALSE ;
149+ __try {
150+ ProbeForRead (data, static_cast <size_t >(section->PointerToRawData ) + section->SizeOfRawData );
151+ }
152+ __except (EXCEPTION_EXECUTE_HANDLER) {
153+ return FALSE ;
154+ }
149155 alloc_size = section->SizeOfRawData ;
150156 cp = true ;
151157 }
@@ -354,15 +360,23 @@ static BOOL BuildImportTable(PMEMORYMODULE module) {
354360 return result;
355361}
356362
357- HMEMORYMODULE MemoryLoadLibrary (const void * data, size_t size) {
363+ // static BOOL PerformForwardExport(PMEMORYMODULE module) {
364+ // PIMAGE_EXPORT_DIRECTORY exports;
365+ // PIMAGE_NT_HEADERS headers = GetImageNtHeaders(module);
366+ // PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(headers, IMAGE_DIRECTORY_ENTRY_EXPORT);
367+ // if (!directory->Size)return TRUE;
368+ // return FALSE;
369+ //
370+ // }
371+
372+ HMEMORYMODULE MemoryLoadLibrary (const void * data) {
358373 PMEMORYMODULE hMemoryModule = nullptr ;
359374 PIMAGE_DOS_HEADER dos_header, new_dos_header;
360375 PIMAGE_NT_HEADERS old_header, new_header;
361- unsigned char * code ;
376+ unsigned char * base ;
362377 ptrdiff_t locationDelta;
363- SYSTEM_INFO sysInfo;
378+ static SYSTEM_INFO sysInfo{} ;
364379 PIMAGE_SECTION_HEADER section;
365- DWORD i;
366380 size_t optionalSectionSize;
367381 size_t lastSectionEnd = 0 ;
368382 size_t alignedImageSize;
@@ -371,40 +385,36 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
371385 POINTER_LIST* blockedMemory = nullptr ;
372386#endif
373387
374- if (!CheckSize (size, sizeof (IMAGE_DOS_HEADER))) return nullptr ;
375- dos_header = (PIMAGE_DOS_HEADER)data;
376- if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
377- SetLastError (ERROR_BAD_EXE_FORMAT);
378- return nullptr ;
379- }
380-
381- if (!CheckSize (size, dos_header->e_lfanew + sizeof (IMAGE_NT_HEADERS))) return nullptr ;
382- old_header = (PIMAGE_NT_HEADERS) & ((const unsigned char *)(data))[dos_header->e_lfanew ];
383- if (old_header->Signature != IMAGE_NT_SIGNATURE) {
384- SetLastError (ERROR_BAD_EXE_FORMAT);
385- return nullptr ;
386- }
387-
388- if (old_header->FileHeader .Machine != HOST_MACHINE) {
389- SetLastError (ERROR_BAD_EXE_FORMAT);
390- return nullptr ;
391- }
392-
393- if (old_header->OptionalHeader .SectionAlignment & 1 ) {
394- // Only support section alignments that are a multiple of 2
395- SetLastError (ERROR_BAD_EXE_FORMAT);
396- return nullptr ;
388+ __try {
389+ ProbeForRead (data, sizeof (IMAGE_DOS_HEADER));
390+ dos_header = (PIMAGE_DOS_HEADER)data;
391+ if (dos_header->e_magic != IMAGE_DOS_SIGNATURE) {
392+ SetLastError (ERROR_BAD_EXE_FORMAT);
393+ return nullptr ;
394+ }
395+ ProbeForRead (data, dos_header->e_lfanew + sizeof (IMAGE_NT_HEADERS));
396+ old_header = (PIMAGE_NT_HEADERS)((size_t )data + dos_header->e_lfanew );
397+ if (old_header->Signature != IMAGE_NT_SIGNATURE ||
398+ !ProbeForRead (data, old_header->OptionalHeader .SizeOfHeaders ) ||
399+ old_header->FileHeader .Machine != HOST_MACHINE ||
400+ old_header->OptionalHeader .SectionAlignment & 1 ) {
401+ SetLastError (ERROR_BAD_EXE_FORMAT);
402+ return nullptr ;
403+ }
404+ // only dll image support
405+ if (!(old_header->FileHeader .Characteristics & IMAGE_FILE_DLL)) {
406+ SetLastError (ERROR_NOT_SUPPORTED);
407+ return nullptr ;
408+ }
397409 }
398-
399- // only dll image support
400- if (!(old_header->FileHeader .Characteristics & IMAGE_FILE_DLL)) {
401- SetLastError (ERROR_NOT_SUPPORTED);
410+ __except (EXCEPTION_EXECUTE_HANDLER) {
411+ SetLastError (ERROR_INVALID_DATA);
402412 return nullptr ;
403413 }
404-
414+
405415 section = IMAGE_FIRST_SECTION (old_header);
406416 optionalSectionSize = old_header->OptionalHeader .SectionAlignment ;
407- for (i = 0 ; i < old_header->FileHeader .NumberOfSections ; i++, section++) {
417+ for (DWORD i = 0 ; i < old_header->FileHeader .NumberOfSections ; i++, section++) {
408418 size_t endOfSection;
409419 if (section->SizeOfRawData == 0 ) {
410420 // Section without data in the DLL
@@ -419,7 +429,7 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
419429 }
420430 }
421431
422- GetNativeSystemInfo (&sysInfo);
432+ if (!sysInfo. dwPageSize ) GetNativeSystemInfo (&sysInfo);
423433 alignedImageSize = AlignValueUp (old_header->OptionalHeader .SizeOfImage , sysInfo.dwPageSize );
424434 if (alignedImageSize != AlignValueUp (lastSectionEnd, sysInfo.dwPageSize )) {
425435 SetLastError (ERROR_BAD_EXE_FORMAT);
@@ -430,45 +440,45 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
430440 // reserve memory for image of library
431441 // XXX: is it correct to commit the complete memory region at once?
432442 // calling DllEntry raises an exception if we don't...
433- if (!(code = (LPBYTE)VirtualAlloc ((LPVOID)(old_header->OptionalHeader .ImageBase ), alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
443+ if (!(base = (LPBYTE)VirtualAlloc ((LPVOID)(old_header->OptionalHeader .ImageBase ), alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
434444 if (!(old_header->OptionalHeader .DllCharacteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE)) {
435445 SetLastError (ERROR_BAD_EXE_FORMAT);
436446 return nullptr ;
437447 }
438- if (!(code = (LPBYTE)VirtualAlloc (nullptr , alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
448+ if (!(base = (LPBYTE)VirtualAlloc (nullptr , alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
439449 SetLastError (ERROR_OUTOFMEMORY);
440450 return nullptr ;
441451 }
442452 }
443453
444454#ifdef _WIN64
445455 // Memory block may not span 4 GB boundaries.
446- while ((((uintptr_t )code ) >> 32 ) < (((uintptr_t )(code + alignedImageSize)) >> 32 )) {
456+ while ((((uintptr_t )base ) >> 32 ) < (((uintptr_t )(base + alignedImageSize)) >> 32 )) {
447457 POINTER_LIST* node = new POINTER_LIST;
448458 if (!node) {
449- VirtualFree (code , 0 , MEM_RELEASE);
459+ VirtualFree (base , 0 , MEM_RELEASE);
450460 FreePointerList (blockedMemory);
451461 SetLastError (ERROR_OUTOFMEMORY);
452462 return nullptr ;
453463 }
454464
455465 node->next = blockedMemory;
456- node->address = code ;
466+ node->address = base ;
457467 blockedMemory = node;
458468
459- if (!(code = (LPBYTE)VirtualAlloc (nullptr , alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
469+ if (!(base = (LPBYTE)VirtualAlloc (nullptr , alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE))) {
460470 FreePointerList (blockedMemory);
461471 SetLastError (ERROR_OUTOFMEMORY);
462472 return nullptr ;
463473 }
464474 }
465475#endif
466476
467- new_dos_header = (PIMAGE_DOS_HEADER)code ;
468- new_header = (PIMAGE_NT_HEADERS)(code + dos_header->e_lfanew );
469- hMemoryModule = (PMEMORYMODULE)(code + old_header->OptionalHeader .SizeOfHeaders );
477+ new_dos_header = (PIMAGE_DOS_HEADER)base ;
478+ new_header = (PIMAGE_NT_HEADERS)(base + dos_header->e_lfanew );
479+ hMemoryModule = (PMEMORYMODULE)(base + old_header->OptionalHeader .SizeOfHeaders );
470480 RtlZeroMemory (hMemoryModule, sizeof (MEMORYMODULE));
471- hMemoryModule->codeBase = code ;
481+ hMemoryModule->codeBase = base ;
472482 hMemoryModule->pageSize = sysInfo.dwPageSize ;
473483 hMemoryModule->Signature = MEMORY_MODULE_SIGNATURE;
474484 hMemoryModule->SizeofHeaders = old_header->OptionalHeader .SizeOfHeaders ;
@@ -477,18 +487,14 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
477487 hMemoryModule->blockedMemory = blockedMemory;
478488#endif
479489
480- if (!CheckSize (size, old_header->OptionalHeader .SizeOfHeaders )) {
481- goto error;
482- }
483-
484490 // copy PE header to code
485491 memcpy (new_dos_header, dos_header, old_header->OptionalHeader .SizeOfHeaders );
486492 new_header->OptionalHeader .SizeOfImage = (DWORD)(alignedImageSize);
487- new_header->OptionalHeader .ImageBase = (size_t )code ;
493+ new_header->OptionalHeader .ImageBase = (size_t )base ;
488494 new_header->OptionalHeader .BaseOfCode = headers_align;
489495
490496 // copy sections from DLL file block to new memory location
491- if (!CopySections ((LPBYTE)data, size, hMemoryModule)) goto error;
497+ if (!CopySections ((LPBYTE)data, hMemoryModule)) goto error;
492498
493499 // adjust base address of imported data
494500 locationDelta = (ptrdiff_t )(hMemoryModule->codeBase - old_header->OptionalHeader .ImageBase );
@@ -509,7 +515,7 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
509515 if (new_header->OptionalHeader .AddressOfEntryPoint ) {
510516 __try {
511517 // notify library about attaching to process
512- if (!((DllEntryProc)(code + new_header->OptionalHeader .AddressOfEntryPoint ))((HINSTANCE)code , DLL_PROCESS_ATTACH, 0 )) {
518+ if (!((DllEntryProc)(base + new_header->OptionalHeader .AddressOfEntryPoint ))((HINSTANCE)base , DLL_PROCESS_ATTACH, 0 )) {
513519 SetLastError (ERROR_DLL_INIT_FAILED);
514520 goto error;
515521 }
@@ -521,7 +527,7 @@ HMEMORYMODULE MemoryLoadLibrary(const void* data, size_t size) {
521527 hMemoryModule->initialized = TRUE ;
522528 }
523529
524- return code ;
530+ return base ;
525531error:
526532 // cleanup
527533 MemoryFreeLibrary (hMemoryModule);
0 commit comments