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语言,上位机用的 ...
随机推荐
- Android Native IPC 方案支持情况
Binder - 不支持Native层的binder 内存共享 - 不支持 信号量(信号灯) - 不支持 消息队列 - 不支持 信号 - 支持,但是不能用sigqueue传消息,只能用来安装信号,可以 ...
- [译]聊聊C#中的泛型的使用(新手勿入) Seaching TreeVIew WPF 可编辑树Ztree的使用(包括对后台数据库的增删改查) 字段和属性的区别 C# 遍历Dictionary并修改其中的Value 学习笔记——异步 程序员常说的「哈希表」是个什么鬼?
[译]聊聊C#中的泛型的使用(新手勿入) 写在前面 今天忙里偷闲在浏览外文的时候看到一篇讲C#中泛型的使用的文章,因此加上本人的理解以及四级没过的英语水平斗胆给大伙进行了翻译,当然在翻译的过程中发 ...
- 基于Bootstrap的Asp.net Mvc 分页的实现(转)
最近写了一个mvc 的 分页,样式是基于 bootstrap 的 ,提供查询条件,不过可以自己写样式根据个人的喜好,以此分享一下.首先新建一个Mvc 项目,既然是分页就需要一些数据,我这 边是模拟了一 ...
- @Autowired和@Resource装配
从Spring2.5開始就能够使用注解自己主动装配Bean的属性. 使用注解自己主动装配与XML中使用autowire属性自己主动装配并没有太大区别. Spring容器默认禁用注解装配. 所以在基于注 ...
- Linux两块4TB的数据磁盘创建8TB的Raid0
分区表MBR与GPT的说明: MBR:主引导记录,是传统的分区机制,应用于绝大多数使用BIOS的PC设备,MBR+BIOS,MBR支持32位和64位系统,支持的分区数量有限,MBR只支持不超过2T的硬 ...
- tcpdump常用参数说明
(一).学习tcpdump的5个参数 初次使用tcpdump时,使用tcpdump -h命令可以看到它有数十个参数. 根据我们在运维工作中的经验,掌握tcpdump以下5个参数即可满足大部分的工作需要 ...
- Oracle 11g客户端中文乱码问题
问题现象: 客户端安装完毕后,访问表内容,发现中文显示的都是?? 解决方案: 1.修改客户端注册表,路径为HKEY_LOCAL_MACHINE --->SOFTWARE ---> ORAC ...
- makefile之override
override指示符 通常在执行 make 时,如果通过命令行定义了一个变量,那么它将替代在 Makefile中出现的同名变量的定义. 就是说,对于一个在 Makefile 中使用常规方式(使用&q ...
- SVN 安装后报不是内部或外部命令
SVN安装后报不是内部或外部命令,也不是可运行的程序 解决方法:windows安装svn的时候默认是不安装 svn command line这个东西的,重新打开svn的安装exe,选择modify,将 ...
- deb包的2种安装安装方法
一.cydia重启自动安装:用ifunbox进入//var/root/Media/Cydia/AutoInstallCydia/AutoInstall 需要分别单独建立,注意大小写.然后把你要安装的d ...











