Skip to content

Commit 4b3d2a0

Browse files
committed
Merge pull request #33 from joankaradimov/custom-alloc-and-free
Pass alloc/free functions to MemoryLoadLibraryEx
2 parents d88817f + a1fb42d commit 4b3d2a0

File tree

3 files changed

+249
-31
lines changed

3 files changed

+249
-31
lines changed

MemoryModule.c

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ typedef struct {
5656
BOOL initialized;
5757
BOOL isDLL;
5858
BOOL isRelocated;
59+
CustomAllocFunc alloc;
60+
CustomFreeFunc free;
5961
CustomLoadLibraryFunc loadLibrary;
6062
CustomGetProcAddressFunc getProcAddress;
6163
CustomFreeLibraryFunc freeLibrary;
@@ -115,10 +117,11 @@ CopySections(const unsigned char *data, size_t size, PIMAGE_NT_HEADERS old_heade
115117
// uninitialized data
116118
section_size = old_headers->OptionalHeader.SectionAlignment;
117119
if (section_size > 0) {
118-
dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
120+
dest = (unsigned char *)module->alloc(codeBase + section->VirtualAddress,
119121
section_size,
120122
MEM_COMMIT,
121-
PAGE_READWRITE);
123+
PAGE_READWRITE,
124+
module->userdata);
122125
if (dest == NULL) {
123126
return FALSE;
124127
}
@@ -139,10 +142,11 @@ CopySections(const unsigned char *data, size_t size, PIMAGE_NT_HEADERS old_heade
139142
}
140143

141144
// commit memory block and copy data from dll
142-
dest = (unsigned char *)VirtualAlloc(codeBase + section->VirtualAddress,
145+
dest = (unsigned char *)module->alloc(codeBase + section->VirtualAddress,
143146
section->SizeOfRawData,
144147
MEM_COMMIT,
145-
PAGE_READWRITE);
148+
PAGE_READWRITE,
149+
module->userdata);
146150
if (dest == NULL) {
147151
return FALSE;
148152
}
@@ -202,7 +206,7 @@ FinalizeSection(PMEMORYMODULE module, PSECTIONFINALIZEDATA sectionData) {
202206
(sectionData->size % module->pageSize) == 0)
203207
) {
204208
// Only allowed to decommit whole pages
205-
VirtualFree(sectionData->address, sectionData->size, MEM_DECOMMIT);
209+
module->free(sectionData->address, sectionData->size, MEM_DECOMMIT, module->userdata);
206210
}
207211
return TRUE;
208212
}
@@ -429,6 +433,18 @@ BuildImportTable(PMEMORYMODULE module)
429433
return result;
430434
}
431435

436+
LPVOID MemoryDefaultAlloc(LPVOID address, SIZE_T size, DWORD allocationType, DWORD protect, void* userdata)
437+
{
438+
UNREFERENCED_PARAMETER(userdata);
439+
return VirtualAlloc(address, size, allocationType, protect);
440+
}
441+
442+
BOOL MemoryDefaultFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType, void* userdata)
443+
{
444+
UNREFERENCED_PARAMETER(userdata);
445+
return VirtualFree(lpAddress, dwSize, dwFreeType);
446+
}
447+
432448
HCUSTOMMODULE MemoryDefaultLoadLibrary(LPCSTR filename, void *userdata)
433449
{
434450
HMODULE result;
@@ -455,10 +471,12 @@ void MemoryDefaultFreeLibrary(HCUSTOMMODULE module, void *userdata)
455471

456472
HMEMORYMODULE MemoryLoadLibrary(const void *data, size_t size)
457473
{
458-
return MemoryLoadLibraryEx(data, size, MemoryDefaultLoadLibrary, MemoryDefaultGetProcAddress, MemoryDefaultFreeLibrary, NULL);
474+
return MemoryLoadLibraryEx(data, size, MemoryDefaultAlloc, MemoryDefaultFree, MemoryDefaultLoadLibrary, MemoryDefaultGetProcAddress, MemoryDefaultFreeLibrary, NULL);
459475
}
460476

461477
HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
478+
CustomAllocFunc allocMemory,
479+
CustomFreeFunc freeMemory,
462480
CustomLoadLibraryFunc loadLibrary,
463481
CustomGetProcAddressFunc getProcAddress,
464482
CustomFreeLibraryFunc freeLibrary,
@@ -535,17 +553,19 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
535553
// reserve memory for image of library
536554
// XXX: is it correct to commit the complete memory region at once?
537555
// calling DllEntry raises an exception if we don't...
538-
code = (unsigned char *)VirtualAlloc((LPVOID)(old_header->OptionalHeader.ImageBase),
556+
code = (unsigned char *)allocMemory((LPVOID)(old_header->OptionalHeader.ImageBase),
539557
alignedImageSize,
540558
MEM_RESERVE | MEM_COMMIT,
541-
PAGE_READWRITE);
559+
PAGE_READWRITE,
560+
userdata);
542561

543562
if (code == NULL) {
544563
// try to allocate memory at arbitrary position
545-
code = (unsigned char *)VirtualAlloc(NULL,
564+
code = (unsigned char *)allocMemory(NULL,
546565
alignedImageSize,
547566
MEM_RESERVE | MEM_COMMIT,
548-
PAGE_READWRITE);
567+
PAGE_READWRITE,
568+
userdata);
549569
if (code == NULL) {
550570
SetLastError(ERROR_OUTOFMEMORY);
551571
return NULL;
@@ -554,13 +574,15 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
554574

555575
result = (PMEMORYMODULE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MEMORYMODULE));
556576
if (result == NULL) {
557-
VirtualFree(code, 0, MEM_RELEASE);
577+
freeMemory(code, 0, MEM_RELEASE, userdata);
558578
SetLastError(ERROR_OUTOFMEMORY);
559579
return NULL;
560580
}
561581

562582
result->codeBase = code;
563583
result->isDLL = (old_header->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0;
584+
result->alloc = allocMemory;
585+
result->free = freeMemory;
564586
result->loadLibrary = loadLibrary;
565587
result->getProcAddress = getProcAddress;
566588
result->freeLibrary = freeLibrary;
@@ -572,10 +594,11 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
572594
}
573595

574596
// commit memory for headers
575-
headers = (unsigned char *)VirtualAlloc(code,
597+
headers = (unsigned char *)allocMemory(code,
576598
old_header->OptionalHeader.SizeOfHeaders,
577599
MEM_COMMIT,
578-
PAGE_READWRITE);
600+
PAGE_READWRITE,
601+
userdata);
579602

580603
// copy PE header to code
581604
memcpy(headers, dos_header, old_header->OptionalHeader.SizeOfHeaders);
@@ -724,7 +747,7 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
724747

725748
if (module->codeBase != NULL) {
726749
// release memory of library
727-
VirtualFree(module->codeBase, 0, MEM_RELEASE);
750+
module->free(module->codeBase, 0, MEM_RELEASE, module->userdata);
728751
}
729752

730753
HeapFree(GetProcessHeap(), 0, module);

MemoryModule.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ typedef void *HCUSTOMMODULE;
3939
extern "C" {
4040
#endif
4141

42+
typedef LPVOID (*CustomAllocFunc)(LPVOID, SIZE_T, DWORD, DWORD, void*);
43+
typedef BOOL (*CustomFreeFunc)(LPVOID, SIZE_T, DWORD, void*);
4244
typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *);
4345
typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *);
4446
typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);
@@ -58,6 +60,8 @@ HMEMORYMODULE MemoryLoadLibrary(const void *, size_t);
5860
* Dependencies will be resolved using passed callback methods.
5961
*/
6062
HMEMORYMODULE MemoryLoadLibraryEx(const void *, size_t,
63+
CustomAllocFunc,
64+
CustomFreeFunc,
6165
CustomLoadLibraryFunc,
6266
CustomGetProcAddressFunc,
6367
CustomFreeLibraryFunc,
@@ -117,6 +121,22 @@ int MemoryLoadString(HMEMORYMODULE, UINT, LPTSTR, int);
117121
*/
118122
int MemoryLoadStringEx(HMEMORYMODULE, UINT, LPTSTR, int, WORD);
119123

124+
/**
125+
* Default implementation of CustomAllocFunc that calls VirtualAlloc
126+
* internally to allocate memory for a library
127+
*
128+
* This is the default as used by MemoryLoadLibrary.
129+
*/
130+
LPVOID MemoryDefaultAlloc(LPVOID, SIZE_T, DWORD, DWORD, void *);
131+
132+
/**
133+
* Default implementation of CustomFreeFunc that calls VirtualFree
134+
* internally to free the memory used by a library
135+
*
136+
* This is the default as used by MemoryLoadLibrary.
137+
*/
138+
BOOL MemoryDefaultFree(LPVOID, SIZE_T, DWORD, void *);
139+
120140
/**
121141
* Default implementation of CustomLoadLibraryFunc that calls LoadLibraryA
122142
* internally to load an additional libary.

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