分析对象:
D:\AI空间\rxjh(含自动登录.e、旧版本更新.e及旧版本更新.代码目录下的 etxt 导出代码)
分析时间:2026-09-16
这是一个针对《热血江湖》的内存级游戏辅助(挂机工具),采用"DLL 注入 + 窗口线程"架构,共约 9000+ 行主窗口代码、300+ 个子程序。
┌──────────────────────────────────────────────┐
│ 编译目标:DLL(注入到游戏进程内运行) │
├──────────────────────────────────────────────┤
│ 程序集1(入口) │
│ ├ NewDllMain() ← 通过 VirtualQuery/VirtualProtect │
│ │ 改写 PE 入口,接管 DllMain │
│ └ DllMain(DLL_PROCESS_ATTACH) │
│ └ CreateThread → ShowDialog() │
│ ├ 载入 MainDialogWnd 主窗口 │
│ ├ SetWindowLong 替换窗口过程 │
│ └ 消息循环(关闭后 FreeLibraryAndExitThread)│
├──────────────────────────────────────────────┤
│ 窗口程序集_MainDialogWnd(核心,~9257+ 行) │
│ ├ 自动进入游戏 / 角色选择 │
│ ├ 挂机主控(开始挂机 → 寻路线程+时钟+统计) │
│ ├ 封包系统(发包Call + 各类发包子程序) │
│ ├ 背包/仓库/商店遍历(内存结构体解析) │
│ ├ 强化/合成自动化、喊话、签到、回补 │
│ └ 封包拦截(类_超级HOOK)+ 线程安全日志 │
├──────────────────────────────────────────────┤
│ 监视热键程序集:Home 键显隐窗口(50ms 轮询键盘状态)│
│ 模块:魔鬼作坊VIP模块 V8.0、精易模块、薏米模块 │
└──────────────────────────────────────────────┘
技术栈特点:
- 通过 VirtualQuery + PE 头解析(基址+60 取 optional header、+40 取 entry point)定位默认入口,再写入 mov eax, fnAddr; jmp eax({184,...,255,224})实现 DllMain 劫持——这是易语言 DLL 注入的经典写法。
- Call() 与 置入发包() 均为裸内联汇编(置入代码),直接在游戏进程内调用游戏自身的发包函数。
- 使用了 EThread 支持库做线程控制(启动线程/强制结束线程)。
| 模块 | 主要子程序 | 实现方式 |
|---|---|---|
| 自动登录/进游戏 | 自动进入游戏、选择角色进入游戏 |
轮询内存 01844380 判断角色界面;内联汇编 call 0xC114A0 |
| 挂机主控 | _开始挂机_被单击、挂机寻路新、五分钟无经验检测寻路 |
启动寻路线程 + 更新数据时钟(1s) + 功能检测时钟;停止时强制结束 5 类线程 |
| 红蓝保护 | 自动红蓝、遍历背包红药/蓝药 |
读血量基址 03970A70(+4 为内功),低于阈值发包用药品 |
| 地图传送 | 发包飞图、_飞地图XX_被单击 ×9 |
构造 23 字节封包(81 03 协议号 + 地图ID)直接发包 |
| NPC 交互 | 发包对话NPC、发包打开商店、指定ID购买 |
30 字节固定模板封包 + NPC 编号 |
| 背包管理 | 遍历背包、背包统计、背包基址内存遍历 |
背包基址 03B9DCE0,每格 +4 步进指针,名称偏移 64h、编号 54h、数量 D4C,BIG5 转简体 |
| 强化/合成 | 开始强化、发包_强化/合成窗口放物品/放石头/确认/取消 |
全部走封包模拟 |
| 商业行为 | 存卖石头/寒玉石/金刚石、药店买卖、仓库存卖、金香玉购买下晶 |
寻路 + 对话 + 商店封包组合流程 |
| 修炼系统 | 进入南林/北海/东陵/虎峡谷修炼、获取修炼几层 |
修炼装置对话遍历 + 传送 |
| 喊话 | 定时喊话、发包喊话 |
多频道(普通/呐喊/门派/组队/交易)轮播 |
| 封包拦截 | 写封包日志、_拦截发包选择框_被单击 |
类_超级HOOK 钩住发包函数,回显到界面 |
| 统计 | 开始/停止统计信息、刷新经验信息 |
经验/金钱/历练速率统计(读基址+24/+44/+100 处长整数) |
| 配置 | 保存/读取设置、组合框记忆读配置 |
Default.ini + 用户配置 JSON |
| 热键 | 监视热键、监视热键线程 |
自写 50ms 定时器轮询 256 键状态表,Home 显隐窗口 |
所有游戏内存地址以常量写死在 常量.e.txt,游戏更新后这些全部要重找:
| 常量 | 地址 | 用途 |
|---|---|---|
| 坐标/人物基址 | 03BF28CC |
人物、x/y 坐标(+1F84/+1F8C) |
| 背包基址 | 03B9DCE0 |
背包 36 格遍历 |
| 当前血量 | 03970A70 |
血量(+4 内功,+24 经验,+44 历练,+100 金钱) |
| 怪物基址 | 03BE3E68 |
怪物遍历 |
| NPC 基址 | 0183C52C |
NPC 遍历 |
| 发包 call | 0076C080 / ECX 017EF378 |
封包发送函数 |
| 地图基址 | 011E0084 |
地图 ID |
| 仓库/商店/状态栏 | 0182A2DC / 03BC33BC / 03BA387C |
— |
| 角色界面标记 | 01844380 |
自动进游戏轮询 |
| 进入游戏 call | 0xC114A0(ECX=[0x017F02BC]) |
选择角色 |
所有文件中形如 .局部变量 坐标基址, 整数型, 数组 的声明(包括循环变量 i、MSG 结构体等标量),都带有 , 数组 标记。回转到易语言后:
- 标量被当数组用时(如 Buffer = 取空白字节集(28)、msg.wParam)会编译报错或行为异常;
- 建议回转后批量去掉误标的"数组",只保留真正数组的(如 拦截数据, 类型_HOOK数据, 数组, "5" 这种带数量的是真数组)。
遍历背包红药/蓝药 找不到药时返回值错误循环正常走完(未找到红药)时 返回(物品格子 - 1) 会返回 35(最后一格),而不是 -1。调用方 自动红蓝 拿到 35 后会对一个空格发包使用物品。应在循环结束后判断"是否找到过",未找到返回 -1 并在调用方过滤。
使用小助手 与红蓝逻辑的格子序号约定不一致遍历背包红药 返回 格子-1(0 起),使用小助手 里直接 发包使用物品(物品格子-1),但循环上限是 96 而背包数是 36——两个背包区(普通+扩展?)的偏移约定需确认统一,否则会操作错格。
_开始挂机_被单击 停止逻辑用 强制结束线程() 直接杀寻路/回补线程。若线程正持有内存读写句柄或正在发包中途,被强杀可能造成游戏进程崩溃或封包残缺。建议改为" cooperatively 退出":线程内每步检查退出标志(部分已有 寻路线程运行中 = 假 这类标志,但回补/下晶线程仍是强杀)。
代码中已有针对此问题的优化注释(日志缓冲 + 9971 定时器统一刷新、写封包日志 线程安全入口),这部分做得对。但仍有个别按钮事件(如 _超级列表框_喊话列表_当前表项被改变 递归调 _自动喊话_被单击)在多定时器并发下无保护,建议统一走日志/状态缓冲模式。
删除被选表项 用了递归删除再 返回(),实际靠每次删第一项 + 递归实现,效率低且有栈深度风险,改成倒序循环删除即可。_喊话时钟_周期事件 里 是否整数(变量.挂机计时 ÷ 周期) 用浮点除法判断整除,浮点误差可能导致某次跳过/多喊一次,建议用 挂机计时 % 周期 = 0。NewDllMain 中若 VirtualProtect 失败会直接把 DllEntry 改为用户函数地址再 Call,这条兜底路径在 Win10/11 上基本必失败,可加日志说明。封包Eax基址 0076C2A1、当前血量 03970A70 在常量表里重复存在新旧两种写法(十六进制文本 vs 数值),容易改一处漏一处。_测试按钮1_被单击、_购买测试_被单击 等调试入口留在发布代码里,建议清理或用编译条件屏蔽。发包对话NPC/发包打开商店 中删除了"纯查表函数重试"的无效代码块。全局目录 只取一次。超级HOOK(类_超级HOOK)程序集变量在回转时被自动补回并注明原因。数组 声明,否则无法编译。遍历背包红药/蓝药 的 -1 返回 Bug(直接影响自动喝药安全)。强制结束线程。常量.e.txt 并做版本号校验(游戏更新后一处比对即可知失效)。