[原创]非静态成员函数定位及HOOK以DirectX内部成员函数为例
本方法相对比较通用,以HOOK DirectX 的内部成员函数为例,Dx的DLL,如d3d9.dll ,D3DX9_42.dlll并没有导出API,只导出了部分如Direct3DCreate9,而关键功能函数如DrawIndexedPrimitive没有导出。
以D3DX9_42.dlll的D3XFont类的DrawTextA为例子
第一步:编写一个程序,调用要HOOK的功能函数,以DX的例子BasicHLSL(路径:\\Microsoft DirectX SDK (February 2010)\Samples\C++\Direct3D\BasicHLSL)为模板,在OnResetDevice函数(选这个函数是因为,改变下设置就可以激活)中添加代码
DWORD dwAddrPtr2=0x11223344; //这个用于CE搜索内存定位(包括只读属性)
__asm
{
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
}
RECT rect = { 10, 10, 500,200 };
DWORD DW5=g_pFont->DrawTextA(NULL, "XXXXXXXXXXX", -1, &rect, 0,D3DCOLOR_XRGB(255,255,255));
__asm
{
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
}
DWORD dwAddrPtr3=0x11223345; //用于定位
编译运行程序,CE搜索0x11223344 然后上下找有2堆NOP的中间会有一个CALL eax或edx之类的,在此处下断,获取call的地址即为函数所在的地址如0x1000147B(此时,对应同一版本的DLL已经是基址,但对不同系统和版本的地址是不一样的).
接下来获取所有版本的函数地址
搜索上面得到的1000147B,会找到一个或多个调用该地址的2级地址,然后根据成员函数的数量和测试,可以定位调用的函数。
如下
D3DXDebugMute+3A08 - 8B C1 - mov eax,ecx D3DXDebugMute+3A0A - 33 C9 - xor ecx,ecx D3DXDebugMute+3A0C - C7 00 8017B203 - mov [eax],10001780: [D3DXDebugMute+1E21] ;//10001780为ID3DXFont类的开始 D3DXDebugMute+3A12 - 8D 90 A4040000 - lea edx,[eax+000004A4] D3DXDebugMute+3A18 - 89 0A - mov [edx],ecx D3DXDebugMute+3A1A - 89 4A 04 - mov [edx+04],ecx D3DXDebugMute+3A1D - 8D 90 AC040000 - lea edx,[eax+000004AC]
此处10001780+成员函数顺序(顺序查看SDK)*4 此处DrawTextA顺序为第15个,就是10001780+14*4读取该偏移地址刚好是1000147B这个
通用特征码提取,C7 00 ?? ?? ?? ?? 8D 90 ?? ?? ?? ??
有了特征码
然后就可以用Detour开始HOOK了。
这个方法能做很多事,如:性能优化,修改游戏,调用XX....
人无完人,若有疏漏,欢迎指正交流
