【发布时间】:2012-03-14 20:28:13
【问题描述】:
我正在尝试查找在测试应用程序中导入的 wglGetProcAddress (OpenGl32.dll) 条目。出于某种原因,名称为“wglGetProcAddress”的导入确实指向通过在 Opengl32.dll 上调用 GetModuleHandle 和 GetProcAddress 返回的相同函数。
可执行文件已加载到内存中,并且是一个进程,其线程当前处于挂起状态。以下代码正确读取了该可执行文件导入的名称模块及其函数。因此,IAT 不应包含 RVA,因为它已被加载。
HMODULE h = GetModuleHandle("OPENGL32.dll");
DWORD expect_addr = (DWORD)GetProcAddress(h, "wglGetProcAddress");
PIMAGE_IMPORT_DESCRIPTOR import_desc = (PIMAGE_IMPORT_DESCRIPTOR)(pmem + import_dir);
while (import_desc->Name)
{
PIMAGE_THUNK_DATA thunk = (PIMAGE_THUNK_DATA)(pmem + import_desc->OriginalFirstThunk);
while (thunk->u1.Function)
{
PIMAGE_IMPORT_BY_NAME import = (PIMAGE_IMPORT_BY_NAME)(pmem + thunk->u1.AddressOfData);
printf("%s 0x%X\n", import->Name, thunk->u1.Function);
if ((DWORD)expect_addr == (DWORD)thunk->u1.Function)
{
printf("Found wglGetProcAddress\n");
}
else if (!strcmp((const char*)import->Name, "wglGetProcAddress"))
{
printf("Found wglGetProcAddress's import, but the function has a different value.\n");
}
++thunk;
}
++import_desc;
}
GetProcAddress 从该原始值返回地址 60XXC245,其中 XX 变化,但 thunk->u1.Function 始终返回 0xA46D8。 thunk->u1 中的所有内容(Function、AddressOfData、Ordinal 和 ForwarderString)都有 相同的值。导入描述符和导入的名称正确。有人看到我错过了什么吗?
编辑: 我正在尝试其他方法:我正在扫描 pmem(内存中可执行文件的图像)以查找我期望的 IAT 条目,但它也没有找到:
HMODULE h = GetModuleHandle("OPENGL32.dll");
DWORD expect_addr = (DWORD)GetProcAddress(h, "wglGetProcAddress");
printf("Looking for 0x%X\n", expect_addr);
for (int i = 0; i < pmem_size - sizeof(DWORD); i++)
{
if (*(DWORD*)(pmem + i) == expect_addr)
{
printf("0x%X at 0x%X\n", *(DWORD*)(pmem + i), i);
}
}
已解决:我没有意识到,但是使用 CREATE_SUSPENDED 调用 CreateProcess 会阻止 Windows 加载器使用实际地址填充 FirstThunk。如果我让进程运行一秒钟然后挂起线程,它会很好地挂钩 IAT 地址。现在我得去寻找一种方法来解决这个问题。
【问题讨论】:
标签: c hook portable-executable