D3DHOOK方框透视透明窗口外部绘制方法原理

易语言 2020-09-17 21:27:53

D3DHOOK方框透视透明窗口外部绘制方法原理

首先我们需要创建一个windows窗口,这里直接使用易语言创建就行
' 自己创建一个窗口并载入(我们将用这个窗口作为透明的绘制窗口)
载入 (窗口1, , 假)

' 读取被创建的窗口的句柄
窗口句柄 = 窗口1.取窗口句柄 ()

' 接下来使用SetWindowLongA设置窗口样式,GetWindowLong的意思便是获取窗口原来的样式,整句话的意思就是窗口原有的样式基础上再添加一些样式!!创建窗口的详细样式大家自己百度一下就知道了
SetWindowLongA (窗口句柄, -16, 位与 (GetWindowLong (窗口句柄, -20), 位取反 (位或 (256, 1))))

' 激活并显示一个窗口。如果窗口被最小化或最大化,系统将其恢复到原来的尺寸和大小。应用程序在第一次显示窗口的时候应该指定此标志。nCmdShow=1。
ShowWindow (窗口句柄, 1)

' 更新客户区
UpdateWindow (窗口句柄)

' 设置窗口的扩展样式
SetWindowLongA (窗口句柄, -20, 589992)

' 将窗口设置为透明,参数1为需要透明的窗口的句柄;参数2则是需要被透明掉的颜色,0为黑色;参数3表示透明度,0-255,0表示完全透明,255为完全不透明,这里是完全透明;参数4则是透明方式
SetLayeredWindowAttributes (窗口句柄, 0, 0, 1)

一些游戏为了防止创建第三方绘制窗口,会强制将自己的游戏窗口置顶,这样你创建的透明绘制窗口就无法绘制到游戏窗口的上层,解决办法就是使用SetWindowPos将游戏窗口取消强制置顶!

纯源码例子已经打包,看懂了此例子也就不用再去使用别人的D3D绘制模块了,自己就可以编写纯源码D3D绘制了!

D3D HOOK就相当于是补丁,就像是我们给游戏额外开发了一个新功能一样,绘制帧数都和游戏一模一样。其缺点就是,修改游戏内存会触发游戏内的冗余代码检验。俗称CRC检测。
那么为了绕过CRC检测,于是诞生了我们的外部窗口绘制,其原理就是在游戏窗口的上层创建一层透明窗口,然后我们的绘制函数是运行在这个透明窗口上的,而这个透明窗口与我们的游戏窗口属于两个不相关的进程,所以也就不会被游戏进程的CRC检测到了。当然也有一些人会选择直接干掉CRC检测,例如将执行检测的那段代码入口nop掉,或者jmp等,再者是抹掉注入DLL的PE特征等。

这里拿d3d9做示例:当我们打开FPS游戏程序后,首先会创建一个正常的windows窗口,然后会调用Direct3DCreate9这个函数来创建一个D3D对象,然后通过这个D3D对象利用CreateDevice函数来创建一个D3D设备,再然后就可以调用各种绘制函数在这个D3D设备上绘制各种图形,如人物模型、游戏地图等、最后调用Present这个函数将前面调用的绘制函数渲染出的图形提交给显卡以显示到显示器上~
而D3D HOOK的原理则是通过修改游戏程序的内存实现绘制,如通过GetProcAddress函数获取到Direct3DCreate9这个函数的地址,然后我们就可以通过Direct3DCreate9函数继续获取到CreateDevice函数的地址,然后通过CreateDevice函数又可以获取到Present的地址,而D3D HOOK的就是Present这个地址,通过Hook Present这个地址在Present函数之前加入我们自己的绘制函数渲染后执行Present将图形提交给显卡至显示器!
备注:Hook是一种可以改变代码执行流程的技术,例如某FPS游戏将人物及地图绘制完成后将要调用Present函数把图形提交给显卡,而我们用过hook技术修改了这个Present函数,将其跳转到我们自己编写的函数里,在这个函数里我们可以尽情的写我们自己需要执行的代码,例如计算敌人的位置并绘制出方框。当我们自己的函数运行完之后再调用Present函数,使得游戏绘制的模型和我们绘制的方框一起被显卡绘制。