I'm trying to locate the entry for wglGetProcAddress (OpenGl32.dll) imported in a test application. For some reason, the import whose name is "wglGetProcAddress" does point to the same function returned by calling GetModuleHandle and GetProcAddress on Opengl32.dll.
The executable file has been loaded into memory and is a process with its thread currently suspended. The following code correctly reads the names modules and their functions imported by that executable. Hence, the IAT should not contain RVAs since it has been loaded.
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 from that original value returns the address 60XXC245 where XX varies, but thunk->u1.Function always returns 0xA46D8. Everything in thunk->u1 (Function, AddressOfData, Ordinal and ForwarderString) has the same value. The names of the import descriptors and imports correct. Does anyone see what I'm missing?
Edit: I'm trying something else: I'm scanning pmem (image of the executable in memory) for what I expect is the IAT entry, but it doesn't locate that either:
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);
}
}
SOLVED: I didn't realize it, but calling CreateProcess with CREATE_SUSPENDED prevents the windows loader from populating FirstThunk with the actual addresses. If I let the process run for a second and then suspend the thread, it hooks the IAT address perfectly fine. Now I have to go look for a way to fix that.