Visual leak Detact 模块导出函数替代
BOOL PatchImport (HMODULE importmodule, moduleentry_t *module)
{
//参数1 - 模块的句柄,HMODULE kernel32 = GetModuleHandleW(L"kernel32.dll");
// 参数2
替代函数信息 moduleentry_t ntdllPatch [] = {
// "ntdll.dll", NULL, ldrLoadDllPatch,
// };
if (exportmodule == NULL)
return FALSE;
IMAGE_IMPORT_DESCRIPTOR *idte;IMAGE_SECTION_HEADER *section;
ULONG size;
// 为导入模块找到导出模块的IDT表,导入模块可能含有多个iat表,每个iat表含有对于的api地址再里面,遍历所有的iat表格,找到我们关心的函数,替换成我们想要hook的函数。
g_imageLock.Enter();
__try
{
// typedef struct _IMAGE_IMPORT_DESCRIPTOR {
// union {
// DWORD Characteristics; // 0 for terminating null import descriptor
// DWORD OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
// } DUMMYUNIONNAME;
// DWORD TimeDateStamp; // 0 if not bound,
// -1 if bound, and real date\time stamp
// in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)
//DWORD ForwarderChain; // -1 if no forwarders
// DWORD Name;
// DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses)
//} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
IMAGE_DIRECTORY_ENTRY_IMPORT, &size, §ion);
}
__except(FilterFunction(GetExceptionCode()))
{
idte = NULL;
}
g_imageLock.Leave();
if (idte == NULL) {
// This module has no IDT (i.e. it imports nothing).
return FALSE;
}
int result = 0;
while (idte->FirstThunk != 0x0) {
PCHAR name = (PCHAR)R2VA(importmodule, idte->Name);
UNREFERENCED_PARAMETER(name);
//替换表当中包含我们所有想要替换的函数
patchentry_t *entry = module->patchTable;
int i = 0;
while(entry->importName)
{
//导入函数
LPCSTR importname = entry->importName;
// hook函数名
LPCVOID replacement = entry->replacement;// Get the *real* address of the import. If we find this address in the IAT,
// then we've found the entry that needs to be patched.
FARPROC import2 = VisualLeakDetector::_RGetProcAddress(exportmodule, importname);
FARPROC import = GetProcAddress(exportmodule, importname);
if ( import2 )
import = import2;
// Perhaps the named export module does not actually export the named import?
if (import == NULL)
{
entry++; i++;
continue;
}
// Locate the import's IAT entry.
IMAGE_THUNK_DATA *iate = (IMAGE_THUNK_DATA*)R2VA(importmodule, idte->FirstThunk);
while (iate->u1.Function != 0x0)
{
if (iate->u1.Function != (DWORD_PTR)import)
{
iate++;
continue;
}
// Found the IAT entry. Overwrite the address stored in the IAT
// entry with the address of the replacement. Note that the IAT
// entry may be write-protected, so we must first ensure that it is
// writable.
if ( import != replacement )
{
if (entry->original != NULL)
*entry->original = (LPVOID)iate->u1.Function;
//亮点,这边hook我们想要的函数。
DWORD protect;
VirtualProtect(&iate->u1.Function, sizeof(iate->u1.Function), PAGE_EXECUTE_READWRITE, &protect);
iate->u1.Function = (DWORD_PTR)replacement;
VirtualProtect(&iate->u1.Function, sizeof(iate->u1.Function), protect, &protect);
}
// The patch has been installed in the import module.
result++;
iate++;
}
entry++; i++;
}
idte++;
}
// The import's IAT entry was not found. The importing module does not
// import the specified import.
return result > 0;
}