我正在使用经典的设置来挂接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中?构建DLL时我链接了d3d9.lib是否与事实有关?
答案 0 :(得分:0)
您的构建配置是什么(即调试或发布)?看起来编译器的优化在这里也很重要。
对于发布版本,我无法重现该问题-这两个地址相同。
对于Debug版本,您的假设是正确的。这是因为当您直接在代码中引用Direct3DCreate9
时,您是在自己的模块中调用存根代码,这将进一步从Import Address Table获取真实的Direct3DCreate9
地址。>
为了更好地说明这一概念,
请注意,Visual Studio已经告诉您这两个地址来自不同的模块。
让我们看看地址0x008f1249
:
不超过jmp
。进一步查看0x08FCFAD
:
另一跳。最后0x0913220
:
请记住D3D9Create_Original
的值-这是与D3D9Create_Original
相同的真实地址。