Skip to content

Commit 44ae72d

Browse files
committed
Added API to delegate resolving of dependencies to custom methods (github issue fancycode#5, inspired by pull request fancycode#9)
1 parent 0c19658 commit 44ae72d

File tree

2 files changed

+76
-10
lines changed

2 files changed

+76
-10
lines changed

MemoryModule.c

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,13 @@
5151
typedef struct {
5252
PIMAGE_NT_HEADERS headers;
5353
unsigned char *codeBase;
54-
HMODULE *modules;
54+
HCUSTOMMODULE *modules;
5555
int numModules;
5656
int initialized;
57+
CustomLoadLibraryFunc loadLibrary;
58+
CustomGetProcAddressFunc getProcAddress;
59+
CustomFreeLibraryFunc freeLibrary;
60+
void *userdata;
5761
} MEMORYMODULE, *PMEMORYMODULE;
5862

5963
typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
@@ -239,15 +243,15 @@ BuildImportTable(PMEMORYMODULE module)
239243
{
240244
int result=1;
241245
unsigned char *codeBase = module->codeBase;
242-
HMODULE * tmp;
246+
HCUSTOMMODULE *tmp;
243247

244248
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
245249
if (directory->Size > 0) {
246250
PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (codeBase + directory->VirtualAddress);
247251
for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) {
248252
POINTER_TYPE *thunkRef;
249253
FARPROC *funcRef;
250-
HMODULE handle = LoadLibraryA((LPCSTR) (codeBase + importDesc->Name));
254+
HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata);
251255
if (handle == NULL) {
252256
#if DEBUG_OUTPUT
253257
OutputLastError("Can't load library");
@@ -256,9 +260,9 @@ BuildImportTable(PMEMORYMODULE module)
256260
break;
257261
}
258262

259-
tmp = (HMODULE *)realloc(module->modules, (module->numModules+1)*(sizeof(HMODULE)));
263+
tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE)));
260264
if (tmp == NULL) {
261-
FreeLibrary(handle);
265+
module->freeLibrary(handle, module->userdata);
262266
result = 0;
263267
break;
264268
}
@@ -275,10 +279,10 @@ BuildImportTable(PMEMORYMODULE module)
275279
}
276280
for (; *thunkRef; thunkRef++, funcRef++) {
277281
if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) {
278-
*funcRef = (FARPROC)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
282+
*funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata);
279283
} else {
280284
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef));
281-
*funcRef = (FARPROC)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
285+
*funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata);
282286
}
283287
if (*funcRef == 0) {
284288
result = 0;
@@ -287,7 +291,7 @@ BuildImportTable(PMEMORYMODULE module)
287291
}
288292

289293
if (!result) {
290-
FreeLibrary(handle);
294+
module->freeLibrary(handle, module->userdata);
291295
break;
292296
}
293297
}
@@ -296,7 +300,36 @@ BuildImportTable(PMEMORYMODULE module)
296300
return result;
297301
}
298302

303+
static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata)
304+
{
305+
HMODULE result = LoadLibraryA(filename);
306+
if (result == NULL) {
307+
return NULL;
308+
}
309+
310+
return (HCUSTOMMODULE) result;
311+
}
312+
313+
static FARPROC _GetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata)
314+
{
315+
return (FARPROC) GetProcAddress((HMODULE) module, name);
316+
}
317+
318+
static void _FreeLibrary(HCUSTOMMODULE module, void *userdata)
319+
{
320+
FreeLibrary((HMODULE) module);
321+
}
322+
299323
HMEMORYMODULE MemoryLoadLibrary(const void *data)
324+
{
325+
return MemoryLoadLibraryEx(data, _LoadLibrary, _GetProcAddress, _FreeLibrary, NULL);
326+
}
327+
328+
HMEMORYMODULE MemoryLoadLibraryEx(const void *data,
329+
CustomLoadLibraryFunc loadLibrary,
330+
CustomGetProcAddressFunc getProcAddress,
331+
CustomFreeLibraryFunc freeLibrary,
332+
void *userdata)
300333
{
301334
PMEMORYMODULE result;
302335
PIMAGE_DOS_HEADER dos_header;
@@ -349,6 +382,10 @@ HMEMORYMODULE MemoryLoadLibrary(const void *data)
349382
result->numModules = 0;
350383
result->modules = NULL;
351384
result->initialized = 0;
385+
result->loadLibrary = loadLibrary;
386+
result->getProcAddress = getProcAddress;
387+
result->freeLibrary = freeLibrary;
388+
result->userdata = userdata;
352389

353390
// commit memory for headers
354391
headers = (unsigned char *)VirtualAlloc(code,
@@ -463,7 +500,7 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
463500
// free previously opened libraries
464501
for (i=0; i<module->numModules; i++) {
465502
if (module->modules[i] != INVALID_HANDLE_VALUE) {
466-
FreeLibrary(module->modules[i]);
503+
module->freeLibrary(module->modules[i], module->userdata);
467504
}
468505
}
469506

MemoryModule.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,43 @@
3131

3232
typedef void *HMEMORYMODULE;
3333

34+
typedef void *HCUSTOMMODULE;
35+
3436
#ifdef __cplusplus
3537
extern "C" {
3638
#endif
3739

40+
typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *);
41+
typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *);
42+
typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);
43+
44+
/**
45+
* Load DLL from memory location.
46+
*
47+
* All dependencies are resolved using default LoadLibrary/GetProcAddress
48+
* calls through the Windows API.
49+
*/
3850
HMEMORYMODULE MemoryLoadLibrary(const void *);
3951

40-
FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *);
52+
/**
53+
* Load DLL from memory location using custom dependency resolvers.
54+
*
55+
* Dependencies will be resolved using passed callback methods.
56+
*/
57+
HMEMORYMODULE MemoryLoadLibraryEx(const void *,
58+
CustomLoadLibraryFunc,
59+
CustomGetProcAddressFunc,
60+
CustomFreeLibraryFunc,
61+
void *);
62+
63+
/**
64+
* Get address of exported method.
65+
*/
66+
FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);
4167

68+
/**
69+
* Free previously loaded DLL.
70+
*/
4271
void MemoryFreeLibrary(HMEMORYMODULE);
4372

4473
#ifdef __cplusplus

0 commit comments

Comments
 (0)