.版本 2 .支持库 spec '══════════════════════════════════════════════════════════════════ ' 开关小助手(精易模块)纠正版 v2 2026-09-25 '══════════════════════════════════════════════════════════════════ ' ▎你原稿里的 9 处错误,逐条修正如下 ' ' ① 调用取助手控件 时只传了 1 个参数 —— 它有两个(主线程编号、按钮名称) ' → 编译报「参数数量不匹配」 ' ' ② 子程序头写法冲突: ' .子程序 开关小助手, , , 31是开 32是关 ' 第二列是「返回值类型」、第四列是「备注」,可你后面又写了 .参数 状态 ' → 带 .参数 时第二列至少要留一个类型,建议写 逻辑型 ' ' ③ 状态 参数被覆写: ' 状态 = 内存_读整数型 (..., 控件地址 + 364) ' → 把入参 31/32 冲掉了,后面 push 出去的会是 0 而不是 31/32 ' ' ④ ECX = 控件地址 + 4 是错的 ' → 那条「+4」是虚调用调度器的约定,跟 0x682880 不是一条路, ' 正确做法是「传控件对象本身」(原稿注掉的汇编里实际也是这么想的) ' ' ⑤ +0x364 过滤(按钮名称取编号)是「找不到控件」的真凶 ' → 实测池里 4 个内挂丸控件的 +0x364 全是 0,比对永远不成立 ' → 该子程序整块删除,改为纯名称匹配 ' ' ⑥ S = N —— 计次循环变量 N 从 1 起,索引整体错开一位 ' ' ⑦ .默认 分支里那条 调试输出 会刷屏:14998 次循环里匹配到多少打多少 ' → 删掉;真要调试也该改成计数打一行 ' ' ⑧ 名称必须传简体:「启动内挂丸」。原稿传繁体「啟動內掛丸」一个都匹配不上 ' (+0x368 经 BIG5→简体 出来就是简体) ' ' ⑨ 最关键的一条:调 0x682880 必崩 ' → 它分派的 cmd 0x31 handler 是 0x683834,第一句 ' mov edx,[0x3C441BC] → 0/-1 ' movzx eax,byte [edx+0x54C0] → 读 0x54C0,落在 64KB 禁区 → ACCESS_VIOLATION ' → 点按钮不走它。真正能用的是 v3.2 那套虚表点击(实机已验证) ' ' ▎点按钮的正确链路(来源:助手验证_极简版_易语言.txt v3.2,实机验证过) ' 助手窗口 = [[NPC基址] + 0x414] 打开内挂丸面板后才会写入 ' 按钮 = [助手窗口 + 3938] 开始挂机 / [助手窗口 + 393C] 停止挂机 ' 父窗口 = [按钮 + 4] ' 点击 = push 0 → push 命令ID → push 0x3F4 ' → ecx = 父窗口 → call [父窗口虚表 + 4] ' 父窗口虚表应为 0x10A20F8,槽1 = 0xA3F3D0,0x3F4 分支调用 0xA3F700 ' ' ▎机器码字节规则(v3.2 踩过的坑,照抄别改) ' 104 = 0x68 = push imm32 → { 104, 244, 3, 0, 0 } = push 0x3F4 ✓ ' 106 = 0x6A = push imm8 → { 106, 49 } = push 0x31 ✓ ' 若把 0x31 写成 104 形式(68 31 00 00 00)会连带吃掉下一字节,整段错位 ✗ ' ' ▎死规矩:父窗口 必须是第一个局部变量 ' 机器码 8B 4D FC(mov ecx,[ebp-4])取的就是第一个局部变量,顺序变了就取错值 ' ' ▎用法 ' 开关小助手 (31) 开(开始挂机) ' 开关小助手 (32) 关(停止挂机) '══════════════════════════════════════════════════════════════════ ' ───────────────────────────────────────────────────────────── ' 主入口:31 = 开 32 = 关 ' ───────────────────────────────────────────────────────────── .子程序 开关小助手, 逻辑型, 公开, 31是开 32是关 .参数 状态, 整数型, , 31是开 32是关 .局部变量 助手窗口, 整数型 .局部变量 按钮, 整数型 .局部变量 父窗口, 整数型 ' ★ 必须第一个!别挪位 .局部变量 偏移, 整数型 .局部变量 虚表, 整数型 ' 助手窗口内偏移:3938 = 开始挂机(0x31) 393C = 停止挂机(0x32) .如果 (状态 = 31) 偏移 = 3938 .否则 偏移 = 393C .如果结束 助手窗口 = 内存_读整数型 (全局_进程句柄, 内存_读整数型 (全局_进程句柄, #NPC基址值) + 十六到十 (“414”)) .如果真 (助手窗口 = 0 或 助手窗口 = -1) 写日志 (“开关小助手失败【助手窗口未创建,先在游戏里打开内挂丸面板】” + #换行符) 返回 (假) .如果真结束 按钮 = 内存_读整数型 (全局_进程句柄, 助手窗口 + 偏移) .如果真 (按钮 = 0 或 按钮 = -1) 写日志 (“开关小助手失败【按钮=0 偏移=” + 到文本 (偏移) + “】” + #换行符) 返回 (假) .如果真结束 父窗口 = 内存_读整数型 (全局_进程句柄, 按钮 + 4) .如果真 (父窗口 = 0 或 父窗口 = -1) 写日志 (“开关小助手失败【父窗口=0】” + #换行符) 返回 (假) .如果真结束 虚表 = 内存_读整数型 (全局_进程句柄, 父窗口) 写日志 (“链路【窗口=” + 到文本 (助手窗口) + “ 按钮=” + 到文本 (按钮) + “ 父窗口=” + 到文本 (父窗口) + “ 虚表=” + 十到十六 (虚表) + “】” + #换行符) ' ── 点击机器码:push 0 / push 命令ID / push 0x3F4 / ecx=父窗口 / call [虚表+4] ── 置入代码 ({ 96 }) ' 60 pushad 置入代码 ({ 106, 0 }) ' 6A 00 push 0 lParam .如果 (状态 = 31) 置入代码 ({ 106, 49 }) ' 6A 31 push 0x31 开始挂机 .否则 置入代码 ({ 106, 50 }) ' 6A 32 push 0x32 停止挂机 .如果结束 置入代码 ({ 104, 244, 3, 0, 0 }) ' 68 F4 03 00 00 push 0x3F4 msg 置入代码 ({ 139, 77, 252 }) ' 8B 4D FC mov ecx,[ebp-4] 父窗口 置入代码 ({ 139, 17 }) ' 8B 11 mov edx,[ecx] 置入代码 ({ 255, 82, 4 }) ' FF 52 04 call [edx+4] → 0xA3F3D0 置入代码 ({ 97 }) ' 61 popad 延迟 (取随机数 (300, 600)) 写日志 (“开关小助手【” + 到文本 (状态) + “】已发出” + #换行符) 返回 (真) ' ───────────────────────────────────────────────────────────── ' 辅助:按名称在控件池里找控件对象(修正版) ' ★ 已删掉 +0x364 那道错误的过滤,也不再需要「按钮名称取编号」 ' ★ 名称必须传简体,例如 “启动内挂丸” / “停止内挂丸” / “关闭内挂丸” ' ' 实测命中的槽(2026-09-25): ' 槽4231 控件=1335282848 名称=启动内挂丸 ' 槽4232 控件=1335272936 名称=停止内挂丸 ' 槽4233 控件=1335271520 名称=设定内挂丸 ' 槽4234 控件=1335274352 名称=关闭内挂丸 ' 槽4270 控件=1335323912 名称=设定内挂丸的攻击行动范围。 ' ───────────────────────────────────────────────────────────── .子程序 取助手控件, 长整数型, 公开, 按简体名称在控件池里找控件对象 .参数 按钮名称, 文本型 .局部变量 S, 整数型 .局部变量 控件对象, 长整数型 .局部变量 读取值, 文本型 S = 0 .判断循环首 (S < 14998) 控件对象 = 内存_读整数型 (全局_进程句柄, #全局大列表基址 + S × 4) .如果真 (控件对象 > 0 且 控件对象 ≠ 65535) ' +0x368 = 872 是名称(BIG5 码),+0x364 是 0,别再拿它做判断 读取值 = 编码_BIG5到简体 (内存_读文本型 (全局_进程句柄, 控件对象 + 872, 0)) .如果真 (读取值 = 按钮名称) 返回 (控件对象) .如果真结束 .如果真结束 S = S + 1 处理事件 () .判断循环尾 () 返回 (0) ' ───────────────────────────────────────────────────────────── ' 实验:拿池里的控件对象去点(⚠ 未验证,先单独试,别同时在用) ' 用途:确认「控件池里的内挂丸控件」跟「助手窗口的按钮」是不是同一套结构。 ' 用法: 内挂丸_点池控件 (取助手控件 (“启动内挂丸”), 49) ' 判据: 日志里 父窗口虚表 若打印 10A20F8 → 跟 v3.2 一致,这条路能通; ' 若是别的数 → 取错对象了,别再用。 ' ───────────────────────────────────────────────────────────── .子程序 内挂丸_点池控件, 逻辑型, 公开, 实验用 .参数 控件对象, 长整数型 .参数 命令字, 整数型, , 49开 50关 .局部变量 父窗口, 整数型 ' ★ 必须第一个!别挪位 .如果真 (控件对象 ≤ 65536 或 控件对象 = -1) 写日志 (“点池控件失败【控件对象非法=” + 到文本 (控件对象) + “】” + #换行符) 返回 (假) .如果真结束 ' 池控件里的父窗口指针,位置同助手窗口按钮(+4);不一样的话按日志反馈调整 父窗口 = 内存_读整数型 (全局_进程句柄, 控件对象 + 4) 写日志 (“池控件【控件=” + 到文本 (控件对象) + “ 父窗口=” + 到文本 (父窗口) + “ 虚表=” + 十到十六 (内存_读整数型 (全局_进程句柄, 父窗口)) + “】” + #换行符) .如果真 (父窗口 = 0 或 父窗口 = -1) 写日志 (“点池控件失败【父窗口=0,控件对象里 +4 处不是父窗口】” + #换行符) 返回 (假) .如果真结束 置入代码 ({ 96 }) 置入代码 ({ 106, 0 }) 置入代码 ({ 106, 命令字 }) 置入代码 ({ 104, 244, 3, 0, 0 }) 置入代码 ({ 139, 77, 252 }) 置入代码 ({ 139, 17 }) 置入代码 ({ 255, 82, 4 }) 置入代码 ({ 97 }) 延迟 (取随机数 (300, 600)) 写日志 (“点池控件命令已发出” + #换行符) 返回 (真)