← cd ../

~/labs/workshops/gba-firered/03-ferramentas

Tools and setupmGBA, Ghidra, Python, Capstone, and GDB ready for class.

This chapter prepares the environment. Do everything before the hands-on class, because downloads and installation take time and interrupt the workshop flow.

There are five pieces:

mGBA        runs the game and has a built-in debugger.
Ghidra      performs static analysis of the ROM code.
Python      runs the project helpers (disassembler, RAM search).
Capstone    the library used by the disassembler.
ARM GDB     talks to mGBA for dynamic analysis.

mGBA

mGBA is the emulator. It also serves a debug server that GDB can access, which is why it is the workshop choice.

On Ubuntu or Debian:

sudo apt update
sudo apt install -y mgba-qt mgba-sdl

If your distribution does not have the package, or ships an old version, download the official AppImage from https://mgba.io/downloads.html and run it like this:

chmod +x mGBA-*.AppImage
./mGBA-*.AppImage

Load the ROM with File, Load ROM, and point it to rom/PokemonFireRed.gba. Keep the save file with the same name next to the ROM, as explained in notes/save-prep.md, so the game opens with the Continue option.

Ghidra

Ghidra is the static analysis tool. It disassembles the ROM into instructions, finds functions, and shows a pseudo-C version next to the Assembly.

It needs Java. Download Ghidra from the official NSA site (https://ghidra-sre.org) or from the project’s GitHub, unzip it, and run:

./ghidraRun

The first time, create a new project with File, New Project, and give it a name such as firered-workshop. Chapter 04 shows the ROM import step by step.

Python and Capstone

The project helpers are Python 3 scripts. The main one depends on Capstone, the disassembly library.

sudo apt install -y python3 python3-pip
pip3 install capstone

Check that Capstone was installed:

python3 -c "import capstone; print(capstone.__version__)"

If a version number appears, you are ready.

The project disassembler

The file tools/disasm_gba.py disassembles any ROM address, in ARM or Thumb. It is the way to check Ghidra without relying only on it. All chapter 02 examples were generated with it.

Usage:

# ARM, starting from an address, with size in bytes
python3 tools/disasm_gba.py 0x08000204 --size 0x34

# Thumb, just add --thumb
python3 tools/disasm_gba.py 0x080003A4 --size 0x20 --thumb

It converts the memory address to the file offset by itself, using the base 0x08000000 explained in chapter 01. If you pass an address outside the ROM, it warns you.

The RAM finder

The file ram_find.py compares two EWRAM dumps and shows which addresses had one value before and another value after. That is what reduces the entire memory to a few candidates in chapter 05. It reads two files:

ewram_hp24.bin   EWRAM dump with HP at 24
ewram_hp21.bin   EWRAM dump with HP at 21

And prints the addresses where the value changed from 24 to 21, testing three sizes: 8, 16, and 32 bits. Chapter 05 uses this in practice.

GDB for ARM

GDB is the debugger that connects to mGBA to pause the game, read registers, and set watchpoints. You need a version with ARM support. In many distributions the package is gdb-multiarch:

sudo apt install -y gdb-multiarch

The project already includes a ready configuration file, gdbinit-gba. It sets GDB to ARM little endian and Thumb mode by default, which is what the GBA uses most. To connect GDB to mGBA, first enable the debug server inside mGBA, in Tools, Start GDB server, and then run:

gdb-multiarch -x gdbinit-gba

Inside GDB, connect with:

target remote localhost:2345

How to confirm everything is right

Run this quick test. It exercises both sides, static and dynamic:

1. Run:
     python3 tools/disasm_gba.py 0x08000000 --size 0x10
   It should show:
     08000000: b        #0x8000204

2. Open the ROM in mGBA and see the game running with the save.

3. Open Ghidra. Leave the import for chapter 04.

If step 1 works, the ROM and Python are right. If step 2 works, the emulator and save are right. You can continue.

What to take from this chapter

- mGBA runs the game and serves debug on port 2345.
- Ghidra performs static analysis.
- tools/disasm_gba.py checks disassembly outside Ghidra.
- ram_find.py compares EWRAM dumps to find a value.
- gdb-multiarch with gdbinit-gba performs dynamic analysis.