News: 11 March 2016 - Forum Rules
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia, Danke

Author Topic: ASM hacking in GBA ROMs  (Read 10485 times)

ziddia

  • Guest
ASM hacking in GBA ROMs
« on: June 20, 2013, 08:19:43 pm »
Hi,

I'm fairly new to ROM hacking, which I really only got into to try and write some tools to hack Pokemon Mystery Dungeon, which doesn't seem to have any tools for it anywhere at the moment.

So far, I've had no trouble working with text editing, as all pieces of text, such as menus, item descriptions, and dungeon names, are all encoded with ASCII. However, my next goal (to change the partner Pokemon you can choose in the beginning of the game) is somewhat of a roadblock to me - I haven't worked with a debugger or a disassembler before, and I have some experience with x86 assembly, but none in ARM or Thumb.

Basically, what I'm asking is if there are some documents or some other sort of assistance that would teach me how to find the data I need to edit in the ROM. I'm using VBA-SDL-H as a debugger, and I have a copy of IDA Pro if I need to disassemble the code, if that helps at all.

Thanks!

FAST6191

  • Hero Member
  • *****
  • Posts: 2962
    • View Profile
Re: ASM hacking in GBA ROMs
« Reply #1 on: June 21, 2013, 05:42:29 am »
Docs
well there is
http://nocash.emubase.de/gbatek.htm
I like
http://www.coranac.com/tonc/text/asm.htm
http://www.heyrick.co.uk/assembler/ and http://www.heyrick.co.uk/armwiki/Main_Page are also worth a look.
I prattled on a tiny bit in my GBA/DS docs though it is probably not quite so useful in your position (it was mainly aimed at those new to assembly)
http://www.romhacking.net/forum/index.php?topic=14708.0

Otherwise it is ARM7 TDMI assembly --
Unlike X86 you need to use dedicated instructions to pull from or go into memory (there is DMA as well -- http://drunkencoders.com/files/2013/03/unequivocal-answer.html )
There is no divide instruction. Various BIOS commands (arctan, square root and various divides are available as well as decompression, a memory transfer and some graphics related stuff are available in the BIOS) or on the DS the maths coprocessor can be used instead. Nothing stopping a dev from setting up log tables either and the "code it to multiply instead" option is always present.
No floating point worth speaking of. BCD, various types of fixed point or software floating point are your main options. You can get a remainder and play with that if you want though.
It is a RISC processor so everything is quite basic and there is no 40 cycle SIMD stuff to contend with. On the flip side if you did want the niceties afforded by the 40 cycle SIMD stuff you will now have to spend 200 cycles and do it one by one.
No 3d worth speaking of beyond the mode 7 a like stuff the graphics system has.
Immediates can not be the full 32 bits so shifts are common. (getting FFFF FFFF in a register might involve something like mov FFFF into R? and then shift r? by 16 bits then adding FFFF into R?). Edit -- see later comments. All high bits is not the best example.
There is THUMB mode which is broadly speaking a 16 mode with 32 bit registers (albeit fewer than ARM mode) that makes for faster code in a lot of cases (I would not be surprised to see games spend upwards of 90% of their time in THUMB mode and certainly a lot of the main loops/functions in a game)
Piplining is limited to a 2 instruction read ahead, no branch prediction or anything like that. The only real time this matters if you try to read the program counter which will be 2 instructions ahead by the time it has it in memory. Rather than try to be flash with hooks there just branch.

Though you could run code from the memory it is quite small and the memory mapped cart uses fast enough memory that it can do it so most games do not do this. Typically this is 08000000 through 09FFFFFF in memory but there are mirrors at different waitstates (which can be changed to be faster or slower if you really want).

If you already have IDA you have a great disassembler. There should be some GBA plugins but I am not sure what goes there right now
http://www.romhacking.net/documents/361/ covers basic tracing with VBA-SDL-H and http://labmaster.bios.net.nz/vba-sdl-h/ covers much of the usage with it.
I also suggest a quick scan through
http://www.romhacking.net/documents/337/

What you want may be subtly different to graphics but setting breakpoints and reverse engineering reads/codes are roughly the same anywhere, I would check to see if there are any cheats that can do things like this as they are great places to get ideas on how to set about things. Likewise it might not boil down to assembly hack to implement it -- the game could read a value from memory instead (in my experience pokemon games actually do the database/crude database lookup thing quite well, for the DS but http://www.pipian.com/ierukana/hacking/ds_evos.html ).

The final quick trick is the finding the binary in the GBA ROM trick. The GBA ROM is self contained without a filesystem in almost all cases. However the GBA binary is easy to find save perhaps for two games ( http://doc.kodewerx.org/hacking_gba.html#psc ).
The idea runs the first command is the first byte and it jumps to the end of the header usually. This then sets up the basic IO which would have bored you in most assembly tutorials (save perhaps Art of Assembly) and then the first reference to something in the 08XXXXXX range is the first proper instruction.

Finally and perhaps more important than some other stuff I already mentioned is that ARM publish manuals for their chips
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0210c/index.html
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0201d/
Other nice links
http://www.scss.tcd.ie/~waldroj/3d1/arm_arm.pdf
http://quirkygba.blogspot.com/2008/12/things-you-never-wanted-to-know-about.html
http://imrannazar.com/ARM-Opcode-Map

For the others reading there is no real programming tutorials with reference to ARM assembly that I have seen, X86 has a few though and http://stuff.pypt.lt/ggt80x86a/asm1.htm and http://www.plantation-productions.com/Webster/www.artofasm.com/index.html are two of the nicer ones.
« Last Edit: July 02, 2013, 05:15:23 pm by FAST6191 »

henke37

  • Hero Member
  • *****
  • Posts: 643
    • View Profile
Re: ASM hacking in GBA ROMs
« Reply #2 on: June 21, 2013, 08:28:43 am »
I am pretty sure that there is an OR high for the times when you want to set the high part of a register directly.

FAST6191

  • Hero Member
  • *****
  • Posts: 2962
    • View Profile
Re: ASM hacking in GBA ROMs
« Reply #3 on: June 21, 2013, 02:24:26 pm »
There is but the ARM stuff has a pretty mean shift setup that gets used in production often enough and EOR/XOR can be slightly fiddly (I was mainly using the set all high as an example).

Dwedit

  • Sr. Member
  • ****
  • Posts: 307
    • View Profile
    • Dwedit's Website
Re: ASM hacking in GBA ROMs
« Reply #4 on: July 02, 2013, 04:27:08 pm »
Moving 0xFFFFFFFF into r0 is done with the MVN instruction, short for 'move negated'.  It moves the complement of a register or immediate value into a register, so MVN r0,#0 is the same as mov r0,#0xFFFFFFFF.
Arbitrary 32-bit loads are done with the ldr r0,=XXXXXXXX psuedoinstruction.  This is implemented with a literal pool.  The assembler implements this for you.  The actual instruction changes to ldr r0,[pc,#xxxx], and the literal pool can be up to 1024 bytes away from the instruction.
"We are merely sprites that dance at the beck and call of our button-pressing overlord."

FAST6191

  • Hero Member
  • *****
  • Posts: 2962
    • View Profile
Re: ASM hacking in GBA ROMs
« Reply #5 on: July 02, 2013, 05:19:30 pm »
Yeah all high was a bad example in real world things.

Is the psuedoinstruction in most assemblers/disassemblers? I agree not many people work from binary backwards and if the OP is using IDA it is probably a moot point, however given you have probably worked with the ARM-SDT for the last however many years where others of us get to play with somewhat more crude tools I have to ask.

Dwedit

  • Sr. Member
  • ****
  • Posts: 307
    • View Profile
    • Dwedit's Website
Re: ASM hacking in GBA ROMs
« Reply #6 on: July 02, 2013, 07:49:41 pm »
I use GCC now, because linkscripts are powerful if you need to edit them.  You can even stick some code inside of fast Video RAM and run it from there.  The C code generation still leaves some to be desired, but I use mostly ASM anyway.

Only shortcoming of GCC is that it can't do register-relative symbols, so I was using a workaround with macros.

If you want to hack GBA roms easily with GCC, I made a template program for easily patching code.  You can find it in this thread on Nesdev, and you use DevKitArm as the compiler.  You say "patchat <address>" and it uses incbin magic to include the original code up to that point, then you can add your replacement code.  But in my patch project, literal pools weren't working, because the assembler gets confused about the size of the code.  The LDR rx,= psuedoinstruction is somewhat ambiguous, because the assembler might use a mov or adr statement if the immediate value fits, so I'm sure that's why the literal pools are failing.

By the way, the other common psuedoinstructions are "adr" and "adrl".  ADR moves a pc-relative address into a register, it compiles to an ADD or SUB instruction.  ADRL is a two-instruction version for longer distances.  It takes one cycle for ADR, or two cycles for ADRL to execute, whereas LDR ,= takes at least 3 cycles.
NO$GBA's integrated assembler (shareware version is awesome) supports most of the psuedoinstructions, but it can't create LDR ,= instructions out of nothing, since it needs an existing address inside a literal pool.
"We are merely sprites that dance at the beck and call of our button-pressing overlord."

FAST6191

  • Hero Member
  • *****
  • Posts: 2962
    • View Profile
Re: ASM hacking in GBA ROMs
« Reply #7 on: July 03, 2013, 05:32:26 am »
Very shiny, wonder if I could adapt it for DS overlays.