D3D HOOK实现透视讲解
实现目的:
目前大部分游戏通过Direct3D实现3D效果,通过挂钩相应函数,可以实现3D透视,屏幕挂字效果。而透视,屏蔽特定效果,设置透明在很多游戏(特别是FPS)中发挥着巨大的作用!
实现思路:
[D3D]
DirectX的功能都是以COM组件的形式提供的。在Direct3D中,主要通过采取以下操作来实现编程:
调用适当的函数获取接口指针;
调用接口的方法(成员函数)来完成所需功能;
用完接口后,调用Release方法进行“释放”,注意释放顺序应该和获取它们的顺序相反。
D3D的实现流程:
大体可以分为:设计,渲染和显示三个部分。通过设计物体的顶点,贴图,材质等信息,并将坐标转换为屏幕坐标后,调用渲染方式,根据坐标变化,材质文理等计算亮度,进行背面消除,裁剪,投影和视口计算,最后在后备缓冲中绘制好图形交换到当前缓冲区。
设计阶段:
这里介绍部分概念方便大家理解
图元
在d3d编程中,所有的图形都是由图元组成的,例如:


这些图元分为点列,线列,线带,三角形列,三角形带,三角扇形
顶点缓存
顶点缓存通常除顶点坐标之外还包括法线,颜色,纹理等数据。
索引缓存
索引缓存就是将顶点的具体数据和代表图元格式的顶点顺序分开存储:顶点数据仍然放到顶点缓存区中,索引缓存区则按照图元格式,顺序存放顶点的索引。
如

A,B,C,D对应的顶点缓存索引为0 1 2 3,按照三角形的列的组成顺序,把顶点索引值存入索引缓存区,4个三角形分别为△ACB、△ADC、△ABD、△BCD(注意顶点排列顺序和可视面的关系),则索引序列为0 2 1 0 3 2 0 1 3 1 2 3。这样原本要用12个顶点数据构建一个三棱锥,使用索引缓存后,只需要4个。
Z缓存
在Direct3D中,使用深度缓存区(Depth Buffer)来进行消隐处理(隐藏面消除),以确保实体被遮挡的部分不被显示。Z缓存是最常用的一种深度缓存,它因为用Z坐标作为判断深度(远近)的依据而得名,其工作原理如图14所示,图中的渲染表面相当于Direct3D窗口,Z缓存用来保存窗口中各个像素的深度。在消隐时,Direct3D先用背景色(或纹理)填充渲染表面,Z缓存则统一设置成最大深度,即投影变换中后裁剪平面的距离,然后逐像素处理渲染表面:对于任意一个像素,Direct3D逐一测试所有与该像素重叠的三角形,如果三角形中像素对应点的Z坐标小于Z缓存中的数值,也就是说,此三角形离观察者较近,则像素取该点的颜色,同时像素在Z缓存中的深度也设为该点的Z坐标,然后继续测试下一个三角形... ...

坐标变换

渲染
在Direct3D中,一个设备对象至少包含两个显示缓存区:当前缓存区(Front Buffer)和后备缓存区(Back Buffer),前者可以看成Direct3D窗口的映射。当我们渲染图形时,实际上并不是直接在窗口上输出,而是在后备缓存区上绘图。渲染完毕后,交换两个缓存区,使原来的后备缓存区变成当前缓存区,从而实现窗口刷新。快速重复此过程,就会在屏幕上形成连续的动画

有了上述的一些基本概念之后,我们就可以编写出自己的d3d Demo:
详情见demo
[D3D HACK]
通过上述了解,我们发现渲染中有个函数SetRenderState()可以设置渲染状态,通过设置不同的参数既可以实现我们想要的功能:
透视:
SetRenderState(D3DRS_ZENABLE, FALSE)
去除烟雾:
SetRenderState(D3DRS_FOGENABLE, FALSE)
设置多边形填充模式:
SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME) //线填充模式,D3D在多边形的每个边绘制一条线
......
[D3D HOOK]实现
分析发现在绘制图形之前,通过顶点缓存,然后调用DrawIndexedPrimitive或者DrawPrimitive来绘制图形。所以通过hook此函数就能感知绘图操作,进而实现我们想要的功能。
可以知道Direct3D在内存中的布局为:

为了得到偏移,我们调试一下:
单步到call edx
此时打开pchunter,查看d3d9.dll所在地址
通过计算可以得到偏移为:+2B6B1(此偏移只针对win7,不保证其他平台下的偏移是否正确)
我们构造寻址函数
HANDLE handle = GetModuleHandle(L"d3d9.dll");
if (handle == INVALID_HANDLE_VALUE)
{
OutputDebugString(L"get d3d9.dll failed\n");
return NULL;
}
return (ULONG_PTR)handle + 0x2B6B1;
构造跳转型型hook
if(VirtualProtect((LPVOID)g_uladdr,5,PAGE_EXECUTE_READWRITE,&dwoldprotect))
{
DWORD dwjmp = (DWORD)New_DrawIndexedPrimitive - g_uladdr - 5;
_asm
{
mov eax, g_uladdr
mov byte ptr[eax], 0xe9
add eax, 1
mov ebx, dwjmp
mov dword ptr[eax], ebx
}
}
VirtualProtect((LPVOID)g_uladdr,5,dwoldprotect,&dwoldprotect);
构造hook函数
查找DrawIndexedPrimitive定义:
HRESULT DrawIndexedPrimitive(
[in] D3DPRIMITIVETYPE Type,
[in] INT BaseVertexIndex,
[in] UINT MinIndex,
[in] UINT NumVertices,
[in] UINT StartIndex,
[in] UINT PrimitiveCount
);
官方给了6个参数,通过调试我们发现,需要将this传进去
故构造函数如下
HRESULT WINAPI New_DrawIndexedPrimitive(
LPDIRECT3DDEVICE9 m_pDevice,
D3DPRIMITIVETYPE Type,
INT BaseVertexIndex,
UINT MinIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount
)
{
//做你想要的功能
return Old_DrawIndexedPrimitive(m_pDevice, Type,BaseVertexIndex, MinIndex, NumVertices, StartIndex, PrimitiveCount);
}
构建跳转
分析函数头5个字节
构建跳转
__declspec(naked) HRESULT WINAPI Old_DrawIndexedPrimitive(
LPDIRECT3DDEVICE9 m_pDevice,
D3DPRIMITIVETYPE Type,
INT BaseVertexIndex,
UINT MinIndex,
UINT NumVertices,
UINT StartIndex,
UINT PrimitiveCount
)
{
_asm
{
mov edi,edi
push ebp
mov ebp, esp
mov eax, g_dwjmpto
jmp eax
}
}
注入游戏:
实现透视
实现线框透明:
Direct3D的核心功能集中在IDirect3DDevice9的接口中,只要能hook其中的EndScence(), DrawPrimitive()或DrawIndexedPrimitive()就能感知绘图操作,进而实现我们想要的功能!
jpg改rar
D3D HOOK实现透视讲解的更多相关文章
- 书评第001篇:《C++黑客编程揭秘与防范》
本书基本信息 作者:冀云(编著) 出版社:人民邮电出版社 出版时间:2012-6-1 ISBN:9787115280640 版次:1 页数:265 字数:406000 印刷时间:2012-6-1 开本 ...
- FPS 游戏实现D3D透视
FPS游戏可以说一直都比较热门,典型的代表有反恐精英,穿越火线,绝地求生等,基本上只要是FPS游戏都会有透视挂的存在,而透视挂还分为很多种类型,常见的有D3D透视,方框透视,还有一些比较高端的显卡透视 ...
- D3D游戏降帧的动态创建D3D设备以及ShellCode HOOK玩法
欢迎转载,转载请注明出处:http://blog.csdn.net/gnorth/article/details/9327971 说白了,也就是HOOK掉Present,这种代码,其实百度上某些地方有 ...
- Hook(钩子技术)基本知识讲解,原理
一.什么是HOOK(钩子) API Windows消息传递机制,当在应用程序进行相关操作,例如点击鼠标.按下键盘,操作窗口等,操作系统能够感知这一事件,接着把此消息放到系统消息队列,然后到应用程序的 ...
- 关于hook d3d在war3上绘图的几点疑问
学到了. 你得记住,com接口全是stdcall调用方式,不是thiscall,不要搞错了,不信,你看接口定义 因为com调用得兼容c调用,而c没有thiscall调用方式stdcall时,this指 ...
- [ZZ] D3D中的模板缓存(3)
http://www.cppblog.com/lovedday/archive/2008/03/25/45334.html http://www.cppblog.com/lovedday/ D3D中的 ...
- 逆向知识之CS辅助/外挂专题.2.实现CS1.6透视原理
逆向知识之CS辅助/外挂专题.2.实现CS1.6透视原理 一丶透视简介 我们涉及到FPS游戏.免不了说透视.自瞄什么的. 在CS1.6中. 有OpenGl.也有D3D. 透视的方法很多. gl透视(也 ...
- HOOK技术的一些简单总结
好久没写博客了, 一个月一篇还是要尽量保证,今天谈下Hook技术. 在Window平台上开发任何稍微底层一点的东西,基本上都是Hook满天飞, 普通应用程序如此,安全软件更是如此, 这里简单记录一些常 ...
- 电脑控制台灯(c# hook,显示室温,联网校正时间)
突发奇想,于是便写了一个小程序用于控制台灯,这几天功能也在不断的完善中,目前基本已经完成.下面进行功能的简述的代码的分析. 整体设计包含下位机程序和上位机程序.下位机用的c语言,上位机用的 ...
随机推荐
- C++:模板友元
模板友元函数在类内声明类外定义时都必须加模板前缀,另外模板要写在一个文件内 // generates undefined error for the operator<< function ...
- Android成长之路-手势识别的实现
手势识别系统: 先把手势库放到项目中:(创建手势库见下一篇博客) 在res文件夹下新建一个名为raw的文件夹,然后把手势库放进去 然后开始项目的创建: strings.xml: <?xml ...
- CentOS 安装 升级Firefox
把旧版本的firefox卸掉: # yum erase firefox 然后安装新版本: # yum firefox
- JUC组件扩展(三):BlockingQueue(阻塞队列)详解
一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大 ...
- Decoration2:引入Angularjs显示前台一条数据
SpringMVC内置的RestFul API格式采用的是最复杂最全面的HATEOAS规范,对于简单应用来说,前台解析起来不方便,我们下面主要想办法重新定义一种简单的RestFulAPI. (1)先是 ...
- 【Android】13.4 使用SQLite.NET.Async-PCL访问SQLite数据库
分类:C#.Android.VS2015: 创建日期:2016-02-27 一.简介 这一节演示如何利用以异步方式(async.await)访问SQLite数据库. 二.示例4运行截图 下面左图为初始 ...
- svn move (mv,rename,ren)
svn 重命名文件: [root@NGINX-APACHE-SVN pro]# svn move 20160624新建数据库表.txt 201.txt A 201.txt D 20160624新建数据 ...
- SCWS 中文分词
SCWS 中文分词v1.2.3 开源免费的中文分词系统,PHP分词的上乘之选! 首页 下载 演示 文档 关于 服务&支持 API/HTTP 论坛 捐赠 源码@github 文档目录 SCWS- ...
- Logstash日志字段拆分grok
参考和测试网站:http://grokdebug.herokuapp.com 例如:test-39.dev.abc-inc.com Mon Apr 24 13:53:58 CST 2017 2017- ...
- androidStudio简便安装
最近在公司由eclipse换为androidstudio,说句实话,androidstudio还是蛮好用的,但是自己刚刚安装的时候遇到很多的问题,问了度娘,各种说法都有,还是捣鼓不得,于是自己尝试,弄 ...











