|
我整理了一下d3d的基本结构,简单的注释了一段源码,一起来了解一下direct3d的世界吧。
1:d3d的初始化
LPDIRECT3D9 g_pD3D=NULL;//d3d对象
LPDIRECT3DDEVICE9 g_pd3dDevice=NULL;//d3d设备对象
LPDIRECT3DVERTEXBUFFER9 g_pVB=NULL;//顶点缓冲
//初始化D3D
HRESULT InitD3D(HWND hWnd)
{
//创建D3D
g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
//填充D3DDevice结构
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
//创建D3DDevice
g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp,&g_pd3dDevice);
//初始化几何数据
HRESULT InitGeometry()
{
//初始化顶点数据
CUSTOMVERTEX g_Vertices[]= { {-1.0f,-1.0f,0.0f,0xffff0000,}, {1.0f,-1.0f,0.0f,0xff0000ff,}, {0.0f,1.0f,0.0f,0xffffffff,}, };
//创建顶点缓冲区
g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0,D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT,&g_pVB,NULL)
//填入顶点数据
VOID*pVertices;
g_pVB->Lock(0,sizeof(g_Vertices),(void**)&pVertices,0)
returnE_FAIL;
memcpy(pVertices,g_Vertices,sizeof(g_Vertices));
g_pVB->Unlock();
//渲染函数
VOID Render()
{
pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
pDevice->SetRenderState(D3DRS_ZFUNC,D3DCMP_NEVER);//更改这两个渲染状态就可以实现透视功能
//清空缓冲
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
g_pd3dDevice->BeginScene()
//在BeginScene后台缓存绘制图形
//开始绘制图形
g_pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX)); g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,1);
g_pd3dDevice->EndScene();
//在EndScene结束后台缓存渲染图形
//在这可以得到我们的颜色,画准心。
g_pd3dDevice->Present(NULL,NULL,NULL,NULL);//将后台缓存绘制的图形提交到前台缓存显示
}
//清理资源
VOID Cleanup()
{
g_pVB->Release();//释放顶点缓存对象
g_pd3dDevice->Release();//释放设备对象
g_pD3D->Release();//释放d3d对象
}
下面是一篇网上的透视源码作简要注释
bool StartDll=1;
bool WallHack=1;//定义布尔变量用来判断是否开启透视功能
typedef HRESULT(WINAPI* DrawIndexedPrimitive_)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount);//从这开始是detours hook com接口需要的参数,后面有如何用detours hook com接口的方法,这里定义了一个类型
DrawIndexedPrimitive_ pDrawIndexedPrimitive;
HRESULT WINAPI nDrawIndexedPrimitive(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinIndex,UINT NumVertices, UINT StartIndex, UINT PrimitiveCount)//我们的hack函数。
{
IDirect3DVertexBuffer9* pStreamData = NULL;
UINT iOffsetInBytes,iStride;
pDevice->GetStreamSource(0,&pStreamData,&iOffsetInBytes,&iStride); //用来获取stride,前面是定义这个函数的三个参数
if ( iStride == 40 &&WallHack==1)//这里进行透视判断,当stride=40,WallHack=1时开启透视,如果我们不知道游戏人物的stride,可以增加一个变量把40替换掉,用自加来判断人物st
{
pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);//这里是更改渲染状态,禁用z轴,实现透视的方法,这应该都知道吧。
pDevice->SetRenderState(D3DRS_ZFUNC,D3DCMP_NEVER);
//再给一种写法,两种效果是不一样,下面的人物自身不会透视,看不到自身的结构。
pDevice->SetRenderState(D3DRS_ZENABLE,false);
pDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
pDrawIndexedPrimitive(pDevice,Type,BaseVertexIndex, MinIndex, NumVertices, StartIndex,
PrimitiveCount);
pDevice->SetRenderState(D3DRS_ZENABLE,true);
pDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID);
}
return pDrawIndexedPrimitive(pDevice, Type, BaseVertexIndex, MinIndex, NumVertices, StartIndex, PrimitiveCount);//返回值
}
int StartHack ();
BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call, LPVOID lpReserved )//这是默认的 DLL格式
{
if (StartDll)
{
StartDll=0;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)StartHack, NULL, NULL, NULL);
}
return TRUE;
}
int StartHack ()//取tb,方法不止一种,我们也可以通过d3d对象来取tb数组,取hook函数位置,自己可以打开d3d头文件数数是在第几个~~
{
char s[1000];
DWORD offsetBase=0x4FE571A0;
for(;; Sleep(500))
{
offsetBase=(DWORD)GetModuleHandle ("d3d9.dll");
if (offsetBase)
break;
}
DWORD a[2];
a[0]=offsetBase+0x88840;
sprintf (s,"[Noobshooter] Module d3d9 =%08X,Offset FuncHook =%08X",offsetBase,a[0]);
OutputDebugString (s);
pDrawIndexedPrimitive = (DrawIndexedPrimitive_)DetourFunction((PBYTE)a[0],(PBYTE)nDrawIndexedPrimitive);//进行绕到我们的函数,参数,地址,我们的函数
for (;;Sleep (500))//按键的判断
{
if (GetAsyncKeyState (VK_F9)!=0)
{
Beep (2000,200);
Wallhack=1;
}
if (GetAsyncKeyState (VK_F10)!=0)
{
Beep (3000,200);
WallHack=0;
}
}
return 1;
这是detours1.5用来hook com接口的格式
HRESULT STDCALL (*pfSeekTrampoline)(
IStream * This,
LARGE_INTEGER dlibMove,
DWORD dwOrigin,
ULARGE_INTEGER *plibNewPos);
HRESULT STDCALL SeekDetour(
IStream * This,
LARGE_INTEGER dlibMove,
DWORD dwOrigin,
ULARGE_INTEGER *plibNewPos)
{
return pfSeekTrampoline(This, dlibMove, dwOrgin, plibNewPos);
}
void detour_member_function(IStream *pi)
{
(*(PBYTE*)pfSeekTrampoline) = DetourFunction(
(PBYTE)pi->lpVtbl->Seek,
(PBYTE)SeekDetour);
};
看完有什么收获没?~~其实很简单,有兴趣的来交流下吧 |
评分
-
查看全部评分
|