WinDbg x64扩展,用于反汇编活动函数,并使用LLM生成经过验证的伪代码。


该项目是一个 Windows x64 WinDbg 扩展骨架,它通过名称或地址解析函数,重建确定性的控制流视图,并直接从扩展中询问 LLM 以生成伪代码。
src/extension:WinDbg 扩展 DLL 和 !decomp 命令。src/shared:扩展共享的 JSON、分析器、协议和验证器代码。scripts:构建和供应商复制辅助工具。third_party/dbgeng:可选的供应商 dbgeng.h 和 dbgeng.lib 副本。third_party/zydis:供应商提供的稳定版 Zydis 源代码树,存在时默认使用。xmm0 至 xmm3,带有向量零惯用法保护以避免虚假传入参数/deobf:on|off 控制是否允许恢复的混淆事实指导伪 C 重写从构建输出加载扩展,然后对符号或地址运行 !decomp:```text
.load C:\path\to\decomp.dll
!decomp /doctor
!decomp module!FunctionName
!decomp 0x7ffb`12345678
当设置看起来有问题时,或者启用 LLM provider 之前,使用 `/doctor`:```text
!decomp /doctor
!decomp /doctor:net
/doctor 不需要目标且不调用提供者。它报告配置路径/加载状态、提供者/模型/端点摘要、认证存在性(不含机密)、超时/令牌/分块设置、DML支持、会话类/限定符、处理器类型和PDB注意事项。/doctor:net 会被当作显式网络检查请求接受,但目前报告跳过提供者ping。该扩展不会从doctor模式执行网络探测。靶标可以是公有/私有符号、导出的函数名或地址。如果靶标解析为函数内的地址,扩展会尝试从符号、展开数据和控制流启发式方法中恢复所在函数范围。对包含空格的靶标加引号:```text !decomp "my module!Function With Spaces"
正常命令路径执行本地分析、构建分析器事实、可选地调用已配置的LLM端点、根据恢复的证据验证响应,并输出伪C代码以及置信度、警告和不确定性注释:```text
!decomp ntdll!RtlAllocateHeap
!decomp kernel32!Sleep
!decomp game.exe!CheckIntegrity
Normal(正常)、brief(简要)和 explain(解释)输出模式包含一个紧凑的进度流,即使在未使用 /verbose 时也是如此。长 LLM 运行会显示本地分析完成、分块进度、重试通知、合并启动、验证以及 Ctrl+Break 取消提示。机器可读模式(例如 /view:json、/view:facts、/view:prompt 和 /view:data)会抑制进度行和 DML 辅助链接,以便脚本仅接收所请求的有效载荷。
使用 /view:* 来选择你想要查看的内容。这保持了命令界面的简洁性:一个选项控制所有输出模式。```text
!decomp /view:brief module!HotPath
!decomp /view:explain module!BranchyFunction
!decomp /view:json module!FunctionName
!decomp /view:facts module!FunctionName
!decomp /view:prompt module!FunctionName
!decomp /view:data module!FunctionName
!decomp /view:analyzer module!FunctionName
!decomp /view:plan module!FunctionName
- `brief` 打印目标、置信度、摘要以及第一个不确定性或验证器警告。
- `explain` 添加证据、控制流、类型提示、观察到的行为和调用目标部分。
- `json` 打印机器可读的请求和响应 JSON。
- `facts` 仅打印分析器事实并禁用 LLM 路径。
- `prompt` 打印精确的系统提示、用户提示和提示事实。它会禁用 LLM 调用。
- `data` 打印一个稳定的 JSON 快照,旨在用于 WinDbg JavaScript/NatVis 风格的自动化。
- `analyzer` 渲染确定性仅分析器伪代码路径,而不调用 LLM。
- `plan` 执行本地分析并打印预检计划,而不调用 LLM 或更新结果缓存。它包括目标/模块/范围计数、PDB 可用性、会话策略、估计的分块、与提示大小相关的计数以及实用建议。
当命令似乎卡住或你想看到完整的进度流时,使用 `/verbose`:```text
!decomp /verbose module!SlowFunction
!decomp /verbose /view:json module!SlowFunction
/verbose 会打印本地阶段,例如目标解析、函数范围恢复、字节读取、反汇编、分析器事实构建、PDB/会话增强、伪代码标记化以及验证器结果。/verbose 还会打印提示大小、请求令牌预算、HTTP 连接/发送/接收阶段、响应块大小、完成原因、提取的模型 JSON 预览、重试次数以及验证器反馈的重试决策。/verbose 用完整跟踪替换紧凑进度流。在紧凑进度行不足以诊断时间花费时使用它。!decomp 命令期间,在 WinDbg 中按 Ctrl+Break 请求取消。扩展程序在本地分析阶段和等待 LLM 工作线程之间检查中断,然后要求活动的同步 HTTP I/O 停止。旧版别名例如 /brief、/explain、/json、/facts-only、/debug-prompt、/data-model、/dx 和 /no-llm 仍然适用于旧脚本,但新示例使用 /view:*。
窗口查看器:```text !decomp /view:window module!FunctionName !decomp /view:window /view:explain module!FunctionName
- `/view:window` 对目标执行正常的 `!decomp` 结果路径,并在单独查看器中打开完整的渲染结果。
- 该查看器使用与控制台路径相同的响应渲染器,然后在找到调试器窗口时,打开一个由调试器窗口拥有的原生 Win32 无模式工具窗口。
- 调试器输出报告原生查看器窗口句柄。如果无法创建查看器窗口,命令会打印警告并回退到正常的控制台结果。
- 仅限 DML 的链接在查看器中呈现为带有命令字符串的文本标签。当 RichEdit 可用时,窗口使用 GitHub 风格的 RTF 布局,包含章节标题、元数据样式和伪代码高亮;否则回退为纯文本。
- 当当前会话有之前的缓存结果时,查看器会显示左侧历史列表,以便您在当前输出和之前的反编译结果之间切换,而无需重新运行分析。
- `/view:json`、`/view:facts`、`/view:prompt` 和 `/view:data` 仍保持为机器可读的控制台输出,不会重定向到查看器。
大型函数:```text
!decomp /limit:deep module!LargeFunction
!decomp /limit:huge module!VeryLargeFunction
!decomp /limit:12000 module!VeryLargeFunction
!decomp /timeout:120000 module!SlowFunction
/limit:deep 将指令上限提升至 8192。/limit:huge 将指令上限提升至 16384。/limit:N 设置显式的指令上限。/timeout:MS 覆盖本次调用的请求超时时间。decomp.llm.json 控制;命令行指令上限控制扩展在提示前尝试恢复多少本地代码。/deep、/huge 和 /maxinsn:N 仍然受支持。混淆感知反编译:```text !decomp /deobf:on module!FlattenedFunction !decomp /deobf:off module!FlattenedFunction !decomp /view:facts /deobf:off module!FlattenedFunction
- `/deobf:on` 为默认选项。分析器仍会发出原始事实,但高置信度的 OLLVM 风格分发器恢复、不透明死边证明、替换习语以及语义 CFG 覆盖层可能会指导提示事实、合并策略、验证器冲突策略以及结构化伪 C 恢复。
- `/deobf:off` 保留 `obfuscation`、`semantic_control_flow` 和 `deobfuscation_readiness` 事实可见,但禁用重写安全操作,保持控制流结构基于原始 CFG,并告知提示/合并/验证器路径保留原始混淆形状。
- 当你希望直接检查分发器、虚假分支或替换表面,而不是让扩展恢复反混淆结构时,请使用 `/deobf:off`。
- `/deobfuscation:on|off` 作为更长的别名被接受。
缓存和重放助手:```text
!decomp /view:json module!FunctionName
!decomp /last:json
!decomp /view:explain module!FunctionName
!decomp /last:explain
!decomp /view:facts module!FunctionName
!decomp /last:facts
!decomp /view:data module!FunctionName
!decomp /last:data
!decomp /view:prompt module!FunctionName
!decomp /last:prompt
!decomp /history
!decomp /refresh module!FunctionName
!decomp /last:2:explain
!decomp /last:2:json
/last:json 打印上一次的请求/响应 JSON,无需重新运行分析。/last:explain 重新渲染上一次的完整结果并包含解释部分,无需重新运行分析或调用 LLM。/last:facts 打印上一次结果中的分析器事实,无需重新运行分析。/last:data 打印上一次的数据模型快照,无需重新运行分析。/last:prompt 打印上一次的提示转储,无需重新运行分析。/history 列出内存中的结果环形缓冲区。索引 1 是最新的结果。/refresh <target> 绕过该目标持久化制作的回放,运行全新的本地分析和 LLM 分析,并在成功获得 LLM 支持的结果后替换保存的制作。/last:N:explain、/last:N:json、/last:N:facts、/last:N:data 和 /last:N:prompt 按历史索引回放较旧的缓存结果,无需重新运行本地分析或调用 LLM。/last:* 模式是终端回放命令。如果在同一命令中存在目标,则回放缓存的制作,并且不会为该目标启动本地分析或 LLM 请求。DML 导航:
actions 行,其中包含针对同一目标的可点击 explain、json、facts、prompt、data-model 和 history 链接。nav 行,其中包含入口反汇编、入口断点和最新制作回放链接。会话感知和观察到的行为细节:
/view:json、/view:facts、/view:prompt 和普通 LLM 模式包含 session_policy。session_policy 记录调试类、限定符、执行种类、分析策略、转储/实时/内核标志以及 TTD 支持是否已加载。observed_behavior 记录当前的 rip、rsp、可读时的返回地址、Microsoft x64 寄存器参数样本(rcx、rdx、r8、r9)、重复的内存访问热点和建议的 TTD 命令。ttdext.dll 或 TTDReplay.dll,扩展会添加建议的 dx @$cursession.TTD.Calls(...) 查询,而不是静默地假装已经收集了跟踪数据。用户修正开关允许您在调试器缺乏足够语义信息时从命令行修补分析器事实:```text !decomp /fix:noreturn:FatalError module!FunctionName !decomp /fix:type:rcx=MY_TYPE* module!FunctionName !decomp /fix:field:[rcx+18h]=uint32_t module!FunctionName !decomp /fix:rename:v3=request module!FunctionName !decomp /fix:clear
- `/fix:noreturn:name` 将匹配的调用视为无返回,用于后备反汇编、CFG恢复、ABI事实和验证器检查。
- `/fix:type:expr=TYPE` 添加高置信度的用户类型提示。
- `/fix:field:expr=TYPE` 添加高置信度的用户字段提示。
- `/fix:rename:old=new` 添加重命名提示,并将该重命名应用于最终伪代码标识符。
- `/fix:clear` 清除所有会话持久的修正覆盖。
环境变量 `DECOMP_NORETURN_OVERRIDES` 仍然支持。命令行 `/fix:noreturn:` 的值在当前 WinDbg 会话中叠加于原始环境值之上。
修正开关是会话持久的:
- `/fix:noreturn:`、`/fix:type:`、`/fix:field:` 和 `/fix:rename:` 会被加载的扩展记住,并在后续的 `!decomp` 运行中重用。
- `/fix:clear` 清除所有会话持久的修正,并将无返回环境覆盖恢复为扩展加载时的原始值。
- 仍支持旧的 `/noreturn:`、`/type:`、`/field:`、`/rename:` 和 `/clear-overrides`。
格式错误的修正值会被忽略,并在 `uncertainties` 中报告,而不会缓存。例如,`/fix:type:rcx` 会被忽略,因为它不包含 `expr=TYPE` 对。
建议的调查工作流程:
1. 从 `!decomp /view:facts target` 开始,确认函数范围、基本块、调用、导入、PDB 数据和会话事实看起来合理。
2. 在发起 LLM 请求之前,使用 `!decomp /view:plan target` 估计分块、提示大小、超时风险和符号质量。
3. 当提示大小、语言或证据选择看起来有问题时,使用 `!decomp /view:prompt target`。
4. 运行 `!decomp target` 获取完整的已验证伪 C 结果。
5. 当回放已有的持久化工件但需要重新分析时,使用 `!decomp /refresh target`。
6. 如果结果看起来不正确,运行 `!decomp /view:explain target` 并检查验证器警告、证据覆盖和建议的修复。
7. 添加针对性的修正,例如 `/fix:noreturn:`、`/fix:type:`、`/fix:field:` 或 `/fix:rename:`,然后重新运行同一目标。
8. 在比较几个最近的结果时,使用 `/history` 和索引化的 `/last:N:*` 回放。
9. 在提交错误或比较不同构建的行为时,捕获 `/view:json` 或 `/last:json`。
## 分析器事实表面
最近的分析器事实会特意通过 `/view:json`、`/view:facts`、`/view:prompt` 和普通 LLM 模式传递。首先检查的高价值字段:
- `stack_pointer` 记录每条指令的栈偏移、帧相对别名和置信度。
- `call_arguments` 记录调用站点恢复的寄存器和栈参数,包括在证据足够强时附近跨基本块的栈存储。
- `pdb.prototype_parameters` 记录结构化原型参数名称、类型、序号、ABI 位置和来源置信度。
- `control_flow` 包含循环归纳变量、初始值、步长、边界、方向、跳转表地址、case 目标、default 目标、范围边界、有符号性以及恢复时的索引表达式。
- `callee_summaries` 和调用目标事实包括直接调用、间接调用和虚调用/vtable 候选,以及已知的 Win32/NT/Rtl 内存、分配、释放和状态语义。
- `obfuscation` 暴露 OLLVM 风格的控制流平坦化分发器候选、状态变量、恢复的语义边、不透明谓词和标量替换惯用法。
- `semantic_control_flow` 暴露从混淆事实中恢复的活跃/死边,即使在使用 `/deobf:off` 时仍可供检查。
- `deobfuscation_readiness` 暴露 `enabled`、安全的重写动作、被阻止的假设、优先级事实路径、计数和置信度。当禁用时,它记录策略决定并阻止去混淆的控制流重写。
- 提示事实选择将高信号条目排在前面,然后通过扩散采样保持分布,从而使大函数不会丢失所有低频证据。
## 推荐的 dbgeng 设置
最快的方法是将头文件和导入库引入项目中。
预期的供应商布局:```text
third_party\dbgeng\inc\dbgeng.h
third_party\dbgeng\lib\dbgeng.lib
您可以手动复制它们,或使用辅助脚本。
powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-DbgengVendor.ps1 ` -SourceRoot 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64'
### 从显式文件路径准备供应商副本```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-DbgengVendor.ps1 `
-HeaderPath 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\sdk\inc\dbgeng.h' `
-LibraryPath 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\dbgeng.lib'
一旦存在 third_party\dbgeng,Build.ps1 会自动优先使用它,通常不需要 DEBUGGERS_ROOT。
该仓库可以使用以下任意一种方式:
third_party\zydis 源码FetchContent默认行为是 auto,当 third_party\zydis 存在时优先使用,否则在 CMake 配置期间回退到获取 Zydis。
预期的供应商布局:```text third_party\zydis\CMakeLists.txt third_party\zydis\include\Zydis\Zydis.h third_party\zydis\dependencies\zycore\CMakeLists.txt
刷新或创建供应商副本:```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-ZydisVendor.ps1
你也可以从已下载的本地源代码树中进行vendor操作:```powershell powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-ZydisVendor.ps1 ` -SourcePath 'C:\path\to\zydis'
## 构建
推荐使用 Visual Studio 开发者 PowerShell 或开发者命令提示符。
构建后的 `decomp.dll` 现在嵌入了取自 `version.txt` 的 Windows 文件版本信息。
### 正常构建```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Build.ps1 -Reconfigure
cmake --build build --config Debug ctest --test-dir build -C Debug --output-on-failure cmake --build build --config Release ctest --test-dir build -C Release --output-on-failure
`decomp_snapshot_tests` 涵盖了针对恢复的栈参数、SIMD/FP ABI输入、向量零惯用法抑制、循环归纳偏好、开关元数据、虚调用元数据、OLLVM风格的混淆事实、`/deobf:off`策略、已知API摘要、提示事实选择以及验证器接地检查的分析器/协议/验证器合约。
### 遗留的 dbgeng 构建```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Build-Legacy.ps1 -Reconfigure
powershell -ExecutionPolicy Bypass -File .\scripts\Invoke-ReleaseBuild.ps1
此脚本将 `version.txt` 中的最后一个组件增加 `1`,强制重新配置,然后构建 Release DLL。例如,`1.0.0.7` 变为 `1.0.0.8`。
### 常用选项
- `-Configuration Release|Debug`
- `-Clean`
- `-Reconfigure`
- `-ConfigureOnly`
- `-Verbose`
- `-ZydisSource Auto|Vendor|Fetch`
- `-ZydisVendorDir 'C:\path\to\zydis'`
- `-DebuggersRoot 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64'`
- `-DbgengIncludeDir 'E:\works\windbg_llm_decomp_2\windbg_llm_decomp\third_party\dbgeng\inc'`
- `-DbgengLibrary 'E:\works\windbg_llm_decomp_2\windbg_llm_decomp\third_party\dbgeng\lib\dbgeng.lib'`
### 供应商优先示例```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Build.ps1 `
-Configuration Release `
-ZydisSource Vendor `
-Reconfigure `
-Verbose
powershell -ExecutionPolicy Bypass -File .\scripts\Build.ps1 -Configuration Release
-DbgengIncludeDir 'E:\works\windbg_llm_decomp_2\windbg_llm_decomp\third_party\dbgeng\inc' -DbgengLibrary 'E:\works\windbg_llm_decomp_2\windbg_llm_decomp\third_party\dbgeng\lib\dbgeng.lib'
-Reconfigure
构建脚本会自动尝试定位以下内容:
- `cmake.exe` 来自 PATH、独立 CMake 或 Visual Studio 捆绑的 CMake
- 项目根目录下的 `third_party\dbgeng`
- `DEBUGGERS_ROOT` 来自环境变量或常见的 Windows Kits 位置
Zydis 源选择方式如下:
- `Auto`:优先使用 `third_party\zydis`,否则在配置时获取 `Zydis`
- `Vendor`:需要可用的 `third_party\zydis` 目录树或通过 `-ZydisVendorDir` 传递的路径
- `Fetch`:忽略供应商目录树,始终让 CMake 下载 `Zydis`
`DEBUGGERS_ROOT` 可以指向一个使用以下布局之一的调试器根目录:
- `sdk\inc\dbgeng.h` 和 `sdk\lib\dbgeng.lib`
- `sdk\inc\dbgeng.h` 和 `sdk\lib\amd64\dbgeng.lib`
- `sdk\inc\dbgeng.h` 和 `sdk\lib\x64\dbgeng.lib`
- `sdk\inc\dbgeng.h` 和 `dbgeng.lib`
- `inc\dbgeng.h` 和 `lib\dbgeng.lib`
- `inc\dbgeng.h` 和 `lib\amd64\dbgeng.lib`
- `inc\dbgeng.h` 和 `lib\x64\dbgeng.lib`
- `dbgeng.h` 和 `dbgeng.lib`
如果你的安装不符合这些布局,请直接传递 CMake 路径:```powershell
cmake -S . -B build-manual -G "Visual Studio 17 2022" -A x64 `
-DDBGENG_INCLUDE_DIR='E:\works\windbg_llm_decomp_2\windbg_llm_decomp\third_party\dbgeng\inc' `
-DDBGENG_LIBRARY='E:\works\windbg_llm_decomp_2\windbg_llm_decomp\third_party\dbgeng\lib\dbgeng.lib'
cmake --build build-manual --config Release
如果您的 dbgeng.h 版本过旧,导致在 GetSymbolEntryOffsetRegions 或 GetSymbolEntryString 上编译失败,请使用 Build-Legacy.ps1 或手动传递 CMake 选项。
当 DECOMP_USE_SYMBOL_ENTRY_APIS=OFF 时,扩展将回退到:
GetFunctionEntryByOffset 进行基于 x64 unwind 的范围恢复GetNameByOffset 加上启发式反汇编该扩展自动使用 WinDbg 已为目标模块加载的符号和类型信息。
PDB 丰富有两个实际层级:
这对伪代码生成的影响:
arg1)重命名为 PDB 名称(如 ctx)ctx->Statestate == StateRunning重要限制:
当前行为是自动的。PDB 使用没有单独的配置开关;质量取决于 WinDbg 已经加载了什么以及当前作用域能否与目标函数匹配。
将 decomp.llm.json 放置在与 decomp.dll 相同的目录中。
该文件不仅用于网络 LLM 设置。
provider、endpoint、model、token 预算和分块设置影响 LLM 路径。display_language 影响摘要和不确定性中使用的自然语言。syntax_highlighting 影响 WinDbg 中 DML 感知输出可用时的伪代码渲染。display_language 和 syntax_highlighting 仍用于 /view:analyzer 和 mock provider 输出。示例:```json { "provider": "openai-compatible", "endpoint": "https://api.openai.com/v1/chat/completions", "model": "gpt-5.4-2026-03-05", "api_key_env": "OPENAI_API_KEY", "timeout_ms": 120000, "max_completion_tokens": 12000, "force_chunked": false, "chunk_trigger_instructions": 900, "chunk_trigger_blocks": 36, "chunk_block_limit": 24, "chunk_count_limit": 16, "chunk_completion_tokens": 6000, "merge_completion_tokens": 12000, "display_language": { "mode": "auto", "tag": "en-US", "name": "English" }, "syntax_highlighting": { "keyword_color": "warnfg", "type_color": "emphfg", "function_name_color": "srcid", "identifier_color": "wfg", "number_color": "changed", "string_color": "srcstr", "char_color": "srcchar", "comment_color": "subfg", "preprocessor_color": "verbfg", "operator_color": "srcannot", "punctuation_color": "srcpair" } }
ChatGPT订阅示例:```json
{
"provider": "chatgpt",
"model": "gpt-5.5",
"chatgpt_auth_file": "%USERPROFILE%\\.codex\\auth.json",
"timeout_ms": 120000,
"max_completion_tokens": 12000,
"force_chunked": false,
"chunk_trigger_instructions": 900,
"chunk_trigger_blocks": 36,
"chunk_block_limit": 24,
"chunk_count_limit": 16,
"chunk_completion_tokens": 6000,
"merge_completion_tokens": 12000,
"reasoning_effort": "medium"
}
对于 provider: "chatgpt",endpoint 是可选的,默认值为 https://chatgpt.com/backend-api/codex/responses。也接受像 https://chatgpt.com/backend-api/codex 这样的基础 URL,并会归一化为 /responses。扩展程序从配置的认证文件中读取 tokens.access_token 和 tokens.refresh_token,通过 OpenAI OAuth 刷新过期的 JWT 访问令牌,并将刷新后的令牌集写回该文件。默认的认证文件是 %USERPROFILE%\.codex\auth.json,因此可以直接复用 Codex CLI ChatGPT 的登录信息。扩展程序不会在 WinDbg 内部启动浏览器或开始 OAuth 登录流程;如果认证文件缺失、无效或无法再刷新,请在 WinDbg 外部运行 codex login,然后重试 !decomp。对于一次性测试,可以使用 access_token 或 access_token_env 代替认证文件。api_key、、 和 专用于兼容 OpenAI 的 API 密钥提供商,ChatGPT 提供商会忽略它们。
支持的键:
providerendpointmodelapi_keyapi_key_envaccess_tokenaccess_token_envchatgpt_auth_filereasoning_efforttimeout_msmax_completion_tokensforce_chunkedchunk_trigger_instructionschunk_trigger_blocks支持的 display_language 键:
modetagnamedisplay_language.mode 接受:
autofixed支持的 syntax_highlighting 键:
keyword_colortype_colorfunction_name_coloridentifier_colornumber_colorstring_colorchar_colorcomment_colorpreprocessor_coloroperator_colorpunctuation_colorsyntax_highlighting 颜色的工作原理:
<col fg="..."> 传递给 WinDbg DML。verbfg、warnfg、emphfg、srcid 等名称不会映射到每台机器上的统一颜色。#FF8800)。实际颜色来自 WinDbg,而非 decomp.llm.json。实际后果:
syntax_highlighting 中的槽名称,而不是认为扩展程序忽略了你的设置。高亮可见的条件:
/view:json 输出不会通过 DML 渲染。相反,它会携带 pseudo_c_tokens,以便外部工具可以应用自己的语法高亮。常见的 DML 前景色槽:
wfg
默认窗口前景文本。normfg
正常命令窗口文本。emphfg
强调文本。微软默认将其记录为浅蓝色,但确切外观仍取决于主题。warnfg
警告文本。errfg
错误文本。verbfg
详细文本。changed
已更改的数据。微软默认将其记录为红色。常见的面向源代码的 DML 前景色槽:
srcnum
数值常量。srcchar
字符常量。srcstr
字符串常量。srcid
标识符。srckw
关键字。srcpair
括号或匹配符号对。srccmnt
注释。srcdrct
指令。srcspid
特殊标识符。srcannot
源代码注释或类似注释的元素。示例:
verbfg 表示“详细前景色槽”,而不是“一个特定的蓝色名称”。warnfg 表示“警告前景色槽”,而不是“总是黄色或橙色”。function_name_color: "srcid" 表示“使用 WinDbg 的标识符槽来渲染函数名”。如果你在调整深色主题下的颜色:
srcid 导致函数名显示太暗,请从 function_name_color: "emphfg" 或 function_name_color: "verbfg" 开始。identifier_color: "normfg" 或 identifier_color: "wfg",使它们保持可读但不过分抢夺关键字的风头。comment_color: "subfg"。官方参考:
已签入的 decomp.llm.json.example 仅包含扩展程序实际读取的有效顶级设置。
仅供参考的示例:
遵循 PC UI 语言:```json { "display_language": { "mode": "auto" } }
强制英语:```json
{
"display_language": {
"mode": "fixed",
"tag": "en-US",
"name": "English"
}
}
强制韩语:```json { "display_language": { "mode": "fixed", "tag": "ko-KR", "name": "Korean" } }
深色语法高亮预设:```json
{
"syntax_highlighting": {
"keyword_color": "warnfg",
"type_color": "emphfg",
"function_name_color": "srcid",
"identifier_color": "wfg",
"number_color": "changed",
"string_color": "verbfg",
"char_color": "srcchar",
"comment_color": "subfg",
"preprocessor_color": "normfg",
"operator_color": "srcannot",
"punctuation_color": "srcpair"
}
}
亮色语法高亮预设:```json { "syntax_highlighting": { "keyword_color": "emphfg", "type_color": "warnfg", "function_name_color": "srcid", "identifier_color": "normfg", "number_color": "changed", "string_color": "verbfg", "char_color": "srcchar", "comment_color": "subfg", "preprocessor_color": "srcannot", "operator_color": "wfg", "punctuation_color": "subfg" } }
`/view:json` 响应详情示例:
- JSON 响应包含 `pseudo_c` 和 `pseudo_c_tokens`。
- `pseudo_c_tokens` 是一个确定性的令牌流,适用于外部语法高亮。
- 序列化请求包含 `preferred_natural_language_tag` 和 `preferred_natural_language_name`,它们反映了在应用 `display_language.mode` 后解析出的显示语言。
- 分析器事实现在包含 P0 质量字段:
`ir_values`、`block_value_states`、`control_flow` 和 `abi`。
- `ir_values` 公开了类似 SSA 的值 ID、定义点、目标、规范表达式、使用链接、常量/副本标志以及死定义提示。
- `block_value_states` 公开了每个基本块的活跃输入/活跃输出到达定义、规范值、存储类、收敛状态和置信度。
- `stack_pointer` 公开了每条指令的堆栈增量、框架相对别名、原始基址/偏移量和置信度。
- `control_flow` 公开了结构化区域候选,例如 `natural_loop`、`if_else_candidate` 和 `switch_candidate`,附带块证据、循环归纳元数据、switch 表/默认值/范围元数据、符号性、索引表达式和置信度。
- `abi` 公开了 Microsoft x64 影子空间假设、主叫槽证据、框架/序言/尾声识别、无返回调用证据、尾调用候选、thunk 候选、导入包装器候选,以及从寄存器和堆栈存储中恢复的调用参数。
- 分析器事实现在也包含 P1 语义字段:
`type_hints`、`idioms` 和 `callee_summaries`。
- `type_hints` 公开了指针、局部变量、字段偏移量、类似数组、类似枚举、类似位标志和虚表候选的证据,附带来源和置信度。当 PDB 数据可用时,作用域参数/局部变量、字段提示和枚举常量也会被提升到这个统一的类型提示流中。
- `idioms` 公开了对识别的辅助函数和编译器模式(如内存复制/填充、字符串复制、安全 cookie 检查、堆栈探测、分配/释放辅助函数、聚合初始化器和 RIP 相对全局/导入加载)的更高层次替换。
- `callee_summaries` 公开了直接和间接被调用者的返回类型、参数模型、副作用、内存效应、所有权、来源和置信度提示;当 WinDbg 可以解析时,符号/类型丰富的调用目标将替换初始启发式摘要,并且虚拟调用候选包含目标表达式以及恢复后的 vtable 偏移量。
- 已知的 Win32/NT/Rtl API 摘要描述了当符号名称可用时的内存复制/填充/清零、分配、释放、状态和错误行为。
- 提示事实包含 `analyzer_skeleton` 和 `graph_summary`,以便模型从基于证据的草稿开始,而不是从空白页面开始。
- `graph_summary` 提供入口块、控制流区域、规范化条件和具有明确截断策略的代表性高信号块。提示事实选择现在对高信号条目进行排名,并使用扩展抽样来保持大型事实集的代表性。
- `evidence_graph` 公开高信号事实节点和溯源边,以便 IR 值、块值状态、内存访问、调用目标、类型提示、PDB 提示和观察到的行为可以追溯到指令和块证据。
- `obfuscation`、`semantic_control_flow` 和 `deobfuscation_readiness` 公开了 OLLVM 样式恢复事实,以及对于当前命令是否启用了反混淆重写指导。
- 验证器响应包含旧版 `warnings` 以及结构化的 `issues` 条目。每个问题都带有 `severity`、`code`、`message` 和可选的 `evidence`,以便工具可以过滤错误(如 `branch.true_target_not_successor`)与低风险警告分开。
- 验证器检查现在比较规范化的分支真/假目标与 CFG 后继者,比较伪代码分支密度与恢复的条件分支,交叉检查直接被调用者摘要与伪代码调用效果,验证证据图节点/边的基础,并检查块值状态引用回恢复的块和 IR 值。
- Normal 和 explain 输出可能包含一个简洁的 `suggested fixes`(建议修复)部分。这些是保守的 `/fix:*` 命令,源自验证器问题、PDB 支持的重新命名机会或重复观察到的内存热点。支持 DML 的输出将立即可应用的建议呈现为针对同一目标的可点击重跑链接;占位符字段类型建议在 `TYPE` 被替换之前保持纯文本。
- 在 LLM 模式下,扩展会自动将验证器问题反馈到一个重试提示中。当重试保留或改善验证器质量时,保留重试结果;否则保留原始响应并添加一个不确定注释。
- `session_policy` 和 `observed_behavior` 公开了 WinDbg 特定的上下文,如实时/转储/内核/TTD 类似策略、当前帧寄存器参数样本、内存热点和建议的跟踪查询。
- 当符号/类型数据可用时,序列化请求现在也包含一个 `pdb` 对象。
- `pdb.availability` 报告丰富级别,例如 `none`、`symbols`、`typed` 或 `scoped`。
- `pdb.params`、`pdb.locals`、`pdb.field_hints`、`pdb.enum_hints` 和 `pdb.source_locations` 旨在作为供外部工具或离线分析使用的机器可读语义提示。
可选的环境覆盖:
- `DECOMP_LLM_PROVIDER`
- `DECOMP_LLM_ENDPOINT`
- `DECOMP_LLM_MODEL`
- `DECOMP_LLM_API_KEY`
- `OPENAI_API_KEY`
- `DECOMP_LLM_CHATGPT_ACCESS_TOKEN`
- `DECOMP_LLM_CODEX_ACCESS_TOKEN`
- `KERNFORGE_CODEX_ACCESS_TOKEN`
- `DECOMP_LLM_CHATGPT_AUTH_FILE`
- `DECOMP_LLM_CODEX_AUTH_FILE`
- `KERNFORGE_CODEX_AUTH_FILE`
- `DECOMP_LLM_REASONING_EFFORT`
- `DECOMP_LLM_TIMEOUT_MS`
- `DECOMP_LLM_MAX_COMPLETION_TOKENS`
- `DECOMP_LLM_FORCE_CHUNKED`
- `DECOMP_LLM_CHUNK_TRIGGER_INSTRUCTIONS`
- `DECOMP_LLM_CHUNK_TRIGGER_BLOCKS`
- `DECOMP_LLM_CHUNK_BLOCK_LIMIT`
- `DECOMP_LLM_CHUNK_COUNT_LIMIT`
- `DECOMP_LLM_CHUNK_COMPLETION_TOKENS`
- `DECOMP_LLM_MERGE_COMPLETION_TOKENS`
- `DECOMP_NORETURN_OVERRIDES`
逗号或分号分隔的函数名片段,在回退反汇编、CFG 后继恢复、ABI 事实和验证器检查期间被视为无返回目标。示例:`DECOMP_NORETURN_OVERRIDES=MyAbort;PanicAndExit`。
质量优先说明:
- 该扩展现在支持大型函数的分块多遍分析。
- 分析器在优化之前将 IR 值事实、块值状态、控制流区域、证据图事实和 x64 ABI/无返回证据发送给 LLM,因此 `/view:analyzer`、`/view:json` 和普通 LLM 模式都共享相同的 P0 证据基础。
- 验证器根据分析器证据交叉检查循环、switch、无返回、分支目标、返回行为、被调用者调用效果、证据图的接地、块值状态一致性、证据覆盖范围和可疑标识符声明。当自信的陈述超出恢复的事实时,它会降低信任度,并使用稳定的严重性/代码对标记每个问题。
- 当验证器反馈发现模式错误、事实冲突或调整后的置信度非常低时,LLM 路径会执行一次自动重试,将验证器问题附加到提示中。
- 云端模型的一个良好起点是 `max_completion_tokens=12000`、`chunk_completion_tokens=6000` 和 `merge_completion_tokens=12000`,设置 `force_chunked=false`,分块触发放置于约 `900 条指令` 或 `36 个块`。
- 仅在分块管道压力测试时保持 `force_chunked=true`。对于质量优先的反编译,对于扁平化或分发器繁重的函数,通常需要单个提示,直到函数足够大以超过配置的分块触发器。
- 对于云端模型,保持 `timeout_ms` 较高。`120000` 是比 `15000` 更安全的起点。
- 如果对于大型函数质量仍然较弱,请在缩小 `/limit:N` 之前提高 `chunk_count_limit`。
- 如果未配置端点,扩展将回退到确定性模拟提供程序。
- 即使扩展使用 `/view:analyzer` 或模拟提供程序,`display_language` 和 `syntax_highlighting` 仍然会影响用户看到的内容。
## WinDbg 冒烟测试
1. 使用 `Build.ps1` 或 `Build-Legacy.ps1` 构建。
2. 将 `decomp.llm.json` 放在构建好的 `decomp.dll` 旁边。
3. 启动 WinDbg。环境变量仅为可选覆盖。
4. 加载扩展。
5. 在启用 LLM 路径之前验证仅分析器模式。```text
.load C:\path\to\decomp.dll
!decomp /view:analyzer ntdll!RtlAllocateHeap
!decomp /view:facts kernel32!Sleep
然后验证LLM模式:```text !decomp ntdll!RtlAllocateHeap !decomp /view:json ntdll!RtlAllocateHeap !decomp 0x7ffb`12345678
预期检查:
- `target`、`entry` 和 `module` 应保持一致解析
- `regions` 对于普通函数应为非零
- `/view:analyzer` 仍应打印分析器置信度和伪代码存根
- LLM 模式应填充 `summary`、`pseudo_c`、`pseudo_c_tokens` 和 `verified`
- `/view:json` 输出应在序列化请求中包含 `preferred_natural_language_tag` 和 `preferred_natural_language_name`
- 当加载私有或富 PDB 时,`/view:json` 还应包含 `pdb.prototype`、`pdb.params` 以及可能的 `pdb.locals`
- 对于类型化结构体和枚举,`/view:json` 可能包含 `pdb.field_hints` 和 `pdb.enum_hints`
## ChatGPT Subscription Example```powershell
$env:DECOMP_LLM_PROVIDER = "chatgpt"
$env:DECOMP_LLM_MODEL = "gpt-5.5"
$env:DECOMP_LLM_CHATGPT_AUTH_FILE = "$env:USERPROFILE\.codex\auth.json"
$env:DECOMP_LLM_TIMEOUT_MS = "120000"
如果认证文件包含刷新令牌,扩展会在发送请求前刷新已过期的访问令牌。DECOMP_LLM_CHATGPT_ACCESS_TOKEN 可用于临时持有者令牌,但对于正常的 WinDbg 会话,认证文件路径更佳,因为它能跨越令牌过期。扩展在 !decomp 期间绝不会打开浏览器;当需要交互式 ChatGPT 登录时,请在 WinDbg 外部运行 codex login。
$env:DECOMP_LLM_ENDPOINT = "http://127.0.0.1:11434/v1/chat/completions" $env:DECOMP_LLM_MODEL = "qwen2.5-coder:14b" $env:DECOMP_LLM_API_KEY = "ollama"
### LM Studio```powershell
$env:DECOMP_LLM_ENDPOINT = "http://127.0.0.1:1234/v1/chat/completions"
$env:DECOMP_LLM_MODEL = "local-model"
$env:DECOMP_LLM_API_KEY = "lm-studio"
$env:DECOMP_LLM_ENDPOINT = "http://127.0.0.1:8000/v1/chat/completions" $env:DECOMP_LLM_MODEL = "Qwen/Qwen2.5-Coder-14B-Instruct" $env:DECOMP_LLM_API_KEY = "local"
decomp.dll 旁边的 artifact 文件夹下。操作员无需单独执行保存命令。request、response、data_model、debug_prompt 以及一个包含 Win32/KD 版本值、构建字符串、可选的 NtBuildLab 和构建指纹的 kernel_build 对象。!decomp <target> 命令会自动在目标解析和函数 RVA 恢复后检查 artifact\<kernel_build>\... 路径。如果保存的 kernel_build 与当前操作系统构建匹配,则该扩展会回放制作,而无需读取函数字节、运行本地分析器传递或调用 LLM。/last:* 视图,因此点击 explain、json、facts、prompt 或 data-model 不会启动新的反编译运行。/last-json、/last-explain、/last-facts、/last-data-model、/last-dx 和 /last-prompt 仍然受支持。api_key_envDECOMP_LLM_API_KEYOPENAI_API_KEYchunk_block_limitchunk_count_limitchunk_completion_tokensmerge_completion_tokensdisplay_languagesyntax_highlighting