2016-11-29 16:53:39 +00:00
|
|
|
#include "MemoryModule.h"
|
|
|
|
#include "MyLoadLibrary.h"
|
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
#include "uthash.h"
|
2016-11-29 16:53:39 +00:00
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
#include "debug.h"
|
2016-11-29 16:53:39 +00:00
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
typedef struct {
|
|
|
|
PSTR name;
|
2019-09-24 18:27:23 +00:00
|
|
|
PSTR fileName;
|
|
|
|
|
2019-07-11 15:58:33 +00:00
|
|
|
HCUSTOMMODULE module;
|
|
|
|
int refcount;
|
2016-11-29 16:53:39 +00:00
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
UT_hash_handle by_name;
|
2019-09-24 18:27:23 +00:00
|
|
|
UT_hash_handle by_filename;
|
2019-09-09 15:03:31 +00:00
|
|
|
UT_hash_handle by_module;
|
|
|
|
} HCUSTOMLIBRARY, *PHCUSTOMLIBRARY;
|
2016-11-29 16:53:39 +00:00
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
typedef struct {
|
|
|
|
PHCUSTOMLIBRARY by_module;
|
|
|
|
PHCUSTOMLIBRARY by_name;
|
2019-09-24 18:27:23 +00:00
|
|
|
PHCUSTOMLIBRARY by_filename;
|
2019-09-09 15:03:31 +00:00
|
|
|
SRWLOCK lock;
|
2019-09-24 18:27:23 +00:00
|
|
|
PDL_CALLBACKS pCallbacks;
|
2019-09-09 15:03:31 +00:00
|
|
|
} HLIBRARIES, *PHLIBRARIES;
|
2016-11-29 16:53:39 +00:00
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
static PHLIBRARIES libraries = NULL;
|
2016-11-29 16:53:39 +00:00
|
|
|
|
2019-09-07 15:51:30 +00:00
|
|
|
VOID MySetLibraries(PVOID pLibraries) {
|
|
|
|
if (!libraries) {
|
|
|
|
dprint("Initialize libraries with: %p\n", pLibraries);
|
|
|
|
libraries = pLibraries;
|
|
|
|
} else {
|
|
|
|
dprint("Libraries already initialized\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PVOID MyGetLibraries() {
|
|
|
|
return (PVOID) libraries;
|
|
|
|
}
|
|
|
|
|
2016-11-29 16:53:39 +00:00
|
|
|
/****************************************************************
|
|
|
|
* Search for a loaded MemoryModule in the linked list, either by name
|
|
|
|
* or by module handle.
|
|
|
|
*/
|
2019-09-09 15:03:31 +00:00
|
|
|
static PHCUSTOMLIBRARY _FindMemoryModule(LPCSTR name, HMODULE module)
|
2016-11-29 16:53:39 +00:00
|
|
|
{
|
2019-09-09 15:03:31 +00:00
|
|
|
PHCUSTOMLIBRARY phIdx = NULL;
|
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
if (!name && !module)
|
|
|
|
return NULL;
|
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
if (!libraries)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
AcquireSRWLockShared(&libraries->lock);
|
|
|
|
|
|
|
|
if (name) {
|
2019-09-24 18:27:23 +00:00
|
|
|
LPCSTR srcName = NULL;
|
2019-09-09 15:03:31 +00:00
|
|
|
PSTR psName;
|
2019-09-24 18:27:23 +00:00
|
|
|
PSTR psFileName;
|
|
|
|
PSTR psi;
|
|
|
|
size_t len, fileNameLen;
|
2019-09-09 15:03:31 +00:00
|
|
|
|
|
|
|
srcName = strrchr(name, '\\');
|
2019-09-24 18:27:23 +00:00
|
|
|
if (srcName)
|
|
|
|
srcName ++;
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
if (!srcName || !srcName[0]) {
|
2019-09-09 15:03:31 +00:00
|
|
|
srcName = strrchr(name, '/');
|
2019-09-24 18:27:23 +00:00
|
|
|
if (srcName)
|
|
|
|
srcName ++;
|
|
|
|
}
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
if (!srcName || !srcName[0])
|
2019-09-09 15:03:31 +00:00
|
|
|
srcName = name;
|
|
|
|
|
|
|
|
len = strlen(srcName);
|
2019-09-24 18:27:23 +00:00
|
|
|
fileNameLen = strlen(name);
|
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
psName = _alloca(len + 1);
|
2019-09-24 18:27:23 +00:00
|
|
|
psFileName = _alloca(fileNameLen + 1);
|
2019-09-09 15:03:31 +00:00
|
|
|
memcpy(psName, srcName, len+1);
|
2019-09-24 18:27:23 +00:00
|
|
|
memcpy(psFileName, name, len+1);
|
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
_strupr(psName);
|
2019-09-24 18:27:23 +00:00
|
|
|
_strupr(psFileName);
|
|
|
|
|
|
|
|
psi = strrchr(psName, '.');
|
|
|
|
if (psi && !strcmp(psi, ".DLL"))
|
|
|
|
*psi = '\0';
|
|
|
|
|
|
|
|
for (psi=psFileName; *psi; psi++)
|
|
|
|
if (*psi == '/')
|
|
|
|
*psi = '\\';
|
2019-09-09 15:03:31 +00:00
|
|
|
|
|
|
|
HASH_FIND(
|
2019-09-24 18:27:23 +00:00
|
|
|
by_filename, libraries->by_filename,
|
|
|
|
psFileName, fileNameLen, phIdx
|
2019-09-09 15:03:31 +00:00
|
|
|
);
|
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
if (!phIdx) {
|
|
|
|
HASH_FIND(
|
|
|
|
by_name, libraries->by_name,
|
|
|
|
psName, len, phIdx
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
dprint(
|
|
|
|
"_FindMemoryModule by name %s -> %p (%p)\n",
|
|
|
|
psName, phIdx, phIdx? phIdx->module : NULL);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
HASH_FIND(
|
|
|
|
by_module, libraries->by_module,
|
|
|
|
&module, sizeof(void *), phIdx
|
|
|
|
);
|
|
|
|
|
|
|
|
dprint("_FindMemoryModule by module %p -> %p (%p)\n", module, phIdx, phIdx? phIdx->module : NULL);
|
2019-07-11 15:58:33 +00:00
|
|
|
}
|
2019-09-09 15:03:31 +00:00
|
|
|
|
|
|
|
ReleaseSRWLockShared(&libraries->lock);
|
|
|
|
|
|
|
|
return phIdx;
|
2016-11-29 16:53:39 +00:00
|
|
|
}
|
|
|
|
|
2019-09-27 18:16:13 +00:00
|
|
|
static PHCUSTOMLIBRARY _FindMemoryModuleW(LPCWSTR name)
|
|
|
|
{
|
|
|
|
PSTR pszName = NULL;
|
|
|
|
PHCUSTOMLIBRARY 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 = _FindMemoryModule(pszName, NULL);
|
|
|
|
|
|
|
|
LocalFree(pszName);
|
|
|
|
|
|
|
|
return hResult;
|
|
|
|
}
|
|
|
|
|
2019-12-07 21:23:54 +00:00
|
|
|
#ifdef _PUPY_PRIVATE_WS2_32
|
|
|
|
static
|
|
|
|
NTSTATUS CALLBACK MyEtwRegister (
|
|
|
|
LPCGUID ProviderId,
|
|
|
|
PVOID EnableCallback,
|
|
|
|
PVOID CallbackContext,
|
|
|
|
PULONGLONG RegHandle
|
|
|
|
) {
|
|
|
|
static ULONGLONG dwFakeRegHandle = 0x80000000;
|
|
|
|
dprint(
|
|
|
|
"MyEtwRegister "
|
|
|
|
"GUID=%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x -> %p\n",
|
|
|
|
ProviderId->Data1, ProviderId->Data2, ProviderId->Data3,
|
|
|
|
ProviderId->Data4[0], ProviderId->Data4[1],
|
|
|
|
ProviderId->Data4[2], ProviderId->Data4[3],
|
|
|
|
ProviderId->Data4[4], ProviderId->Data4[5],
|
|
|
|
ProviderId->Data4[6], ProviderId->Data4[7],
|
|
|
|
dwFakeRegHandle
|
|
|
|
);
|
|
|
|
|
|
|
|
*RegHandle = dwFakeRegHandle ++;
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
ULONG CALLBACK MyEtwEventWrite (
|
|
|
|
ULONGLONG RegHandle,
|
|
|
|
PVOID EventDescriptor,
|
|
|
|
ULONG UserDataCount,
|
|
|
|
PVOID UserData
|
|
|
|
) {
|
|
|
|
dprint("MyEtwEventWrite (RegHandle: %p)\n", RegHandle);
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
ULONG CALLBACK MyEtwEventWriteFull (
|
|
|
|
ULONGLONG RegHandle,
|
|
|
|
PVOID EventDescriptor,
|
|
|
|
USHORT EventProperty,
|
|
|
|
LPCGUID ActivityId,
|
|
|
|
LPCGUID RelatedActivityId,
|
|
|
|
ULONG UserDataCount,
|
|
|
|
PVOID UserData
|
|
|
|
) {
|
|
|
|
dprint("EtwEventWriteFull (RegHandle: %p)\n", RegHandle);
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
NTSTATUS CALLBACK MyEtwUnregister (
|
|
|
|
ULONGLONG RegHandle
|
|
|
|
) {
|
|
|
|
dprint("MyEtwUnregister (RegHandle: %p)\n", RegHandle);
|
|
|
|
return ERROR_SUCCESS;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
static DL_CALLBACKS callbacks = {
|
|
|
|
MyLoadLibraryA, MyLoadLibraryW,
|
|
|
|
MyLoadLibraryExA, MyLoadLibraryExW,
|
|
|
|
MyGetModuleHandleA, MyGetModuleHandleW,
|
2019-09-26 12:02:43 +00:00
|
|
|
MyGetModuleFileNameA, MyGetModuleFileNameW,
|
2019-09-24 18:27:23 +00:00
|
|
|
MyGetProcAddress,
|
2019-09-26 12:02:43 +00:00
|
|
|
MyFreeLibrary,
|
|
|
|
|
|
|
|
MyFindResourceA, MyFindResourceW,
|
|
|
|
MyFindResourceExA, MyFindResourceExW,
|
|
|
|
MySizeofResource, MyLoadResource,
|
|
|
|
|
|
|
|
GetProcAddress,
|
|
|
|
GetModuleFileNameA, GetModuleFileNameW,
|
2019-12-07 21:23:54 +00:00
|
|
|
FindResourceExW, SizeofResource, LoadResource,
|
|
|
|
|
|
|
|
#ifdef _PUPY_PRIVATE_WS2_32
|
|
|
|
MyEtwRegister, MyEtwEventWrite,
|
|
|
|
MyEtwEventWriteFull, MyEtwUnregister
|
|
|
|
#endif
|
2019-09-24 18:27:23 +00:00
|
|
|
};
|
|
|
|
|
2016-11-29 16:53:39 +00:00
|
|
|
/****************************************************************
|
|
|
|
* Insert a MemoryModule into the linked list of loaded modules
|
|
|
|
*/
|
2019-09-09 15:03:31 +00:00
|
|
|
static PHCUSTOMLIBRARY _AddMemoryModule(
|
|
|
|
LPCSTR name, HCUSTOMMODULE module)
|
2016-11-29 16:53:39 +00:00
|
|
|
{
|
2019-09-09 15:03:31 +00:00
|
|
|
PHCUSTOMLIBRARY hmodule = (PHCUSTOMLIBRARY) malloc(
|
|
|
|
sizeof(HCUSTOMLIBRARY));
|
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
LPCSTR srcName = NULL;
|
|
|
|
PSTR psi;
|
2019-09-09 15:03:31 +00:00
|
|
|
|
|
|
|
if (!libraries) {
|
|
|
|
libraries = (PHLIBRARIES) malloc(sizeof(HLIBRARIES));
|
|
|
|
libraries->by_module = NULL;
|
|
|
|
libraries->by_name = NULL;
|
2019-09-24 18:27:23 +00:00
|
|
|
libraries->by_filename = NULL;
|
|
|
|
libraries->pCallbacks = &callbacks;
|
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
InitializeSRWLock(&libraries->lock);
|
|
|
|
dprint("Initialize libraries: %p\n", libraries);
|
|
|
|
}
|
|
|
|
|
|
|
|
srcName = strrchr(name, '\\');
|
2019-09-24 18:27:23 +00:00
|
|
|
if (srcName)
|
|
|
|
srcName ++;
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
if (!srcName || !srcName[0]) {
|
2019-09-09 15:03:31 +00:00
|
|
|
srcName = strrchr(name, '/');
|
2019-09-24 18:27:23 +00:00
|
|
|
if (srcName)
|
|
|
|
srcName ++;
|
|
|
|
}
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
if (!srcName || !srcName[0])
|
2019-09-09 15:03:31 +00:00
|
|
|
srcName = name;
|
|
|
|
|
|
|
|
hmodule->refcount = 1;
|
|
|
|
hmodule->name = strdup(srcName);
|
2019-09-24 18:27:23 +00:00
|
|
|
hmodule->fileName = strdup(name);
|
2019-09-09 15:03:31 +00:00
|
|
|
hmodule->module = module;
|
|
|
|
|
|
|
|
_strupr(hmodule->name);
|
2019-09-24 18:27:23 +00:00
|
|
|
_strupr(hmodule->fileName);
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
psi = strchr(hmodule->name, '.');
|
|
|
|
if (psi && !strcmp(psi, ".DLL"))
|
|
|
|
*psi = '\0';
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
for (psi=hmodule->fileName; *psi; psi++)
|
|
|
|
if (*psi == '/')
|
|
|
|
*psi = '\\';
|
|
|
|
|
|
|
|
AcquireSRWLockExclusive(&libraries->lock);
|
2019-09-09 15:03:31 +00:00
|
|
|
|
|
|
|
HASH_ADD_KEYPTR(
|
|
|
|
by_module, libraries->by_module,
|
|
|
|
&hmodule->module, sizeof(hmodule->module),
|
|
|
|
hmodule
|
|
|
|
);
|
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
dprint(
|
|
|
|
"_AddMemoryModule(%s (%s), %p)\n",
|
|
|
|
hmodule->name,
|
|
|
|
hmodule->fileName,
|
|
|
|
module
|
|
|
|
);
|
2019-09-09 15:03:31 +00:00
|
|
|
|
|
|
|
HASH_ADD_KEYPTR(
|
|
|
|
by_name, libraries->by_name, hmodule->name,
|
|
|
|
strlen(hmodule->name), hmodule
|
|
|
|
);
|
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
HASH_ADD_KEYPTR(
|
|
|
|
by_filename, libraries->by_filename, hmodule->fileName,
|
|
|
|
strlen(hmodule->fileName), hmodule
|
|
|
|
);
|
2019-09-09 15:03:31 +00:00
|
|
|
|
|
|
|
ReleaseSRWLockExclusive(&libraries->lock);
|
|
|
|
|
|
|
|
dprint("_AddMemoryModule(%s, %p) -> %p[%d] (hmod=%p)\n",
|
|
|
|
hmodule->name, module, hmodule, hmodule->refcount, module);
|
|
|
|
|
|
|
|
return hmodule;
|
2016-11-29 16:53:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************
|
|
|
|
* Public functions
|
|
|
|
*/
|
2019-09-26 12:02:43 +00:00
|
|
|
|
|
|
|
DWORD CALLBACK MyGetModuleFileNameW(HMODULE hModule, LPWSTR lpwStr, DWORD dwSize)
|
2016-11-29 16:53:39 +00:00
|
|
|
{
|
2019-09-09 15:03:31 +00:00
|
|
|
PHCUSTOMLIBRARY lib;
|
2019-09-24 18:27:23 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
lib = _FindMemoryModule(NULL, hModule);
|
|
|
|
if (lib) {
|
|
|
|
DWORD dwRet = MemoryModuleFileNameW(lib->module, lpwStr, dwSize);
|
|
|
|
if (dwRet == 0xFFFFFFFF) {
|
|
|
|
dwRet = MultiByteToWideChar(
|
|
|
|
CP_ACP, 0,
|
|
|
|
lib->fileName, strlen(lib->fileName),
|
|
|
|
lpwStr, dwSize
|
|
|
|
);
|
2019-09-24 18:27:23 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
dprint(
|
|
|
|
"MyGetModuleFileNameW -> %s (conv: %d)\n",
|
|
|
|
lib->fileName, dwRet
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
dprint(
|
|
|
|
"MyGetModuleFileNameW -> proxied (ret: %d)\n", dwRet
|
|
|
|
);
|
|
|
|
}
|
2016-11-29 16:53:39 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
return dwRet;
|
|
|
|
} else {
|
|
|
|
dprint("MyGetModuleFileNameW %p -> unregistered\n", hModule);
|
|
|
|
}
|
|
|
|
|
|
|
|
return GetModuleFileNameW(hModule, lpwStr, dwSize);
|
2019-09-25 11:29:54 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
DWORD CALLBACK MyGetModuleFileNameA(HMODULE hModule, LPSTR lpStr, DWORD dwSize)
|
2019-09-25 11:29:54 +00:00
|
|
|
{
|
2019-09-26 12:02:43 +00:00
|
|
|
PHCUSTOMLIBRARY lib;
|
2019-09-25 11:29:54 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
lib = _FindMemoryModule(NULL, hModule);
|
|
|
|
if (lib) {
|
|
|
|
DWORD dwRet = MemoryModuleFileNameA(lib->module, lpStr, dwSize);
|
|
|
|
if (dwRet == 0xFFFFFFFF) {
|
|
|
|
size_t reqSize = strlen(lib->fileName);
|
|
|
|
if (reqSize < dwSize) {
|
|
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
dwRet = 0;
|
|
|
|
} else {
|
|
|
|
memcpy(lpStr, lib->fileName, reqSize);
|
|
|
|
if (dwSize+1 == reqSize) {
|
|
|
|
lpStr[reqSize] = '\0';
|
|
|
|
}
|
|
|
|
dwRet = reqSize;
|
|
|
|
}
|
2019-09-25 11:29:54 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
dprint(
|
|
|
|
"MyGetModuleFileNameA -> %s (conv: %d)\n",
|
|
|
|
lib->fileName, dwRet
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
dprint(
|
|
|
|
"MyGetModuleFileNameA -> proxied (ret: %s/%d)\n", lpStr, dwRet
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return dwRet;
|
|
|
|
} else {
|
|
|
|
dprint("MyGetModuleFileNameA %p -> unregistered\n", hModule);
|
2019-09-25 11:29:54 +00:00
|
|
|
}
|
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
return GetModuleFileNameA(hModule, lpStr, dwSize);
|
|
|
|
}
|
2019-09-25 11:29:54 +00:00
|
|
|
|
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
HMODULE CALLBACK MyGetModuleHandleA(LPCSTR name)
|
|
|
|
{
|
|
|
|
PHCUSTOMLIBRARY lib;
|
2019-09-25 11:29:54 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
lib = _FindMemoryModule(name, NULL);
|
|
|
|
if (lib)
|
|
|
|
return lib->module;
|
2019-09-25 11:29:54 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
return GetModuleHandleA(name);
|
|
|
|
}
|
2019-09-25 11:29:54 +00:00
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
HMODULE MyLoadLibrary(LPCSTR name, void *bytes, void *dllmainArg)
|
|
|
|
{
|
|
|
|
return MyLoadLibraryEx(
|
|
|
|
name, bytes, dllmainArg, NULL, MEMORY_LOAD_DEFAULT
|
2019-09-25 11:29:54 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
HMODULE
|
2019-09-26 12:02:43 +00:00
|
|
|
MyLoadLibraryEx(
|
|
|
|
LPCSTR name, const void *bytes, void *dllmainArg,
|
|
|
|
const void *pvExports, MEMORY_LOAD_FLAGS flags)
|
2019-09-25 11:29:54 +00:00
|
|
|
{
|
|
|
|
HMODULE hLoadedModule = NULL;
|
2019-09-24 18:27:23 +00:00
|
|
|
|
|
|
|
dprint("MyLoadLibrary '%s'..\n", name);
|
2019-09-26 12:02:43 +00:00
|
|
|
if (flags & MEMORY_LOAD_FROM_HMODULE) {
|
2019-09-25 11:29:54 +00:00
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
lib = _FindMemoryModule(name, NULL);
|
2019-09-27 18:16:13 +00:00
|
|
|
if (lib) {
|
|
|
|
lib->refcount ++;
|
2019-09-25 11:29:54 +00:00
|
|
|
return lib->module;
|
2019-09-27 18:16:13 +00:00
|
|
|
}
|
2019-09-25 11:29:54 +00:00
|
|
|
} else {
|
|
|
|
hLoadedModule = MyGetModuleHandleA(name);
|
|
|
|
}
|
2019-09-24 18:27:23 +00:00
|
|
|
|
|
|
|
dprint("MyLoadLibrary %s registered? %p\n", name, hLoadedModule);
|
|
|
|
|
2019-09-23 15:13:59 +00:00
|
|
|
if (hLoadedModule)
|
|
|
|
return hLoadedModule;
|
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
if (bytes) {
|
2019-09-24 18:27:23 +00:00
|
|
|
HCUSTOMMODULE mod;
|
|
|
|
PDL_CALLBACKS cb = libraries ? libraries->pCallbacks : &callbacks;
|
|
|
|
|
|
|
|
dprint("Callbacks: %p\n", cb);
|
|
|
|
|
2019-09-26 12:02:43 +00:00
|
|
|
mod = MemoryLoadLibraryEx(bytes, cb, dllmainArg, pvExports, flags);
|
2019-09-07 15:51:30 +00:00
|
|
|
|
|
|
|
dprint(
|
|
|
|
"MyLoadLibrary: loading %s, buf=%p (dllmainArg=%p) -> %p\n",
|
|
|
|
name, bytes, dllmainArg, mod
|
|
|
|
);
|
|
|
|
|
2019-07-11 15:58:33 +00:00
|
|
|
if (mod) {
|
2019-09-09 15:03:31 +00:00
|
|
|
PHCUSTOMLIBRARY lib = _AddMemoryModule(name, mod);
|
2019-07-11 15:58:33 +00:00
|
|
|
dprint("MemoryLoadLibraryEx: loaded %s -> %p (%p)\n", name, mod, lib->module);
|
|
|
|
return lib->module;
|
|
|
|
} else {
|
|
|
|
dprint("MemoryLoadLibraryEx(%s, %p) failed\n", name, bytes);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dprint("MyLoadLibrary: fallback to OS LoadLibrary %s\n", name);
|
|
|
|
return LoadLibrary(name);
|
2016-11-29 16:53:39 +00:00
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
HMODULE CALLBACK MyGetModuleHandleW(LPCWSTR name) {
|
2019-09-27 18:16:13 +00:00
|
|
|
PHCUSTOMLIBRARY hResult = _FindMemoryModuleW(name);
|
2019-09-24 18:27:23 +00:00
|
|
|
if (hResult)
|
|
|
|
return hResult;
|
|
|
|
|
|
|
|
return GetModuleHandleW(name);
|
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
HMODULE CALLBACK MyLoadLibraryExA(LPCSTR name, HANDLE hFile, DWORD dwFlags) {
|
2019-09-27 18:16:13 +00:00
|
|
|
PHCUSTOMLIBRARY hResult = _FindMemoryModule(name, NULL);
|
|
|
|
if (hResult) {
|
|
|
|
hResult->refcount ++;
|
|
|
|
return hResult->module;
|
|
|
|
}
|
2019-09-24 18:27:23 +00:00
|
|
|
|
|
|
|
return LoadLibraryExA(name, hFile, dwFlags);
|
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
HMODULE CALLBACK MyLoadLibraryExW(LPCWSTR name, HANDLE hFile, DWORD dwFlags) {
|
2019-09-27 18:16:13 +00:00
|
|
|
PHCUSTOMLIBRARY hResult = _FindMemoryModuleW(name);
|
|
|
|
if (hResult) {
|
|
|
|
hResult->refcount ++;
|
|
|
|
return hResult->module;
|
|
|
|
}
|
2019-09-24 18:27:23 +00:00
|
|
|
|
|
|
|
return LoadLibraryExW(name, hFile, dwFlags);
|
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
HMODULE CALLBACK MyLoadLibraryA(LPCSTR name) {
|
2019-09-27 18:16:13 +00:00
|
|
|
PHCUSTOMLIBRARY hResult = _FindMemoryModule(name, NULL);
|
|
|
|
if (hResult) {
|
|
|
|
hResult->refcount ++;
|
|
|
|
return hResult->module;
|
|
|
|
}
|
2019-09-24 18:27:23 +00:00
|
|
|
|
|
|
|
return LoadLibraryA(name);
|
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
HMODULE CALLBACK MyLoadLibraryW(LPCWSTR name) {
|
2019-09-27 18:16:13 +00:00
|
|
|
PHCUSTOMLIBRARY hResult = _FindMemoryModuleW(name);
|
|
|
|
if (hResult) {
|
|
|
|
hResult->refcount ++;
|
|
|
|
return hResult->module;
|
|
|
|
}
|
2019-09-24 18:27:23 +00:00
|
|
|
|
|
|
|
return LoadLibraryW(name);
|
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
BOOL CALLBACK MyFreeLibrary(HMODULE module)
|
2016-11-29 16:53:39 +00:00
|
|
|
{
|
2019-09-09 15:03:31 +00:00
|
|
|
PHCUSTOMLIBRARY lib = _FindMemoryModule(NULL, module);
|
2019-09-27 18:16:13 +00:00
|
|
|
|
2019-07-11 15:58:33 +00:00
|
|
|
if (lib) {
|
2019-09-27 18:16:13 +00:00
|
|
|
dprint("MyFreeLibrary(%p) -> %s REFCNT: %d\n",
|
|
|
|
module, lib->name, lib->refcount);
|
|
|
|
|
2019-09-09 15:03:31 +00:00
|
|
|
if (--lib->refcount == 0) {
|
|
|
|
AcquireSRWLockExclusive(&libraries->lock);
|
|
|
|
|
|
|
|
HASH_DELETE(by_name, libraries->by_name, lib);
|
2019-09-24 18:27:23 +00:00
|
|
|
HASH_DELETE(by_filename, libraries->by_filename, lib);
|
2019-09-09 15:03:31 +00:00
|
|
|
HASH_DELETE(by_module, libraries->by_module, lib);
|
|
|
|
|
|
|
|
ReleaseSRWLockExclusive(&libraries->lock);
|
|
|
|
|
|
|
|
free(lib->name);
|
|
|
|
free(lib);
|
|
|
|
|
2019-07-11 15:58:33 +00:00
|
|
|
MemoryFreeLibrary(module);
|
2019-09-09 15:03:31 +00:00
|
|
|
}
|
2019-07-11 15:58:33 +00:00
|
|
|
return TRUE;
|
|
|
|
} else
|
|
|
|
return FreeLibrary(module);
|
2016-11-29 16:53:39 +00:00
|
|
|
}
|
|
|
|
|
2019-09-25 18:08:44 +00:00
|
|
|
FARPROC CALLBACK MyGetProcAddress(HMODULE module, LPCSTR procname)
|
2016-11-29 16:53:39 +00:00
|
|
|
{
|
2019-09-24 18:27:23 +00:00
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
FARPROC fpFunc = NULL;
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
lib = _FindMemoryModule(NULL, module);
|
2019-09-26 12:02:43 +00:00
|
|
|
if (lib)
|
|
|
|
fpFunc = MemoryGetProcAddress(lib->module, procname);
|
|
|
|
else
|
2019-09-24 18:27:23 +00:00
|
|
|
fpFunc = GetProcAddress(module, procname);
|
2019-09-09 15:03:31 +00:00
|
|
|
|
2019-09-24 18:27:23 +00:00
|
|
|
if (HIWORD(procname) == 0) {
|
|
|
|
dprint("MyGetProcAddress(%p, %d) -> %p (lib: %p)\n",
|
2019-09-27 18:16:13 +00:00
|
|
|
module, LOWORD(procname), fpFunc, lib);
|
2019-09-24 18:27:23 +00:00
|
|
|
} else {
|
2019-09-27 18:16:13 +00:00
|
|
|
dprint("MyGetProcAddress(%p, %s) -> %p (lib: %p)\n", module, procname, fpFunc, lib);
|
2019-09-24 18:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return fpFunc;
|
2016-11-29 16:53:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
FARPROC MyFindProcAddress(LPCSTR modulename, LPCSTR procname)
|
|
|
|
{
|
2019-09-24 18:27:23 +00:00
|
|
|
HCUSTOMMODULE mod = MyGetModuleHandleA(modulename);
|
2019-07-11 15:58:33 +00:00
|
|
|
void *addr = NULL;
|
|
|
|
/* dprint("MyFindProcAddress(%s, %s) -> %p\n", modulename, procname, mod); */
|
|
|
|
if (mod) {
|
|
|
|
addr = MyGetProcAddress(mod, procname);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* dprint("MyFindProcAddress(%s, %s) -> %p\n", modulename, procname, addr); */
|
|
|
|
return addr;
|
2016-11-29 16:53:39 +00:00
|
|
|
}
|
2019-09-26 12:02:43 +00:00
|
|
|
|
2019-09-27 18:16:13 +00:00
|
|
|
HRSRC CALLBACK MyFindResourceA(HMODULE module, LPCSTR name, LPCSTR type)
|
2019-09-26 12:02:43 +00:00
|
|
|
{
|
|
|
|
HRSRC res;
|
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
|
|
|
|
lib = _FindMemoryModule(NULL, module);
|
|
|
|
if (lib)
|
|
|
|
res = (HRSRC) MemoryFindResourceA(lib->module, name, type);
|
|
|
|
else
|
|
|
|
res = FindResourceA(module, name, type);
|
|
|
|
|
|
|
|
dprint("MyFindResourceA(%p, %s, %s) -> %p (%p)\n", module, name, type, res, lib);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-27 18:16:13 +00:00
|
|
|
HRSRC CALLBACK MyFindResourceW(HMODULE module, LPCWSTR name, LPCWSTR type)
|
2019-09-26 12:02:43 +00:00
|
|
|
{
|
|
|
|
HRSRC res;
|
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
|
|
|
|
lib = _FindMemoryModule(NULL, module);
|
|
|
|
if (lib)
|
|
|
|
res = (HRSRC) MemoryFindResourceW(lib->module, name, type);
|
|
|
|
else
|
|
|
|
res = FindResourceW(module, name, type);
|
|
|
|
|
|
|
|
dprint("MyFindResourceA(%p, %p, %p) -> %p (%p)\n", module, name, type, res, lib);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-27 18:16:13 +00:00
|
|
|
HRSRC CALLBACK MyFindResourceExA(HMODULE hModule, LPCSTR name, LPCSTR type, WORD language)
|
2019-09-26 12:02:43 +00:00
|
|
|
{
|
|
|
|
HRSRC res;
|
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
|
|
|
|
lib = _FindMemoryModule(NULL, hModule);
|
|
|
|
if (lib)
|
|
|
|
res = (HRSRC) MemoryFindResourceExA(lib->module, name, type, language);
|
|
|
|
else
|
|
|
|
res = FindResourceExA(hModule, name, type, language);
|
|
|
|
|
|
|
|
dprint("MyFindResourceExA(%p, %s, %s, %d) -> %p (%p)\n", hModule, name, type, language, res, lib);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-27 18:16:13 +00:00
|
|
|
HRSRC CALLBACK MyFindResourceExW(HMODULE hModule, LPCWSTR name, LPCWSTR type, WORD language)
|
2019-09-26 12:02:43 +00:00
|
|
|
{
|
|
|
|
HRSRC res;
|
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
|
|
|
|
lib = _FindMemoryModule(NULL, hModule);
|
|
|
|
if (lib)
|
|
|
|
res = (HRSRC) MemoryFindResourceExW(lib->module, name, type, language);
|
|
|
|
else
|
|
|
|
res = FindResourceExW(hModule, name, type, language);
|
|
|
|
|
|
|
|
dprint("MyFindResourceExA(%p, %p, %p, %d) -> %p (%p)\n", hModule, name, type, language, res, lib);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-27 18:16:13 +00:00
|
|
|
DWORD CALLBACK MySizeofResource(HMODULE hModule, HRSRC resource)
|
2019-09-26 12:02:43 +00:00
|
|
|
{
|
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
DWORD res;
|
|
|
|
|
|
|
|
lib = _FindMemoryModule(NULL, hModule);
|
|
|
|
if (lib)
|
|
|
|
res = MemorySizeofResource(lib->module, (HMEMORYRSRC) resource);
|
|
|
|
else
|
|
|
|
res = SizeofResource(hModule, resource);
|
|
|
|
|
|
|
|
dprint("MySizeofResource(%p, %p) -> %d (%p)\n", hModule, resource, res, lib);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-09-27 18:16:13 +00:00
|
|
|
LPVOID CALLBACK MyLoadResource(HMODULE hModule, HRSRC resource)
|
2019-09-26 12:02:43 +00:00
|
|
|
{
|
|
|
|
PHCUSTOMLIBRARY lib;
|
|
|
|
LPVOID res;
|
|
|
|
|
|
|
|
lib = _FindMemoryModule(NULL, hModule);
|
|
|
|
if (lib)
|
|
|
|
res = MemoryLoadResource(lib->module, (HMEMORYRSRC) resource);
|
|
|
|
else
|
|
|
|
res = LoadResource(hModule, resource);
|
|
|
|
|
|
|
|
dprint("MyLoadResource(%p, %p) -> %d (%p)\n", hModule, resource, res, lib);
|
|
|
|
return res;
|
|
|
|
}
|