wowdump 0.3.5 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -6
- package/dist/analysis/runtime-dump.js +2 -2
- package/dist/cli.js +120 -176
- package/dist/core/build-adapters.js +0 -8
- package/dist/debug/cdb.js +412 -0
- package/dist/reader/broker.js +20 -10
- package/dist/reader/launcher.js +5 -5
- package/dist/reader/main.js +18 -35
- package/dist/reader/windows.js +2 -2
- package/dist/toolchain.js +3 -3
- package/package.json +4 -5
- package/skills/wowdump/SKILL.md +13 -16
- package/skills/wowdump/references/commands.md +36 -57
- package/skills/wowdump/references/disassemble.md +45 -35
- package/skills/wowdump/references/evidence-workflow.md +8 -36
- package/skills/wowdump/references/profiles.md +43 -34
- package/skills/wowdump/references/request-schema.md +9 -25
- package/skills/wowdump/references/windbg.md +63 -0
- package/skills/wowdump/references/workflow.md +14 -36
- package/dist/analysis/frida-runtime.js +0 -715
- package/dist/analysis/runtime-script.js +0 -156
- package/dist/frida-worker.js +0 -153
- package/skills/wowdump/references/dynamic.md +0 -54
- package/skills/wowdump/scripts/dynamic-session.js +0 -133
package/skills/wowdump/SKILL.md
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wowdump
|
|
3
|
-
description:
|
|
3
|
+
description: 使用 wowdump CLI 定位和读取 WoW 原生内存字段,结合 CDB、IDA Pro MCP 或 iced-x86 证据生成并验证 Reader profile。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# wowdump
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
先明确要读的对象、字段和单位。例如“角色属性”中的暴击等级与暴击百分比是不同字段;不要用 Aura、资源值等其他结果替代。
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
1. 运行 `wowdump targets`,使用返回的 PID、路径、buildKey 和哈希;多个目标且用户尚未指定时请用户选择。
|
|
11
|
+
2. 有匹配 build/hash 的已验证 profile 时直接 Reader 读取。用户要求全新分析时,创建新 session,不使用旧候选作为本轮发现。
|
|
12
|
+
3. 未知字段按 [定位流程](references/workflow.md) 收集证据;需要静态分析时先读 [IDA 与局部反汇编](references/disassemble.md)。
|
|
13
|
+
4. 按 [Profile 格式与生命周期](references/profiles.md) 构建候选,按 [验证方法](references/evidence-workflow.md) 分别验证读取、字段含义和复用能力。
|
|
14
|
+
5. 返回字段、单位、观测时间和证据路径。用户确认持久化后保存 profile;已有保存授权时沿用。
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
4. 没有可用 profile 时,由 Agent 编写并显式传入 GumJS:`wowdump analyze dynamic --pid <pid> --build <buildKey> --script <GumJS> --confirm`。脚本可做快照、有限 Hook 和事件采集。
|
|
17
|
-
5. 动态线索需要静态证据时运行 `wowdump analyze runtime --kind dump`。dump 只写当前 session 的 `.text/.rdata/.pdata`,`.data` 通过 `--sections` 按需加入;不创建新的静态数据库。
|
|
18
|
-
6. 优先让 IDA Pro MCP 打开该 build 的 `database/ida/Wow.i64`,按 manifest 将 runtime overlay 映射到原始 Wow.exe,输出函数 RVA、字符串 RVA、XREF、结构偏移和字段类型。没有 IDA MCP 时,用 iced-x86 对相关范围局部反汇编。
|
|
19
|
-
7. 将静态结果和动态证据合并为 runtime session 下的 `candidate.profile.json`,只保存 RVA/相对偏移,不保存绝对地址。
|
|
20
|
-
8. 用 `wowdump analyze runtime --kind verify --profile <candidate> --confirm` 做 broker 实读;确认 build/hash、地址、类型、边界和读取值一致后,才把 profile 复制到 `~/.wowdump/<buildKey>/profile/`。
|
|
16
|
+
按需查阅:
|
|
17
|
+
- [命令参数](references/commands.md):CLI 用法。
|
|
18
|
+
- [字段定义](references/request-schema.md):目标含义不明确时。
|
|
19
|
+
- [CDB 使用与退出限制](references/windbg.md):执行 dump 或 debug 前。
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
目录统一为 `~/.wowdump/<buildKey>/`:`database/` 保存静态数据库,`runtime/<session>/` 保存本轮证据与候选,`profile/` 保存已确认的持久化接口。Reader 读取 profile。broker 首次 UAC 后复用,空闲 20 分钟退出。
|
|
23
22
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
IDA MCP 使用长 TTL 会话(默认 `idle_ttl_sec: 3600`)。每次查询前先做 health probe;出现 `worker not reachable` 时按 `references/disassemble.md` 重新打开并只重试一次。IDA worker 与 Windows broker 独立,broker 的 UAC 复用不会保持 IDA worker 存活。
|
|
23
|
+
脚本和任务证据放在 runtime session,具体地址由本轮分析确定。保留禁用 Frida Hook 和 Stalker 的约束。
|
|
@@ -1,93 +1,72 @@
|
|
|
1
1
|
# wowdump 命令参考
|
|
2
2
|
|
|
3
|
-
Windows
|
|
3
|
+
Windows 下内存和 CDB 请求都连接同一个管理员 broker。首次连接请求 UAC,后续请求复用该进程,空闲 20 分钟退出。
|
|
4
4
|
|
|
5
5
|
## 发现目标
|
|
6
6
|
|
|
7
7
|
```powershell
|
|
8
8
|
wowdump targets
|
|
9
|
-
wowdump targets --pid
|
|
9
|
+
wowdump targets --pid <pid>
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
使用输出中的 `pid`、`path`、`buildKey` 和哈希。多个目标时先让用户选择。
|
|
13
13
|
|
|
14
|
-
##
|
|
15
|
-
|
|
16
|
-
```powershell
|
|
17
|
-
wowdump analyze dynamic `
|
|
18
|
-
--pid 33976 `
|
|
19
|
-
--build "retail@12.1.0.69587" `
|
|
20
|
-
--script "C:\work\discover-state.js" `
|
|
21
|
-
--export collect `
|
|
22
|
-
--args '{"fields":["playerAuras","nearbyEnemies","cooldowns"]}' `
|
|
23
|
-
--duration-ms 5000 `
|
|
24
|
-
--confirm
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
CLI 会把结果保存到 `~/.wowdump/<buildKey>/runtime/<session-id>/dynamic.json`,并在 stdout 返回 session 目录。
|
|
28
|
-
|
|
29
|
-
导出供静态分析的运行时模块段。默认只导出 `.text/.rdata/.pdata`;需要运行时全局状态时显式加入 `.data`:
|
|
14
|
+
## CDB 段导出
|
|
30
15
|
|
|
31
16
|
```powershell
|
|
32
17
|
wowdump analyze runtime `
|
|
33
|
-
--pid
|
|
34
|
-
--build "
|
|
18
|
+
--pid <pid> `
|
|
19
|
+
--build "<buildKey>" `
|
|
35
20
|
--kind dump `
|
|
36
21
|
--sections .text .rdata .pdata `
|
|
37
22
|
--confirm
|
|
38
23
|
```
|
|
39
24
|
|
|
40
|
-
输出写入 `~/.wowdump/<buildKey>/runtime/<session
|
|
25
|
+
输出写入 `~/.wowdump/<buildKey>/runtime/<session>/dump/`,包括 `manifest.json`、`.text.bin` 等二进制和 `cdb.log`。stdout 只返回路径、段摘要、字节数和 SHA-256;不会嵌入大段字节。
|
|
41
26
|
|
|
42
|
-
|
|
27
|
+
## CDB 断点和命令
|
|
43
28
|
|
|
44
29
|
```powershell
|
|
45
|
-
wowdump
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
30
|
+
wowdump analyze debug `
|
|
31
|
+
--pid <pid> `
|
|
32
|
+
--build "<buildKey>" `
|
|
33
|
+
--rva <confirmedRva> `
|
|
34
|
+
--kind breakpoint `
|
|
35
|
+
--max-hits 3 `
|
|
36
|
+
--duration-ms 3000 `
|
|
37
|
+
--confirm
|
|
49
38
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
--
|
|
53
|
-
--
|
|
54
|
-
--
|
|
55
|
-
--
|
|
39
|
+
wowdump analyze debug `
|
|
40
|
+
--pid <pid> `
|
|
41
|
+
--build "<buildKey>" `
|
|
42
|
+
--kind command `
|
|
43
|
+
--cdb-commands '["lm","r","~"]' `
|
|
44
|
+
--cdb-args '["-lines"]' `
|
|
56
45
|
--confirm
|
|
57
46
|
```
|
|
58
47
|
|
|
59
|
-
`
|
|
60
|
-
|
|
61
|
-
## 静态定位
|
|
48
|
+
`breakpoint` 只接受一个静态确认的 RVA,输出寄存器、返回地址、线程 ID 和页面证据。`command` 允许 Agent 提供有界 CDB 命令数组;所有参数通过 `spawn` 数组传递,禁止 shell 拼接。
|
|
62
49
|
|
|
63
|
-
|
|
50
|
+
## 数据库和验证
|
|
64
51
|
|
|
65
52
|
```powershell
|
|
66
|
-
|
|
53
|
+
wowdump database status --build "<buildKey>"
|
|
54
|
+
wowdump analyze runtime --pid <pid> --build "<buildKey>" --kind verify --profile <profile.json> --confirm
|
|
67
55
|
```
|
|
68
56
|
|
|
69
|
-
|
|
57
|
+
`verify` 只读取 profile 定义的 RVA、指针链和类型,不读取 IDA 数据库或 dump 文件。验证成功并得到用户确认后,才保存到 `~/.wowdump/<buildKey>/profile/`。
|
|
70
58
|
|
|
71
|
-
|
|
72
|
-
wowdump memory read `
|
|
73
|
-
--pid 33976 `
|
|
74
|
-
--build "retail@12.1.0.69587" `
|
|
75
|
-
--profile "$HOME\.wowdump\retail@12.1.0.69587\profile\player-state.json" `
|
|
76
|
-
--field playerAuras nearbyEnemies cooldowns
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
需要连续观察时使用 `memory watch start/poll/stop`。字段未定义、模块不匹配、指针为空或发生短读时,保留 JSON 证据并停止该字段,不改写 profile。
|
|
80
|
-
|
|
81
|
-
需要枚举目标进程的虚拟内存布局时使用 `memory regions`。它通过同一个管理员 broker 调用 Windows `VirtualQueryEx`,默认只返回 `MEM_COMMIT` 区域;查询有地址范围和数量上限,不会把整片地址空间读入内存:
|
|
59
|
+
## Reader
|
|
82
60
|
|
|
83
61
|
```powershell
|
|
84
|
-
wowdump memory
|
|
85
|
-
--pid
|
|
86
|
-
--
|
|
87
|
-
--
|
|
88
|
-
--
|
|
62
|
+
wowdump memory read `
|
|
63
|
+
--pid <pid> `
|
|
64
|
+
--build "<buildKey>" `
|
|
65
|
+
--profile "$HOME\.wowdump\<buildKey>\profile\player-state.json" `
|
|
66
|
+
--field playerStats
|
|
67
|
+
wowdump memory regions --pid <pid> --start <startAddress> --end <endAddress> --max-regions 20000
|
|
89
68
|
```
|
|
90
69
|
|
|
91
|
-
|
|
70
|
+
Reader 使用 `ReadProcessMemory` 和 `VirtualQueryEx` 做有界读取,返回实际地址、读取长度、解析值和证据。
|
|
92
71
|
|
|
93
|
-
|
|
72
|
+
断点退出限制见 [windbg.md](windbg.md);candidate 验证步骤见 [profiles.md](profiles.md)。尖括号参数需替换后运行。
|
|
@@ -1,52 +1,62 @@
|
|
|
1
|
-
#
|
|
1
|
+
# IDA 与局部反汇编
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 选择与复用
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
先发现当前可调用的 IDA Pro MCP 工具及参数 schema,不假定存在特定工具名或 TTL 参数。
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
用 database status 获取数据库路径和状态。身份匹配且 ready 时优先打开已有数据库;不存在或 stale 时以原始 Wow.exe 创建。写库前使用环境提供的数据库锁;工具缺少锁能力时保持单一写入者并记录限制。保存后检查文件与状态,不能把打开 session 当作完成建库,也不手工改成 ready 冒充完成。
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- Hex-Rays 插件页:https://plugins.hex-rays.com/mrexodia/ida-pro-mcp
|
|
9
|
+
原始 PE 是主输入,保留节区、导入和异常信息。需要运行时证据时先读 [windbg.md](windbg.md),用 dump 导出 .text/.rdata/.pdata,按需加 .data。段 .bin 是 overlay,不作为完整程序打开。检查 manifest 身份、大小、哈希及 shortRead。
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
## 地址映射
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
codex plugin add ida-pro-mcp@mrexodia
|
|
17
|
-
```
|
|
13
|
+
段内偏移 = 目标 RVA - sectionRva,读取窗口必须落在实际文件范围内。
|
|
14
|
+
IDA 地址 = 数据库 image base + sectionRva,不硬编码 image base。
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
runtime dump 的绝对指针包含 ASLR。改变段加载地址不等于修正指针;分析表项时先减 manifest.moduleBase 得到 RVA,再映射到 IDA 地址。保留原始指针作证据。.data 只代表当前 session;写入持久库前保留 overlay 来源和恢复方式,避免污染原始文件视图。
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
只输出请求字段相关的函数/字符串 RVA、引用、结构偏移、类型和调用关系。查找方法见 [workflow.md](workflow.md),全量函数/字符串列表不是 profile。
|
|
22
19
|
|
|
23
|
-
##
|
|
20
|
+
## 会话失联
|
|
24
21
|
|
|
25
|
-
|
|
22
|
+
用实际支持的健康查询或轻量读取检查 session;支持 TTL 时可延长空闲时间。失联后保存证据,重新打开同一数据库并重试一次。仍失败则转 iced-x86 或报告环境问题。broker 与 IDA worker 生命周期独立。
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
## iced-x86 局部解码示例
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
{
|
|
31
|
-
"input_path": "C:\\Games\\World of Warcraft\\_retail_\\Wow.exe",
|
|
32
|
-
"mode": "prefer_headless",
|
|
33
|
-
"run_auto_analysis": true,
|
|
34
|
-
"build_caches": true,
|
|
35
|
-
"init_hexrays": true,
|
|
36
|
-
"idle_ttl_sec": 3600
|
|
37
|
-
}
|
|
38
|
-
```
|
|
26
|
+
在任务 session 创建 .cjs 文件。传入已安装 wowdump 的 package.json 绝对路径以解析随包依赖;全局安装根可通过 npm root -g 获取。
|
|
39
27
|
|
|
40
|
-
|
|
28
|
+
参数依次为 package.json、段 .bin、sectionRva、起始 RVA、字节数、manifest.moduleBase。示例有界解码一个窗口,输出指令 RVA,不提供自动反编译或全局 XREF。
|
|
41
29
|
|
|
42
|
-
|
|
30
|
+
~~~javascript
|
|
31
|
+
const fs = require("node:fs");
|
|
32
|
+
const { createRequire } = require("node:module");
|
|
33
|
+
const [pkg, file, section, start, size, base] = process.argv.slice(2);
|
|
34
|
+
const { Decoder, DecoderOptions, Formatter, FormatterSyntax } = createRequire(pkg)("iced-x86");
|
|
35
|
+
const rva = BigInt(start), sectionRva = BigInt(section), moduleBase = BigInt(base);
|
|
36
|
+
const offset = rva - sectionRva, length = Number(size);
|
|
37
|
+
const bytes = fs.readFileSync(file);
|
|
38
|
+
if (offset < 0n || !Number.isSafeInteger(length) || length < 1 || length > 65536 ||
|
|
39
|
+
offset + BigInt(length) > BigInt(bytes.length)) throw new Error("Invalid byte window");
|
|
40
|
+
const decoder = new Decoder(64, bytes.subarray(Number(offset), Number(offset) + length), DecoderOptions.None);
|
|
41
|
+
const formatter = new Formatter(FormatterSyntax.Intel);
|
|
42
|
+
decoder.ip = moduleBase + rva;
|
|
43
|
+
try {
|
|
44
|
+
while (decoder.canDecode) {
|
|
45
|
+
const instruction = decoder.decode();
|
|
46
|
+
try {
|
|
47
|
+
console.log(JSON.stringify({ rva: "0x" + (instruction.ip - moduleBase).toString(16),
|
|
48
|
+
text: formatter.format(instruction), invalid: instruction.isInvalid }));
|
|
49
|
+
if (instruction.isInvalid) break;
|
|
50
|
+
} finally { instruction.free(); }
|
|
51
|
+
}
|
|
52
|
+
} finally { decoder.free(); formatter.free(); }
|
|
53
|
+
~~~
|
|
43
54
|
|
|
44
|
-
|
|
45
|
-
2. 用相同 `input_path` 和 `idle_ttl_sec: 3600` 重新调用 `idb_open`。
|
|
46
|
-
3. 对新 session 做 `server_health`,成功后重试原查询一次。
|
|
47
|
-
4. 第二次仍失联时停止扩大分析范围,保存已取得的 JSON 证据并转用 iced-x86 或请求用户稍后重试。
|
|
55
|
+
起点应来自函数边界或已确认控制流,任意字节可解码不代表代码。RIP 相对目标由下一条指令地址加有符号位移得到,地址运算使用 BigInt。窗口不足时按控制流扩展并记录范围;解码成功不证明字段语义。
|
|
48
56
|
|
|
49
|
-
|
|
50
|
-
- IDA 不可用时,Agent 使用 npm 内置的 `iced-x86` 对 manifest 指向的局部 RVA 反汇编,输出模块 RVA、指令文本、访问偏移和证据。Agent 负责把这些线索与运行时字段对应起来,再用 dynamic 验证 `root`、`pointerChain`、`layout/type`、计数上限和停止条件。不要把一次运行的绝对地址写进持久化 profile。
|
|
57
|
+
## IDA MCP 来源
|
|
51
58
|
|
|
52
|
-
|
|
59
|
+
- [项目仓库](https://github.com/mrexodia/ida-pro-mcp)
|
|
60
|
+
- [Hex-Rays 插件目录](https://plugins.hex-rays.com/mrexodia/ida-pro-mcp)
|
|
61
|
+
|
|
62
|
+
按安装版本 README 发现工具;已有可用 MCP 时直接使用。
|
|
@@ -1,41 +1,13 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 验证字段,而不只验证读取
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
每个字段分别记录三层结论:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
1. **读取有效**:build/hash 匹配,指针链有来源,读取完整,类型和边界正确。保留地址、dataHex、bytesRead、complete、解析值及命令结果。短读或错误不转换为零值。
|
|
6
|
+
2. **语义有效**:与同一时刻角色面板或其他独立观测对照。百分比、等级、基础值和有效值分开;记录允许的舍入误差。请用户配合一次可控变化(例如换装),读取变化前后值,核对变化方向和幅度。一次相等仅是候选支持证据。
|
|
7
|
+
3. **复用有效**:新进程或重启后的 moduleBase 变化时,同一 profile 仍解析到正确对象。未做这一步就标记“跨进程未验证”,不要报告长期稳定。
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
不要求用户每次都重新配合已有验证;新字段首次建立语义时才补相应证据。输出 evidence 文件包含字段名、来源文件/函数 RVA、假设、原始读数、观测时间、对照值、转换公式及验证状态。多个字段逐个记录,局部成功不代表全部成功。
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
`analyze runtime --kind verify` 当前只执行 ProfileEngine 读取,返回 `verified:true` 表示读取调用成功;它不做角色面板对照,也不自动证明语义或重启复用。当前 candidate 状态兼容步骤见 [profiles.md](profiles.md)。
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
- 候选地址或 `rva`、字节样本、来源和采样时间
|
|
13
|
-
- 每个请求字段对应的线索
|
|
14
|
-
|
|
15
|
-
不要导出整段进程内存。把 `durationMs`、Hook 数量、事件数量和读取范围限制在请求所需范围内。
|
|
16
|
-
|
|
17
|
-
## Disassemble(按需使用)
|
|
18
|
-
|
|
19
|
-
`analyze runtime --kind dump` 的 `manifest.json` 和段文件是静态分析输入;`--runtime-export` 仍可指向 dynamic JSON。只有 dynamic 线索不足以确认函数、布局或类型时才调用 IDA Pro MCP;没有时再用 iced-x86 解码。分析后回到 dynamic 或 `analyze runtime --kind verify --profile <file>` 验证。输出 profile 时,每个字段至少给出:
|
|
20
|
-
|
|
21
|
-
```json
|
|
22
|
-
{
|
|
23
|
-
"name": "playerAuras",
|
|
24
|
-
"module": "Wow.exe",
|
|
25
|
-
"rva": "0x123456",
|
|
26
|
-
"pointerChain": [{ "offset": "0x20", "type": "pointer" }],
|
|
27
|
-
"type": "array",
|
|
28
|
-
"elementSize": 64,
|
|
29
|
-
"evidence": [{ "source": "ida-pro-mcp", "functionRva": "0x123000" }]
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
没有可靠定位时输出 `confidence: "candidate"`,不要填充猜测地址。
|
|
34
|
-
|
|
35
|
-
## Reader
|
|
36
|
-
|
|
37
|
-
Reader 根据模块名、RVA、指针链和类型执行原子读取;它不负责猜测结构,也不执行 Frida/IDA。一次读取结果应保留实际地址、请求大小、已读字节、解析值和错误状态。
|
|
38
|
-
|
|
39
|
-
需要连续数据时使用 `memory watch` 或重复 `memory read`。运行时模块基址可能变化,profile 保存 RVA,不保存本次运行的绝对地址。
|
|
40
|
-
|
|
41
|
-
## Verify
|
|
13
|
+
dump 的日志、manifest 和段字节属于取证材料;检查每段大小、哈希和 shortRead 后再引用。分析输出中的 RVA、结构偏移、类型和调用关系必须能追溯到这些材料或原始 PE。
|
|
@@ -1,45 +1,54 @@
|
|
|
1
|
-
# Profile
|
|
1
|
+
# Profile 格式与生命周期
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 地址规则
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- runtime VA = 本轮 moduleBase + RVA;IDA VA = 数据库 image base + RVA。
|
|
6
|
+
- 对象偏移以对象指针为基准,不直接加到模块基址。
|
|
7
|
+
- root.rva 默认只加模块基址;root.dereference:true 才读取根处的 8 字节指针。
|
|
8
|
+
- pointerChain 每步先加 offset,默认再读取指针;dereference:false 仅加偏移。
|
|
9
|
+
- fields 是字段名到定义的对象;复杂布局使用 layout。
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
~/.wowdump/<buildKey>/
|
|
9
|
-
├── build.json
|
|
10
|
-
├── database/
|
|
11
|
-
│ ├── database.json
|
|
12
|
-
│ └── ida/Wow.i64
|
|
13
|
-
├── profile/ # 只放用户确认保存的 profile
|
|
14
|
-
│ ├── player-state.json
|
|
15
|
-
│ └── combat-state.json
|
|
16
|
-
└── runtime/<session-id>/ # 当前任务证据
|
|
17
|
-
├── target.json
|
|
18
|
-
├── dynamic.json
|
|
19
|
-
├── dump/manifest.json
|
|
20
|
-
├── ida-evidence.json
|
|
21
|
-
├── candidate.profile.json
|
|
22
|
-
└── verify.json
|
|
23
|
-
```
|
|
11
|
+
## 最小示例
|
|
24
12
|
|
|
25
|
-
|
|
13
|
+
下例全部地址、build 和哈希都是合成测试数据,不能用于游戏。它读取全局指针,再从对象 +0x20 读取 f32。
|
|
26
14
|
|
|
27
|
-
|
|
15
|
+
~~~json
|
|
16
|
+
{
|
|
17
|
+
"schema": "wowdump.profile.v1",
|
|
18
|
+
"id": "example-stat",
|
|
19
|
+
"buildKey": "fixture@1",
|
|
20
|
+
"executableSha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
|
21
|
+
"readerStatus": "candidate",
|
|
22
|
+
"confidence": "candidate",
|
|
23
|
+
"module": { "name": "Fixture.exe" },
|
|
24
|
+
"fields": {
|
|
25
|
+
"exampleValue": {
|
|
26
|
+
"root": { "rva": "0x100", "dereference": true },
|
|
27
|
+
"pointerChain": [{ "offset": "0x20", "dereference": false }],
|
|
28
|
+
"type": "f32"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"evidence": [{ "source": "synthetic-example", "semanticVerified": false, "restartVerified": false }]
|
|
32
|
+
}
|
|
33
|
+
~~~
|
|
28
34
|
|
|
29
|
-
|
|
35
|
+
替换为本轮证实的身份、RVA、偏移和类型。直接模块标量无需解引用。数组使用 layout.kind:"array"、item、stride、count;动态计数格式先核对当前 Reader 并设置 maxItems。结构使用 layout.kind:"struct" 和 fields。复杂布局先核对当前实现或验证用例,不自创 schema。
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
~/.wowdump/<buildKey>/runtime/<session-id>/
|
|
33
|
-
```
|
|
37
|
+
## 当前 verify 状态限制
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
CLI 的 verify 调用同一个 ProfileEngine,要求 readerStatus:"reader_ready";直接传 candidate 会返回 PROFILE_NOT_READY。
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
保留 candidate.profile.json 原件。证据足够进行小范围读取后,在 runtime session 创建 verification-input.profile.json,仅为适配执行门槛设置 readerStatus:"reader_ready",confidence 与 evidence 仍保持候选。用此副本执行 verify,单独保存 verify.json;状态标签不能证明验证完成。若新版本正式支持 candidate 验证,使用其正式流程。
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
2. 向用户展示候选 profile 的路径、字段和验证结果,询问是否保存为该 build 的持久化 profile。
|
|
41
|
-
3. 用户确认后,将候选复制到 `~/.wowdump/<buildKey>/profile/<profile-id>.json`,保留 `buildKey`、来源和验证证据。
|
|
42
|
-
4. 目标文件已存在时先询问覆盖,或使用新的 profile-id;不要静默覆盖。
|
|
43
|
-
5. 后续读取优先使用这个绝对路径,或用 `wowdump profiles --build <buildKey>` 列出它。Reader 只读取 profile,不读取 `database/ida` 和 `runtime/dump/*.bin`。
|
|
43
|
+
语义验证见 [evidence-workflow.md](evidence-workflow.md)。验证失败时保留错误和候选状态,不复制到持久化目录。
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
## 保存与复用
|
|
46
|
+
|
|
47
|
+
统一在 ~/.wowdump/<buildKey>/:
|
|
48
|
+
- database/ 保存每个 build 的静态数据库。
|
|
49
|
+
- runtime/<session>/ 保存 target、dump、静态证据、候选、验证副本和 verify.json。
|
|
50
|
+
- profile/ 保存用户确认的已验证 profile。
|
|
51
|
+
|
|
52
|
+
buildKey 使用 targets 返回的安全单层目录名。profile 必须带真实 executableSha256;build/hash 不匹配重新分析,缺少哈希不视作匹配。
|
|
53
|
+
|
|
54
|
+
展示字段、单位、验证范围和绝对路径。用户确认后复制到 profile/<id>.json;已有保存授权直接沿用。覆盖现有文件前确认覆盖范围。未做重启测试时保留限制。profile 不保存 moduleBase、堆绝对地址或 IDA session ID。
|
|
@@ -1,28 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 确定字段含义
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
通常在任务记录中列明目标即可;无需为每次查询创建额外请求 JSON。这些描述不是 CLI 接受的 schema。
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
{ "name": "nearbyEnemies", "kind": "unit-list", "scope": "around-player" },
|
|
12
|
-
{ "name": "cooldowns", "kind": "cooldown", "scope": "player" }
|
|
13
|
-
],
|
|
14
|
-
"limits": { "maxUnits": 64, "maxAuras": 64, "maxEvents": 100, "durationMs": 5000 },
|
|
15
|
-
"dynamic": { "script": "discover-state.js", "stalker": { "enabled": false } }
|
|
16
|
-
}
|
|
17
|
-
```
|
|
5
|
+
| 用户目标 | 需要确定 |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| 角色属性 | 玩家;暴击/急速/精通/全能;等级数值还是百分比;当前有效值还是基础值 |
|
|
8
|
+
| Buff/Debuff | 玩家还是目标;有益/有害;持续时间单位和层数 |
|
|
9
|
+
| 技能冷却 | 技能 ID;剩余时间、完整冷却还是充能;区分 GCD |
|
|
10
|
+
| 附近敌人 | 范围、单位类型、敌对/存活条件;姓名板集合不等于附近全部敌人 |
|
|
18
11
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
常见字段映射:
|
|
22
|
-
|
|
23
|
-
- 我方 Buff:`kind: "aura", scope: "player", direction: "helpful"`
|
|
24
|
-
- 敌方 Debuff:`kind: "aura", scope: "target", direction: "harmful"`
|
|
25
|
-
- 技能冷却:`kind: "cooldown", scope: "player"`
|
|
26
|
-
- 周围敌人:`kind: "unit-list", scope: "around-player"`
|
|
27
|
-
|
|
28
|
-
这些是查询意图。没有 reader-ready profile 定义前,不要把 dynamic 的一次性地址交给长期 reader。
|
|
12
|
+
用户已说“暴击全能那些”时,先按面板当前二级属性组织字段;等级与百分比分开命名。只在含义影响分析且上下文不足时询问。每个字段记录原始类型、单位、转换公式和观测条件;原始数值不带单位时不要猜换算系数。
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# WinDbg CDB 参考
|
|
2
|
+
|
|
3
|
+
## 探测
|
|
4
|
+
|
|
5
|
+
CLI 按以下顺序寻找 `cdb.exe`:`WOWDUMP_CDB`、Windows SDK x64、WinDbg 安装目录、最后的 `where.exe cdb.exe`。只读探测,不自动下载,也不修改环境变量。找不到时返回 `CDB_NOT_FOUND`。
|
|
6
|
+
|
|
7
|
+
## 段导出
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
wowdump analyze runtime `
|
|
11
|
+
--pid <pid> `
|
|
12
|
+
--build <buildKey> `
|
|
13
|
+
--kind dump `
|
|
14
|
+
--sections .text .rdata .pdata `
|
|
15
|
+
--confirm
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Node 从原始 PE 读取 section RVA 和 virtual size,broker 内部执行等价的:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
.writemem "<absolute output path>" <runtimeStart> <runtimeEnd>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
输出在 `~/.wowdump/<buildKey>/runtime/<session>/dump/`,包含 `manifest.json`、段二进制和 `cdb.log`。JSON 只保存路径、大小、哈希和引擎信息,不内嵌大段字节。
|
|
25
|
+
|
|
26
|
+
## 断点
|
|
27
|
+
|
|
28
|
+
```powershell
|
|
29
|
+
wowdump analyze debug `
|
|
30
|
+
--pid <pid> `
|
|
31
|
+
--build <buildKey> `
|
|
32
|
+
--rva <rva> `
|
|
33
|
+
--kind breakpoint `
|
|
34
|
+
--max-hits 3 `
|
|
35
|
+
--duration-ms 3000 `
|
|
36
|
+
--confirm
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
默认脚本使用硬件执行断点,只记录 RIP、RCX、RDX、R8、R9、RSP、返回地址和线程 ID。当前脚本在下一次命中时才检查计数上限,达到记录上限不保证立即退出。broker 用 `VirtualQueryEx` 检查入口页和返回地址页,结果写入 session 的 `debug.json`。
|
|
40
|
+
|
|
41
|
+
## 其他调试命令
|
|
42
|
+
|
|
43
|
+
Agent 可以显式提交 CDB 命令数组,适合寄存器、线程、模块和符号诊断:
|
|
44
|
+
|
|
45
|
+
```powershell
|
|
46
|
+
wowdump analyze debug `
|
|
47
|
+
--pid <pid> `
|
|
48
|
+
--build <buildKey> `
|
|
49
|
+
--kind command `
|
|
50
|
+
--cdb-commands '["lm","r","~"]' `
|
|
51
|
+
--cdb-args '["-lines"]' `
|
|
52
|
+
--confirm
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
命令和参数通过 `spawn(file, args, {shell:false})` 传递;不要把它们拼成 shell 字符串。调试命令必须有时限,输出会截断到证据上限。
|
|
56
|
+
|
|
57
|
+
## 当前生命周期限制
|
|
58
|
+
|
|
59
|
+
当前 CLI 使用 -p 附加、-cf 命令文件,默认末尾追加 q,没有默认选择非侵入式附加。shell:false 只描述启动方式,不限制 CDB 命令本身的作用。
|
|
60
|
+
|
|
61
|
+
超时会终止 CDB,并在 Windows 使用 taskkill /T /F 清理进程树;这不能证明正常 detach。detached:true 当前是固定输出,也不是证据。不要把 q 当成经过实测的正常脱离保证。
|
|
62
|
+
|
|
63
|
+
执行前核对当前版本的附加方式、退出命令和时限。断点退出与真实目标存活尚未完成端到端验证;字段定位先使用静态证据和 Reader,调试退出验证先在可控测试进程完成。超时后记录目标是否存活和可响应,不仅看退出码。透传参数会改变附加模式,避免重复提供冲突的目标参数。
|
|
@@ -1,45 +1,23 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 从目标字段到地址
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 建立本轮证据
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- **要后续反复读取**:Dynamic 仍然先行,但必须补齐稳定的 RVA、指针链、类型、边界,并用 Reader 实际读通后再保存 profile。
|
|
5
|
+
运行 targets 后确认身份,检查 database status。为当前任务保留 runtime session,记录目标字段、已证实事实、候选、已排除假设和下一项证据缺口。继续任务时读取这份记录,避免重复全量扫描。
|
|
7
6
|
|
|
8
|
-
##
|
|
7
|
+
## 定位字段
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
| --- | --- | --- |
|
|
12
|
-
| 不知道模块/进程 | `wowdump targets` | PID、路径、buildKey、模块基址明确 |
|
|
13
|
-
| 不知道对象或函数是否被调用 | Dynamic GumJS 枚举、有限扫描或 Hook | 得到对象地址、候选函数或调用事件 |
|
|
14
|
-
| 需要给 IDA/iced 模块证据 | `wowdump analyze runtime --kind dump` | 得到默认 `.text`、`.rdata`、`.pdata` 和 manifest;`.data` 仅按需加入 |
|
|
15
|
-
| 有候选函数但不知道其语义 | Dynamic Hook,配合用户触发一次相关动作 | `this`、参数、返回值与目标字段相关 |
|
|
16
|
-
| 有调用但不知道字段偏移/类型 | IDA Pro MCP 局部反汇编;无 IDA 时 iced-x86 | 指令访问行为能解释对象和字段 |
|
|
17
|
-
| 静态候选需要运行时确认 | 回到 Dynamic Hook 或快照 | 候选 RVA 在当前模块命中且数据变化符合预期 |
|
|
18
|
-
| 字段定义已完成 | `wowdump memory read` | broker reader 实际读取成功,值与动态结果一致 |
|
|
9
|
+
从与目标相关的字符串、符号、调用点或已有本轮证据开始,按需使用 IDA;具体输入和地址映射见 [disassemble.md](disassemble.md)。
|
|
19
10
|
|
|
20
|
-
|
|
11
|
+
- 名称字符串只说明存在该名称。检查其引用、邻近表项、注册调用和重定位线索,确定哪里存放函数指针。没有直接 XREF 时,检查 RIP 相对引用和表间接访问;不要把字符串 RVA 当作函数入口。
|
|
12
|
+
- 沿已确认函数分析参数来源、调用者、返回路径和实际内存访问。区分 getter、包装函数和格式化函数;看见名称或一条 load 指令不足以证明字段含义。
|
|
13
|
+
- 沿对象来源回溯到可解释的根:模块全局指针、索引表或对象容器。记录每次“加偏移”及“解引用”。函数 RVA 与堆对象字段偏移分开记录。
|
|
14
|
+
- 区分读取原始字段和计算结果。若返回值由多个量计算,记录各依赖及公式;Reader 没有相应表达能力时明确返回原始量,不把它标成最终面板值。
|
|
15
|
+
- 用页面查询和小范围读取检验指针链、类型、容器边界。需要调用证据时先读 [windbg.md](windbg.md) 中的当前限制。
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
2. 没有 profile 时优先执行 Agent 编写的 GumJS。脚本可以直接 Hook 已知 RVA,也可以在限定范围内扫描候选。
|
|
24
|
-
3. Dynamic 只拿到线索时,先用 `analyze runtime --kind dump` 导出当前 session 的相关 PE 段,再让 IDA Pro MCP 复用 build database 分析对应函数、字符串和交叉引用。不要把 dump 当成 profile。
|
|
25
|
-
4. 没有 IDA MCP 时直接使用 iced-x86 对 manifest 指向的局部范围解码,得到候选后仍回到 Dynamic 验证。
|
|
26
|
-
5. 每轮最多扩大一个维度:函数数量、扫描范围、读取字节数或采样时长。连续两轮没有新增证据时,停止扩大并请求用户触发相关游戏动作或确认字段范围。
|
|
17
|
+
一次只扩大足以检验假设的范围,但没有找到候选时继续换证据路径:字符串引用失败可检查注册表和调用者;入口存在但对象不明可回溯根;值不匹配可检查类型、派生公式和状态条件。每次记录排除理由。工具失败不等于字段不存在。
|
|
27
18
|
|
|
28
|
-
##
|
|
19
|
+
## 转交 Reader
|
|
29
20
|
|
|
30
|
-
|
|
21
|
+
根据证据填写 [profiles.md](profiles.md) 的真实字段结构,执行 [evidence-workflow.md](evidence-workflow.md) 的验证。页面可读、数值合理和名称相似都不能单独证明语义正确。
|
|
31
22
|
|
|
32
|
-
|
|
33
|
-
- RVA 来自同版本静态或运行时证据,且入口字节一致;
|
|
34
|
-
- `root`/对象获取路径、字段偏移、类型和边界有指令或运行时记录支持;
|
|
35
|
-
- broker-backed Reader 实际读取成功;
|
|
36
|
-
- 读取结果与 Dynamic 快照或 Hook 返回值一致,或差异有明确解释。
|
|
37
|
-
|
|
38
|
-
任何一项缺失都保留 `candidate`,继续在 Dynamic 与 IDA/iced 之间切换,不填充猜测地址。
|
|
39
|
-
|
|
40
|
-
## 运行约束
|
|
41
|
-
|
|
42
|
-
- GumJS 必须显式通过 `--script` 提供;每次运行自行负责 attach、Hook、采集、限时和 cleanup。
|
|
43
|
-
- Hook、扫描、事件、读取字节和总时长都设置上限;默认不启用 `Stalker`。
|
|
44
|
-
- 临时证据放在 `~/.wowdump/<buildKey>/runtime/<session>/`;只有用户确认的 profile 才进入 `profile/`。
|
|
45
|
-
- 不为单次查询修改 `src/` 或重新编译 CLI;实验逻辑放在临时 GumJS。
|
|
23
|
+
真正缺少目标进程、工具入口或可观察状态时,明确缺少的条件并保留进度;不要以“少量扫描没结果”代替结论。
|