# mem_trace

> **Tool `tools/emu/mem_trace.py`** (library, Emulators). Record which instructions read and write chosen memory while an emulated function runs.

A library: other tools and your own scripts import it. [Source on GitHub](https://github.com/tanepiper/game-frame/blob/main/tools/emu/mem_trace.py).

## Its own help

This is the help text in the tool itself, as `./gameframe tool mem_trace` prints it.

```text
Record which instructions read and write chosen memory while an emulated function runs.

This is taint analysis, done on the emulator instead of a live process with Pin or DynamoRIO:
mark some bytes (a buffer read from the save file, a global, a table), call the function, and
list each instruction that touched them.

    from mem_trace import MemTrace
    trace = MemTrace(emu, [(buf, len(data), 'save')], follow_copies=True)
    emu.call(load, buf, len(data), out)
    trace.write('derived/load.memtrace')   # "label<TAB>r|w<TAB>offset<TAB>size<TAB>module+offset"
    trace.readers()                           # {module+offset: count}, the code that read the bytes

With `follow_copies`, a write made by the same instruction that just read marked bytes (a
`rep movs`, an unrolled copy) marks the destination too, with the same label.

With `registers`, values are also followed through registers, as Pin-based taint tools do.
Capstone gives the registers each instruction reads and writes. An instruction that reads a
marked register or marked memory marks every register and every byte it writes. One that
reads nothing marked clears the registers it writes. Registers used only to form an address
do not pass their mark on, and `xor r, r` clears r. Memory written by unmarked values keeps
its mark, so the result can mark too much, never too little. `reg_log()` lists each
instruction that passed a mark on.
```
