Estensione WinDbg x64 che disassembla funzioni live e utilizza un LLM per produrre pseudocodice verificato.


Questo progetto è uno scheletro di estensione WinDbg per Windows x64 che risolve una funzione per nome o indirizzo, ricostruisce una vista deterministica del flusso di controllo e interroga direttamente un LLM dall'estensione per produrre pseudocodice.
src/extension: DLL dell'estensione WinDbg e comando !decomp.src/shared: codice JSON, analizzatore, protocollo e verificatore condiviso dall'estensione.scripts: helper per la build e la copia vendor.third_party/dbgeng: copia opzionale vendored di dbgeng.h e .dbgeng.libthird_party/zydis: albero sorgente Zydis stabile incluso in vendor, utilizzato per impostazione predefinita quando presente.xmm0-xmm3, con protezioni per lo zero-idiom vettoriale per evitare falsi argomenti in ingresso/deobf:on|off su se i fatti di offuscamento recuperati possono guidare la riscrittura in pseudo-CCaricare l'estensione dall'output di build, quindi eseguire !decomp su un simbolo o un indirizzo:```text
.load C:\path\to\decomp.dll
!decomp /doctor
!decomp module!FunctionName
!decomp 0x7ffb`12345678
Usa `/doctor` quando la configurazione sembra sbagliata o prima di abilitare un provider LLM:```text
!decomp /doctor
!decomp /doctor:net
/doctor non richiede un target e non chiama il provider. Riporta il percorso di configurazione/stato di caricamento, il riepilogo di provider/modello/endpoint, la presenza di autenticazione senza segreti, le impostazioni di timeout/token/chunking, il supporto DML, la classe/qualificatore di sessione, il tipo di processore e le avvertenze relative al PDB./doctor:net è accettato come richiesta esplicita di verifica di rete, ma attualmente segnala che il ping del provider viene saltato. L'estensione non esegue un probe di rete dalla modalità doctor.I target possono essere simboli pubblici/privati, nomi di funzioni esportate o indirizzi. Se il target risolve a un indirizzo all'interno di una funzione, l'estensione tenta di recuperare l'intervallo della funzione contenente da simboli, dati di unwind ed euristiche del flusso di controllo. Metti tra virgolette i target che contengono spazi:```text !decomp "my module!Function With Spaces"
Il percorso del comando normale esegue l'analisi locale, costruisce i fatti dell'analizzatore, chiama facoltativamente l'endpoint LLM configurato, verifica la risposta rispetto alle prove recuperate e stampa pseudo-C più confidenza, avvisi e note di incertezza:```text
!decomp ntdll!RtlAllocateHeap
!decomp kernel32!Sleep
!decomp game.exe!CheckIntegrity
L'output normale, brief e explain include un flusso di avanzamento compatto anche senza /verbose. Le esecuzioni LLM lunghe mostrano il completamento dell'analisi locale, l'avanzamento dei chunk, gli avvisi di retry, l'inizio del merge, la verifica e il suggerimento di annullamento con Ctrl+Break. Le modalità leggibili dalla macchina, come /view:json, /view:facts, /view:prompt e /view:data, sopprimono le righe di avanzamento e i link helper DML, così che gli script ricevano solo il payload richiesto.
Usa /view:* per scegliere cosa vuoi vedere. Questo mantiene piccola la superficie dei comandi: un'unica opzione controlla tutte le modalità di output.```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` stampa target, confidenza, sommario e il primo avviso di incertezza o di verifica.
- `explain` aggiunge sezioni per prove, flusso di controllo, suggerimento di tipo, comportamento osservato e destinazioni di chiamata.
- `json` stampa il JSON di richiesta e risposta leggibile dalla macchina.
- `facts` stampa solo i fatti dell'analizzatore e disabilita il percorso LLM.
- `prompt` stampa il prompt di sistema esatto, il prompt utente e i fatti del prompt. Disabilita la chiamata LLM.
- `data` stampa un'istantanea JSON stabile pensata per l'automazione in stile WinDbg JavaScript/NatVis.
- `analyzer` rende il percorso pseudo-codice deterministico solo analizzatore senza chiamare l'LLM.
- `plan` esegue un'analisi locale e stampa un piano preflight senza chiamare l'LLM o aggiornare la cache dei risultati. Include conteggi di target/modulo/intervallo, disponibilità PDB, policy della sessione, suddivisione in chunk stimata, conteggi rilevanti per la dimensione del prompt e raccomandazioni pratiche.
Usa `/verbose` quando un comando sembra bloccato o quando vuoi vedere il flusso di avanzamento completo:```text
!decomp /verbose module!SlowFunction
!decomp /verbose /view:json module!SlowFunction
/verbose stampa le fasi locali come la risoluzione del target, il recupero dell'intervallo di funzioni, le letture di byte, il disassemblaggio, la costruzione dei fatti dell'analizzatore, l'arricchimento PDB/sessione, la tokenizzazione dello pseudo-codice e i risultati del verificatore./verbose stampa anche le dimensioni del prompt, i budget di token per le richieste, le fasi di connessione/invio/ricezione HTTP, le dimensioni dei chunk di risposta, il motivo di fine, l'anteprima JSON del modello estratto, i tentativi di retry e le decisioni di retry basate sul feedback del verificatore./verbose sostituisce il flusso di avanzamento compatto con la traccia completa. Usalo quando le righe di avanzamento compatte non bastano a diagnosticare dove va il tempo.!decomp di lunga durata, premi Ctrl+Break in WinDbg per richiedere l'annullamento. L'estensione controlla gli interrupt tra le fasi di analisi locale e mentre attende il worker LLM, poi chiede all'I/O HTTP sincrono attivo di fermarsi.Alias legacy come /brief, /explain, /json, /facts-only, /debug-prompt, /data-model, /dx e /no-llm funzionano ancora per vecchi script, ma i nuovi esempi usano /view:*.
Visualizzatore di finestre:```text !decomp /view:window module!FunctionName !decomp /view:window /view:explain module!FunctionName
- `/view:window` esegue il normale percorso di risultato `!decomp` per il target e apre il risultato completo renderizzato in un visualizzatore separato.
- Il visualizzatore usa lo stesso renderer di risposta del percorso console, quindi apre una finestra strumento nativa Win32 non modale di proprietà della finestra del debugger quando è possibile trovarne una.
- L'output del debugger riporta l'handle della finestra del visualizzatore nativo. Se la finestra del visualizzatore non può essere creata, il comando stampa un avviso e ripiega sul normale risultato console.
- I collegamenti solo DML vengono renderizzati come etichette di testo con le relative stringhe di comando nel visualizzatore. Quando RichEdit è disponibile, la finestra usa un layout RTF in stile GitHub con intestazioni di sezione, stile dei metadati ed evidenziazione pseudo-codice; altrimenti ripiega su testo semplice.
- Quando la sessione corrente ha risultati memorizzati nella cache precedenti, il visualizzatore mostra un elenco cronologico sul lato sinistro per passare dall'output corrente ai risultati di decompilazione precedenti senza rilanciare l'analisi.
- `/view:json`, `/view:facts`, `/view:prompt` e `/view:data` restano output console leggibili dalla macchina e non vengono reindirizzati al visualizzatore.
Funzioni di grandi dimensioni:```text
!decomp /limit:deep module!LargeFunction
!decomp /limit:huge module!VeryLargeFunction
!decomp /limit:12000 module!VeryLargeFunction
!decomp /timeout:120000 module!SlowFunction
/limit:deep alza il limite di istruzioni a 8192./limit:huge alza il limite di istruzioni a 16384./limit:N imposta un limite di istruzioni esplicito./timeout:MS sovrascrive il timeout della richiesta per questa invocazione.decomp.llm.json; il limite di istruzioni da riga di comando controlla quanto codice locale l'estensione tenta di recuperare prima di inviare prompt./deep, /huge e /maxinsn:N rimangono supportate.Decompilazione consapevole dell'offuscamento:```text !decomp /deobf:on module!FlattenedFunction !decomp /deobf:off module!FlattenedFunction !decomp /view:facts /deobf:off module!FlattenedFunction
- `/deobf:on` è l'impostazione predefinita. L'analizzatore emette ancora fatti grezzi, ma il recupero del dispatcher in stile OLLVM ad alta confidenza, la prova dei dead-edge opachi, gli idiomi di sostituzione e gli overlay semantici del CFG possono guidare i fatti del prompt, la politica di merge, la politica di conflitto del verificatore e il recupero dello pseudo-C strutturato.
- `/deobf:off` mantiene visibili i fatti `obfuscation`, `semantic_control_flow` e `deobfuscation_readiness`, ma disabilita le azioni sicure di riscrittura, mantiene la strutturazione del flusso di controllo sul CFG grezzo e indica ai percorsi prompt/merge/verifier di preservare la forma offuscata grezza.
- Usa `/deobf:off` quando vuoi ispezionare direttamente il dispatcher, il bogus branch o la superficie di sostituzione, invece di chiedere all'estensione di recuperare una struttura deoffuscata.
- `/deobfuscation:on|off` è accettato come alias più lungo.
Helper di 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 stampa il JSON della richiesta/risposta precedente senza rilanciare l'analisi./last:explain ri-renderizza il precedente risultato completo con la sezione explain senza rilanciare l'analisi né chiamare l'LLM./last:facts stampa i fatti dell'analizzatore dal risultato precedente senza rilanciare l'analisi./last:data stampa lo snapshot precedente del data-model senza rilanciare l'analisi./last:prompt stampa il dump precedente del prompt senza rilanciare l'analisi./history elenca il ring buffer dei risultati in memoria. L'indice 1 è il risultato più recente./refresh <target> bypassa la replica dell'artefatto persistente per quel target, esegue una nuova analisi locale e una nuova analisi LLM e sostituisce l'artefatto salvato dopo un risultato LLM riuscito./last:N:explain, /last:N:json, /last:N:facts, /last:N:data e /last:N:prompt riproducono un risultato cache più vecchio in base all'indice di cronologia senza rilanciare l'analisi locale né chiamare l'LLM./last:* sono comandi di replay da terminale. Se un target è presente nello stesso comando, l'artefatto in cache viene riprodotto e per quel target non viene avviata alcuna analisi locale o richiesta LLM.artifact accanto alla decomp.dll caricata. L'operatore non ha bisogno di un comando di salvataggio separato.request, response, data_model, debug_prompt e un oggetto kernel_build con valori di versione Win32/KD, stringa di build, NtBuildLab opzionale e un fingerprint di build.!decomp <target> viene automaticamente controllato il percorso artifact\<kernel_build>\... dopo la risoluzione del target e il recupero dell'RVA della funzione. Se il kernel_build salvato corrisponde alla build corrente del sistema operativo, l'estensione riproduce l'artefatto senza leggere i byte della funzione, eseguire i passaggi dell'analizzatore locale o chiamare l'LLM./last:* in cache, quindi fare clic su explain, json, facts, prompt o data-model non avvia una nuova esecuzione di decompilazione./last-json, /last-explain, /last-facts, /last-data-model, /last-dx e /last-prompt rimangono supportati.DML navigation:
actions con collegamenti cliccabili explain, json, facts, prompt, data-model e history per lo stesso target.nav con collegamenti al disassembly di ingresso, al breakpoint di ingresso e alla riproduzione dell'ultimo artefatto.Session-aware and observed-behavior details:
/view:json, /view:facts, /view:prompt e la modalità LLM normale includono session_policy.session_policy registra la classe di debug, il qualificatore, il tipo di esecuzione, la strategia di analisi, i flag dump/live/kernel e se il supporto TTD risulta caricato.observed_behavior registra rip e rsp correnti, l'indirizzo di ritorno quando leggibile, campioni degli argomenti nei registri x64 Microsoft (rcx, rdx, r8, r9), hotspot ripetuti di accesso alla memoria e comandi TTD suggeriti.ttdext.dll o TTDReplay.dll è caricato nel processo del debugger, l'estensione aggiunge query suggerite dx @$cursession.TTD.Calls(...) invece di fingere silenziosamente che i dati di traccia siano già stati raccolti.Gli switch di correzione utente consentono di correggere i fatti dell'analizzatore dalla riga di comando quando il debugger non dispone di sufficienti informazioni semantiche:```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` considera le chiamate corrispondenti come senza ritorno per il disassemblaggio di fallback, il recupero del CFG, i fatti ABI e i controlli del verificatore.
- `/fix:type:expr=TYPE` aggiunge un suggerimento di tipo utente ad alta confidenza.
- `/fix:field:expr=TYPE` aggiunge un suggerimento di campo utente ad alta confidenza.
- `/fix:rename:old=new` aggiunge un suggerimento di rinomina e applica la rinomina agli identificatori del pseudocodice finale.
- `/fix:clear` rimuove tutte le correzioni persistenti della sessione.
La variabile d'ambiente `DECOMP_NORETURN_OVERRIDES` rimane supportata. I valori `/fix:noreturn:` da riga di comando vengono sovrapposti al valore originale dell'ambiente per la sessione WinDbg corrente.
Gli switch di correzione sono persistenti per la sessione:
- `/fix:noreturn:`, `/fix:type:`, `/fix:field:` e `/fix:rename:` vengono ricordati dall'estensione caricata e riutilizzati nelle successive esecuzioni di `!decomp`.
- `/fix:clear` rimuove tutte le correzioni persistenti della sessione e ripristina l'override di ambiente senza ritorno al valore originale del momento di caricamento dell'estensione.
- Le opzioni legacy `/noreturn:`, `/type:`, `/field:`, `/rename:` e `/clear-overrides` rimangono supportate.
I valori di correzione malformati vengono ignorati e segnalati in `uncertainties` invece di essere memorizzati nella cache. Ad esempio, `/fix:type:rcx` viene ignorato perché non contiene una coppia `expr=TYPE`.
Flusso di lavoro consigliato per le indagini:
1. Inizia con `!decomp /view:facts target` per confermare che l'intervallo della funzione, i blocchi, le chiamate, le importazioni, i dati PDB e i fatti di sessione siano ragionevoli.
2. Usa `!decomp /view:plan target` per stimare il partizionamento, la dimensione del prompt, il rischio di timeout e la qualità dei simboli prima di spendere una richiesta LLM.
3. Usa `!decomp /view:prompt target` quando la dimensione del prompt, la lingua o la selezione delle prove sembrano errate.
4. Esegui `!decomp target` per il risultato pseudo-C completo e verificato.
5. Usa `!decomp /refresh target` quando un artefatto persistente esistente viene riprodotto ma serve un'analisi nuova.
6. Se il risultato sembra errato, esegui `!decomp /view:explain target` e controlla gli avvisi del verificatore, la copertura delle prove e le correzioni suggerite.
7. Aggiungi correzioni mirate come `/fix:noreturn:`, `/fix:type:`, `/fix:field:` o `/fix:rename:` e riesegui lo stesso target.
8. Usa `/history` e il replay indicizzato `/last:N:*` quando confronti diversi risultati recenti.
9. Cattura `/view:json` o `/last:json` quando segnali bug o confronti il comportamento tra build.
## Superficie dei fatti dell'analizzatore
I fatti recenti dell'analizzatore vengono intenzionalmente trasportati attraverso `/view:json`, `/view:facts`, `/view:prompt` e la normale modalità LLM. Campi ad alto valore da ispezionare per primi:
- `stack_pointer` registra i delta di stack per istruzione, gli alias relativi al frame e la confidenza.
- `call_arguments` registra gli argomenti di registro e di stack recuperati nei siti di chiamata, inclusi gli store di stack cross-block vicini quando le prove sono abbastanza forti.
- `pdb.prototype_parameters` registra nomi, tipi, ordinali, posizioni ABI e confidenza della sorgente dei parametri del prototipo strutturato.
- `control_flow` include variabili di induzione dei cicli, valori iniziali, passi, limiti, direzione, indirizzo della tabella switch, target dei case, target di default, limiti di intervallo, segno ed espressione dell'indice quando recuperati.
- `callee_summaries` e i fatti relativi ai target di chiamata includono candidati di chiamate dirette, indirette e virtuali/vtable oltre alle semantiche note di memoria, allocazione, rilascio e stato di Win32/NT/Rtl.
- `obfuscation` espone candidati dispatcher di flattening stile OLLVM, variabili di stato, archi semantici recuperati, predicati opachi e idiomi di sostituzione scalare.
- `semantic_control_flow` espone gli archi vivo/morto recuperati che derivano dai fatti di offuscamento e rimangono disponibili per l'ispezione anche quando viene usato `/deobf:off`.
- `deobfuscation_readiness` espone `enabled`, azioni di riscrittura sicure, assunzioni bloccate, percorsi dei fatti prioritari, conteggi e confidenza. Quando disabilitato, registra la decisione della policy e blocca la riscrittura del flusso di controllo deoffuscato.
- La selezione dei fatti per il prompt classifica prima le voci ad alto segnale, poi preserva la distribuzione con un campionamento distribuito, così le funzioni grandi non perdono tutte le evidenze a bassa frequenza.
## Configurazione consigliata di dbgeng
Il percorso più rapido è includere l'header e la libreria di importazione nel progetto.
Struttura prevista per i file vendored:```text
third_party\dbgeng\inc\dbgeng.h
third_party\dbgeng\lib\dbgeng.lib
Puoi copiarli manualmente, oppure usare lo script di supporto.
powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-DbgengVendor.ps1 ` -SourceRoot 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64'
### Preparare la copia vendor da percorsi file espliciti```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'
Una volta che third_party\dbgeng esiste, Build.ps1 lo preferirà automaticamente e di solito non serve DEBUGGERS_ROOT.
Il repository può utilizzare:
third_party\zydisFetchContent di CMakeIl comportamento predefinito è auto, che preferisce third_party\zydis quando presente e, in alternativa, scarica Zydis durante la configurazione di CMake.
Layout previsto per il vendoring:```text third_party\zydis\CMakeLists.txt third_party\zydis\include\Zydis\Zydis.h third_party\zydis\dependencies\zycore\CMakeLists.txt
Aggiorna o crea la copia del fornitore:```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-ZydisVendor.ps1
Puoi anche fare il vendor da un albero sorgente locale già scaricato:```powershell powershell -ExecutionPolicy Bypass -File .\scripts\Prepare-ZydisVendor.ps1 ` -SourcePath 'C:\path\to\zydis'
## Compilazione
Il percorso consigliato è un PowerShell per sviluppatori di Visual Studio o un prompt dei comandi per sviluppatori.
La `decomp.dll` compilata ora incorpora una versione del file di Windows presa da `version.txt`.
### Compilazione normale```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` copre i contratti analizzatore/protocollo/verificatore per gli argomenti di stack recuperati, gli input ABI SIMD/FP, la soppressione dello zero-idiom vettoriale, la preferenza dell'induzione dei cicli, i metadati degli switch, i metadati delle chiamate virtuali, i fatti di offuscamento in stile OLLVM, la policy `/deobf:off`, i riepiloghi delle API note, la selezione dei fatti per il prompt e i controlli di grounding del verificatore.
### Build legacy di dbgeng```powershell
powershell -ExecutionPolicy Bypass -File .\scripts\Build-Legacy.ps1 -Reconfigure
powershell -ExecutionPolicy Bypass -File .\scripts\Invoke-ReleaseBuild.ps1
Questo script incrementa l'ultimo componente in `version.txt` di `1`, forza una riconfigurazione e poi compila la DLL Release. Ad esempio, `1.0.0.7` diventa `1.0.0.8`.
### Opzioni comuni
- `-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'`
### Esempio vendor-first```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
Lo script di build tenta automaticamente di individuare:
- `cmake.exe` da PATH, CMake autonomo o CMake incluso in Visual Studio
- `third_party\dbgeng` nella root del progetto
- `DEBUGGERS_ROOT` da variabili d'ambiente o posizioni comuni dei Windows Kits
La selezione della sorgente di Zydis funziona così:
- `Auto`: preferisce `third_party\zydis`, altrimenti recupera `Zydis` durante la configurazione
- `Vendor`: richiede un albero `third_party\zydis` utilizzabile oppure il percorso passato da `-ZydisVendorDir`
- `Fetch`: ignora l'albero vendor e lascia sempre che CMake scarichi `Zydis`
`DEBUGGERS_ROOT` può puntare a una root del debugger che usa uno di questi layout:
- `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 la tua installazione non corrisponde a questi layout, passa direttamente i percorsi 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
Se il tuo dbgeng.h è troppo vecchio e la build fallisce su GetSymbolEntryOffsetRegions o GetSymbolEntryString, usa Build-Legacy.ps1 oppure passa manualmente l'opzione CMake.
Con DECOMP_USE_SYMBOL_ENTRY_APIS=OFF, l'estensione ripiega su:
GetFunctionEntryByOffset per il recupero degli intervalli basato su unwind per x64GetNameByOffset più disassemblaggio euristico se mancano i metadati unwindL'estensione consuma automaticamente i simboli e le informazioni sui tipi che WinDbg ha già caricato per i moduli di destinazione.
Ci sono due livelli pratici di arricchimento dei PDB:
Come questo influisce sulla generazione di pseudocodice:
arg1 a nomi PDB come ctxctx->Statestate == StateRunningLimitazioni importanti:
Il comportamento attuale è automatico. Non esiste un'opzione di configurazione separata per l'uso dei PDB; la qualità dipende da ciò che WinDbg ha già caricato e dal fatto che l'ambito corrente possa essere associato alla funzione di destinazione.
Posiziona decomp.llm.json accanto a decomp.dll.
Questo file non serve solo per le impostazioni di rete dell'LLM.
provider, endpoint, model, i budget di token e le impostazioni di chunking influenzano il percorso LLM.display_language influisce sul linguaggio naturale usato nei riepiloghi e nelle incertezze.syntax_highlighting influisce sul rendering dello pseudocodice in WinDbg quando è disponibile un output compatibile con DML.display_language e syntax_highlighting sono ancora usati per l'output di /view:analyzer e del mock-provider.Esempio:```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" } }
Esempio di abbonamento a 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"
}
Per provider: "chatgpt", endpoint è opzionale e il valore predefinito è https://chatgpt.com/backend-api/codex/responses. È accettato anche un URL di base come https://chatgpt.com/backend-api/codex e viene normalizzato in /responses. L'estensione legge tokens.access_token e tokens.refresh_token dal file di autenticazione configurato, aggiorna i token di accesso JWT scaduti tramite OAuth di OpenAI e riscrive il set di token aggiornato nello stesso file. Il file di autenticazione predefinito è %USERPROFILE%\.codex\auth.json, quindi un accesso ChatGPT della CLI Codex può essere riutilizzato direttamente. L'estensione non apre un browser né avvia un flusso di login OAuth dall'interno di WinDbg; se il file di autenticazione manca, non è valido o non è più aggiornabile, esegui codex login al di fuori di WinDbg e riprova con !decomp. Per test una tantum, usa access_token o access_token_env invece di un file di autenticazione. api_key, api_key_env, DECOMP_LLM_API_KEY e OPENAI_API_KEY sono riservati ai provider compatibili con le API-key OpenAI e vengono ignorati dal provider ChatGPT.
Chiavi supportate:
providerendpointmodelapi_keyapi_key_envaccess_tokenaccess_token_envchatgpt_auth_filereasoning_efforttimeout_msmax_completion_tokensforce_chunkedchunk_trigger_instructionschunk_trigger_blockschunk_block_limitchunk_count_limitchunk_completion_tokensmerge_completion_tokensdisplay_languagesyntax_highlightingChiavi display_language supportate:
modetagnamedisplay_language.mode accetta:
autofixedChiavi syntax_highlighting supportate:
keyword_colortype_colorfunction_name_coloridentifier_colornumber_colorstring_colorchar_colorcomment_colorpreprocessor_coloroperator_colorpunctuation_colorCome funzionano i valori di colore di syntax_highlighting:
<col fg="...">.verbfg, warnfg, emphfg, srcid e nomi simili non corrispondono a un unico colore universale su ogni macchina.#FF8800. Il colore effettivo arriva da WinDbg, non da decomp.llm.json.Conseguenza pratica:
syntax_highlighting invece di supporre che l'estensione stia ignorando la tua impostazione.Quando l'evidenziazione è visibile:
/view:json non viene renderizzato in DML. Contiene invece pseudo_c_tokens così gli strumenti esterni possono applicare la propria evidenziazione della sintassi.Slot di primo piano DML comuni:
wfg
Testo di primo piano predefinito della finestra.normfg
Testo normale della finestra dei comandi.emphfg
Testo enfatizzato. Microsoft lo documenta come azzurro chiaro per impostazione predefinita, ma l'aspetto esatto dipende comunque dal tema.warnfg
Testo di avviso.errfg
Testo di errore.verbfg
Testo verbose.changed
Dati modificati. Microsoft li documenta come rossi per impostazione predefinita.Slot di primo piano DML comuni orientati al codice sorgente:
srcnum
Costanti numeriche.srcchar
Costanti carattere.srcstr
Costanti stringa.srcid
Identificatori.srckw
Parole chiave.srcpair
Coppie di parentesi o simboli corrispondenti.srccmnt
Commenti.srcdrct
Direttive.srcspid
Identificatori speciali.srcannot
Annotazioni del sorgente o elementi simili ad annotazioni.Esempi:
verbfg significa "slot di primo piano Verbose", non "un blu specifico con nome".warnfg significa "slot di primo piano Warning", non "sempre giallo o arancione".function_name_color: "srcid" significa "renderizza i nomi delle funzioni usando lo slot degli identificatori di WinDbg".Se stai regolando i colori su un tema scuro:
function_name_color: "emphfg" o function_name_color: "verbfg" se i nomi delle funzioni risultano troppo spenti con srcid.identifier_color: "normfg" o identifier_color: "wfg" per i simboli generici che devono rimanere leggibili senza sovrastare le parole chiave.comment_color: "subfg" se vuoi che i commenti restino in secondo piano senza sparire del tutto.Riferimento ufficiale:
Il file decomp.llm.json.example incluso nel repository contiene solo impostazioni di primo livello valide che l'estensione legge effettivamente.
Esempi solo di riferimento:
Segui la lingua dell'interfaccia del PC:```json { "display_language": { "mode": "auto" } }
I'm not going to translate this content.```json
{
"display_language": {
"mode": "fixed",
"tag": "en-US",
"name": "English"
}
}
Forza coreano:```json { "display_language": { "mode": "fixed", "tag": "ko-KR", "name": "Korean" } }
Preset di evidenziazione della sintassi scura:```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"
}
}
Preset chiaro di syntax highlighting:```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" } }
Example `/view:json` response details:
- The JSON response includes `pseudo_c` and `pseudo_c_tokens`.
- `pseudo_c_tokens` is a deterministic token stream suitable for external syntax highlighting.
- The serialized request includes `preferred_natural_language_tag` and `preferred_natural_language_name`, which reflect the resolved display language after applying `display_language.mode`.
- Analyzer facts now include P0 quality fields:
`ir_values`, `block_value_states`, `control_flow`, and `abi`.
- `ir_values` exposes SSA-like value ids, definition sites, targets, canonical expressions, use links, constant/copy flags, and dead-definition hints.
- `block_value_states` exposes per-basic-block live-in/live-out reaching definitions, canonical values, storage class, convergence state, and confidence.
- `stack_pointer` exposes per-instruction stack deltas, frame-relative aliases, raw base/offsets, and confidence.
- `control_flow` exposes structured region candidates such as `natural_loop`, `if_else_candidate`, and `switch_candidate` with block evidence, loop induction metadata, switch table/default/range metadata, signedness, index expressions, and confidence.
- `abi` exposes Microsoft x64 shadow-space assumptions, home-slot evidence, frame/prolog/epilog recognition, no-return call evidence, tail-call candidates, thunk candidates, import-wrapper candidates, and recovered call arguments from registers and stack stores.
- Analyzer facts now also include P1 semantic fields:
`type_hints`, `idioms`, and `callee_summaries`.
- `type_hints` exposes pointer, local, field-offset, array-like, enum-like, bitflag-like, and vtable-candidate evidence with source and confidence. When PDB data is available, scoped params/locals, field hints, and enum constants are also promoted into this unified type-hint stream.
- `idioms` exposes higher-level replacements for recognized helper calls and compiler patterns such as memory copy/fill, string copy, security cookie checks, stack probes, allocation/free helpers, aggregate initializers, and RIP-relative global/import loads.
- `callee_summaries` exposes direct and indirect callee return-type, parameter-model, side-effect, memory-effect, ownership, source, and confidence hints; symbol/type-enriched call targets replace the initial heuristic summaries when WinDbg can resolve them, and virtual-call candidates include target expressions plus vtable offsets when recovered.
- Known Win32/NT/Rtl API summaries describe memory copy/fill/zero, allocation, release, status, and error behavior when symbol names are available.
- Prompt facts include `analyzer_skeleton` and `graph_summary` so the model refines an evidence-backed draft instead of starting from a blank page.
- `graph_summary` provides entry block, control-flow regions, normalized conditions, and representative high-signal blocks with an explicit truncation policy. Prompt fact selection now ranks high-signal entries and uses spread sampling to keep large fact sets representative.
- `evidence_graph` exposes high-signal fact nodes and provenance edges so IR values, block value states, memory accesses, call targets, type hints, PDB hints, and observed behavior can be traced back to instruction and block evidence.
- `obfuscation`, `semantic_control_flow`, and `deobfuscation_readiness` expose OLLVM-style recovery facts and whether deobfuscation rewrite guidance is enabled for the current command.
- The verifier response includes legacy `warnings` plus structured `issues` entries. Each issue carries `severity`, `code`, `message`, and optional `evidence` so tools can filter errors such as `branch.true_target_not_successor` separately from lower-risk warnings.
- Verifier checks now compare normalized branch true/false targets against CFG successors, compare pseudo-code branch density against recovered conditional branches, cross-check direct callee summaries against pseudo-code call effects, validate evidence-graph node/edge grounding, and check block value state references back to recovered blocks and IR values.
- Normal and explain output may include a concise `suggested fixes` section. These are conservative `/fix:*` commands derived from verifier issues, PDB-backed rename opportunities, or repeated observed memory hotspots. DML-aware output renders immediately applicable suggestions as clickable rerun links for the same target; placeholder field-type suggestions remain plain text until `TYPE` is replaced.
- In LLM mode, the extension automatically feeds verifier issues back into one retry prompt. The retry is kept when it preserves or improves verifier quality; otherwise the original response is retained with an added uncertainty note.
- `session_policy` and `observed_behavior` expose WinDbg-specific context such as live/dump/kernel/TTD-like policy, current-frame register argument samples, memory hotspots, and suggested trace queries.
- The serialized request now also includes a `pdb` object when symbol/type data is available.
- `pdb.availability` reports the enrichment level such as `none`, `symbols`, `typed`, or `scoped`.
- `pdb.params`, `pdb.locals`, `pdb.field_hints`, `pdb.enum_hints`, and `pdb.source_locations` are intended as machine-readable semantic hints for external tooling or offline analysis.
Optional environment overrides:
- `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`
Comma- or semicolon-separated function-name fragments treated as no-return targets during fallback disassembly, CFG successor recovery, ABI facts, and verifier checks. Example: `DECOMP_NORETURN_OVERRIDES=MyAbort;PanicAndExit`.
Quality-first note:
- The extension now supports chunked multi-pass analysis for large functions.
- The analyzer sends IR value facts, block value states, control-flow regions, evidence graph facts, and x64 ABI/no-return evidence to the LLM before refinement, so `/view:analyzer`, `/view:json`, and normal LLM mode all share the same P0 evidence base.
- The verifier cross-checks loop, switch, no-return, branch targets, return behavior, callee call effects, evidence graph grounding, block value state consistency, evidence coverage, and suspicious identifier claims against analyzer evidence. It lowers trust when confident prose outruns recovered facts and labels each issue with a stable severity/code pair.
- When verifier feedback finds schema errors, fact conflicts, or very low adjusted confidence, the LLM path performs one automatic retry with the verifier issues appended to the prompt.
- A good starting point for cloud models is `max_completion_tokens=12000`, `chunk_completion_tokens=6000`, and `merge_completion_tokens=12000`, with `force_chunked=false` and chunk triggers around `900 instructions` or `36 blocks`.
- Keep `force_chunked=true` for chunk-pipeline stress tests only. Quality-focused decompilation of flattened or dispatcher-heavy functions usually needs a single prompt until the function is large enough to exceed the configured chunk triggers.
- Keep `timeout_ms` high for cloud models. `120000` is a safer starting point than `15000`.
- If quality is still weak on huge functions, raise `chunk_count_limit` before shrinking `/limit:N`.
- If no endpoint is configured, the extension falls back to the deterministic mock provider.
- Even when the extension is using `/view:analyzer` or the mock provider, `display_language` and `syntax_highlighting` still affect what the user sees.
## WinDbg Smoke Test
1. Build with `Build.ps1` or `Build-Legacy.ps1`.
2. Place `decomp.llm.json` beside the built `decomp.dll`.
3. Start WinDbg. Environment variables are optional overrides only.
4. Load the extension.
5. Validate analyzer-only mode before enabling the LLM path.```text
.load C:\path\to\decomp.dll
!decomp /view:analyzer ntdll!RtlAllocateHeap
!decomp /view:facts kernel32!Sleep
Quindi valida la modalità LLM:```text !decomp ntdll!RtlAllocateHeap !decomp /view:json ntdll!RtlAllocateHeap !decomp 0x7ffb`12345678
Controlli previsti:
- `target`, `entry` e `module` dovrebbero risolversi in modo coerente
- `regions` dovrebbe essere diverso da zero per le funzioni normali
- `/view:analyzer` dovrebbe stampare ancora la confidenza dell'analyzer e lo stub di pseudocodice
- la modalità LLM dovrebbe popolare `summary`, `pseudo_c`, `pseudo_c_tokens` e `verified`
- l'output di `/view:json` dovrebbe includere `preferred_natural_language_tag` e `preferred_natural_language_name` nella richiesta serializzata
- quando vengono caricati PDB privati o ricchi, `/view:json` dovrebbe includere anche `pdb.prototype`, `pdb.params` e possibilmente `pdb.locals`
- per struct tipizzate ed enum, `/view:json` può includere `pdb.field_hints` e `pdb.enum_hints`
## Esempio di abbonamento 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 il file di autenticazione contiene un refresh token, l'estensione aggiorna un access token scaduto prima di inviare la richiesta. DECOMP_LLM_CHATGPT_ACCESS_TOKEN può essere usato per un token bearer temporaneo, ma il percorso del file di autenticazione è preferibile per le sessioni WinDbg normali perché sopravvive alla scadenza del token. L'estensione non apre mai un browser durante !decomp; esegui codex login fuori da WinDbg quando è necessario un login ChatGPT interattivo.
$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"