Luvdis
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)' ✔
Metadata
Release files for Luvdis 0.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| luvdis-0.9.0.tar.gz | 307.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| luvdis-0.9.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 616.7 kB
Release files / luvdis-0.9.0.tar.gz
| Download URL | luvdis-0.9.0.tar.gz |
|---|---|
| Size | 307.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
67d5d3f1e998c7fc81344204320785a63e4325ff722f65430c9c4616dacb1c7d
|
|
BLAKE2b-256 checksum How to use checksums |
8e2a463426e81c12d390bd42b05d71f26aaaff5eca1370ca4e52b7f45ac0b81a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.7
|
Release files / luvdis-0.9.0-py3-none-any.whl
| Download URL | luvdis-0.9.0-py3-none-any.whl |
|---|---|
| Size | 309.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
90456e07546ba5730cbe17bed5c626d8942182a3b6cf0657685af5db1df58b36
|
|
BLAKE2b-256 checksum How to use checksums |
c93752d2b1680225ab412e3564d1f591ac11b16ba72e9d2dc40ea98b581c83d7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.9.7
|