
Extensão do WinDbg x64 que desmonta funções ativas e usa um LLM para produzir pseudocódigo verificado.


Este projeto é um esqueleto de extensão WinDbg para Windows x64 que resolve uma função por nome ou endereço, reconstrói uma visão determinística de fluxo de controle e consulta diretamente um LLM a partir da extensão para produzir pseudocódigo.
src/extension: DLL de extensão do WinDbg e comando !decomp.src/shared: código JSON, analisador, protocolo e verificador compartilhado pela extensão.scripts: auxiliares de build e cópia de fornecedores.third_party/dbgeng: cópia opcional embutida de dbgeng.h e dbgeng.lib.third_party/zydis: árvore de origem estável do Zydis embutida, usada por padrão quando presente.xmm0 até xmm3, com guardas de idioma vetorial zero para evitar argumentos recebidos falsos/deobf:on|off sobre se os fatos de ofuscação recuperados podem guiar a reescrita de pseudo-CCarregue a extensão a partir da saída do build e então execute !decomp contra um símbolo ou um endereço:```text
.load C:\path\to\decomp.dll
!decomp /doctor
!decomp module!FunctionName
!decomp 0x7ffb`12345678
Use `/doctor` quando a configuração parecer errada ou antes de ativar um provedor de LLM:```text
!decomp /doctor
!decomp /doctor:net
/doctor não requer um alvo e não chama o provedor. Ele relata o caminho de configuração/estado de carregamento, resumo de provedor/modelo/endpoint, presença de autenticação sem segredos, configurações de timeout/token/chunking, suporte a DML, classe/qualificador de sessão, tipo de processador e ressalvas do PDB./doctor:net é aceito como uma solicitação explícita de verificação de rede, mas atualmente relata que o ping do provedor é ignorado. A extensão não realiza uma sondagem de rede no modo doctor.Alvos podem ser símbolos públicos/privados, nomes de funções exportadas ou endereços. Se o alvo resolver para um endereço dentro de uma função, a extensão tenta recuperar o intervalo da função que o contém a partir de símbolos, dados de unwind e heurísticas de fluxo de controle. Coloque aspas em alvos que contenham espaços:```text !decomp "my module!Function With Spaces"
O caminho de comando normal realiza análise local, constrói fatos do analisador, opcionalmente chama o endpoint de LLM configurado, verifica a resposta contra as evidências recuperadas e imprime pseudo-C mais confiança, avisos e notas de incerteza:```text
!decomp ntdll!RtlAllocateHeap
!decomp kernel32!Sleep
!decomp game.exe!CheckIntegrity
A saída normal, brief e explain inclui um fluxo de progresso compacto mesmo sem /verbose. Execuções longas de LLM mostram a conclusão da análise local, o progresso dos blocos, avisos de nova tentativa, início da mesclagem, verificação e a dica de cancelamento Ctrl+Break. Modos legíveis por máquina, como /view:json, /view:facts, /view:prompt e /view:data, suprimem linhas de progresso e links auxiliares de DML, para que os scripts recebam apenas o payload solicitado.
Use /view:* para escolher o que deseja ver. Isso mantém a superfície de comandos pequena: uma opção controla todos os modos de saída.```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` imprime alvo, confiança, resumo e a primeira incerteza ou aviso do verificador.
- `explain` adiciona seções de evidências, fluxo de controle, dica de tipo, comportamento observado e alvo de chamada.
- `json` imprime o JSON de requisição e resposta legível por máquina.
- `facts` imprime apenas os fatos do analisador e desativa o caminho do LLM.
- `prompt` imprime o prompt de sistema exato, o prompt do usuário e os fatos do prompt. Ele desativa a chamada do LLM.
- `data` imprime um snapshot JSON estável destinado à automação no estilo WinDbg JavaScript/NatVis.
- `analyzer` renderiza o caminho determinístico de pseudocódigo somente do analisador, sem chamar o LLM.
- `plan` executa análise local e imprime um plano de pré-execução sem chamar o LLM ou atualizar o cache de resultados. Inclui contagens de alvo/módulo/intervalo, disponibilidade de PDB, política de sessão, divisão em blocos estimada, contagens relevantes ao tamanho do prompt e recomendações práticas.
Use `/verbose` quando um comando parecer travado ou quando você quiser ver o fluxo completo de progresso:```text
!decomp /verbose module!SlowFunction
!decomp /verbose /view:json module!SlowFunction
/verbose imprime etapas locais como resolução de alvo, recuperação de intervalo de funções, leituras de bytes, desmontagem, construção de fatos do analisador, enriquecimento de PDB/sessão, tokenização de pseudocódigo e resultados do verificador./verbose também imprime tamanhos de prompt, orçamentos de tokens de solicitação, estágios de conexão/envio/recebimento HTTP, tamanhos de blocos de resposta, motivo de conclusão, pré-visualização do JSON do modelo extraído, tentativas de repetição e decisões de repetição com feedback do verificador./verbose substitui o fluxo de progresso compacto pelo rastreamento completo. Use-o quando as linhas de progresso compactas não forem suficientes para diagnosticar onde o tempo está sendo gasto.!decomp de longa duração, pressione Ctrl+Break no WinDbg para solicitar o cancelamento. A extensão verifica interrupções entre os estágios de análise local e enquanto aguarda o worker de LLM e, em seguida, pede que a E/S HTTP síncrona ativa pare.Aliases legados como /brief, /explain, /json, /facts-only, /debug-prompt, /data-model, /dx e /no-llm ainda funcionam para scripts antigos, mas os novos exemplos usam /view:*.
Visualizador de janela:```text !decomp /view:window module!FunctionName !decomp /view:window /view:explain module!FunctionName
- `/view:window` executa o caminho normal de resultado do `!decomp` para o alvo e abre o resultado totalmente renderizado em um visualizador separado.
- O visualizador usa o mesmo renderizador de respostas do caminho de console e, em seguida, abre uma janela de ferramenta nativa do Win32 não modal, de propriedade da janela do depurador quando uma puder ser encontrada.
- A saída do depurador informa o identificador da janela do visualizador nativo. Se a janela do visualizador não puder ser criada, o comando imprime um aviso e volta a usar o resultado normal do console.
- Links exclusivos em DML são renderizados como rótulos de texto com suas strings de comando no visualizador. Quando o RichEdit está disponível, a janela usa um layout RTF estilo GitHub com cabeçalhos de seção, estilo de metadados e realce de pseudocódigo; caso contrário, ela volta a usar texto simples.
- Quando a sessão atual tem resultados anteriores em cache, o visualizador mostra uma lista de histórico no lado esquerdo para que você possa alternar entre a saída atual e resultados de descompilação anteriores sem executar a análise novamente.
- `/view:json`, `/view:facts`, `/view:prompt` e `/view:data` permanecem como saídas de console legíveis por máquina e não são redirecionadas para o visualizador.
Funções grandes:```text
!decomp /limit:deep module!LargeFunction
!decomp /limit:huge module!VeryLargeFunction
!decomp /limit:12000 module!VeryLargeFunction
!decomp /timeout:120000 module!SlowFunction
/limit:deep eleva o limite de instruções para 8192./limit:huge eleva o limite de instruções para 16384./limit:N define um limite de instruções explícito./timeout:MS substitui o timeout da solicitação para esta invocação.decomp.llm.json; o limite de instruções da linha de comando controla quanto do código local a extensão tenta recuperar antes de solicitar o prompt./deep, /huge e /maxinsn:N continuam suportados.Decompilação ciente de ofuscação:```text !decomp /deobf:on module!FlattenedFunction !decomp /deobf:off module!FlattenedFunction !decomp /view:facts /deobf:off module!FlattenedFunction
- `/deobf:on` é o padrão. O analisador ainda emite fatos brutos, mas a recuperação de dispatcher estilo OLLVM de alta confiança, prova de arestas mortas opacas, idiomas de substituição e sobreposições semânticas de CFG podem orientar fatos de prompt, política de merge, política de conflito do verificador e recuperação estruturada de pseudo-C.
- `/deobf:off` mantém os fatos `obfuscation`, `semantic_control_flow` e `deobfuscation_readiness` visíveis, mas desativa ações seguras de reescrita, mantém a estruturação do fluxo de controle no CFG bruto e instrui os caminhos de prompt/merge/verificador a preservar a forma ofuscada bruta.
- Use `/deobf:off` quando quiser inspecionar o dispatcher, o ramo falso (bogus branch) ou a superfície de substituição diretamente, em vez de pedir à extensão para recuperar uma estrutura desofuscada.
- `/deobfuscation:on|off` é aceito como um alias mais longo.
Auxiliares de cache e replay:```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 imprime o JSON de solicitação/resposta anterior sem reexecutar a análise./last:explain renderiza novamente o resultado completo anterior com a seção explain sem reexecutar a análise nem chamar o LLM./last:facts imprime os fatos do analisador do resultado anterior sem reexecutar a análise./last:data imprime o snapshot do modelo de dados anterior sem reexecutar a análise./last:prompt imprime o dump do prompt anterior sem reexecutar a análise./history lista o buffer circular de resultados em memória. O índice 1 é o resultado mais recente./refresh <target> ignora a reprodução de artefato persistente para esse alvo, executa uma nova análise local e análise LLM e substitui o artefato salvo após um resultado bem-sucedido apoiado por LLM./last:N:explain, /last:N:json, /last:N:facts, /last:N:data e reproduzem um resultado em cache mais antigo pelo índice do histórico, sem reexecutar a análise local nem chamar o LLM.Navegação DML:
actions com links clicáveis explain, json, facts, prompt, data-model e history para o mesmo alvo.nav com links de desmontagem da entrada, breakpoint de entrada e reprodução do último artefato.Detalhes de reconhecimento de sessão e comportamento observado:
/view:json, /view:facts, /view:prompt e o modo LLM normal incluem session_policy.session_policy registra a classe de depuração, o qualificador, o tipo de execução, a estratégia de análise, os flags dump/live/kernel e se o suporte a TTD parece carregado.observed_behavior registra o rip atual, rsp, endereço de retorno quando legível, amostras de argumentos em registradores Microsoft x64 (rcx, rdx, r8, r9), pontos de acesso à memória repetidos e comandos TTD sugeridos.ttdext.dll ou estiver carregado no processo do depurador, a extensão adiciona consultas sugeridas em vez de fingir silenciosamente que os dados de rastreamento já foram coletados.As opções de correção do usuário permitem corrigir os fatos do analisador pela linha de comando quando o depurador não tem informação semântica suficiente:```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` trata chamadas correspondentes como sem retorno para desmontagem de fallback, recuperação de CFG, fatos de ABI e verificações do verificador.
- `/fix:type:expr=TYPE` adiciona uma dica de tipo de usuário de alta confiança.
- `/fix:field:expr=TYPE` adiciona uma dica de campo de usuário de alta confiança.
- `/fix:rename:old=new` adiciona uma dica de renomeação e aplica a renomeação aos identificadores finais do pseudocódigo.
- `/fix:clear` limpa todas as substituições de correção persistentes da sessão.
A variável de ambiente `DECOMP_NORETURN_OVERRIDES` continua suportada. Os valores de linha de comando `/fix:noreturn:` são sobrepostos ao valor original da variável de ambiente para a sessão atual do WinDbg.
Os comutadores de correção são persistentes na sessão:
- `/fix:noreturn:`, `/fix:type:`, `/fix:field:` e `/fix:rename:` são lembrados pela extensão carregada e reutilizados em execuções posteriores de `!decomp`.
- `/fix:clear` limpa todas as correções persistentes da sessão e restaura a substituição de ambiente para no-return ao seu valor original do momento em que a extensão foi carregada.
- Os comandos `/noreturn:`, `/type:`, `/field:`, `/rename:` e `/clear-overrides` legados continuam suportados.
Valores de correção malformados são ignorados e relatados em `uncertainties`, em vez de serem armazenados em cache. Por exemplo, `/fix:type:rcx` é ignorado porque não contém um par `expr=TYPE`.
Fluxo de trabalho recomendado para investigação:
1. Comece com `!decomp /view:facts target` para confirmar que o intervalo da função, blocos, chamadas, importações, dados PDB e fatos da sessão parecem razoáveis.
2. Use `!decomp /view:plan target` para estimar o particionamento, o tamanho do prompt, o risco de timeout e a qualidade dos símbolos antes de gastar uma solicitação de LLM.
3. Use `!decomp /view:prompt target` quando o tamanho do prompt, o idioma ou a seleção de evidências parecer incorreto.
4. Execute `!decomp target` para obter o resultado completo em pseudo-C verificado.
5. Use `!decomp /refresh target` quando um artefato persistente existente estiver sendo reproduzido, mas você precisar de uma análise nova.
6. Se o resultado parecer incorreto, execute `!decomp /view:explain target` e inspecione os avisos do verificador, a cobertura de evidências e as correções sugeridas.
7. Adicione correções direcionadas, como `/fix:noreturn:`, `/fix:type:`, `/fix:field:` ou `/fix:rename:`, e execute novamente o mesmo alvo.
8. Use `/history` e a reprodução indexada `/last:N:*` ao comparar vários resultados recentes.
9. Capture `/view:json` ou `/last:json` ao relatar bugs ou comparar o comportamento entre versões.
## Superfície de Fatos do Analisador
Os fatos recentes do analisador são intencionalmente transportados por `/view:json`, `/view:facts`, `/view:prompt` e pelo modo LLM normal. Campos de alto valor para inspecionar primeiro:
- `stack_pointer` registra deltas de pilha por instrução, aliases relativos ao frame e confiança.
- `call_arguments` registra argumentos de registro e pilha recuperados em locais de chamada, incluindo armazenamentos de pilha entre blocos próximos quando a evidência é forte o suficiente.
- `pdb.prototype_parameters` registra nomes de parâmetros de protótipo estruturado, tipos, ordinais, localizações de ABI e confiança da fonte.
- `control_flow` inclui variáveis de indução de loop, valores iniciais, passos, limites, direção, endereço da tabela de switch, alvos de caso, alvo padrão, limites de intervalo, sinalização e expressão de índice quando recuperados.
- `callee_summaries` e fatos de alvos de chamada incluem candidatos a chamadas diretas, indiretas e virtuais/vtable, além de semânticas conhecidas de memória, alocação, liberação e status do Win32/NT/Rtl.
- `obfuscation` expõe candidatos a dispatcher de achatamento (flattening) estilo OLLVM, variáveis de estado, arestas semânticas recuperadas, predicados opacos e idiomas de substituição escalar.
- `semantic_control_flow` expõe arestas vivas/mortas recuperadas que são derivadas de fatos de ofuscação e permanecem disponíveis para inspeção mesmo quando `/deobf:off` é usado.
- `deobfuscation_readiness` expõe `enabled`, ações de reescrita seguras, suposições bloqueadas, caminhos de fatos prioritários, contagens e confiança. Quando desabilitado, registra a decisão de política e bloqueia a reescrita do fluxo de controle desofuscado.
- A seleção de fatos do prompt classifica primeiro as entradas de alto sinal e depois preserva a distribuição com amostragem distribuída, para que funções grandes não percam todas as evidências de baixa frequência.
## Configuração Recomendada do dbgeng
O caminho mais rápido é incorporar (vendor) o cabeçalho e a biblioteca de importação ao projeto.
Layout de vendor esperado:```text
third_party\dbgeng\inc\dbgeng.h
third_party\dbgeng\lib\dbgeng.lib
Pode copiá-los manualmente ou usar o script auxiliar.
powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-DbgengVendor.ps1 ` -SourceRoot 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64'
### Prepare cópia do fornecedor a partir de caminhos de arquivo explícitos```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'
Quando third_party\dbgeng existir, Build.ps1 o preferirá automaticamente e você geralmente não precisa de DEBUGGERS_ROOT.
O repositório pode usar qualquer uma das opções:
third_party\zydisFetchContent do CMakeO comportamento padrão é auto, que prefere third_party\zydis quando presente e recorre à obtenção de Zydis durante a configuração do CMake.
Layout esperado do vendor:```text third_party\zydis\CMakeLists.txt third_party\zydis\include\Zydis\Zydis.h third_party\zydis\dependencies\zycore\CMakeLists.txt
Atualize ou crie a cópia do fornecedor:```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-ZydisVendor.ps1
Você também pode fazer o vendor a partir de uma árvore de código-fonte local já baixada:```powershell powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-ZydisVendor.ps1 ` -SourcePath 'C:\path\to\zydis'
## Build
O caminho recomendado é um Visual Studio Developer PowerShell ou Developer Command Prompt.
O `decomp.dll` compilado agora incorpora uma versão de arquivo do Windows obtida de `version.txt`.
### Compilação normal```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` cobre os contratos do analisador/protocolo/verificador para argumentos de pilha recuperados, entradas de ABI SIMD/FP, supressão de zero-idiom vetorial, preferência de indução de loop, metadados de switch, metadados de chamada virtual, fatos de ofuscação no estilo OLLVM, política `/deobf:off`, resumos de API conhecidos, seleção de fatos para o prompt e verificações de fundamentação do verificador.
### Build legado do dbgeng```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Build-Legacy.ps1 -Reconfigure
powershell -ExecutionPolicy Bypass -File .\scripts\Invoke-ReleaseBuild.ps1
Este script incrementa o último componente em `version.txt` em `1`, força uma reconfiguração e então compila a DLL de Release. Por exemplo, `1.0.0.7` torna-se `1.0.0.8`.
### Opções comuns
- `-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'`
### Exemplo com prioridade para o fornecedor```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
O script de build tenta localizar automaticamente:
- `cmake.exe` a partir do PATH, do CMake autônomo ou do CMake incluído no Visual Studio
- `third_party\dbgeng` na raiz do projeto
- `DEBUGGERS_ROOT` a partir de variáveis de ambiente ou de locais comuns do Windows Kits
A seleção da fonte do Zydis funciona assim:
- `Auto`: prefere `third_party\zydis`; caso contrário, busca `Zydis` durante a configuração
- `Vendor`: exige uma árvore `third_party\zydis` utilizável ou o caminho passado por `-ZydisVendorDir`
- `Fetch`: ignora a árvore do vendor e sempre deixa o CMake baixar `Zydis`
`DEBUGGERS_ROOT` pode apontar para uma raiz de depurador que usa um destes layouts:
- `sdk\inc\dbgeng.h` e `sdk\lib\dbgeng.lib`
- `sdk\inc\dbgeng.h` e `sdk\lib\amd64\dbgeng.lib`
- `sdk\inc\dbgeng.h` e `sdk\lib\x64\dbgeng.lib`
- `sdk\inc\dbgeng.h` e `dbgeng.lib`
- `inc\dbgeng.h` e `lib\dbgeng.lib`
- `inc\dbgeng.h` e `lib\amd64\dbgeng.lib`
- `inc\dbgeng.h` e `lib\x64\dbgeng.lib`
- `dbgeng.h` e `dbgeng.lib`
Se a sua instalação não corresponder a esses layouts, passe os caminhos do CMake diretamente:```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
Se o seu dbgeng.h for muito antigo e o build falhar em GetSymbolEntryOffsetRegions ou GetSymbolEntryString, use Build-Legacy.ps1 ou passe a opção do CMake manualmente.
Com DECOMP_USE_SYMBOL_ENTRY_APIS=OFF, a extensão recorre a:
GetFunctionEntryByOffset para recuperação de intervalo baseada em unwind x64GetNameByOffset mais desmontagem heurística se os metadados de unwind estiverem ausentesA extensão consome automaticamente símbolos e informações de tipo que o WinDbg já carregou para os módulos de destino.
Há dois níveis práticos de enriquecimento de PDB:
Como isso afeta a geração de pseudocódigo:
arg1 para nomes PDB, como ctxctx->Statestate == StateRunningLimitações importantes:
O comportamento atual é automático. Não há uma opção de configuração separada para o uso de PDB; a qualidade depende do que o WinDbg já carregou e se o escopo atual pode ser correspondido à função de destino.
Coloque decomp.llm.json ao lado de decomp.dll.
Este arquivo não serve apenas para configurações de LLM em rede.
provider, endpoint, model, orçamentos de token e configurações de chunking afetam o caminho do LLM.display_language afeta a linguagem natural usada em resumos e incertezas.syntax_highlighting afeta a renderização de pseudocódigo no WinDbg quando uma saída ciente de DML está disponível.display_language e syntax_highlighting ainda são usados para a saída de /view:analyzer e do provedor simulado (mock provider).Exemplo:```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" } }
Exemplo de assinatura do 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"
}
Para provider: "chatgpt", o endpoint é opcional e, por padrão, usa https://chatgpt.com/backend-api/codex/responses. Uma URL base como https://chatgpt.com/backend-api/codex também é aceita e normalizada para /responses. A extensão lê tokens.access_token e tokens.refresh_token do arquivo de autenticação configurado, renova tokens de acesso JWT expirados por meio do OAuth da OpenAI e grava o conjunto de tokens renovado de volta nesse arquivo. O arquivo de autenticação padrão é %USERPROFILE%\.codex\auth.json, portanto um login ChatGPT da CLI do Codex pode ser reutilizado diretamente. A extensão não abre um navegador nem inicia um fluxo de login OAuth de dentro do WinDbg; se o arquivo de autenticação estiver ausente, inválido ou não puder mais ser renovado, execute codex login fora do WinDbg e tente !decomp novamente. Para testes pontuais, use access_token ou access_token_env em vez de um arquivo de autenticação. , , e são reservados para provedores compatíveis com API de chave da OpenAI e são ignorados pelo provedor ChatGPT.
Chaves suportadas:
providerendpointmodelapi_keyapi_key_envaccess_tokenaccess_token_envchatgpt_auth_filereasoning_efforttimeout_msmax_completion_tokensforce_chunkedchunk_trigger_instructionschunk_trigger_blocksChaves suportadas de display_language:
modetagnamedisplay_language.mode aceita:
autofixedChaves suportadas de syntax_highlighting:
keyword_colortype_colorfunction_name_coloridentifier_colornumber_colorstring_colorchar_colorcomment_colorpreprocessor_coloroperator_colorpunctuation_colorComo funcionam os valores de cor de syntax_highlighting:
<col fg="...">.verbfg, warnfg, emphfg, srcid e nomes semelhantes não mapeiam para uma cor universal em todas as máquinas.#FF8800. A cor efetiva vem do WinDbg, não de decomp.llm.json.Consequência prática:
syntax_highlighting em vez de presumir que a extensão está ignorando sua configuração.Quando o realce está visível:
/view:json não é renderizada com DML. Em vez disso, ela carrega pseudo_c_tokens para que ferramentas externas possam aplicar seu próprio realce de sintaxe.Slots de primeiro plano comuns do DML:
wfg
Texto padrão de primeiro plano da janela.normfg
Texto normal da janela de comando.emphfg
Texto enfatizado. A Microsoft documenta isso como azul claro por padrão, mas a aparência exata ainda depende do tema.warnfg
Texto de aviso.errfg
Texto de erro.verbfg
Texto detalhado.changed
Dados alterados. A Microsoft documenta isso como vermelho por padrão.Slots de primeiro plano comuns do DML orientados a código-fonte:
srcnum
Constantes numéricas.srcchar
Constantes de caractere.srcstr
Constantes de string.srcid
Identificadores.srckw
Palavras-chave.srcpair
Chaves ou pares de símbolos correspondentes.srccmnt
Comentários.srcdrct
Diretivas.srcspid
Identificadores especiais.srcannot
Anotações de código-fonte ou elementos semelhantes a anotações.Exemplos:
verbfg significa "slot de primeiro plano detalhado", não "um azul específico nomeado".warnfg significa "slot de primeiro plano de aviso", não "sempre amarelo ou laranja".function_name_color: "srcid" significa "renderizar nomes de função usando o slot de identificador do WinDbg".Se você estiver ajustando cores em um tema escuro:
function_name_color: "emphfg" ou function_name_color: "verbfg" se os nomes de função parecerem apagados demais com srcid.identifier_color: "normfg" ou identifier_color: "wfg" para símbolos gerais que devem permanecer legíveis sem se sobrepor às palavras-chave.comment_color: "subfg" se quiser que os comentários fiquem em segundo plano sem desaparecer completamente.Referência oficial:
O decomp.llm.json.example incluído no repositório contém apenas configurações válidas de nível superior que a extensão realmente lê.
Exemplos apenas como referência:
Seguir o idioma da interface do PC:```json { "display_language": { "mode": "auto" } }
Forçar inglês:```json
{
"display_language": {
"mode": "fixed",
"tag": "en-US",
"name": "English"
}
}
Forçar coreano:```json { "display_language": { "mode": "fixed", "tag": "ko-KR", "name": "Korean" } }
Predefinição escura de realce de sintaxe:```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"
}
}
Predefinição de realce de sintaxe para tema claro:```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" } }
Exemplo de detalhes da resposta `/view:json`:
- A resposta JSON inclui `pseudo_c` e `pseudo_c_tokens`.
- `pseudo_c_tokens` é um fluxo de tokens determinístico adequado para realce de sintaxe externo.
- A solicitação serializada inclui `preferred_natural_language_tag` e `preferred_natural_language_name`, que refletem o idioma de exibição resolvido após aplicar `display_language.mode`.
- Os fatos do analisador agora incluem campos de qualidade P0:
`ir_values`, `block_value_states`, `control_flow` e `abi`.
- `ir_values` expõe IDs de valor semelhantes a SSA, locais de definição, alvos, expressões canônicas, links de uso, flags de constante/cópia e dicas de definição morta.
- `block_value_states` expõe definições de alcance live-in/live-out por bloco básico, valores canônicos, classe de armazenamento, estado de convergência e confiança.
- `stack_pointer` expõe deltas de pilha por instrução, aliases relativos ao frame, base/offsets brutos e confiança.
- `control_flow` expõe candidatos a região estruturada, como `natural_loop`, `if_else_candidate` e `switch_candidate`, com evidência de bloco, metadados de indução de loop, metadados de tabela/padrão/intervalo de switch, sinalização, expressões de índice e confiança.
- `abi` expõe suposições de shadow space do Microsoft x64, evidência de home slot, reconhecimento de frame/prólogo/epílogo, evidência de chamadas sem retorno, candidatos a tail call, candidatos a thunk, candidatos a wrapper de importação e argumentos de chamada recuperados de registradores e armazenamentos na pilha.
- Os fatos do analisador agora também incluem campos semânticos P1:
`type_hints`, `idioms` e `callee_summaries`.
- `type_hints` expõe evidências de ponteiro, local, deslocamento de campo, semelhante a array, semelhante a enum, semelhante a bitflag e candidato a vtable, com fonte e confiança. Quando os dados de PDB estão disponíveis, parâmetros/locais com escopo, dicas de campo e constantes de enum também são promovidos para este fluxo unificado de dicas de tipo.
- `idioms` expõe substituições de nível superior para chamadas de auxiliares reconhecidas e padrões do compilador, como cópia/preenchimento de memória, cópia de string, verificações de cookie de segurança, sondas de pilha, auxiliares de alocação/liberação, inicializadores agregados e cargas globais/de importação relativas a RIP.
- `callee_summaries` expõe dicas de tipo de retorno, modelo de parâmetro, efeito colateral, efeito de memória, propriedade, fonte e confiança para chamados diretos e indiretos; alvos de chamada enriquecidos com símbolo/tipo substituem os resumos heurísticos iniciais quando o WinDbg consegue resolvê-los, e candidatos a chamadas virtuais incluem expressões de alvo e offsets de vtable quando recuperados.
- Os resumos conhecidos de APIs Win32/NT/Rtl descrevem cópia/preenchimento/zero de memória, alocação, liberação, status e comportamento de erro quando nomes de símbolo estão disponíveis.
- Os fatos do prompt incluem `analyzer_skeleton` e `graph_summary` para que o modelo refine um rascunho baseado em evidências em vez de começar de uma página em branco.
- `graph_summary` fornece bloco de entrada, regiões de fluxo de controle, condições normalizadas e blocos representativos de alto sinal com uma política explícita de truncamento. A seleção de fatos do prompt agora classifica entradas de alto sinal e usa amostragem distribuída para manter grandes conjuntos de fatos representativos.
- `evidence_graph` expõe nós de fato de alto sinal e arestas de proveniência para que valores de IR, estados de valor de bloco, acessos à memória, alvos de chamada, dicas de tipo, dicas de PDB e comportamento observado possam ser rastreados até evidências de instrução e bloco.
- `obfuscation`, `semantic_control_flow` e `deobfuscation_readiness` expõem fatos de recuperação no estilo OLLVM e se a orientação de reescrita de desofuscação está habilitada para o comando atual.
- A resposta do verificador inclui `warnings` legadas e entradas `issues` estruturadas. Cada issue carrega `severity`, `code`, `message` e `evidence` opcional para que ferramentas possam filtrar erros como `branch.true_target_not_successor` separadamente de avisos de menor risco.
- As verificações do verificador agora comparam alvos normalizados de desvio verdadeiro/falso com sucessores do CFG, comparam a densidade de desvios do pseudocódigo com desvios condicionais recuperados, cruzam resumos de chamados diretos com efeitos de chamada do pseudocódigo, validam o ancoramento de nós/arestas do grafo de evidências e verificam referências de estado de valor de bloco de volta para blocos e valores de IR recuperados.
- A saída normal e a de explain podem incluir uma seção concisa `suggested fixes`. Esses são comandos conservadores `/fix:*` derivados de issues do verificador, oportunidades de renomeação apoiadas por PDB ou hotspots de memória observados repetidamente. A saída compatível com DML renderiza sugestões imediatamente aplicáveis como links clicáveis de reexecução para o mesmo alvo; sugestões de tipo de campo com espaço reservado permanecem como texto simples até que `TYPE` seja substituído.
- No modo LLM, a extensão alimenta automaticamente os issues do verificador de volta em um prompt de nova tentativa. A nova tentativa é mantida quando preserva ou melhora a qualidade do verificador; caso contrário, a resposta original é mantida com uma nota de incerteza adicionada.
- `session_policy` e `observed_behavior` expõem contexto específico do WinDbg, como política live/dump/kernel/semelhante a TTD, amostras de argumentos de registro do frame atual, hotspots de memória e consultas de rastreamento sugeridas.
- A solicitação serializada agora também inclui um objeto `pdb` quando há dados de símbolo/tipo disponíveis.
- `pdb.availability` relata o nível de enriquecimento, como `none`, `symbols`, `typed` ou `scoped`.
- `pdb.params`, `pdb.locals`, `pdb.field_hints`, `pdb.enum_hints` e `pdb.source_locations` são destinados a dicas semânticas legíveis por máquina para ferramentas externas ou análise offline.
Substituições opcionais de ambiente:
- `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`
Fragmentos de nomes de função separados por vírgula ou ponto e vírgula tratados como alvos sem retorno durante a desmontagem de fallback, recuperação de sucessores do CFG, fatos de ABI e verificações do verificador. Exemplo: `DECOMP_NORETURN_OVERRIDES=MyAbort;PanicAndExit`.
Nota sobre prioridade à qualidade:
- A extensão agora suporta análise multi-passagem fragmentada para funções grandes.
- O analisador envia fatos de valor de IR, estados de valor de bloco, regiões de fluxo de controle, fatos do grafo de evidências e evidências de ABI/sem retorno x64 para o LLM antes do refinamento, de modo que `/view:analyzer`, `/view:json` e o modo LLM normal compartilham a mesma base de evidências P0.
- O verificador cruza loops, switch, sem retorno, alvos de desvio, comportamento de retorno, efeitos de chamada de chamados, ancoramento do grafo de evidências, consistência do estado de valor de bloco, cobertura de evidências e alegações suspeitas de identificadores com as evidências do analisador. Ele reduz a confiança quando uma prosa confiante ultrapassa os fatos recuperados e rotula cada issue com um par estável de severidade/código.
- Quando o feedback do verificador encontra erros de esquema, conflitos de fatos ou confiança ajustada muito baixa, o caminho do LLM realiza uma nova tentativa automática com os issues do verificador anexados ao prompt.
- Um bom ponto de partida para modelos em nuvem é `max_completion_tokens=12000`, `chunk_completion_tokens=6000` e `merge_completion_tokens=12000`, com `force_chunked=false` e gatilhos de fragmentação em torno de `900 instructions` ou `36 blocks`.
- Mantenha `force_chunked=true` apenas para testes de estresse do pipeline de fragmentação. A descompilação focada em qualidade de funções achatadas (flattened) ou com muitos dispatchers normalmente precisa de um único prompt até que a função seja grande o suficiente para exceder os gatilhos de fragmentação configurados.
- Mantenha `timeout_ms` alto para modelos em nuvem. `120000` é um ponto de partida mais seguro do que `15000`.
- Se a qualidade ainda estiver fraca em funções enormes, aumente `chunk_count_limit` antes de reduzir `/limit:N`.
- Se nenhum endpoint estiver configurado, a extensão usa o provedor mock determinístico como fallback.
- Mesmo quando a extensão está usando `/view:analyzer` ou o provedor mock, `display_language` e `syntax_highlighting` ainda afetam o que o usuário vê.
## Teste de Fumaça do WinDbg
1. Compile com `Build.ps1` ou `Build-Legacy.ps1`.
2. Coloque `decomp.llm.json` ao lado do `decomp.dll` compilado.
3. Inicie o WinDbg. As variáveis de ambiente são apenas substituições opcionais.
4. Carregue a extensão.
5. Valide o modo somente analisador antes de habilitar o caminho do LLM.```text
.load C:\path\to\decomp.dll
!decomp /view:analyzer ntdll!RtlAllocateHeap
!decomp /view:facts kernel32!Sleep
Em seguida, valide o modo LLM:```text !decomp ntdll!RtlAllocateHeap !decomp /view:json ntdll!RtlAllocateHeap !decomp 0x7ffb`12345678
- `target`, `entry` e `module` devem resolver de forma consistente
- `regions` deve ser diferente de zero para funções normais
- `/view:analyzer` ainda deve imprimir a confiança do analyzer e o stub do pseudocódigo
- O modo LLM deve preencher `summary`, `pseudo_c`, `pseudo_c_tokens` e `verified`
- a saída de `/view:json` deve incluir `preferred_natural_language_tag` e `preferred_natural_language_name` no request serializado
- quando PDBs privados ou ricos estiverem carregados, `/view:json` também deve incluir `pdb.prototype`, `pdb.params` e possivelmente `pdb.locals`
- para structs e enums tipados, `/view:json` pode incluir `pdb.field_hints` e `pdb.enum_hints`
## Exemplo de Assinatura do ChatGPT```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"
Se o arquivo de autenticação contiver um token de atualização, a extensão renova um token de acesso expirado antes de enviar a solicitação. DECOMP_LLM_CHATGPT_ACCESS_TOKEN pode ser usado para um token bearer temporário, mas o caminho do arquivo de autenticação é melhor para sessões normais do WinDbg porque ele sobrevive à expiração do token. A extensão nunca abre um navegador durante !decomp; execute codex login fora do WinDbg quando for necessário um login interativo do ChatGPT.
$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"
/last:N:prompt/last:* são comandos de reprodução de terminal. Se um alvo estiver presente no mesmo comando, o artefato em cache é reproduzido e nenhuma análise local ou solicitação de LLM é iniciada para esse alvo.artifact ao lado do decomp.dll carregado. O operador não precisa de um comando de salvamento separado.request, response, data_model, debug_prompt e um objeto kernel_build com valores de versão Win32/KD, string de build, NtBuildLab opcional e uma impressão digital do build.!decomp <target> verifica automaticamente o caminho artifact\<kernel_build>\... após a resolução do alvo e a recuperação do RVA da função. Se o kernel_build salvo corresponder ao build atual do SO, a extensão reproduz o artefato sem ler os bytes da função, executar passes do analisador local ou chamar o LLM./last:* em cache; portanto, clicar em explain, json, facts, prompt ou data-model não inicia uma nova execução de descompilação./last-json, /last-explain, /last-facts, /last-data-model, /last-dx e /last-prompt continuam suportados.TTDReplay.dlldx @$cursession.TTD.Calls(...)api_keyapi_key_envDECOMP_LLM_API_KEYOPENAI_API_KEYchunk_block_limitchunk_count_limitchunk_completion_tokensmerge_completion_tokensdisplay_languagesyntax_highlighting