GBA Romhacking Help

Discussion in 'GBA - Game Development, ROM Hacks and Translations' started by goemon_guy, Jun 24, 2017.

  1. goemon_guy
    OP

    goemon_guy GBAtemp Regular

    Member
    115
    9
    Aug 16, 2011
    Canada
    Canada
    I'm looking into hacking a GBA game, (Konjiki no Gash Bell: Makai no Bookmark) but I'm running into some issues trying to do a few things. Namely:

    -Finding the decompression routine for text/graphics
    -Finding the location of graphics such as fonts

    I've been using NO$GBA's built in debugger to do my reverse engineering, and it's allowed me to figure out where text is loaded in RAM. However, I thought it would be as simple as setting a write breakpoint on the text when it is loaded, and tracing backwards to figure out where in the ROM it's loaded from. From there, I'd have the address that the text is at in the ROM, and could work on cracking the decompression algorithm.

    THe issue is that the write breakpoint never breaks when the text is loaded. It breaks several times before it is loaded, but never as text is loaded into RAM.
    Because of this, I am at a loss how to figure out where the text is in the ROM.

    Does anyone with any experience in this area have any suggestions? I've been looking at this for a few hours but no results have come of it.

    If anyone wanted to see what I'm describing, the text loads into RAM at 0x02003FA8, and I had a write breakpoint set at that location.
     
  2. FAST6191

    FAST6191 Techromancer

    pip Reporter
    23,155
    8,895
    Nov 21, 2005
    The GBA BIOS comes with a whole bunch of its own compression routines. I assume you have done the obvious of do a scan for them (various tools for this one, and you can also set logging or breakpoints for SWI calls to said decompression routines. It certainly can still be fully custom or at least not use the BIOS ones but that is rare, especially for a mid 2004 Banpresto anime tie in.

    I assume you did not load a savestate for your RAM breakpoint -- no sense in waiting for a write if the game had already written it long before your savestate was made. A write breakpoint should have fired, it might not have told you much if it was compression and copying from one point in RAM to another but it should have fired.

    I should also say for fonts might be a custom width. Japanese tends to be fixed with but it could be some smaller size so pressing page down a lot might not get you anywhere, not to mention it might be in bitpacked mode (somewhere between a type of compression and a straight up graphics mode, several tile editors will have a 1bpp mode of some form you can try).

    If I have time later I will have a look as well but for now I will go with that.
     
  3. goemon_guy
    OP

    goemon_guy GBAtemp Regular

    Member
    115
    9
    Aug 16, 2011
    Canada
    Canada
    Already having significant progress over what I would have found last night.
    I had read that the BIOS had its own function calls, but it never clued into me to actually trace them and see what they do.
    Managed to find the location of the compressed text almost instantly, and was able to decompress it.

    That's what I assume is the easy part. Next, I need to figure out where the font is. I tried what you suggested, looking through a program such as tlp or TM in 1bpp mode, but that found nothing that I could recognize as a font.
    Tracing the SWI functions doesn't seem to bring up anything related to the font, however.

    From last night, I was putting write breakpoints on the VRAM location where the font is loaded and printed out.
    I also tried tracing the code execution from a read breakpoint on the text, but neither of these lead me to anything in particular about how it reads the font from the game.

    EDIT:
    So, after a ton of searching around in Tile Molester, I found the game's font in 2bpp.
    The problem is, it looks badly organized, and I'm not sure how it would be possible to edit it in its current state. I'm not sure if there's some sort of compression going on with it, or what, but changing the modes around doesn't yield any better results.
     

    Attached Files:

    Last edited by goemon_guy, Jun 24, 2017
  4. Pablitox

    Pablitox GBAtemp Advanced Fan

    Member
    709
    359
    Oct 18, 2011
    United States
    the tiles aren't aligned is my best guess. Using crystaltile2 and various combinations of ctrl+arrows can arrange the tiles in such a way you'll see them just fine.
     
    Last edited by Pablitox, Jun 24, 2017 - Reason: sorry, meant ctrl+arrows
  5. goemon_guy
    OP

    goemon_guy GBAtemp Regular

    Member
    115
    9
    Aug 16, 2011
    Canada
    Canada
    Yep, you were right about that. Playing around with Crystaltile2, I was able to get a good look at the font.

    I have one main question now, though.
    If I wanted to add asm code at the end of the rom, in blank/expanded space, what would be the best way to branch to it?

    My idea was to copy the subroutine to a blank spot at the end of the ROM, branch to it by writing the address in ROM at an address, loading the address into r15 to bl r15 to it. Then, the copied subroutine returns by popping the address like it should and returns to the next instruction after my custom re-routing code, which pops again to return to whatever sent it there in the first place.

    I can only imagine this is the most inefficient way of doing this though.
     
    Last edited by goemon_guy, Jun 25, 2017
    Pablitox likes this.
  6. FAST6191

    FAST6191 Techromancer

    pip Reporter
    23,155
    8,895
    Nov 21, 2005
    That is pretty much it. Obviously you have to account for registers (push and pop exist for a reason, though still best if you don't branch in a branch if you don't have to), conditionals (say a compare fail happens and you carry that with you to your routine and that causes fun) and states (branch in thumb mode but need ARM or vice versa, as well as returning in the proper mode), and anything else that needs to be accounted for (can't update the screen save during a vblank sort of thing) but if you have a point to hook it at and branch there then carry on. If you are thinking all the predictive branching stuff we see with modern X86 then don't, there a bunch of quirks if you want to go reading http://www.coranac.com/tonc/text/asm.htm and http://problemkaputt.de/gbatek.htm and http://blog.quirk.es/2008/12/things-you-never-wanted-to-know-about.html but ARM7TDMI is really quite simple when you get down to it.

    If this is say for a variable width/line height placement font hack then that is pretty much how I would do it.
     
    Pablitox likes this.
  7. goemon_guy
    OP

    goemon_guy GBAtemp Regular

    Member
    115
    9
    Aug 16, 2011
    Canada
    Canada
    At least I'm on the right track in some way.

    Ran into a snag though: If I mov r15,r0 for example, the PC automatically changes to the new address without saving a return address. I can't seem to use any function other than bl r15 in the assembler (bl r0, for example, generates a parameter error), so how can I branch with a return address. (Keep in mind, the jump takes place over 080858E4 to 087DA0BC).

    Ahh, I see now. Bl only has the capability of branching to a label, whereas Blx would be able to branch to the address in a register.
    However, this sets the cpu in arm9 mode...
     
    Last edited by goemon_guy, Jun 25, 2017
    Pablitox likes this.