aboutsummaryrefslogtreecommitdiffstats
path: root/TODO
blob: 78568aec4a5a90687facc000cb8620f8ec1d64cd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
## INCOMPLETE LIST OF TODO's
## ----------------------------------------------------------------------------

bugs:

current:
[~] DITCH ida-pro-mcp -> our own idalib worker (idatui/worker.py + WorkerClient)
    [x] worker + WorkerClient (drop-in for IDAClient, same tool shapes)
    [x] --backend {worker,mcp}; worker is now the DEFAULT for opening a binary
    [x] worker spawns under the IDA python; {"result":...} wrapping to match MCP
    [ ] run the pilot suite against --backend worker (blocked: idalib reaping here)
    [ ] progress reporting during analysis (worker streams notes to the overlay)
    [ ] once solid: delete client.py, server/patch_server.py, spawn.sh, and
        launch.py's whole supervisor/ensure_server/lock-sweep dance
[x] RPC endpoint for robot-spectator-ida
    -> progressssss

ez:
[x] opcodes (toggle) in disas view

doable:
[ ] stress test: big fucking binaries (canon rtos blob)

hard:
[ ] deal with PLT stubs and such (oh god here we go)
[~] how to deal with non-function-body regions?
    -> we want to be able to do data/type definitions in .data etc.
    -> M0 done: navigating to a non-function EA opens a flat listing instead of
       refusing; c/p/u edit verbs (define code/function/undefine) with
       bump_items() cache invalidation + region->func upgrade.
    -> M1 done: server `heads` walker (walks item-ends so undefined bytes show
       as `db ?` and arbitrary addresses land exactly) + ListingModel.
    -> M2 done: ListingView — virtualized flat listing (code+data+undefined,
       kind-styled), wired into nav/follow/xrefs/hex/edit-verbs. region views
       now use it (not the DisasmModel stopgap).
    -> M3 done: `d` = typed make_data prompt in the listing (define data in
       .data with any C type: int, char[16], my_struct, ...); undefined byte
       runs coalesce into `db N dup(?)` rows so big .bss doesn't explode.
    -> M4 (in progress):
       [x] string auto-detect: 'a' = make_string in the listing (IDA's 'A').
       [x] back-paging / streaming: listing primes the viewport instantly and
           streams the rest in the background (was load_all -> blank pane for
           seconds on a big .text). concurrency-safe page loads.
       [x] struct-typed data expansion: a struct global expands into indented
           member rows (+off name type) in the listing.
       [x] unify the function disasm view as a filtered listing: DisasmModel now
           sources its lines from the `heads` walker bounded to [func.start,
           func.end) (total via disasm include_total to avoid response-size
           truncation). Both code views render from the one listing mechanism;
           the DisasmView UI (opcode bytes/Tab/rename) is preserved. Full suite
           127/1 (1 = pre-existing flaky filter).
    -> M4 COMPLETE.

crazy:
[ ] multi/split view ala ghidra?
    -> would be interesting to make arbitrary compositions of disas/decomp/hex 
        views and keep them all in sync cursor wise etc.

done-ish:
[x] if `drive pc` hits a decompilation error it somehow causes a long timeout on client side
[x] remove stupid textual chrome/scaffolding
[~] hex editor? (viewer at least)
[x] make unit tests not suck (why unittest? because we're reward hackers!)
[x] (re-)typing
[x] struct editor
[ ] cant rename local label
    -> api limitations, might fix (not super important)
[x] rename -> history stack pop -> old name
[x] page up/down cursor x/y preserve
[x] hlsearch should jump cursor
[x] makes names pane sortable (addr/name columns)



## The scenario suite mutates a PERSISTENT database

tests/test_scenarios.py runs against targets/echo.i64 and every edit it makes is
saved there. A scenario that undefines an instruction leaves that instruction
undefined for every later run — decomp_follow_self started failing "for no
reason" and stayed failing until the .i64 was deleted and re-analysed.

That also poisoned an investigation: an `edit_keeps_view` check looked flaky
(cursor jumping 0x20c6 -> 0x2094 about one run in three) and was almost
certainly the database drifting between runs, not a race. Any conclusion drawn
from repeated runs of a mutating scenario is suspect.

Worth fixing properly: either give the suite a scratch copy of the binary per
run, or have mutating scenarios undo themselves. Until then, `rm targets/*.i64`
before trusting a failure that appeared without a code change.

Coverage for "an edit must not move the view" lives in tests/test_blob_ui.py,
which builds its own throwaway binary and can mutate freely.

## Assembly syntax highlighting (WIP, patch in docs/wip-asm-spans.patch)

The listing shows the mnemonic bright and everything after it in one body
colour. IDA already classifies every token, for every processor, so there is
nothing to lex — generate_disasm_line() emits \x01<tag>text\x02<tag> and the tag
says what the text IS. A pygments asm lexer would be a worse guess and would
need a dialect per architecture.

The patch: _idatui_spans() in patch_server parses those tags into
[[kind, text], ...] (insn/reg/num/str/name/seg/cmt/punct), heads rows carry
"spans", Head.spans holds them, and ListingView renders via _span_segments()
with a fallback to today's mnemonic/rest split. Verified working on echo:

  lea rcx, function; "usage"  ->  insn text reg punct text name cmt
  coverage over 400 rows: insn 344, reg 402, punct 397, name 156, num 47, cmt 44

Palette rule used: NEUTRALS for the machine (mnemonic brightest, registers at
body weight since they are most of the text), HUES only where they carry meaning
(numbers, strings, symbols), structure recedes so commas and brackets stop
competing with operands.

Two things learned that the patch encodes:
* The constants are SCOLOR_DATNAME / SCOLOR_CODNAME — there is no SCOLOR_DNAME.
  Guessing fails SILENTLY: an unmapped tag renders as body text, so symbols just
  aren't blue and nothing says why.
* Spans must be whitespace-collapsed exactly as `text` is, walking characters
  rather than per-span, because a run of spaces straddles spans. The row only
  gets spans when the two agree, so a mismatch degrades instead of corrupting.

NOT MERGED because it breaks one check: listing_view "undefining a data head
yields an unknown run" now reports kind=data. Reproducible, and bisected to this
change (10/0 with it stashed, 9/1 with it applied) on a fresh .i64. Cause not yet
found — the span code doesn't touch `kind`, which is computed from the flags
before spans are attached, so the suspicion is that adding "spans" to the row
dict perturbs something in the undefine path's re-read (caching keyed on the row
shape?). Find that before merging.

Also still plain: DisasmView (the function-scoped view) renders Line objects from
the `disasm` tool, which doesn't emit spans. Same treatment needed there.