热血江湖外挂
- 1.0:最新版人物信息基址:0x02C166D8;最新版背包存放基址:0x02E3B3E4
- 2.0:最新版物品使用call 为0x00838480
- 3.0:
- 人物基址:0x02C176D8;
- 背包存放基址:0x02E3C3E4;
- 游戏主窗口基址:0x01195F88;
- 使用物品的学习向工CALL:0x008384F0;
- 人物动作基址:0x02E3CD58;
- 动作使用的CALL:0x007139E0;
- 所有对象数组:0x2E64A28;
- 怪物基址:0x427FBA0
- 角色对象基址:0x427FBA0
- 一般游戏开发的时候,相关的使用数据都是放到一个结构或者是一个类中,那么这些数据的具逆具集内存地址相距的比较近;
- 一般内存地址使用CE工具逆向出来后表示为Client.exe+278A75C,表示软件地址加上偏移量为其基址
- 生命值PH: Client.exe+278A75C = 02B8A758
- 内功值MH: Client.exe+278A75C = 02B8A75C
- 进行商品的学习向工买卖实现金币值的变动
- 基址:Client.exe+278A7BC = 02B8A7BC
- OD软件的使用
- 人物属性值以及对应的内存地址
- 基址 02B8A6D8
- +0:人物名字
- +80:生命值(红/HP)
- +84:内功值(蓝/MP)
- +88:愤怒值
- +8C:最大生命值
- +90:最大内功值
- +94:最大值愤怒值
- +98:当前经验值
- +A0:升级到下一级要的经验值
- 势力
- +36:名声
- +34:一字节空间表示等级
- +35:一字节空间表示 几转
- +AC:历练
- 制造
- 熟练度
- 灵兽持有
- 精力
- +C8:攻击
- 武器命中
- +CC:防御
- 武器防御
- +D0:命中
- 对人战斗
- +D4:回避
- 对怪攻击
- 武功回避
- 对怪防御
- +B0:心
- +B4:气
- +B8:体
- +BC:魂
- +E4:金币值
- 气功值分析
- 气功点数:基址 + F0 = 02b8a7c8
- 第num个气功的点数:(一个字节)02B8A6D8+0f0+4*num
- 可能是第num个气功的ID(没有就为0):02B8A6D8+0f0+4*num+2
- 步骤
- 获取窗口对应的进程的PID
- 根据PID 获取进程
- 获取游戏进程的PID
- 根据PID 获取进程
- 在目标进程分配内存空间,方便写入DLL 全路径
- 将DLL 全路径写入到目标进程
- 远程注入DLL
- 等待目标进程执行完成
- 释放进程空间
- 关闭线程句柄
- 整数
- QWORD 类型变量 nq前缀 //8字节 无符号整数 不能表示负数
- DWORD 类型变量 nd前缀 //4字节 无符号整数 不能表示负数
- WORD 类型变量 nw前缀 //2字节 无符号整数 不能表示负数
- BYTE 类型变量 nb前缀 //1字节 无符号整数 不能表示负数
- int 带符号类型 ni前缀 //4字节 带符号整数 可表示正负数
- _int64 带符号整型 ni64//8字节 带符号整数 不能表示负数
- UINT 类型变量 ui前缀 // 无符号整数 一般是使用4字节
- //浮点数
- float 单精度浮点数 fl前缀
- double 双精度浮点数 fd前缀
- 字符串
- char*和char [] sz前缀 //PCHAR szp
- CString str前缀
- 结构名 T开头全大写
- 类名 C开头单词首字大写
整合游戏数据步骤
-
新建解决方案GameData
-
创建头文件BaseGame.h和 StructGame.h
-
创建源文件StructGame.cpp
-
配置链接库路径
-
配置 附加包含目录
-
配置 添加库目录
-
配置编译输出路径
-
修改输出目录
- 在游戏中,对应的具逆具集物品都会有一个结构/类,包含了物品的学习向工一些信息
- 使用物品实际上调用了应该CALL
以金疮药为例
-
寻CALL 的过程
-
使用CE工具找到对象地址指针
-
去查看访问改指针的地址
-
使用OD 工具对这些地址进行动态调试
-
远程注入代码(使用金疮药)
-
背包数据的分析
- 背包在游戏中一般会写成应该结构体/类来存放物品对象
- 物品对象在背包中使用数组的形式存在
- 汇编中数组的访问方式一般是 数组基址 + 4 * i(' i '为数组下标)
- 查找背包数组基址:
- 找到背包的物品格
- 反复讲里面的物品拿出/放入
- 使用CE工具进程分析
-
结果
- 存放背包基址的内存空间:0x02DAF3E4
- 第num 个格子的数据获取
- *背包基址+num*4+0x43C
- 注:0x43 是偏移量
- 物品对象指针 + 0x64 = 物品名字
- 物品对象指针 + 0xf9 = 对物品的描述
- 物品对象指针 + 0xC4C = 物品剩余数量
封装背包结构体
实现初始化方法(getDate())
调试调用
文件结构
封装函数
-
文件结构
造成异常的原因:
- 游戏主线程与外挂线程同时访问共享数据区域,造成程序异常
- 让两个线程依次使用共享数据或者将注入线程到主线程
模拟游戏主线程和辅助线程同时执行
解决方式
-
将程序注入到主线程
-
使用临界区
-
1
-
2、具逆具集代码
-
定义基址
-
定义结构
-
实现结构方法
-
在HOOK 内定义测试方法
-
实现
-
控件调用
-
目录结构
- 思路:
- 通过选中的对象逆向回溯出动作的数组
- 通过动作对象访问逆向回溯到攻击CALL 附近
- 封包断点bp WSASend
-
通过选中动作,利用CE 查找基址
-
使用OD 分析访问内存信息,具逆具集得到基址
动作公式:[02e3bd58]+43c+4*0
-
找动作的CALL
-
使用CE 分析动作对象的调用访问
-
得到一下信息
-
使用OD分析得动作CALL为
- 封装动作对象
- 封装动作对象列表
- 封装使用对象功能函数
封装
-
封装基址
-
封装结构
-
实现结构方法
-
添加消息类型
-
在主线程内调用结构体方法
-
发送消息到主线程
-
绑定控件,执行方法
-
文件结构
选怪功能相关地址
-
玩家:
[2E63A24] //存放的玩家对象的地址
+3428 玩家是否被选中
-
怪物:
[2E63A24]+1A64
选中怪物时,传入怪物的选中ID
没选中怪物时,值为0xFFFF
|