This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

A NES Disassembler

A NES Disassembler
by on (#51062)
So, I got fed up with the NES disassemblers I had tried, and wrote this.
http://sooda.dy.fi/kassu/?p=projects#anda-1
If you report a bug, please include an md5sum of your rom dump, so I can make sure I'll debug with the same ROM dump.
Also, I haven't actually tested the Windows build.
The .nfo file should answer all of your questions, if not, ask those here.

I'm already planning on implementing some more funky functionality:
* data access trace table import
* where-from-called (inter-bank) table import
I'll just leave this list open for you to fill...

Lastly, if you're an emulator author, please either include a tracing feature that outputs a list of jumps like that, or invent(/have invented) a better trace file format.

EDIT: The .exe in the .tar.bz2 file was actually accidentally an ELF file, fixed now. (thanks for the actual Win32 build go to thefox) :)

by on (#51079)
The NFO file didn't work for me for some reason, sorry.

I was wondering if you implemented support for Code/Data logs for FCEUXD or anything like that. A while back, towards around March, I was messing around with Visual Basic and attempted to write a little disassembler of my own. I had some success, and it wasn't a command line utility. You can check it out here: http://www.freewebs.com/the_bott/DisasmTest2.rar . The thread about it I wrote was here: http://nesdev.com/bbs/viewtopic.php?t=4905 . I'm a Windows XP user, so I only made a Windows Executable for it.

The ReadMe included defines what everything does, pretty much. The UI might take a little getting used to, but I found it to be pretty handy after a while. Some of my programming was sloppy, but since I didn't get much feedback for the disassembler, I didn't think people really were interested in a public release, so I didn't try and fix some of the minor inconveniences. The main thing was that I made support for including a CDL file so that it would automatically output code and data correctly. Also, one could choose what to output for data statements, depending on the assembler they want to use to reassemble the disassembly. That was actually my main reason for making it. I wanted to make a disassembler that would output assembler-compatible disassembly.

Anyways, I'd be interested in seeing the capabilities of your disassembler, but the NFO file isn't working for me. Perhaps you could include a text file or something that describes all the capabilities?

by on (#51091)
Version 0.666b?

Be careful, Something is suspisious about this!

by on (#51092)
Protip: NFO files are plain text files. Do not attempt to open them with Microsoft System Information, or whatever Windows gives you as the default file association.

by on (#51093)
Dwedit wrote:
Protip: NFO files are plain text files. Do not attempt to open them with Microsoft System Information, or whatever Windows gives you as the default file association.

Yeah, Windows is pretty dumb since all it uses to identify file types is a 3 letter combination, so it's no surprise that it will get it wrong pretty often.

If you can't open a file by double-clicking, be it because the program associated to that extension doesn't recognize it or because there is no association at all, try looking at it in a text editor. Many times they are just text files, and many other times the first few bytes can give you a clue about what kind of file it actually is.

by on (#51097)
Celius wrote:
I was wondering if you implemented support for Code/Data logs for FCEUXD or anything like that.

I had the same idea, and I hope somebody will implement it some day. I have way too many projects at the moment to do it unfortunately. :)

Another useful feature would be interactive GUI, like in IDA, where you can interactively add comments, labels, structures and stuff like that and also tell the disassembler which blocks are code/data.

by on (#51100)
If you took a look at my disassembler, I did include support for CDL files and it also had a nice GUI to it (It was made with Visual Basic). The version that I posted was not the version I had on my computer before it kind of died on me. The last version had support for labels, and you could define how you wanted labels to be displayed. And also, it disassembles in chunks rather than disassembling the entire ROM at once. You simply tell it where you want to start disassembling from, and then you say how many lines of code you want to disassemble per "step". You can say that you want to disassemble something like 200 lines, and when you click the "step" button, it disassembles 200 lines of code (or data if it's mixed in with code). It also outputs 3 different disassemblies. One is assembler friendly, the next one is informative (It basically just contains the address next to each instruction), and then the last one just outputs .db statements. Another thing I added was defining the data statement. Some assemblers use .db and some use .data or something, and the disassembler allows you to change the statement to whatever you want. You could even lie to it and say that your assembler uses ".barbie" as the data definition statement, haha.

Anyways, it's not the best disassembler, but I started making it and I think it had some good potential. Unfortunately I am missing the source code, so I would have to start over.

by on (#51101)
Well, seems to me like I maybe didn't supply enough instructions here. But, that can be fixed: here's a short tutorial.

InvalidComponent's guide to easy romhacking with ANDA

Hi kids! Tonight we're gonna fix that Mario's game for good! And I am, of course, talking about doing something fun with Dr. Mario.

We'll start up by firing up an emulator which supports the log format described in the .nfo file (y'all windows folks probably want to open it in notepad) and playing the game a bit. (Yay!)
This is probably the hardest step, since at the moment, no official emulators seem to do the trick, so you'll probably be better off just rolling the feature in your own.

Alright, let's play the game a little bit... due to the nature of the disassembler, you have to play the game so that all code you want disassembled is traveled upon at least once. Also, if your game uses some nasty tricks to do jumping, there's a high chance you're going to have to write those addresses accessed in that way down in the log file yourself. ("push bytes to stack, then rts" nasty)

Then, let us run anda!
Code:
invalidco@localhost ~/anda $ ./anda drm.nes drm.s drm.chr drm.jumps

After ANDA warns you about indirect jumps, it'll write the output to drm.s and the graphics to drm.chr. Since this disassembler is still a beta versision, you'll want to make sure the assembler didn't screw anything up and fire up ophis already with the just-disassembled rom:
Code:
invalidco@localhost ~/anda $ ophis drm.s test.nes

And check for differences between files...
Code:
invalidco@localhost ~/anda $ md5sum test.nes drm.nes
d3ec44424b5ac1a4dc77709829f721c9   test.nes
d3ec44424b5ac1a4dc77709829f721c9   drm.nes

Looks good to go, so let's get cracking!

The first thing we need to do is find some unused space to use to store our code. After some search, we'll find something that looks like a padding pattern or something similar at nearly the end of the drm.s. These bytes look like they store nothing significant, (I get a feeling that $0, $ff pattern is a leftover from the eeprom or some other low-level electronics thing) so we'll erase 'em and replace it with our padding code:
Code:
supercoolfunction:
         rts
.advance $ffd0
sub_b1_ffd0:

Since we'll have to be careful in order not to mess the bytes up, we'll just stick a label, an rts and an assembler directive to pad the rest with zeroes. Now, let's find someplace to inject! If you look for the address $4014, you'll find the OAM subroutine pretty fast! There's the usual addresses being written to registers, we'll cut the second one and copy it to our own subroutine, leaving the sprite update routine in the following condition:
Code:
sub_b0_b788:
         lda #$0
         sta $2003
         jsr supercoolfunction
         rts
.advance $b793
sub_b0_b793:

Note that we need to the padding, again, because there are far more complex dependencies hidden in there than I have the time to explain.
Now, we'll do something fun in the supercoolfunction subroutine, like flip all sprites vertically:
Code:
supercoolfunction:
         ldx #$00
*
         lda #$80
         eor $0202,x
         sta $0202,x
         inx
         inx
         inx
         inx
         bne -
         lda #$02
         sta $4014
         rts

Now, assemble, test and feel the newly acquired power coursing through your veins!

EDIT: If you feel some glitching, that's because this code is taking up too much time, you might want to try to restrict the flipped sprites to only a few of the first or use some code that has been optimized a bit better.

by on (#51103)
InvalidComponent wrote:
If you feel some glitching, that's because this code is taking up too much time

Yeah, looping through the sprites flipping them is hardly something you'd do during VBlank when you're about to DMA them.