@@ -70,6 +70,13 @@ struct ExportNameEntry {
7070typedef BOOL (WINAPI * DllEntryProc )(HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpReserved );
7171typedef int (WINAPI * ExeEntryProc )(void );
7272
73+ #ifdef _WIN64
74+ typedef struct POINTER_LIST {
75+ struct POINTER_LIST * next ;
76+ void * address ;
77+ } POINTER_LIST ;
78+ #endif
79+
7380typedef struct {
7481 PIMAGE_NT_HEADERS headers ;
7582 unsigned char * codeBase ;
@@ -87,6 +94,9 @@ typedef struct {
8794 void * userdata ;
8895 ExeEntryProc exeEntry ;
8996 DWORD pageSize ;
97+ #ifdef _WIN64
98+ POINTER_LIST * blockedMemory ;
99+ #endif
90100} MEMORYMODULE , * PMEMORYMODULE ;
91101
92102typedef struct {
@@ -137,6 +147,21 @@ OutputLastError(const char *msg)
137147#endif
138148}
139149
150+ #ifdef _WIN64
151+ static void
152+ FreePointerList (POINTER_LIST * head , CustomFreeFunc freeMemory , void * userdata )
153+ {
154+ POINTER_LIST * node = head ;
155+ while (node ) {
156+ POINTER_LIST * next ;
157+ freeMemory (node -> address , 0 , MEM_RELEASE , userdata );
158+ next = node -> next ;
159+ free (node );
160+ node = next ;
161+ }
162+ }
163+ #endif
164+
140165static BOOL
141166CheckSize (size_t size , size_t expected ) {
142167 if (size < expected ) {
@@ -535,6 +560,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
535560 size_t optionalSectionSize ;
536561 size_t lastSectionEnd = 0 ;
537562 size_t alignedImageSize ;
563+ #ifdef _WIN64
564+ POINTER_LIST * blockedMemory = NULL ;
565+ #endif
538566
539567 if (!CheckSize (size , sizeof (IMAGE_DOS_HEADER ))) {
540568 return NULL ;
@@ -610,9 +638,40 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
610638 }
611639 }
612640
641+ #ifdef _WIN64
642+ // Memory block may not span 4 GB boundaries.
643+ while ((((uintptr_t ) code ) >> 32 ) < (((uintptr_t ) (code + alignedImageSize )) >> 32 )) {
644+ POINTER_LIST * node = (POINTER_LIST * ) malloc (sizeof (POINTER_LIST ));
645+ if (!node ) {
646+ freeMemory (code , 0 , MEM_RELEASE , userdata );
647+ FreePointerList (blockedMemory , freeMemory , userdata );
648+ SetLastError (ERROR_OUTOFMEMORY );
649+ return NULL ;
650+ }
651+
652+ node -> next = blockedMemory ;
653+ node -> address = code ;
654+ blockedMemory = node ;
655+
656+ code = (unsigned char * )allocMemory (NULL ,
657+ alignedImageSize ,
658+ MEM_RESERVE | MEM_COMMIT ,
659+ PAGE_READWRITE ,
660+ userdata );
661+ if (code == NULL ) {
662+ FreePointerList (blockedMemory , freeMemory , userdata );
663+ SetLastError (ERROR_OUTOFMEMORY );
664+ return NULL ;
665+ }
666+ }
667+ #endif
668+
613669 result = (PMEMORYMODULE )HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY , sizeof (MEMORYMODULE ));
614670 if (result == NULL ) {
615671 freeMemory (code , 0 , MEM_RELEASE , userdata );
672+ #ifdef _WIN64
673+ FreePointerList (blockedMemory , freeMemory , userdata );
674+ #endif
616675 SetLastError (ERROR_OUTOFMEMORY );
617676 return NULL ;
618677 }
@@ -626,6 +685,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
626685 result -> freeLibrary = freeLibrary ;
627686 result -> userdata = userdata ;
628687 result -> pageSize = sysInfo .dwPageSize ;
688+ #ifdef _WIN64
689+ result -> blockedMemory = blockedMemory ;
690+ #endif
629691
630692 if (!CheckSize (size , old_header -> OptionalHeader .SizeOfHeaders )) {
631693 goto error ;
@@ -823,6 +885,9 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
823885 module -> free (module -> codeBase , 0 , MEM_RELEASE , module -> userdata );
824886 }
825887
888+ #ifdef _WIN64
889+ FreePointerList (module -> blockedMemory , module -> free , module -> userdata );
890+ #endif
826891 HeapFree (GetProcessHeap (), 0 , module );
827892}
828893
0 commit comments