转自[取决于你] D3D游戏内存HOOK绘制原理教学(DLL注入而非外...
哈喽,祖国的花朵们。开学了,新的学期记得好好加油,好好学习,也记得要和同学们老师们搞好关系~祖国的花朵
https://www.520xyz.com/data/attachment/forum/202009/02/102252xe22retnwsvjt3t3.png
今天应个景来发个d3d游戏的hook绘制教程供花朵们学习参考吧!
好好学习
https://www.520xyz.com/data/attachment/forum/202009/02/102726pzlkrtk7zm9dg9tu.jpg
之前发过一次原理剖析:https://www.xuenixiang.com/thread-2671-1-1.html (D3DHOOK方框透视及透明窗口外部绘制原理解析),这篇文章我猜可能很多人都是看的比较云里雾里吧,因为是纯原理讲解,可能没有基础的花朵们看不太明白,所以今天我们就来实战讲解D3D内存HOOK绘制的原理,也就是某些人所谓的dll注入游戏的那种d3d绘制(不是外部绘制,外部绘制下次再说)。
直接切入主题 D3D初始化
https://www.520xyz.com/data/attachment/forum/202009/02/104040ga003aa20irnbtvq.png
从书中可以看到:“D3D初始化,首先得获取接口IDirect3D9的指针,然后通过这个接口IDirect3D9来创建接口IDirect3DDevice9(这个接口是C++对象),接下来就可以通过这个设备对象IDirect3DDevice9来绘制图形”。
这个初始化的原理在之前的文章有提过:
D3D初始化流程
https://www.520xyz.com/data/attachment/forum/202009/02/105509mgzj1ke2ilewwr3o.png
注意看一下蓝色线画出的地方,Direct3DCreate9创建的D3D对象就是IDirect3D9,然后调用IDirect3D9对象中的CreateDevice函数来创建一个D3D设备IDirect3DDevice9;
注:常用的BeginScene、Presend、EndScene、Clear以及各种顶点绘制函数,都在这个D3D设备IDirect3DDevice9对象里。通俗的来讲,想要绘制各种图形就必须获取这个D3D设备IDirect3DDevice9对象。
接下来是重点,开始重点之前请务必搞清楚上面几个函数和对象之间的关系,多看几遍。
搞清楚了上面几个函数和对象的关系之后,我想大家应该能猜出我们要干啥了吧。没错,就是获取游戏D3D初始化的D3D设备IDirect3DDevice9对象(后面简称D3D设备对象)。说的轻松,怎么获取呢?
获取D3D对象
https://www.520xyz.com/data/attachment/forum/202009/02/112106mesywqmmwagr5gsx.jpg
有请我们大名鼎鼎的HOOK技术出场,要问抢亲哪家强,隔壁老王HOOK强。使用HOOK技术直接把游戏中的D3D设备对象抢过来一起用,说白了就是D3D设备对象给游戏戴了绿帽子。
D3DHOOK
https://www.520xyz.com/data/attachment/forum/202009/02/113518uornbtojnzt33v5k.jpg
本来只有游戏绘制图像在用的D3D设备对象,现在通过HOOK后咱们也可以用游戏的D3D设备对象来绘制图形,绘制框框啥的。比如我们可以HOOK一下这个函数CreateDevice,可以在CreateDevice这个函数创建D3D设备对象的时候将其对象地址拷贝一份然后一起用。
通过对某大佬在本论坛开源的内存DLL绘制的源码进行分析,可以看到大佬们开源的代码是hook了470B11这个地址,所谓的dx_in_游戏代码
https://www.520xyz.com/data/attachment/forum/202009/02/114143g5iui5ib70g3znnz.png
以上是劫持DLL程序入口,调用hook_d3d(dx_in_游戏代码)准备开始HOOK;
进入hook_d3d函数开始分析代码https://www.520xyz.com/data/attachment/forum/202009/02/115228qayt8ra8dtzl4zqx.png
可以看到进入hook_d3d后会先执行hook_init,那么我们再来看下hook_init函数中的代码
https://www.520xyz.com/data/attachment/forum/202009/02/115522mtt3h3pjhklj9a5z.png
大概说一下这个函数做了什么,首先是申请一小片内存,然后在这一小片内存里写上中转的汇编代码,中转汇编代码的作用就是跳转到wjydbg子程序。我们可以在wjydbg子程序中开始写我们自己的绘制图形代码等。。因为wjydbg这个子程序是我们自己创建的。
https://www.520xyz.com/data/attachment/forum/202009/02/120210n6e9bbed9cbbwirr.png
注释写的比较详细,建议配合注释看一遍,消化一下。然后再多看几遍,再消化一下。
现在我们回到游戏刚开始的时候,此时我们还没有开始HOOK;
游戏中dx_in_游戏代码的基址代码状态是这样的:
https://www.520xyz.com/data/attachment/forum/202009/02/120741wha5560r0g8l595h.png
据我分析判断,这个eax的值就是我们所需的D3D设备对象
接下来开始HOOK这里的代码,获取我们想要的EAX的值,HOOK之后代码是这样的:
https://www.520xyz.com/data/attachment/forum/202009/02/121023nd4at94wililmaia.png
可以看到原先绿色那一行的代码变成了Jmp xxxxxxx,jmp就是跳转指令,jmp执行后将会跳转到我们上面所说的中转汇编代码,接下来我们看一下中转汇编代码是什么样的:
https://www.520xyz.com/data/attachment/forum/202009/02/121344pqnuc3tur8unquwm.png
上面的Jmp跳转的就是这里的代码,看一下这里的代码,有一个我们熟悉的名字BugTrap.dll,其实这就是我们劫持DLL注入用的名字。这个mov eax,BugTrap.dll+E8E9命令中的BugTrap.dll+E8E9其实就是我们易语言源码中wjydbg的子程序的地址,call eax就是调用wjydbg();然后后面就是一些恢复指令和跳回执行。
这里能明白不?再理一下思路,举个例子:公交车从A站 B站 C站 D站依次行驶,而我们的HOOK就是在B站和C站之间插了一个我们自己的站点E站,然后公交车的行驶路线就变成了A、B、E、C、D,这样我们就可以在公交车到E站的时候做很多事。因为E站是我们自己的。
源代码我发到附件中,没有用任何模块。直接编译成BugTrap.dll丢到游戏根目录就能看到效果,以后的版本记得更新下dx_in_游戏代码的基址,本源码仅供学习使用,只有绘制功能,没有其他任何效果。仅供学习使用!!!
**** Hidden Message *****
每天都有1次免费给楼主评分送学币的机会! 楼主 获取到游戏设备指针后,能通过指针获取后台游戏画面缓存吗? p76ip76ip76i gs88q 发表于 2020-10-11 01:06
p76ip76ip76i
别水贴 666666666666666666
感谢分享,我会认真学习的! 学习学习 hoaqianggggg 学习一下