代码参考http://bbs.pediy.com/showthread.php?t=85368&page=5
NFS热力追踪可以,但是尘埃3游戏无法实现。
通过DebugView发现,能Hook到Direct3DCreate9函数,跳转到自定义Direct3DCreate9函数。但是无法Hook到CreateDevice,跳转到自定义CreateDevice函数。请大神提供一些思路?
怀疑点:
1、尘埃3游戏没有采用Direct3DCreate9,而是采用Direct3DCreate9Ex,结果我的怀疑是错的;
2、尘埃3运行steam平台上,平台做保护;
3、测试程序打印Direct3DCreate9函数的地址不是固定的,其他能成功的游戏程序是固定的,但是Direct3DCreate9的地址和CreateDevice地址差是固定的;
谢谢大家帮忙啊!!!
部分代码:
void OnHookInit()
{
//这里只是hookDirect3DCreate9
pC=GetProcAddress(GetModuleHandle("d3d9.dll"),"Direct3DCreate9");//获得内存地址
DWORD oldpro=0;
memcpy(d3dcen5bytes,pC,5);
VirtualProtect(pC,5,PAGE_EXECUTE_READWRITE,&oldpro);
*(BYTE*)pC=0xe9;//0xe9在汇编中是跳转指令操作码
*(DWORD*)((BYTE*)pC+1)=(DWORD)hookedDirect3DCreate9-(DWORD)pC-5;//目标地址-原地址-5
}
//当运行到Direct3DCreate9时跳转到这里
LPDIRECT3D9 _stdcall hookedDirect3DCreate9(
UINT SDKVersion
)
{
__asm pushad
memcpy(pC,d3dcen5bytes,5);//首先还原入口的5个字节
m_pD3D=Direct3DCreate9(SDKVersion);
if(m_pD3D/*m_pD3D9Ex*/){//如果成功
pCdev=(void*)*(DWORD*)(*(DWORD*)m_pD3D+0x40);//获得IDirect3D9::CreateDevice的地址指针
DWORD oldpro=0;
memcpy(devcen5bytes,pCdev,5);//保存IDirect3D9::CreateDevice入口5个字节
VirtualProtect(pCdev,5,PAGE_EXECUTE_READWRITE,&oldpro);
*(BYTE*)pCdev=0xe9;
*(DWORD*)((BYTE*)pCdev+1)=(DWORD)hookedCreateDevice-(DWORD)pCdev-5;
}else{//如果失败就再hook一次
DWORD oldpro=0;
VirtualProtect(pC,5,PAGE_EXECUTE_READWRITE,&oldpro);
*(BYTE*)pC=0xe9;
*(DWORD*)((BYTE*)pC+1)=(DWORD)hookedDirect3DCreate9-(DWORD)pC-5;
}
__asm popad
return m_pD3D;
}
//当运行到IDirect3D9::CreateDevice的时候跳转到这里
HRESULT _stdcall hookedCreateDevice(
/*LPDIRECT3D9*/LPDIRECT3D9 pDx9,
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS * pPresentationParameters,
IDirect3DDevice9 ** ppReturnedDeviceInterface
)
{
__asm pushad
memcpy(pCdev,devcen5bytes,5);//先还原入口的5个字节
HRESULT ret=pDx9->CreateDevice( //创建设备
Adapter,
DeviceType,
hFocusWindow,
BehaviorFlags,
pPresentationParameters,
ppReturnedDeviceInterface);
if (ret==D3D_OK){//如果创建设备成功
LPDIRECT3DDEVICE9 m_pDevice=*ppReturnedDeviceInterface;
pPre=(void*)*(DWORD*)(*(DWORD*)m_pDevice+0x44);//获得IDirect3DDevice9::Present的地址指针
memcpy(pren5bytes,pPre,5);//保存IDirect3DDevice9::Present入口的5个字节
DWORD oldpro=0;
VirtualProtect(pPre,5,PAGE_EXECUTE_READWRITE,&oldpro);
*(BYTE*)pPre=0xe9;
*(DWORD*)((BYTE*)pPre+1)=(DWORD)hookedPresent-(DWORD)pPre-5;
}else{//如果失败再hookIDirect3D9::CreateDevice一次
DWORD oldpro=0;
VirtualProtect(pCdev,5,PAGE_EXECUTE_READWRITE,&oldpro);
*(BYTE*)pCdev=0xe9;
*(DWORD*)((BYTE*)pCdev+1)=(DWORD)hookedCreateDevice-(DWORD)pCdev-5;
}
__asm popad
return ret;
}
现在有辅助软件“游戏家家”,可以实现画面顶层绘制,我最终也想达到这种效果。
[培训]科锐逆向工程师培训第53期2025年7月8日开班!