A compilation of resources and approaches I’ve taken to search and understand features of a given system. I don’t claim to be any sort of authority in this matter, and there’s probably more efficient alternatives out there. Take these as starting points to develop your own approaches.

Methodology

We focus on making state explicit: annotating disassemblies, adding breakpoints and watches in a debugger, adding instrumentation for printfs, diffing trace logs…

Some domain-specific differences are worth pointing out:

  • Code patterns (e.g. main loop, frame cap, memory mapped I/O…);
  • Data formats (e.g. 2D tiles with indexed palettes, 3D meshes…);
  • Dynamic analysis via pure CPU emulation may not give the expected results due to missing logic happening outside the game’s main loop (e.g. VBlank routine called via interrupt);

But before applying any approaches, let’s avoid guessing: ask “What is already known about what I will reverse?”. For example, these are some questions I would make for the Playstation 1 console:

Hardware architectures

CPU debuggers

CPU disassemblers

  • radare2
      echo 0800428c | xargs -I{} rasm2 -a mips -b 32 -d {}
      # lw v0, 8(v0)
    
  • MAME: unidasm or skeleton driver that loads ROM and attaches CPU
      make REGENIE=1 TOOLS=1
    
      echo 0800428c | xxd -r -p > /tmp/1 && ./unidasm /tmp/1 -arch mips3le
      # 0: 8c420008  lw        $v0,$8($v0)
    
      # rebuild subset of drivers
      make SUBTARGET=foo SOURCES=src/mame/drivers/foo.cpp
    
  • The Ultimate Disassembly Framework – Capstone – The Ultimate Disassembler

CPU emulators

Debugging the emulator

One of the challenges is in figuring out how the emulated system’s memory maps are allocated in the emulator’s process memory maps, for which a byte signature can be used for translating addresses.

Patching the emulator

Binary patching

ASM patterns

Data formats

Graphics

Emulator dev

ROM dumping

Exploit dev