Skip to content

Commit 9e29595

Browse files
committed
Prevent memory of library from spanning over 4GB bounaries.
Based on code from fancycode#67 / fancycode#79, fixes fancycode#63.
1 parent 55577d9 commit 9e29595

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

MemoryModule.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ struct ExportNameEntry {
7070
typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
7171
typedef 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+
7380
typedef 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

92102
typedef 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+
140165
static BOOL
141166
CheckSize(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

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy