aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorblasty <blasty@local>2026-07-29 18:15:57 +0200
committerblasty <blasty@local>2026-07-29 18:15:57 +0200
commitb06884d91216497fab92685cd1530b4ca6b3c506 (patch)
tree0c23eb7c97ad3f3c8c5d1398071d9b6c93a49cf3 /README.md
parentapp: one instruction map for the decompiled function, not two (diff)
downloadida-tui-b06884d91216497fab92685cd1530b4ca6b3c506.tar.gz
ida-tui-b06884d91216497fab92685cd1530b4ca6b3c506.tar.xz
ida-tui-b06884d91216497fab92685cd1530b4ca6b3c506.zip
trace: memory at time T — stack in the dock, live bytes in hex
M2. Trace.memory(addr, length, idx) reconstructs what memory held at a moment, returning the bytes AND a per-byte "known" mask. The mask is the point: a trace knows what it observed and nothing else, so a byte nobody read or wrote is genuinely unknown and must not be drawn as zero. That distinction is the whole reason to read memory from a trace instead of the database — the database has the file's bytes, the trace has what was actually there. Reads count as evidence, not just writes: an instruction reading a byte reveals what it held then. Indexed by ADDRESS (sorted once, bisect per query), because the question is "what was in this window at time t" and the accesses that matter are the few touching that window, not the tens of thousands in the trace. Where the memory actually is: measured, 0% of accesses in either real trace fall inside the image — every one is stack or heap. So the primary view is the STACK, in the dock, anchored at SP: stack (rsp) ▸7ffff6f99470 ???????????????? 7ffff6f99478 00007ffff6fb0b00 7ffff6f99488 00007ffff6fa94e5 The hex view overlays trace bytes on the file's contents (green = the trace saw this byte at this timestamp, grey = still the file's idea). Correct, and it will matter for a program that writes globals, but on these traces it shows nothing — which is why the stack pane is the deliverable and not a nice-to-have. One bug the work surfaced: MemOp.addr was having the image slide applied to it, which is nonsense for a stack address — it produced -0xc838. The slide relocates the IMAGE; stack and heap have no database counterpart. Memory op addresses now stay in trace space, and memory_raw() queries there, while memory() takes database addresses for the hex view. tests: +9 model (35) covering the known-mask, reads-as-evidence, partial coverage and the writers/accessors queries; +1 differential (12) checking reconstructed memory state against Tenet's own get_memory at sampled timestamps; +5 UI (30) for the stack pane — present, anchored at SP, marks unseen bytes, follows time. 212/0 scenarios.
Diffstat (limited to 'README.md')
-rw-r--r--README.md5
1 files changed, 5 insertions, 0 deletions
diff --git a/README.md b/README.md
index 2d400e5..7d7d8d7 100644
--- a/README.md
+++ b/README.md
@@ -131,6 +131,11 @@ where you're about to go, and the instruction you're standing on. The pseudocode
view is painted too — a trace records instructions, but `decomp_map` says which
instructions each C line covers, so the same trail lands on the decompilation.
+The dock also shows the **stack as of that instant**, read out of the trace.
+Bytes the trace never observed print as `??` rather than zeros — a trace knows
+what it saw and nothing else. The hex view (`\`) gets the same treatment: bytes
+the trace saw at this timestamp are shown in green over the file's own contents.
+
Trace addresses are rebased onto the database automatically — a traced process
is relocated, so nothing lines up until that's solved.