实测环境:YGOnline.exePID 38424,2026-10-18 23:40
所有地址、字段、命令均为活进程实跑结果,未跑过的会明确标注
<账号>.aut = 11812 字节
= 4 字节文件头(6A 00 00 00,只在文件里,内存里没有对应)
+ 4 个槽 × 2952 字节
槽 = 2 页 × 1476 (0x5C4) 字节
页基址 = 文件头4 + 2952 × 槽号 + 0x5C4 × 页号
| 槽 | 页 | 文件内页基址 |
|---|---|---|
| 0 | 0 | 0x000004 |
| 0 | 1 | 0x0005C8 |
| 1 | 0 | 0x000B8C |
| 1 | 1 | 0x001150 |
| 2 | 0 | 0x001714 |
| 2 | 1 | 0x001CD8 |
| 3 | 0 | 0x00229C |
| 3 | 1 | 0x002860 |
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
0x000 | 2 | 页标记 | 01 01=该页有效;00 00=空页 |
0x006 | 4 | 版本标记 | 随账号/版本不同(见过 16 43 01 01、AA 42 01 01) |
0x00C | 4 | floatA | 实测 0.78 / 0.66,疑似主阈值 |
0x010 | 4 | floatB | 实测 0.40 / 0.31 / 0.27,页1 常与页0 不同 |
0x01C | 84 | 数值区 12×8B | 每组前 4B 是 float,后 4B 是运行时计数 |
0x074 | 35 | 开关位图 | ★ 每字节一个功能开关,0/1 |
0x098 | 1 | 档位 | 实测 0 / 3 / 5 / 7 / 50 |
0x09C | 5 | 标志位 | 实测恒 01 01 01 01 01 |
0x0A9 | 1014 | 名单 13×78B | ★ BIG5 文本(辅助武功名) |
0x4A8 | 196 | 第二组设置 | 0x4BA 处还有一份版本标记 |
0x56C | 58 | 参数表 29×2B | ★ 每项取第 1 字节,99=空 |
0x5A6 | 30 | 尾部 | 保留 |
配置基址 base = 0x4C1026DC ← 本次进程值,重启会变
槽 s 页 p 的页基址 = base + 2952*s + 0x5C4*p
本次实测 8 个页地址:
槽0页0 4C1026DC 槽0页1 4C102CA0
槽1页0 4C103264 槽1页1 4C103828
槽2页0 4C103DEC 槽2页1 4C1043B0
槽3页0 4C104974 槽3页1 4C104F38
01 01 00 00 00 00 AA 42 01 01 00 00 14 AE 47 3F 71 3D 8A 3E<br>全内存扫描 → 只有 1 个结果 4C1026DC
base 起 11808 字节 vs 文件 offset 4 起 11808 字节 → 差异 0dump_to() 写出 .aut → 与真实存档 MD5 完全相同 e4df01cd…注意:内存base-4处那 4 字节是堆指针(本次0x1CF20180),不是文件头的6A。
所以不能用「内存里的 4 字节头」当锚点(80 01 F2 1C全内存有 5 处命中,不唯一)。
locate() 会先试上次地址,失败再用 .aut 文件的页头做 AOB。给账号名就行:
cfg.locate('D:/rxjh2025/client/<账号>.aut')
tools/rxjh_cfg.lua,30 个函数)CE → Ctrl+Alt+L → 粘:
local chunk = assert(loadfile('D:/rxjh_out/rxjh_cfg.lua'))
cfg = chunk()
cfg.locate('D:/rxjh2025/client/orzo.aut')
用loadfile而不是dofile——CE 的dofile不返回脚本的返回值。
| 命令 | 作用 |
|---|---|
cfg.table() | 8 个页总览(页基址/标记/floatA/档位/开关数/参数数/名单数) |
cfg.show(0,0) | 槽0页0 完整内容 |
cfg.switches(0,0) | 35 位开关原数组 |
cfg.switch_on(0,0) | 已开启的开关序号 |
cfg.params(0,0) | 29 项参数 |
cfg.item_hex(0,0,3) | 名单第 3 项的原始十六进制 |
cfg.diff_file('…/orzo.aut') | 内存 vs 文件逐字节差异(带字段名标注) |
| 命令 | 作用 |
|---|---|
cfg.set_switch(0,0,30,1) | 打开槽0页0 的第 30 号开关 |
cfg.set_param(0,0,5,20) | 参数表第 5 项 = 20 |
cfg.set_count(0,0,5) | 档位 = 5 |
cfg.item_set_hex(0,0,0,'2FA7…') | 写名单(BIG5 十六进制,Lua 不能编 BIG5) |
写后自动读回校验,返回 true/false + 说明;序号越界、值非 0/1 一律拒绝。
cfg.dump_to('D:/rxjh_out/save.aut') -- 内存 → 文件(不用点游戏保存按钮)
cfg.load_from('D:/rxjh_out/save.aut') -- 文件 → 内存
cfg.diff_file('…/orzo.aut') -- 对拍
往返实测:dump_to → load_from → 再 dump_to,两次文件差异 0 字节。
cfg.trace(20) -- 跑 20 秒,这 20 秒内去游戏里勾一个选项
返回类似:
追踪 20 秒 / 100 次采样,命中 1 个字段:
槽0页0 开关[12] 0x080 00 -> 01
一条就能定一个勾选框。做几轮就能把 35 位全对完。<br>也可以用两步式:cfg.calib_begin() → 改勾选 → cfg.calib_end()。
tools/rxjh_aut.py,离线改文件)set PY=C:\Users\Administrator\.workbuddy\binaries\python\envs\default\Scripts\python.exe
cd D:\AI空间\rxjh\tools
%PY% rxjh_aut.py pages orzo :: 8 个页概览 + 页基址换算
%PY% rxjh_aut.py fields orzo :: 页内字段目录
%PY% rxjh_aut.py list orzo :: 4 个槽概览
%PY% rxjh_aut.py dump chang1 --slot 0 :: 详细内容
%PY% rxjh_aut.py set chang1 --slot 0 --page 0 --switch 16=0 --param 0=18
%PY% rxjh_aut.py copy chang1 --from 0 --to 2
%PY% rxjh_aut.py diff chang1 --a 0 --b 1
%PY% rxjh_aut.py export chang1 snap.json
%PY% rxjh_aut.py import chang1 snap.json --slot 2 --src-slot 0
写盘默认自动 .bak;游戏在跑时会被拦下(--force 才写)。
| 场景 | 用哪条 | 为什么 |
|---|---|---|
| 游戏开着,想立刻改、立刻生效 | CE 内存(rxjh_cfg.lua) | 改的是运行中的真值,不重启 |
| 游戏关了,批量整理 / 备份 / 换配置 | Python 文件(rxjh_aut.py) | 能编 BIG5、能批量、能 JSON |
| 想把当前状态存成模板 | cfg.dump_to('…/模板.aut') | 内存快照即时落盘 |
| 想把模板套给别的号 | 文件复制 + load_from | 结构定长,可直搬 |
| 项目 | 结果 |
|---|---|
| AOB 定位 | 唯一命中 4C1026DC |
| 内存 vs 文件 11808 字节 | 差异 0 |
| 内存导出 MD5 | e4df01cde63fa7af99ad6ac68096d8b8(与真实存档一致) |
写 开关[5] 1 → 读回 | 1,恢复后 0 |
越界 set_switch(0,0,40,1) | 拒绝「开关序号 0..34」 |
非法值 set_switch(0,0,5,2) | 拒绝「值只能是 0 / 1」 |
| 往返 dump→load→dump | 差异 0 字节 |
清 开关[30]/[31] 看 88 个控件 | 控件无变化 → 配置位与面板勾选不是同一组数据 |
未解 1:35 位开关 ↔ 面板哪个勾选框<br>目前只知道 orzo 开着 [30,31]、chang1 开着 [2,3,5,6,7,8,9,10,13,16,30,31,32],但和面板上那 7 个勾选(88 戀人 / 89 刺客 / 90 商人 / 91 撿取 / 113 赤蛇 / 155 東嶺 / 156 解除异常武功)对不上。<br>实锤:把 开关[30]、开关[31] 在内存里清 0,88 个控件的 +0x360 一个都没变。<br>→ 要定映射只能靠 cfg.trace() 对照,或者改文件后重启游戏看面板。
未解 2:0x01C 起的 12 组数值<br>前 4 字节是 float,后 4 字节是会自己往上加的计数(本次 0x92C0E = 600590)。看着像「累计值/时间戳」,不是设置项。
风险
cfg.dump_to() 存一份,出问题用 cfg.load_from() 还原。diff_file 确认基线。