Skip to main content

Luvdis

PyPI - Python Version PyPI GitHub GitHub Workflow Status

A smart Pure-Python GBA (Game Boy Advance) disassembler.

Luvdis is a tool for disassembling GBA ROMs, mostly for the purpose of creating buildable, matching disassemblies.

Features include:

  • Configurable output: Disassemble to stdout, a single file, or separate output into modules based on configuration.
  • Platform accuracy: Other disassembly engines like Capstone recognize instructions that are not legal in ARMv4 on the GBA's processor. Luvdis' custom decoder & disassembler solves this problem by attempting to replicate hardware behavior as closely as possible and only supporting ARMv4.
  • Function discovery: Detect likely THUMB functions and differentiate between code and data.
  • Matching output: Even if something goes wrong and a label overlaps with data, etc, Luvdis' disassembled output should assemble identically to the original ROM.
  • ROM detection: Unsure if you have a good copy of a ROM? Luvdis can let you know with luvdis info!

Contents

Installation

From PyPI

Luvdis requires Python 3.6 or later.

$ python3 -m pip install luvdis --user

From Releases

Arbitrary stable releases can be downloaded from GitHub and installed:

$ python3 -m pip install <path-to-zip> --user

For Windows users, prebuilt binaries are also available.

From latest source

$ python3 -m pip install git+git://https://github.com/arantonitis/luvdis#egg=luvdis

Usage

The simplest way to use Luvdis is to simply give it a ROM and output file:

$ luvdis <path-to-rom> -o rom.s

To assist in function discovery/labeling, a list of functions can be provided:

$ luvdis -c functions.cfg rom.gba -o rom.s

This list should have the following structure:

# '#' starts a comment line.
# Function names are not mandatory; unknown funcs are named sub_<ADDRESS> when output.
arm_func 0x80000D0
thumb_func 0x800024C AgbMain
# If 'thumb_func' or 'arm_func' is omitted, the type is assumed to be 'thumb_func'.
# A module path may also be provided. Each time a new module is encountered, output switches to that path.
# Omitting the module will continue outputting to the same path.
0x80003b0 main.s CallCallbacks

To disassemble only part of a ROM, say, up to the start of read-only data, provide start and stop addresses:

$ luvdis rom.gba --start 0x0800024C --stop 0x0x81b32b4 -o rom.s

FAQ

How can I get rid of large blocks of raw bytes in the disassembly?

By default, Luvdis treats areas of a ROM that it can't determine are executable as byte data. You can change this behavior with the default_mode option:

$ luvdis rom.gba --default_mode THUMB -o rom.s

What about multiboot ROMs?

You can disassemble a multiboot ROM (meant to be loaded in EWRAM at 0x02000000) by passing:

luvdis rom.gba --start 0x02000000

Options

Usage: luvdis disasm [OPTIONS] ROM

  Analyze and disassemble a GBA ROM.

Options:
  --version                   Show the version and exit.
  -o, --output FILE           Disassembly output path. If configuration
                              contains module information, this is only the
                              initial output path.
  -c, --config FILE           Function configuration file.

  -co, --config-out FILE      Output configuration. If any functions are
                              'guessed' by Luvdis, they will appear here.
  -D, --debug                 Turn on/off debugging behavior.
  --start INTEGER             Starting address to disassemble. Defaults to
                              0x8000000 (the start of the ROM).
  --stop INTEGER              Stop disassembly at this address. Defaults to
                              0x9FFFFFF (maximum ROM address).
  --macros FILE               Assembler macro file to '.include' in
                              disassembly. If not specified, default macros
                              are embedded.
  --guess / --no-guess        Turn on/off function guessing & discovery.
                              Default is to perform guessing.
  --min-calls INTEGER RANGE   Minimum number of calls to a function required
                              in order to 'guess' it. Must be at least 1,
                              defaults to 2.
  --min-length INTEGER RANGE  Minimum valid instruction length required in
                              order to 'guess' a function. Must be at least 1,
                              defaults to 3.
  --default-mode [THUMB|BYTE|WORD]
                              Default disassembly mode when the nature of
                              an address is unknown. Defaults to 'BYTE'.
  --help                      Show this message and exit.

ROM Detection

To display information about a ROM and check if its hash is in the database:

$ luvdis info unknown_rom.gba
ROM detected: 'Pocket Monsters - Ruby (Japan)' ✔

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

luvdis-0.9.0.tar.gz (307.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

luvdis-0.9.0-py3-none-any.whl (309.3 kB view details)

Uploaded Python 3

File details

Details for the file luvdis-0.9.0.tar.gz.

File metadata

  • Download URL: luvdis-0.9.0.tar.gz
  • Upload date:
  • Size: 307.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.7

File hashes

Hashes for luvdis-0.9.0.tar.gz
Algorithm Hash digest
SHA256 67d5d3f1e998c7fc81344204320785a63e4325ff722f65430c9c4616dacb1c7d
MD5 480d04276ca5764d0f4abb6ad228c7f2
BLAKE2b-256 8e2a463426e81c12d390bd42b05d71f26aaaff5eca1370ca4e52b7f45ac0b81a

See more details on using hashes here.

File details

Details for the file luvdis-0.9.0-py3-none-any.whl.

File metadata

  • Download URL: luvdis-0.9.0-py3-none-any.whl
  • Upload date:
  • Size: 309.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.7

File hashes

Hashes for luvdis-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 90456e07546ba5730cbe17bed5c626d8942182a3b6cf0657685af5db1df58b36
MD5 785cf8797a03e45e5efa7db2d4591edf
BLAKE2b-256 c93752d2b1680225ab412e3564d1f591ac11b16ba72e9d2dc40ea98b581c83d7

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.9.0 This release

2 files

0.8.0

2 files

0.7.1

2 files

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.4

2 files

0.3.3

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page