Я пытаюсь найти запись для wglGetProcAddress (OpenGl32.dll), импортированного в тестовое приложение. По какой-то причине импорт с именем «wglGetProcAddress» указывает на ту же функцию, возвращаемую путем вызова GetModuleHandle и GetProcAddress для Opengl32.dll.
Исполняемый файл загружен в память и является процессом, поток которого в настоящий момент приостановлен. Следующий код правильно читает имена модулей и их функции, импортированные этим исполняемым файлом. Следовательно, 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) имеет
такое же значение. Имена дескрипторов импорта и импорта правильные. Кто-нибудь видит, чего мне не хватает?
Edit:
Я пытаюсь что-то еще: я сканирую 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);
}
}
решено: Я не понял этого, но вызов CreateProcess с помощью CREATE_SUSPENDED не позволяет загрузчику Windows заполнить FirstThunk действительными адресами. Если я позволю процессу запуститься на секунду, а затем приостановить поток, он отлично перехватит адрес IAT. Теперь мне нужно искать способ исправить это.