给网游写一个挂吧(三) – 启动外挂下
前面的文章给网游写一个挂吧 – 启动外挂上介绍了输入法注入的方法,本文解释第二种方法。
有的游戏限制比较多,可能会将输入法注入也禁用掉……这个时候就需要另想方法了。其实我们的目的很简单,就是要让不知道我们挂存在的游戏,在某个时刻将挂作为游戏的一个组件加载进来。输入法注入是操作系统强制塞给游戏的,当然游戏有权利选择不要。那么我们可以用暴力解决,强制游戏加载外挂:
1. 比如利用缓冲区溢出漏洞(参考文章 如何利用缓冲区溢出的程序错误来运行黑客程序 和 如何利用缓冲区溢出的程序错误来运行黑客程序(续))。
2. 还有就是在游戏每次都会执行的函数上挂个钩子 ,但是一般的Windows钩子都会被游戏禁用掉……而本文的方法是Hook DirectX EndScene函数,即游戏在绘图结束后调用的函数,而且游戏会在一秒内经常调用这个函数,简直就是把它当消息队列使!
WOW – 使用DirectX EndScene注入技术
这个方法可以用在WOW 3.3.5.13930上,现在已经不行了,有兴趣的朋友可以自己搭一个3.3.5.13930的私服试试。据说有很多方法可以注入(DirectX EndScene函数在d3d9.dll文件中):
1、 在游戏文件夹里放一个d3d9.dll,因为Windows是先搜索游戏的工作目录再查找system32文件夹的,所以会加载到自定义的d3d9.dll。
2、 直接在游戏启动前把system32文件夹中的d3d9.dll换成自己的。
3、 使用IDA直接获取EndScene的地址,并且在游戏启动后,修改这个地址的汇编码,使其先调用我们的函数,再由我们的函数将控制权交还给真实的EndScene程序。
4、 在外挂里启动游戏,启动时先将游戏进程暂停,执行一系列Hook操作:
a) 先Hook LoadLibrary以便在游戏加载d3d9.dll的时候;
b) 再Hook d3d9.dll里的Direct3DCreate9函数,
c) 再通过Hook过的Direct3DCreate9函数获取D3D9的指针,
d) 从D3D9指针处Hook D3D9->CreateDevice函数,以获取指向设备的指针Device。
e) 再从Device指针处Hook Device->EndScene函数。
5、 在Windows操作系统里创建一个自己的Device。
6、 或者就是使用SetWindowsHookEx API安装一个系统级别的Hook,然后我们的外挂就会被加载进每一个进程!参考文档:http://www.woodmann.com/forum/archive/index.php/t-11023.htm
这里我只用过第4种方法,因此本文也只介绍第4种方法,这里我们用到EasyHook这个库,这个库允许我们使用C#代码Hook系统API。EasyHook的用法很简单:
1、 在包含Hook函数的托管DLL里,创建一个类,实现了EasyHook.IEntryPoint这个接口。
2、 在类的构造函数里建立与宿主进程的连接。
3、 然后在IEntryPoint.Run函数里,注册你的Hook,下面是以CreateFile这个系统API为例:
1、 public void Run(RemoteHooking.IContext InContext, String InChannelName)
3、 CreateFileHook = LocalHook.Create(
4、 LocalHook.GetProcAddress("kernel32.dll", "CreateFileW"),
5、 new DCreateFile(CreateFile_Hooked),
6、 this);
7、
8、 CreateFileHook.ThreadACL.SetExclusiveACL(new Int32[] {0});
9、 }
在第5行里,那个DCreateFile就是CreateFile在C#中的委托表现方式,因为是通过函数指针的方式执行的,因此会声明成一个委托。
4、 最后在外挂里,使用下面的代码注册Hook:
1、 static void Main(string[] args)
2、 {
3、 Config.Register(
4、 "A FileMon like demo application.",
5、 "FileMon.exe",
6、 "FileMonInject.dll");
7、
8、 RemoteHooking.IpcCreateServer<FileMonInterface>(
9、 ref ChannelName, WellKnownObjectMode.SingleCall);
10、
11、 RemoteHooking.Inject(
12、 Int32.Parse(args[0]),
13、 "FileMonInject.dll",
14、 "FileMonInject.dll",
15、 ChannelName);
16、 }
5、 代码里,还有一个关键的地方,就是Hook后获取的指针是一个COM接口,即拿到的是一个虚函数表,因此在Hook EndScene方法的时候,就是把这个COM接口的EndScene的虚函数指针换成我们自己的,如下表的接口定义和替换方法:
1、 public unsafe class D3D9
2、 {
3、 [StructLayout(LayoutKind.Sequential, Pack = 4)]
4、 public struct IDirect3DDevice9
5、 {
6、 public IntPtr** VFTable;
7、 }
8、 }
9、 public IDirect3DDevice9(D3D9.IDirect3D9* InNativeIDirect3D9,
10、 D3D9.IDirect3DDevice9* InNativeIDirect3DDevice9)
11、 {
12、 NativeIDirect3D9 = InNativeIDirect3D9;
13、 NativeIDirect3DDevice9 = InNativeIDirect3DDevice9;
14、 OverrideFunctions();
15、 }
16、 public D3D9.IDirect3D9* NativeIDirect3D9
17、 {
18、 get; private set;
19、 }
20、 public D3D9.IDirect3DDevice9* NativeIDirect3DDevice9
21、 {
22、 get; private set;
23、 }
24、 private void OverrideFunctions()
25、 {
26、 OriginalEndScene = NativeIDirect3DDevice9->VFTable[0][42];
27、 RealEndScene =
28、 (DelegateEndScene)Marshal.GetDelegateForFunctionPointer(
29、 OriginalEndScene, typeof (DelegateEndScene));
30、 MyEndScene = EndScene;
31、 IntPtr PointerToMyEndScene = Marshal.GetFunctionPointerForDelegate(MyEndScene);
32、 NativeIDirect3DDevice9->VFTable[0][42] = PointerToMyEndScene;
33、 }
34、 public uint EndScene(D3D9.IDirect3DDevice9 Device)
35、 {
36、 // 防止多线程访问
37、 lock (LuaInterface.dataLock)
38、 {
39、 // 先做我们自己的事情,然后再将控制权转移给真正的EndScene函数
40、 return RealEndScene(Device);
41、 }
42、 }
比如在第37行 – 41行,就是在EndScene调用的时候,先做我们的事情,然后再把控制权交给真正的EndScene。而第26行,EndScene函数IDirect3DDevice9的第42个函数,因为在第3行,代码已经将IDirect3DDevice9接口(实际就是一个虚函数表)当成一个普通的C/C++结构体处理 – 而且是32位机上的结构体(如果要支持64位改一下就可以了),而第6行代码,就是把这个虚函数表当作一个普通的数组处理。不过据说在DirectX10里已经把EndScene去掉了……
这种方式,网上已经有完整的源代码,请在此下载(这个代码跟本文讲解使用的代码是不同的,因此有兴趣的朋友可以自行研究下面的代码):
https://github.com/spazzarama/Direct3DHook
而EasyHook的使用方式和详细原理,请参考文档:
http://www.codeproject.com/Articles/27637/EasyHook-The-reinvention-of-Windows-API-hooking
未完待续……
给网游写一个挂吧(三) – 启动外挂下相关推荐
- 给网游写一个挂吧(二) – 启动外挂上
前面的文章给网游写一个挂吧– 反反外挂驱动的驱动,我们已经可以访问游戏的内存之后,接下来需要: 1. 找到游戏里关键元素的偏移量,比如生命值的内存的位置.一般来说,大部分大型3D游戏都 ...
- 给网游写一个挂吧(四) – 调用游戏函数
前面的文章给网游写一个挂吧 – 启动外挂上或给网游写一个挂吧 – 启动外挂下将外挂启动后,那就可以进行读写游戏内存和调用游戏的一些操作了. 读写内存很简单,如果是内挂的话,因为是运行在进程内,甚至都可 ...
- 给网游写一个挂吧(一) – 反反外挂驱动的驱动
去年做了一些研究,研究做外挂的一些相关技术,打算放出来跟大家分享,分享一下我们做挂的一些思路,挂的原理,希望抛砖引玉. 外挂说白了就是用程序代替人去操纵游戏,模拟人向游戏程序发送键盘.鼠标消息.一般的 ...
- 主线3带小号过鸿蒙,《诛仙网游》这四个小号试了下,归云可以过鸿蒙、四象。其他三个能刷鸿蒙么?...
愛上壹座城:爆伤怎么堆啊,我才780 发布于 2020-09-19 12:39:05 郑寒尘:刚刚用比你那个青云差点的青云去单刷鸿蒙,没人带没办法,第一次过了,第二次没注意时间,今天,无限被冰冻魅惑反 ...
- [html] 写一个垂直的三栏布局,第一栏固定顶部,中间铺满,第三栏固定底部
[html] 写一个垂直的三栏布局,第一栏固定顶部,中间铺满,第三栏固定底部 好像有几种写法 我个人比较喜欢的是, <style> html, body { margin: 0; padd ...
- 用java写一个简单的区块链(下)
用java写一个简单的区块链(下) 2018年03月29日 21:44:35 java派大星 阅读数:725 标签: 区块链java 更多 个人分类: 区块链 版权声明:本文为博主原创文章,转载请标明 ...
- 从零写一个编译器(三):语法分析之几个基础数据结构
项目的完整代码在 C2j-Compiler 写在前面 这个系列算作为我自己在学习写一个编译器的过程的一些记录,算法之类的都没有记录原理性的东西,想知道原理的在龙书里都写得非常清楚,但是我自己一开始是不 ...
- 我是如何学习写一个操作系统(三):操作系统的启动之保护模式
前言 上一篇其实已经说完了boot的大致工作,但是Linux在最后进入操作系统之前还有一些操作,比如进入保护模式.在我自己的FragileOS里进入保护模式是在引导程序结束后完成的. 实模式到保护模式 ...
- 游戏服务器系统的选择界面,cocos2dx网游选服界面制作三:服务器单个item界面包装...
前面我们讲到了界面的制作,里面用到了FuWuQiBase这个类. 这个类主要就是我们服务器列表里某一个服务器信息的展示包装. 下面我直接贴代码://FuWuQiBase.h #ifndef _FUWU ...
最新文章
- linux文件I/O操作
- 6001.Cacti监控华为S8512核心交换机多块板卡的CPU和内存
- 卸载 流程_「工具」Windows 卸载软件,这一个就够了
- 【童年回忆】【FC模拟器 + ROM大合集下载】
- git configuration
- 微信支付通知 php,微信支付开发交易通知实例
- 最长公共前缀—leetcode14
- Asp.Net Core 项目搭建 基础配置 和MySql 的使用
- Pentium的指令系统(3)——算术运算指令
- 【java】程序初始化顺序
- 联想主板9针开关接线图_干货丨34个电气控制接线图、电子元件工作原理图
- U盘文件消失没有被隐藏却占内存的几种解决方案
- MongoDB的分片集群
- 使用commons-lang3实现Unicode码转中文
- centos如何安装软件
- MT7620设置GPIO输入中断
- 机器视觉相关的实验室网址、大牛综述
- Python之freshman08 Socket
- 记 · 再看 · 前端社区氛围
- 助力智慧医疗,解析i.MX8MM在麻醉系统中的应用方案
热门文章
- RaDirect交换器-搭建环境
- 基于multisim的fm调制解调_高通二代5G调制解调器骁龙X55实现7Gbps高速率,透露5G三大关键点...
- android 调用.h文件,[Android Studio / NDK] 如何使用javah生成.h文件
- static的用法及其与auto的区别小结
- Web 仿 App 动画竟然引出了“性能杀手”
- 白瑜庆:知乎基于Kubernetes的kafka平台的设计和实现
- iOS相关,过年回来电脑上的证书都失效了
- 未来两年内的九大信息安全威胁(三)
- $routeParams $route.current.params
- Mozilla宣布关闭 Persona