IsoFrieze / DiztinGUIsh

A Super NES ROM Disassembler
GNU General Public License v3.0
255 stars 25 forks source link
disassembler nintendo rom snes snes-rom-disassembler super-nes

DiztinGUIsh ("Diz")

Build Status

A Super NES ROM Disassembler and tracelog capture/analysis tool with a focus on collaborative workflow UX. Exports .asm files ready to be compiled back into the original binary. Written in Winforms/C#.

Diz tools suite: image

Official support channel is #diztinguish in the https://sneslab.net/ discord


Features

Main features

Disassembling programs (like SNES games) for some CPU architectures (like the SNES's 658016) is a pain because you have to know a lot of information about the program at the point where it's running. Diz is designed to make this less of a nightmare.

Demo of basic disassembling: ezgif com-gif-maker

View more docs here: https://github.com/IsoFrieze/DiztinGUIsh/blob/master/DiztinGUIsh/dist/HELP.md


Realtime tracelog capturing: We provide a tight integration with a custom BSNES build to capture CPU tracelog data over a socket connection. You don't have to play the game at 2FPS anymore, or deal with wrangling gigabyte-sized tracelog files. Simply hit 'capture' and Diz will talk directly to a running BSNES CPU, capturing data for as long as you like. Turn the ROM visualizer on and watch this process in realtime.

ezgif com-gif-maker image

For more details, visit the Tracelog capturing tutorial

Other useful features

NOTE: Works fine with stock asar though, there's a bugfix you may want:

Details

Doesn't this already exist?

There is at least one 65C816 disassembler out there already. The biggest issue with it (not with that program, but with disassembling 65C816 in general) is that some instructions assemble to different sizes depending on context. This makes it difficult to automate.

A ROM contains two broad categories of stuff in it: code and data. A perfect disassembler would isolate the code, disassemble it, and leave the data as it is (or maybe neatly format it). Differentiating data from code is already kinda hard, especially if the size of the data isn't explicitly stated. A perfect program would need context to do its job. Turns out that keeping track of all memory and providing context for these situations is pretty much emulation. Some emulators have code/data loggers (CDLs) that mark every executed byte as an instruction and every read byte as data for the purpose of disassembly. A naive approach to disassembling then, would be to disassemble everything as code, then leave it up to a person to go back and mark the data manually. Disassembling code is the most tedius part, so this isn't a bad approach.

In the 65C816 instruction set, several instructions assemble to different lengths depending on whether or not a bit is currently set or reset in the processor flag P register. For example, the sequence C9 00 F0 48 could be CMP.W #$F000 : PHA or CMP.B #$00 : BEQ +72 depending on if the accumulator size flag M is 0 or 1. You could guess, but if you're wrong, the next however many instructions may be incorrect due to treating operands (#$F0) as opcodes (BEQ). This is known as desynching. So now you need context just to be able to disassemble code too.

Now for the most part, you can get away with just disassembling instructions as you hit them, following jumps and branches, and only keeping track of the M and X flags to make sure the special instructions are disassmbled properly. But more likely than not there will be some jump instructions that depend on values in RAM. Keeping track of all RAM just to get those effective addresses would be silly--again, it would basically be emulation at that point. You'll need to manually determine the set of jumps possible, and start new disassmble points from each of those values. Don't forget to carry over those M and X flags!

Things get more complicated if you want to determine the effective address of an instruction. Instructions like LDA.L $038CDA,X have the effective address right in the instruction ($038CDA). But most instructions look something like STA.B $03. The full effective address needs to be deduced from the data bank and direct page registers. Better keep track of those too!

So to take all of this into consideration, DiztinGUIsh tries to make the manual parts of disassembling accurately as speedy as possible, while still automating the easy parts. The goal of this software is to produce an accurate, clean disassembly of SNES games in a timely manner. Any time things look dicey, or if it becomes impossible to disassemble something accurately, the program will pause and wait for more input. Of course, there are options to go ham and just ignore warnings, but proceed at your own risk!

Features

Implemented or currently in progress:

Planned stuff:

"Distinguish" but with a 'z' because it's rad. It's also a GUI application so might as well highlight that fact."