mirror of
https://github.com/fancycode/MemoryModule
synced 2026-06-06 15:44:28 +00:00
Added API to delegate resolving of dependencies to custom methods (github issue #5, inspired by pull request #9)
This commit is contained in:
+46
-9
@@ -51,9 +51,13 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
PIMAGE_NT_HEADERS headers;
|
PIMAGE_NT_HEADERS headers;
|
||||||
unsigned char *codeBase;
|
unsigned char *codeBase;
|
||||||
HMODULE *modules;
|
HCUSTOMMODULE *modules;
|
||||||
int numModules;
|
int numModules;
|
||||||
int initialized;
|
int initialized;
|
||||||
|
CustomLoadLibraryFunc loadLibrary;
|
||||||
|
CustomGetProcAddressFunc getProcAddress;
|
||||||
|
CustomFreeLibraryFunc freeLibrary;
|
||||||
|
void *userdata;
|
||||||
} MEMORYMODULE, *PMEMORYMODULE;
|
} MEMORYMODULE, *PMEMORYMODULE;
|
||||||
|
|
||||||
typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
|
typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
|
||||||
@@ -239,7 +243,7 @@ BuildImportTable(PMEMORYMODULE module)
|
|||||||
{
|
{
|
||||||
int result=1;
|
int result=1;
|
||||||
unsigned char *codeBase = module->codeBase;
|
unsigned char *codeBase = module->codeBase;
|
||||||
HMODULE * tmp;
|
HCUSTOMMODULE *tmp;
|
||||||
|
|
||||||
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||||
if (directory->Size > 0) {
|
if (directory->Size > 0) {
|
||||||
@@ -247,7 +251,7 @@ BuildImportTable(PMEMORYMODULE module)
|
|||||||
for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) {
|
for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) {
|
||||||
POINTER_TYPE *thunkRef;
|
POINTER_TYPE *thunkRef;
|
||||||
FARPROC *funcRef;
|
FARPROC *funcRef;
|
||||||
HMODULE handle = LoadLibraryA((LPCSTR) (codeBase + importDesc->Name));
|
HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
#if DEBUG_OUTPUT
|
#if DEBUG_OUTPUT
|
||||||
OutputLastError("Can't load library");
|
OutputLastError("Can't load library");
|
||||||
@@ -256,9 +260,9 @@ BuildImportTable(PMEMORYMODULE module)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = (HMODULE *)realloc(module->modules, (module->numModules+1)*(sizeof(HMODULE)));
|
tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE)));
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
FreeLibrary(handle);
|
module->freeLibrary(handle, module->userdata);
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -275,10 +279,10 @@ BuildImportTable(PMEMORYMODULE module)
|
|||||||
}
|
}
|
||||||
for (; *thunkRef; thunkRef++, funcRef++) {
|
for (; *thunkRef; thunkRef++, funcRef++) {
|
||||||
if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) {
|
if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) {
|
||||||
*funcRef = (FARPROC)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
|
*funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata);
|
||||||
} else {
|
} else {
|
||||||
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef));
|
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef));
|
||||||
*funcRef = (FARPROC)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
|
*funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata);
|
||||||
}
|
}
|
||||||
if (*funcRef == 0) {
|
if (*funcRef == 0) {
|
||||||
result = 0;
|
result = 0;
|
||||||
@@ -287,7 +291,7 @@ BuildImportTable(PMEMORYMODULE module)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
FreeLibrary(handle);
|
module->freeLibrary(handle, module->userdata);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -296,7 +300,36 @@ BuildImportTable(PMEMORYMODULE module)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata)
|
||||||
|
{
|
||||||
|
HMODULE result = LoadLibraryA(filename);
|
||||||
|
if (result == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (HCUSTOMMODULE) result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FARPROC _GetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata)
|
||||||
|
{
|
||||||
|
return (FARPROC) GetProcAddress((HMODULE) module, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _FreeLibrary(HCUSTOMMODULE module, void *userdata)
|
||||||
|
{
|
||||||
|
FreeLibrary((HMODULE) module);
|
||||||
|
}
|
||||||
|
|
||||||
HMEMORYMODULE MemoryLoadLibrary(const void *data)
|
HMEMORYMODULE MemoryLoadLibrary(const void *data)
|
||||||
|
{
|
||||||
|
return MemoryLoadLibraryEx(data, _LoadLibrary, _GetProcAddress, _FreeLibrary, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
HMEMORYMODULE MemoryLoadLibraryEx(const void *data,
|
||||||
|
CustomLoadLibraryFunc loadLibrary,
|
||||||
|
CustomGetProcAddressFunc getProcAddress,
|
||||||
|
CustomFreeLibraryFunc freeLibrary,
|
||||||
|
void *userdata)
|
||||||
{
|
{
|
||||||
PMEMORYMODULE result;
|
PMEMORYMODULE result;
|
||||||
PIMAGE_DOS_HEADER dos_header;
|
PIMAGE_DOS_HEADER dos_header;
|
||||||
@@ -349,6 +382,10 @@ HMEMORYMODULE MemoryLoadLibrary(const void *data)
|
|||||||
result->numModules = 0;
|
result->numModules = 0;
|
||||||
result->modules = NULL;
|
result->modules = NULL;
|
||||||
result->initialized = 0;
|
result->initialized = 0;
|
||||||
|
result->loadLibrary = loadLibrary;
|
||||||
|
result->getProcAddress = getProcAddress;
|
||||||
|
result->freeLibrary = freeLibrary;
|
||||||
|
result->userdata = userdata;
|
||||||
|
|
||||||
// commit memory for headers
|
// commit memory for headers
|
||||||
headers = (unsigned char *)VirtualAlloc(code,
|
headers = (unsigned char *)VirtualAlloc(code,
|
||||||
@@ -463,7 +500,7 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
|
|||||||
// free previously opened libraries
|
// free previously opened libraries
|
||||||
for (i=0; i<module->numModules; i++) {
|
for (i=0; i<module->numModules; i++) {
|
||||||
if (module->modules[i] != INVALID_HANDLE_VALUE) {
|
if (module->modules[i] != INVALID_HANDLE_VALUE) {
|
||||||
FreeLibrary(module->modules[i]);
|
module->freeLibrary(module->modules[i], module->userdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-1
@@ -31,14 +31,43 @@
|
|||||||
|
|
||||||
typedef void *HMEMORYMODULE;
|
typedef void *HMEMORYMODULE;
|
||||||
|
|
||||||
|
typedef void *HCUSTOMMODULE;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *);
|
||||||
|
typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *);
|
||||||
|
typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load DLL from memory location.
|
||||||
|
*
|
||||||
|
* All dependencies are resolved using default LoadLibrary/GetProcAddress
|
||||||
|
* calls through the Windows API.
|
||||||
|
*/
|
||||||
HMEMORYMODULE MemoryLoadLibrary(const void *);
|
HMEMORYMODULE MemoryLoadLibrary(const void *);
|
||||||
|
|
||||||
FARPROC MemoryGetProcAddress(HMEMORYMODULE, const char *);
|
/**
|
||||||
|
* Load DLL from memory location using custom dependency resolvers.
|
||||||
|
*
|
||||||
|
* Dependencies will be resolved using passed callback methods.
|
||||||
|
*/
|
||||||
|
HMEMORYMODULE MemoryLoadLibraryEx(const void *,
|
||||||
|
CustomLoadLibraryFunc,
|
||||||
|
CustomGetProcAddressFunc,
|
||||||
|
CustomFreeLibraryFunc,
|
||||||
|
void *);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get address of exported method.
|
||||||
|
*/
|
||||||
|
FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free previously loaded DLL.
|
||||||
|
*/
|
||||||
void MemoryFreeLibrary(HMEMORYMODULE);
|
void MemoryFreeLibrary(HMEMORYMODULE);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
Reference in New Issue
Block a user