@@ -70,6 +70,13 @@ struct ExportNameEntry {
70
70
typedef BOOL (WINAPI * DllEntryProc )(HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpReserved );
71
71
typedef int (WINAPI * ExeEntryProc )(void );
72
72
73
+ #ifdef _WIN64
74
+ typedef struct POINTER_LIST {
75
+ struct POINTER_LIST * next ;
76
+ void * address ;
77
+ } POINTER_LIST ;
78
+ #endif
79
+
73
80
typedef struct {
74
81
PIMAGE_NT_HEADERS headers ;
75
82
unsigned char * codeBase ;
@@ -87,6 +94,9 @@ typedef struct {
87
94
void * userdata ;
88
95
ExeEntryProc exeEntry ;
89
96
DWORD pageSize ;
97
+ #ifdef _WIN64
98
+ POINTER_LIST * blockedMemory ;
99
+ #endif
90
100
} MEMORYMODULE , * PMEMORYMODULE ;
91
101
92
102
typedef struct {
@@ -137,6 +147,21 @@ OutputLastError(const char *msg)
137
147
#endif
138
148
}
139
149
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
+
140
165
static BOOL
141
166
CheckSize (size_t size , size_t expected ) {
142
167
if (size < expected ) {
@@ -535,6 +560,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
535
560
size_t optionalSectionSize ;
536
561
size_t lastSectionEnd = 0 ;
537
562
size_t alignedImageSize ;
563
+ #ifdef _WIN64
564
+ POINTER_LIST * blockedMemory = NULL ;
565
+ #endif
538
566
539
567
if (!CheckSize (size , sizeof (IMAGE_DOS_HEADER ))) {
540
568
return NULL ;
@@ -610,9 +638,40 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
610
638
}
611
639
}
612
640
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
+
613
669
result = (PMEMORYMODULE )HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY , sizeof (MEMORYMODULE ));
614
670
if (result == NULL ) {
615
671
freeMemory (code , 0 , MEM_RELEASE , userdata );
672
+ #ifdef _WIN64
673
+ FreePointerList (blockedMemory , freeMemory , userdata );
674
+ #endif
616
675
SetLastError (ERROR_OUTOFMEMORY );
617
676
return NULL ;
618
677
}
@@ -626,6 +685,9 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
626
685
result -> freeLibrary = freeLibrary ;
627
686
result -> userdata = userdata ;
628
687
result -> pageSize = sysInfo .dwPageSize ;
688
+ #ifdef _WIN64
689
+ result -> blockedMemory = blockedMemory ;
690
+ #endif
629
691
630
692
if (!CheckSize (size , old_header -> OptionalHeader .SizeOfHeaders )) {
631
693
goto error ;
@@ -823,6 +885,9 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
823
885
module -> free (module -> codeBase , 0 , MEM_RELEASE , module -> userdata );
824
886
}
825
887
888
+ #ifdef _WIN64
889
+ FreePointerList (module -> blockedMemory , module -> free , module -> userdata );
890
+ #endif
826
891
HeapFree (GetProcessHeap (), 0 , module );
827
892
}
828
893
0 commit comments