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
================================================
[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()就能感知绘图操作,进而实现我们想要的功能!
D3D HOOK实现透视讲解相关推荐
- cs透视源码c语言,[原始] CS1.6透视插件(非D3D Hook)的简单分析(包括透视源代码)...
Cs1.6透视图插件,进行反向操作,编写OpenGL32透视图cs1.6人物透视指令,并与所有人共享今天的成功. . 实际上,它也非常简单,代码很少,所需的工具为cs1.6,ollydebug,vs2 ...
- D3D9 HOOK [透视原理]
最近研究了下FPS游戏透视方法,市面上透视大概分为两种,一种是方框透视 就是在游戏角色模型上画一个框,另外一种就是Z缓冲区透视,这种透视原理是对指定模型(一般是人物模型)禁用Z缓冲进行深度测试,当然这 ...
- Android 插件化原理解析——Hook机制之AMSPMS
在前面的文章中我们介绍了DroidPlugin的Hook机制,也就是代理方式和Binder Hook:插件框架通过AOP实现了插件使用和开发的透明性.在讲述DroidPlugin如何实现四大组件的插件 ...
- android handler的机制和原理_Android 插件化原理——Hook机制之AMSamp;PMS解析
在前面的文章中我们介绍了DroidPlugin的Hook机制,也就是代理方式和Binder Hook:插件框架通过AOP实现了插件使用和开发的透明性.在讲述DroidPlugin如何实现四大组件的插件 ...
- Linux Hook系统调用(适用基于x86_64的4.17.0以上的内核版本)
随着rhel8.0于去年5月初发布以来,开启了rhel8.x的时代,随后一段时间里centos.oracle linux也都发布了基于rhel的8.x系统.前段时间我就安装了个centos8.0,但是 ...
- 关于绝地求生游戏白名单画中画逆向分析
关于绝地求生某辅助白名单画中画逆向分析<二> 拖了好久,最近在忙着找工作,延误给大家分享心得的时间,好了废话不多讲步入正题. 猜测该外挂用的是steam协议了.那怎么来确定他是否用的是st ...
- 安卓高级面试知识整理
安卓高级面试知识整理 Android 四大组件:这是一份全面 & 详细的Activity学习指南 ...
- 截获网易云、酷狗、QQ音乐播放器桌面歌词画面心德
在直播项目中 需要捕获某个窗口的画面并共享 总结了如下几种场景中窗口的捕获方法 1.dc拷贝(BitBlt.PrintWindow) 这是最基本的方法 直接拿到窗口dc 然后从dc中拷贝窗口画面 可优 ...
- [已完结]我在学校举办软件安全讲座提纲
PPT:链接: http://pan.baidu.com/s/1c18L4w4 密码: rp2n 增加了一些东西 有兴趣的可以看看PPT 一些很基础的东西 主流软件的保护--比如SSDT Inline ...
最新文章
- 怎么查看ftp服务器的版本信息,查看ftp服务器版本
- swift5以上版本的代理的实现,详细教你书写代理
- 安装nginx、drizzle和lua
- thinkphp5 --接口实例
- Codevs 1215 迷宫
- 【JavaScript】运算符及其优先级
- 人人网android,人人网Android客户端:真实的在线社交圈
- 网站端服务器返回错误8001,云服务器 http server
- 【GEEK】win10下cmd美化
- outlook邮箱邮件大小限制_附件大小超过了允许的限制错误 - Outlook | Microsoft Docs...
- 【小知识】opencv里去掉小连通区域的函数remove_small_objects()解析
- win10无法使用Linux的samba,拒绝访问
- android电视分辨率是多少合适,电视分辨率多少合适
- 《创业基础》项目创意设计书
- js继承的六种方式详解--认真看完你就会了
- 安卓开发学习之初识ndk开发
- TP4056/4057/4054充电不转灯闪FAE技术
- 360路由器远程连接服务器,“怎样用动态域名实现路由器的远程配置”的解决方案...
- VC++----CRect类
- usboot我怎么那么不相信你呢?
热门文章
- 【web前端(四十五)】javascript高级
- 系统交易策略 hylt
- BestMPRBaseVtk-005-翻车加修车
- CDN 缓存机制阐述
- 宝塔误删mysql数据如何恢复?(救命题)
- 完美解决jasperreports集成ssh后生成HTML图片红叉叉问题和chart不能显示问题
- Windows7搭建ftp服务器
- vr化工安全培训系统制作特点及好处
- Visual 调试代码遇到HTTP Error 500.19-Internal Server Error 错误代码0x80070003
- “后服务”时代 人工智能重新构建保险业生态