Почему получение указателя экспортированной функции напрямую возвращает адрес в том же модуле? - PullRequest
0 голосов
/ 21 января 2019

Я использую классическую установку для перехвата функций d3d9: внедрение DLL, затем получение адресов целевых функций и исправление их с помощью инструкции JMP.

Однако я столкнулся с чем-то, что я не совсем понимаю.Рассмотрим следующий фрагмент из библиотеки DLL, которую я вставлю в целевой процесс:

HMODULE ModuleBasedOnGetAPI = NULL;
HMODULE ModuleBasedOnAddress = NULL;

ModuleBasedOnGetAPI = GetModuleHandleA("d3d9.dll");
D3D9Create_Original = (t_D3D9Create)GetProcAddress(ModuleBasedOnGetAPI,
                      "Direct3DCreate9");

D3D9Create_Original2 = &Direct3DCreate9;
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
                   GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                   (LPCSTR)D3D9Create_Original2, &ModuleBasedOnAddress);

char ModuleBasedOnGetAPI_path[_MAX_PATH];
GetModuleFileNameA(ModuleBasedOnGetAPI, ModuleBasedOnGetAPI_path, _MAX_PATH);

char ModuleBasedOnAddress_path[_MAX_PATH];
GetModuleFileNameA(ModuleBasedOnAddress, ModuleBasedOnAddress_path,
                  _MAX_PATH);

, где D3D9Create_Original и D3D9Create_Original2 являются указателями на функции типа:

IDirect3D9*(__stdcall *)(UINT)

В основном я сделал обычный GetModuleHandleпозвонить и получил имя этого файла.А затем я получил указатель на функцию и использовал GetModuleHandleEx с GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, чтобы в основном определить, из какой DLL поступил этот адрес.

Итак, ModuleBasedOnGetAPI_path - это фактический путь к файлу d3d9.dll.В то время как ModuleBasedOnAddress_path, кажется, путь моей DLL, из которой был взят этот фрагмент.

Так почему же это?почему функция Direct3DCreate9 находится как в моей DLL, так и в d3d9.dll?Есть ли что-то связанное с тем, что я связал d3d9.lib при сборке моей DLL?

1 Ответ

0 голосов
/ 21 января 2019

Какова ваша конфигурация сборки (т. Е. Отладка или выпуск)? Похоже, здесь важна оптимизация компилятора.

Для сборки выпуска я не могу воспроизвести проблему - оба адреса совпадают.

Для сборки отладки ваше предположение верно. Это потому, что когда вы ссылаетесь на Direct3DCreate9 непосредственно в своем коде, вы вызываете код заглушки в своем собственном модуле, который в дальнейшем получит реальный адрес Direct3DCreate9 из таблицы адресов импорта .

Чтобы лучше проиллюстрировать концепцию:

enter image description here

Обратите внимание, что Visual Studio уже сообщает вам, что два адреса из разных модулей.

Посмотрим на адрес 0x008f1249:

enter image description here

Это не более, чем jmp. Взгляните на 0x08FCFAD дальше:

enter image description here

Еще один прыжок. И наконец 0x0913220:

enter image description here

Пожалуйста, вспомните значение D3D9Create_Original - здесь реальный адрес, который совпадает с D3D9Create_Original.

...