分享免费的编程资源和教程

网站首页 > 技术教程 正文

D3D透视辅助原理C++游戏逆向

goqiw 2024-09-12 16:23:44 技术教程 18 ℃ 0 评论

关于D3D透视的文章其实早就有位大牛发过了这里我就以我的视角详细讲讲,制作一个D3D辅助的详细过程吧,下面我还会把源码给大家,也算是个万能模板吧,只要是使用D3D9的游戏都可以吧。

工具 VS2010 ,游戏就是360的终极火力,debugview ,VC++6.0里面的工具(spy++,depends),dxsdk_jun10(开发环境),kerneldective。

下面我就说说原理,3d游戏有使用两种渲染的方法,一种是Direct3D,一种是opengl,所以说开opengl就不能用d3d透视了


,那么我今天说得是使用d3d9这个动态链接库的游戏。

既然是透视那么,必然要hook某个函数对其做做过滤,所以我们可以用depends打开c盘下system32文件夹里面的d3d9.ll


,发现并没有我们想要的DrawIndexedPrimitive这个函数,查阅msdn才发现,都被封装在com组件里,以类的方式调用,所


以当我们查看msdn的时候,总是看到IDirect3DDevice9::DrawIndexedPrimitive ,DrawIndexedPrimitive是在


IDirect3DDevice9这个类里面,所以说要找DrawIndexedPrimitive的地址就变得很棘手了,但是我们可以另辟蹊径自己写一


个D3D9的程序然后自己调用DrawIndexedPrimitive,这时候我们调试它就在DrawIndexedPrimitive下个断点,跟踪就找到


DrawIndexedPrimitive的地址了,因为每一次开机

dll都要重定位,但是每个进程加载相同dll时候dll的基地址不变,只有重启才会变化,我们找到DrawIndexedPrimitive的地址


然后减去我们用kerneldective查看到的d3d9.dll的基地址,这样就得到偏移了,我们编程的时候就可以算出


DrawIndexedPrimitive的地址了。

至于HRESULT DrawIndexedPrimitive(

[in] ,D3DPRIMITIVETYPE Type

[in] INT pDevice,

[in] UINT MinIndex,

[in] UINT NumVertices,

[in] UINT StartIndex,

[in] UINT PrimitiveCount

);

有五个参数其中对我们有用的就是NumVertices(渲染的顶点索引的跨度 ,这个和Strides(数据流中每个顶点所占内存的大


小),都是我们区分人物模型的重要来源,Strides可以这样得到 pDevice->GetStreamSource(0, &Stream_Data, &Stride);


一个简单的调用,获得两个参数后接下来再在游戏中通过char temp【512】 sprint(temp,"d\r


\n",Stride);OutputDebugStrinA\(temp);

来打印,然后打开debugview勾上capture32来接收信息,接下来就可以进行过滤工作了。一般Stirde的值都在100之内而且


也就几个而已,对于这个游戏用Stride判断就可以了,一个个过滤,

我们写个判断语句if(Stride==1){ pDevice->SetRenderState( D3DRS_ZENABLE,FALSE);

else{ pDevice->SetRenderState( D3DRS_ZENABLE,TRUE},SetRenderState的第三个参数为假意思是禁用z轴缓冲。不知道


大家听懂了没,我都是把自己觉得容易的都说出来了。

原理说完了,接下来就是编程解决问题了,这个对于我来说也是个很大的挑战,因为编程我也是不太的菜鸟,其中有些细节


也是困扰了我很久,我会在下面提示需要注意的地方。

首先安装好VS2010 感觉挺不错的加了代码错误提示极大方便了我们,和dxsdk_jun10(开发环境),然后我们在D盘目录


下创建个D3DHook文件夹 打开VS2010 新建

MFC的应用程序类型选择基于对话框,,接着在解决方案中添加win32项目,在应用程序设置中选择dll(名字就叫Hookdll),


勾上导出符号(这是我们注入用的动态链接库),完成,接下去在Hookdll开始写函数了,既然是hook就需要改写进程方法就


是注入,我用的是 HHOOK WINAPI SetWindowsHookEx(

__in int idHook, \\钩子类型

__in HOOKPROC lpfn, \\回调函数地址

__in HINSTANCE hMod, \\实例句柄

__in DWORD dwThreadId); \\线程ID

通过钩子注入,其中 第一个参数就是钩子的类型,其中类型好多详情参考msdn,那就是选择WH_CBT ,这是一个notice类型


的钩子,然后第二个参数回调函数,

LRESULT CALLBACK HookProc

(

int nCode,

WPARAM wParam,

LPARAM lParam

);

就是触发钩子后操作系统会调用这个函数,

简单的dll写好后我们试着编译,编译好了就编译另一个注入用的程序,他需要调用动态链接库所以编译前得配置一下包含


文件等等,右键这个对话框程序的项目点属性-》配置属性-》vc++目录,其中添加包含目录D:\D3DHook\D3DHook


\Hookdll,链接器-》输入-》附加依赖项是Hookdll.lib,链接器-》输入-》常规-》附加库目录是D:\D3DHook\D3DHook


\Debug,然后编译。

配置ide环境,为后面使用d3d绘图函数提供所需文件,也是在项目属性里面VC++目录中的包含文件那一项,添加,

E:\d3d\include,库文件中的那项添加,E:\d3d\lib\x86(我的dx sdk 安装在d:\d3d目录)。这样ide环境就配置好了。

其他,编程的我都在源码里面注释很清楚了。

代码中 jmp 地址换算问题 ,这里有个公式 ,

JMP的地址(88881234) – 代码地址(010073bb) – 5(字节) = 机器码跳转地址(E9 87879e74)

下面讲一下,调试中的问题和工具的使用:

附件,示例代码拿来编译,在Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,0,5,0,1);插入int3断点,运行,


就会断下来了,这还没显示出汇编,按下调试选项-》窗口-》反汇编


,接着F11跟进call eax,就到了,如何用spy++获取窗口类,search下面那个望远镜,点一下,然后鼠标点击新窗口的那个靶子,按住不放,再移到游戏窗口中就会显示出它的类了,class就是类

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表