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语言,上位机用的 ...
随机推荐
- ubuntu下载软件安装包
apt-get -d download xxx ubuntu下载软件安装包命令.仅仅下载deb格式的安装包,不安装. xxx是待下载的安装包.
- js身份证验证算法
var validateIdCard=function (id, backInfo) { var info={ y: "1900", m: "01", d: & ...
- 没有msdtc服务的解决方法(sql server分布式事务挂掉的解决方法)
没有msdtc服务的解决方法如下:1.删除注册表中的键: 开始 运行 regedit 打开注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Servic ...
- Linux 进程资源用量监控和按用户设置进程限制
每个 Linux 系统管理员都应该知道如何验证硬件.资源和主要进程的完整性和可用性.另外,基于每个用户设置资源限制也是其中一项必备技能. 在这篇文章中,我们会介绍一些能够确保系统硬件和软件正常工作的方 ...
- 利用ngModel相关属性及方法自定义表单验证指令
这是一个只能输入偶数的验证指令
- python WSGI框架详解
1.web应用的本质1)浏览器发送一个HTTP请求2)服务器收到请求,生成一个HTML文档3)服务器把HTML文档作为HTTP响应的body发个浏览器4)浏览器收到HTTP响应,从HTTP Body取 ...
- [转] C#与Java的比较
[转] C#与Java的比较 转自:C#与Java的比较 2015-06-26 目录 一.C#.C++和Java二.语言规范的比较 2.1.简单数据类型 2.2.常量 2.3.公用类的入口点 ...
- 在容器中使用erase函数,迭代器的处理
在c++编程中,用到迭代器的时候,往往不知道如何删除当前迭代器指向的元素. erase函数: 返回下一个迭代器. 只使用vector的erase函数,记住,该函数是迭代器失效,返回下一个迭代器. ...
- cocos2dx迷你地图
用CCRenderTexture就可以了,不知是否有更好的方法. if (!miniMap) { miniMap=CCSprite::create(); miniMap->setZOrder() ...
- Unix系统编程()brk,sbrk
在堆上分配内存 进程可以通过增加堆的大小来分配内存,所谓堆是一段长度可变的连续虚拟内存,始于进程的未初始化数据段末尾,随着内存的分配和释放而增减.通常将堆的当前内存边界称为"program ...











