You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
| KB updates from subagent findings |`static-analyzer` writes to `kb.h`; main agent may refine |
46
47
@@ -82,15 +83,17 @@ For deep analysis tasks (finding subsystems, mapping call chains, understanding
82
83
## Examples
83
84
84
85
**"Disable culling in game.exe"**
85
-
1. Spawn `static-analyzer`#1 (r2ghidra): find `SetRenderState` calls with `D3DRS_CULLMODE`, string search for "cull", xrefs to render state functions. Uses `--backend pdg --types kb.h`. Writes to `findings_r2.md`.
86
+
1. Spawn `static-analyzer`#1 (r2ghidra): find `SetRenderState` calls with `D3DRS_CULLMODE`, string search for "cull", xrefs --indirect to find vtable call sites. Uses `--backend pdg --types kb.h`. Writes to `findings_r2.md`.
86
87
2. Spawn `static-analyzer`#2 (pyghidra): same search strategy but decompile with `pyghidra_backend.py decompile`. Writes to `findings.md`.
87
88
3. Immediately tell the user: "Please launch the game — I'll need to attach with livetools to patch culling at runtime once I find the addresses"
88
-
4. When both return, merge findings and use `livetools` to verify and patch: `mem write` to NOP the cull-enable instruction or force `D3DRS_CULLMODE` to `D3DCULL_NONE`
89
+
4. While waiting, run `dataflow.py --constants` on any known render functions to see what cull mode constants flow in (e.g., `eax = 0x2` = D3DCULL_CW)
90
+
5. When both return, merge findings and use `livetools` to verify and patch: `mem write` to NOP the cull-enable instruction or force `D3DRS_CULLMODE` to `D3DCULL_NONE`
89
91
90
92
**"What does function 0x401000 do?"**
91
-
1. Spawn `static-analyzer`: decompile with `--types kb.h`, get callgraph, xrefs
92
-
2. Tell the user: "Static analysis is running. Want me to also trace this function live to see actual register values and call frequency?"
93
-
3. If yes, attach with `livetools trace 0x401000 --count 20 --read`
93
+
1. Spawn `static-analyzer`: decompile with `--types kb.h`, get callgraph --indirect, xrefs
94
+
2. Run `dataflow.py 0x401000 --constants` inline — see what constants flow through
95
+
3. Tell the user: "Static analysis is running. Want me to also trace this function live to see actual register values and call frequency?"
96
+
4. If yes, attach with `livetools trace 0x401000 --count 20 --read`
94
97
95
98
**"Find who writes to address 0x7A0000"**
96
99
1. Spawn `static-analyzer`: `datarefs.py` for static references
|`xrefs.py $B $VA`| Find all calls/jumps TO an address |`xrefs.py binary.exe 0x401000 -t call`|
77
+
|`cfg.py $B $VA`| Control flow graph (basic blocks + edges, text or mermaid). Resolves MSVC switch/jump tables automatically. `--switch-details` shows table info |`cfg.py binary.exe 0x401000 --format mermaid`|
78
+
|`callgraph.py $B $VA`| Caller/callee tree (multi-level, --up/--down N). `--indirect` adds vtable/fptr calls to --down trees |`callgraph.py binary.exe 0x401000 --down 2 --indirect`|
79
+
|`xrefs.py $B $VA`| Find all calls/jumps TO an address. `--indirect` also scans for `call [reg+offset]`, `call [reg]`, `call [addr]`|`xrefs.py binary.exe 0x401000 --indirect`|
80
+
|`dataflow.py $B $VA`| Forward constant propagation (`--constants`) or backward register slice (`--slice VA:REG`) within a function |`dataflow.py binary.exe 0x401000 --constants`|
75
81
|`datarefs.py $B $VA`| Find instructions that reference a global address (mem deref + `--imm` for push/mov constants) |`datarefs.py binary.exe 0x7A0000 --imm`|
76
82
|`structrefs.py $B $OFF`| Find all `[reg+offset]` accesses (struct field usage) |`structrefs.py binary.exe 0x54 --base esi`|
77
83
|`structrefs.py $B --aggregate`| Reconstruct C struct from all field accesses in a function |`structrefs.py binary.exe --aggregate --fn 0x401000 --base esi`|
@@ -92,7 +98,7 @@ Everything else. Tell the subagent WHAT you need, not HOW to run it — it has t
92
98
|`sigdb.py scan $B`| Bulk signature scan against DB |`sigdb.py scan game.exe`|
93
99
|`sigdb.py identify $B $VA`| Single function signature lookup (multi-tier) |`sigdb.py identify game.exe 0x401200`|
|`context.py assemble $B $VA --project $P`| Gather full analysis context for a function |`context.py assemble game.exe 0x401500 --project Warband`|
101
+
|`context.py assemble $B $VA --project $P`| Gather full analysis context for a function. Includes forward constant propagation by default (`--no-dataflow` to skip)|`context.py assemble game.exe 0x401500 --project Warband`|
| KB updates from subagent findings | `static-analyzer` writes to `kb.h`; main agent may refine |
47
48
@@ -83,15 +84,17 @@ For deep analysis tasks (finding subsystems, mapping call chains, understanding
83
84
## Examples
84
85
85
86
**"Disable culling in game.exe"**
86
-
1. Spawn `static-analyzer` #1 (r2ghidra): find `SetRenderState` calls with `D3DRS_CULLMODE`, string search for "cull", xrefs to render state functions. Uses `--backend pdg --types kb.h`. Writes to `findings_r2.md`.
87
+
1. Spawn `static-analyzer` #1 (r2ghidra): find `SetRenderState` calls with `D3DRS_CULLMODE`, string search for "cull", xrefs --indirect to find vtable call sites. Uses `--backend pdg --types kb.h`. Writes to `findings_r2.md`.
87
88
2. Spawn `static-analyzer` #2 (pyghidra): same search strategy but decompile with `pyghidra_backend.py decompile`. Writes to `findings.md`.
88
89
3. Immediately tell the user: "Please launch the game — I'll need to attach with livetools to patch culling at runtime once I find the addresses"
89
-
4. When both return, merge findings and use `livetools` to verify and patch: `mem write` to NOP the cull-enable instruction or force `D3DRS_CULLMODE` to `D3DCULL_NONE`
90
+
4. While waiting, run `dataflow.py --constants` on any known render functions to see what cull mode constants flow in (e.g., `eax = 0x2` = D3DCULL_CW)
91
+
5. When both return, merge findings and use `livetools` to verify and patch: `mem write` to NOP the cull-enable instruction or force `D3DRS_CULLMODE` to `D3DCULL_NONE`
90
92
91
93
**"What does function 0x401000 do?"**
92
-
1. Spawn `static-analyzer`: decompile with `--types kb.h`, get callgraph, xrefs
93
-
2. Tell the user: "Static analysis is running. Want me to also trace this function live to see actual register values and call frequency?"
94
-
3. If yes, attach with `livetools trace 0x401000 --count 20 --read`
94
+
1. Spawn `static-analyzer`: decompile with `--types kb.h`, get callgraph --indirect, xrefs
95
+
2. Run `dataflow.py 0x401000 --constants` inline — see what constants flow through
96
+
3. Tell the user: "Static analysis is running. Want me to also trace this function live to see actual register values and call frequency?"
97
+
4. If yes, attach with `livetools trace 0x401000 --count 20 --read`
95
98
96
99
**"Find who writes to address 0x7A0000"**
97
100
1. Spawn `static-analyzer`: `datarefs.py` for static references
| `xrefs.py $B $VA` | Find all calls/jumps TO an address | `xrefs.py binary.exe 0x401000 -t call` |
78
+
| `cfg.py $B $VA` | Control flow graph (basic blocks + edges, text or mermaid). Resolves MSVC switch/jump tables automatically. `--switch-details` shows table info | `cfg.py binary.exe 0x401000 --format mermaid` |
79
+
| `callgraph.py $B $VA` | Caller/callee tree (multi-level, --up/--down N). `--indirect` adds vtable/fptr calls to --down trees | `callgraph.py binary.exe 0x401000 --down 2 --indirect` |
80
+
| `xrefs.py $B $VA` | Find all calls/jumps TO an address. `--indirect` also scans for `call [reg+offset]`, `call [reg]`, `call [addr]` | `xrefs.py binary.exe 0x401000 --indirect` |
81
+
| `dataflow.py $B $VA` | Forward constant propagation (`--constants`) or backward register slice (`--slice VA:REG`) within a function | `dataflow.py binary.exe 0x401000 --constants` |
76
82
| `datarefs.py $B $VA` | Find instructions that reference a global address (mem deref + `--imm` for push/mov constants) | `datarefs.py binary.exe 0x7A0000 --imm` |
77
83
| `structrefs.py $B $OFF` | Find all `[reg+offset]` accesses (struct field usage) | `structrefs.py binary.exe 0x54 --base esi` |
78
84
| `structrefs.py $B --aggregate` | Reconstruct C struct from all field accesses in a function | `structrefs.py binary.exe --aggregate --fn 0x401000 --base esi` |
@@ -93,7 +99,7 @@ Everything else. Tell the subagent WHAT you need, not HOW to run it — it has t
93
99
| `sigdb.py scan $B` | Bulk signature scan against DB | `sigdb.py scan game.exe` |
94
100
| `sigdb.py identify $B $VA` | Single function signature lookup (multi-tier) | `sigdb.py identify game.exe 0x401200` |
Copy file name to clipboardExpand all lines: .github/copilot-instructions.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,7 +18,8 @@ Run `python verify_install.py` from the repo root before first use. If pyghidra/
18
18
**Never run static analysis tools (`retools`) directly in sequence.** Delegate to the `static-analyzer` agent for all offline analysis. Exceptions — run these inline (all <5s):
19
19
20
20
-`sigdb.py identify` / `fingerprint` — single-function ID or compiler detection
21
-
-`context.py assemble` / `postprocess` — context gathering and decompiler annotation
21
+
-`context.py assemble` / `postprocess` — context gathering and decompiler annotation (assemble now includes forward constant propagation by default; `--no-dataflow` to skip)
0 commit comments