Project1
标题:
关于一段DirectX8,Hook的代码。
[打印本页]
作者:
yangff
时间:
2012-4-21 20:51
标题:
关于一段DirectX8,Hook的代码。
本帖最后由 yangff 于 2012-4-21 20:52 编辑
这段代码是根据Direct9 Hook的修改的,
曾在RMXP上成功过,
但是在VA 的时候似乎失败了?求各种神犇。。。
@晴兰
#include <windows.h>
#include <stdio.h>
#include <d3d8.h>
#include <D3dx8core.h>
#include <d3d9.h>
#ifdef _MANAGED
#pragma managed(push, off)
#endif
IDirect3D8 * _stdcall hookedDirect3DCreate8(UINT SDKVersion);
HRESULT _stdcall hookedCreateDevice(
LPDIRECT3D8 pDx8,
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS * pPresentationParameters,
IDirect3DDevice8 ** ppReturnedDeviceInterface
);
BOOL _stdcall DrawMyText(LPDIRECT3DDEVICE8 pDxdevice,TCHAR* strText ,int nbuf);
//STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface) PURE;
LPDIRECT3D8 m_pD3D=NULL; //Direct3D对象的接口指针
void * pC=NULL;//Direct3DCreate8函数地址指针
void * pCdev=NULL;//IDirect3D8::CreateDevice函数地址指针
void * pPre=NULL;//IDirect3DDevice8::Present函数地址指针
BYTE d3dcen5bytes[5];//用于保存Direct3DCreate8入口的5字节
BYTE devcen5bytes[5];//用于保存IDirect3D8::CreateDevice入口的字节
BYTE pren5bytes[5];//用于保存IDirect3DDevice8::Present入口的5字节
//当程序运行到IDirect3DDevice8::Present入口处将跳转到这里
HRESULT _stdcall hookedPresent(
LPDIRECT3DDEVICE8 pDxdevice,//类的this指针
CONST RECT * pSourceRect,//此参数请参考dx sdk
CONST RECT * pDestRect,//同上
HWND hDestWindowOverride,//同上
CONST RGNDATA * pDirtyRegion//同上
)
{
__asm pushad
//绘制代码开始
if(pCdev && pC && pPre){
char strdraw[]="在RM中描绘文字的蛋疼测试!";
DrawMyText(pDxdevice,strdraw,sizeof strdraw-1);//绘制文本
}
//绘制代码结束
if(pC && pCdev && pPre)
memcpy(pPre,pren5bytes,5);//先还原IDirect3DDevice9::Present入口的5字节
HRESULT retdata= pDxdevice->Present(pSourceRect,pDestRect,hDestWindowOverride,pDirtyRegion);
if(pC && pCdev && pPre){
//DWORD oldpro=0;
//VirtualProtect(pPre,5,PAGE_EXECUTE_READWRITE,&oldpro);
//调用完IDirect3DDevice8::Present后再hook一次
*(BYTE*)pPre=0xe9;
*(DWORD*)((BYTE*)pPre+1)=(DWORD)hookedPresent-(DWORD)pPre-5;
}
__asm popad
return retdata;
}
//当运行到Direct3DCreate8时跳转到这里
IDirect3D8 * _stdcall hookedDirect3DCreate8(
UINT SDKVersion
)
{
__asm pushad
memcpy(pC,d3dcen5bytes,5);//首先还原入口的5个字节
m_pD3D=Direct3DCreate8(SDKVersion);
if(m_pD3D){//如果成功
MessageBox(0,"hookedDirect3DCreate8","hookedDirect3DCreate8",0);
pCdev=(void*)*(DWORD*)(*(DWORD*)m_pD3D+0x30);//获得IDirect3D8::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)hookedDirect3DCreate8-(DWORD)pC-5;
}
__asm popad
return m_pD3D;
}
//当运行到IDirect3D9::CreateDevice的时候跳转到这里
HRESULT _stdcall hookedCreateDevice(
LPDIRECT3D8 pDx8,
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS * pPresentationParameters,
IDirect3DDevice8 ** ppReturnedDeviceInterface
)
{
__asm pushad
memcpy(pCdev,devcen5bytes,5);//先还原入口的5个字节
HRESULT ret=pDx8->CreateDevice( //创建设备
Adapter,
DeviceType,
hFocusWindow,
BehaviorFlags,
pPresentationParameters,
ppReturnedDeviceInterface);
if (ret==D3D_OK){//如果创建设备成功
MessageBox(hFocusWindow,"hookedCreateDevice","hookedCreateDevice",0);
LPDIRECT3DDEVICE8 m_pDevice=*ppReturnedDeviceInterface;
pPre=(void*)*(DWORD*)(*(DWORD*)m_pDevice+0x30);//获得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;
}
//我自己的绘制文本的过程
BOOL _stdcall DrawMyText(LPDIRECT3DDEVICE8 pDxdevice,TCHAR* strText ,int nbuf)
{
if(m_pD3D && pDxdevice){
RECT myrect;
myrect.top=150; //文本块的y坐标
myrect.left=0; //文本块的左坐标
myrect.right=500+myrect.left;
myrect.bottom=100+myrect.top;
pDxdevice->BeginScene();//开始绘制
LOGFONT lf;
ZeroMemory(&lf, sizeof(LOGFONT));
lf.lfHeight = 24; //字体高度
lf.lfWidth = 12; // 字体宽度
lf.lfWeight = 100;
lf.lfItalic = false;
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName, "Times New Roman"); // 字型
ID3DXFont* font=NULL;
if(D3D_OK!=D3DXCreateFontIndirect(pDxdevice, &lf, &font)) //创建字体对象
return false;
font->DrawTextA(strText,nbuf,&myrect,DT_TOP | DT_LEFT,D3DCOLOR_ARGB(0,255,255,255));
pDxdevice->EndScene();//结束绘制
font->Release();//释放对象
}
return true;
}
bool StartHooker()
{
pC=GetProcAddress(GetModuleHandle("d3d8.dll"),"Direct3DCreate8");//获得内存地址
DWORD oldpro=0;
memcpy(d3dcen5bytes,pC,5);
VirtualProtect(pC,5,PAGE_EXECUTE_READWRITE,&oldpro);
*(BYTE*)pC=0xe9;//0xe9在汇编中是跳转指令操作码
*(DWORD*)((BYTE*)pC+1)=(DWORD)hookedDirect3DCreate8-(DWORD)pC-5;//目标地址-原地址-5
//char str[255];
//sprintf(str,"%d",pC);
//MessageBox(0,str,"StartHooker",0);
return true;
}
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
)
{
return 1;
}
复制代码
作者:
凌童鞋
时间:
2012-4-21 21:21
围观神触,召唤
@晴兰
作者:
sdgn
时间:
2018-7-6 20:33
請問怎麼用? 這是 C# 嗎?
作者:
fux2
时间:
2018-7-6 21:26
sdgn 发表于 2018-7-6 20:33
請問怎麼用? 這是 C# 嗎?
显然C++,不过这已经是上古老坟了,而且目前d3dhook的资料一大把……现成的到处都是
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1