DS Hooking Help

Discussion in 'NDS - ROM Hacking and Translations' started by matthewn4444, Aug 11, 2011.

Aug 11, 2011

DS Hooking Help by matthewn4444 at 7:30 AM (1,606 Views / 0 Likes) 17 replies

  1. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    I followed the tutorials at http://crackerscrap.com/index.php?p=docs however it seems that running your code right at 0x2380000 (where the first line of code runs for arm7.bin) does not work on my acekard2i. It works on no$gba but the hacks don't work on my acekard. I then tried to place it a little higher in memory and patched old code inside my asm code and the rom froze (crashed, white screen) while in no$gba it would not crash and it would execute my hack. I don't think running the code at 0x2380000 or anywhere near there allows you to initially run your own code before the nds game starts on flash cards.

    My question is, where is a safe place to do the initial hooking in games? The game I am working with is 128mb so I am not sure where I can safely place the "hook" to not allow flashcards to crash.
     
  2. FAST6191

    Reporter FAST6191 Techromancer

    pip
    Joined:
    Nov 21, 2005
    Messages:
    21,703
    Country:
    United Kingdom
    Different cards can have different issues although AKAIO is usually fairly resilient. Afraid I am not really that well versed in the hooking issues of different cards though. I will say are you sure it is not a patch on AKAIO's part- it has to hook code as well remember (disable any cheats, soft reset and other such features).

    Can I just make sure you are doing an actual hack and not making a cheat- if you are attempting to patch a cheat in there is DSATM for that http://gbatemp.net/index.php?showtopic=80540
    However if this is more intellectual curiosity or a bug in DSATM then that can change things.
    First are you sure it is 2380000 hex that it starts at- most games do this but the odd one can mix things up. Many tools can tell you this (NDSTS being my usual one http://www.no-intro.org/tools.htm ) although if it is an emulator working/cart not issue that could be different.
    If it is a hack and assuming it is not a matter of rejigging some stuff in place why not avoid hooking in this sense and just do a destructive jump to somewhere free in the memory, perform the hack and jump back if it needs to be that. If you are having a hard time finding memory locations the ARM9 files can often include other pieces of data or my personal favourite of error related text- probably never to be seen and if not you could always repoint it to have a token couple of characters and use the space.

    Equally if you stashed the code later in the binary/memory and did not just use it as the end result of a jump are you sure it was not running in THUMB mode or something by this point? I assume you have no compression related issues here (sometimes the binaries are compressed in rom)- if you are hooking the ARM7 (assuming it is uncompressed) to patch code in the now uncompressed ARM9 (once loaded in ram).

    "The game I am working with is 128mb"
    Afraid we are not on the GBA any more (where the entire game and so in some regards code was all in memory) and total rom size is fairly meaningless in all this, apologies for stating something so obvious but the the general idea is the game loads the ARM9 into memory, the ARM7 into memory and then adds in overlays as appropriate. Sure stuff like puzzle quest uses lua and although I have not seen it I am sure some game uses a measure of code modification at runtime.
    The ARM9 traditionally runs all the game logic where the ARM7 does the grunt work and boring stuff and is more or less the same between games (homebrew is often different), overlays are simple code extensions and used almost exclusively with the ARM9 (I do not want to say there are no ARM7 overlays but I have never seen one)

    I suppose to answer Safe place can be anywhere and "nowhere" depending on the game. There are a couple of good bets but on occasion you need to find something else.
     
  3. habababa

    Newcomer habababa Advanced Member

    Joined:
    Nov 24, 2010
    Messages:
    60
    Country:
    Philippines
    you might have overwritten some registers that are to be used by succeeding lines of code.
    or if you did free registers before executing your code, maybe you have overwritten important memory areas.

    what are you using to compile your asm code?
     
  4. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    @habababa: My code above shows that I push and pop the registers, again it works on emulator (if registers were overwritten and not saved, emulator would have crashed as well). I am using cracker's asm compiler (ARM ASM kit from http://crackerscrap.com/index.php?p=docs)

    @FAST6191
    I am making a hack for 7th dragon. I implement the hack very similar to the tutorial, at 0x2380000 it branches (in arm7.bin) to my code at the end of the arm7.bin (so around 0x8FXXXXXX). I use 3 halfwords (12 bytes) to put "ldr r15,=0x8FXXXXXX" at 0x2380000, which when in the emulator it would run jump to my code. Then at my code, it would patch some arm9 code (2 bytes per instruction) and patch overwritten code (those 3 halfwords I had to overwrite to get here) and copy all my code to safe place in memory (which I tried 0x2C00000 that seems that the game doesn't overwrite this address). The arm9 places I overwrote early takes 5 lines of code to jump to 0x2C00000 and execute the hack and then comes back.

    Overwriting thumb code (16 bit) in arm9
    1. push {r0,r1} //r0 = address to jump to, r1 = the flag that tells my code what hack to run
    2. mov r0,#0x2C
    3. lsl r0,r0,#0x20 //r0 is now 0x2C00000
    4. mov r1,#0x1 //r1, at my code it has a switch statement that branches to the part of my code that needs to handle the hack
    5. bx r0 //branches to 0x2C00000 and swaps to arm mode I think (arm7 code?)
    6. continue...

    @0x2C00000 --- now running arm code (arm7, 32 bit instruction)
    1. cmp r1,#0x1
    2. b someplacetohandle

    11. someplacetohandle:
    12. pop {r0,r1}
    13. //patch overwritten code for 5 lines
    18. //Runs my hack for a few lines
    28. bx r14 //goes back to where I left off and goes back to thumb mode (arm9 code), jumps back at 6 from above

    I may have my arm and thumb mixed up but I know arm7, each instruction is a word long and arm9 is halfword for each instruction. That is how I hooked but it doesn't work on flash card (even with all the cheats, patches disabled).

    I do not know but the emulator initially runs my code through arm, is it possible that the flash card is running at 0x2380000 with thumb code? There it is probably doing something stupid and crashing but this is my first time doing this so I am not sure if that is the case (I guess I can attempt it and see what happens). I also noticed that not affecting the arm7 code but just appending my code at the end causes the game to run on the flashcard (which is obvious).
    If this doesn't answer your question I am sorry, I am kind of noob that just learned how to do this a couple of weeks ago and trying to "hack" at it.
     
  5. habababa

    Newcomer habababa Advanced Member

    Joined:
    Nov 24, 2010
    Messages:
    60
    Country:
    Philippines
    are you using dsatm?
    dsatm uses the pseudo-op, ldr r*, =*********** , that works differently with other compilers.

    so r0 and r1 retains their previous values?
     
  6. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    I am sorry, I am not with my code right now and I messed up with the explanation code above (this what happens when you are tired in the morning explaining asm stuff).

    Here's the better version (remember that it works in emulator, so if I made those errors, then the emulator will crash and my hack will not work). This is just a demonstration of how I set it up, doesn't mean this is my code.

    @0x2C00000 --- now running arm code (arm7, 32 bit instruction)
    1. cmp r1,#0x1
    2. beq someplacetohandle

    11. someplacetohandle:
    12. pop {r0,r1}
    13. //patch overwritten code for 5 lines
    14. push {r0-r8} //arbitrary register for this example
    19. //Runs my hack for a few lines
    29. pop {r0-r8}
    30. bx r14 //goes back to where I left off and goes back to thumb mode (arm9 code), jumps back at 6 from above
     
  7. Normmatt

    Member Normmatt Former AKAIO Programmer

    Joined:
    Dec 14, 2004
    Messages:
    2,135
    Country:
    New Zealand

    If you referencing anything from 0x08xxxxxx then your reading from the gba slot which will be blank when run from a slot1 cart and most likely different when run from a slot2 cart.
     
  8. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    0x08xxxxxx is in the gba slot? Well that sucks. Is 0x08xxxxxx always blank initially? Doesn't the arm7.bin get placed in memory initially? The code is there (based off being at the end of the arm7.bin) How do place their code onto a 128mb or larger game if the end of arm7 is at/close to 0x08xxxxxx?

    Edit: I also tried to run the Break Em All game that cracker did the tutorial with, the file size is small and the code he hard was not in the 0x08xxxxxx's and it still froze/crashed on flash card.
     
  9. FAST6191

    Reporter FAST6191 Techromancer

    pip
    Joined:
    Nov 21, 2005
    Messages:
    21,703
    Country:
    United Kingdom
    The DS rom stays on the cart and is loaded to given memory sections at request of the game.
    The only things that are loaded all the time are the ARM9 and ARM7 binaries and later the overlays (although they can be loaded near boot and stick for nearly the entire game) but you should also be able to find their intended location easily enough (the game can have several locations it uses for overlays) with something like crystaltile2. DS rom protocol http://nocash.emubase.de/gbatek.htm#dscartridgeprotocol The GBA just references, copies or more likely DMA transfers stuff around but not the DS.

    Yeah 08000000-09FFFFFF is the GBA memory slot (same on the GBA although the GBA/GBA mode also has a few mirrors at higher wait states), I am not sure what it is at boot ( http://nocash.emubase.de/gbatek.htm#unpredictablethings has something but I am not sure if it applies here) or even if you can write to it and hope to have it do anything useful.

    I will ponder this a bit longer (I can not help but feel this is a very convoluted method) but I will leave you with http://imrannazar.com/The-Smallest-NDS-File to read.
     
  10. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    I played around with asm in the file and concluded that the address at 0x08xxxxxx is not valid (therefore calling this crashes the game). I am however not sure how I am suppose to place the hack. I thought appending it to the arm7 would be sufficient enough to get my hack into the game, however, arm7.bin attaches my code there (0x08xxxxxx) and I have no idea how to get it lower (memory wise) or able to be used on flash cards. I am sure there is many ways however I have no idea how to do so. There are a few translation patches on games but I am sure something is moving it there. I will investigate the overlays but I would like to know if there is a way to place my code somewhere for it to be able to be accessed when running flash cards.
     
  11. rastsan

    Member rastsan 8 baller, Death Wizard

    Joined:
    May 28, 2008
    Messages:
    962
    Location:
    toronto
    Country:
    Canada
    If this helps the overlay is static.
     
  12. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    Ok I solved it. Thanks for all your help but I am pretty stupid. I didn't realize that 0x08xxxxxx was a copy of the code because once the game starts it overrides around 0x23A70F0 and that is where the code really is initially. I applied my jump to 0x23A70F0 instead of 0x08xxxxxx (where it will copy my code and place it in another place in memory). Now I have other problems to fix but I guess I am good for now.

    Thanks for all you help again, now I can move on XD.



    Edit: Got another problem. I am trying to hook from arm9 (thumb) to arm7 code (my code) (arm) and then go back. I think to switch between thumb and arm is bx r# however doing it from arm doesnt work. I am not sure how it work since it works for emulator but freezes on flash card.

    From Cracker's tutorial:
    @37FFB20 (thumb)
    ldr r0,[r1]
    cmp r0,#0x0
    blt 0x37FFB3C
    mov r2,#0x5
    ldr r4,[r15,#-0x2]
    bx r4
    .long 0x23FE000
    mov r4,#0x8

    Notice that r4 is being loaded with a new value right after our hook so we know it is safe to use it for our jump.

    @23FE000 (arm)
    stmdb r13!,{r0-r12,r14} ;@ Save registers to stack
    ;@ Start of your function
    ...
    ;@ End of your function
    ldmia r13!,{r0-r12,r14} ;@ Restore registers from stack
    sub r0,r2 ;@ Patch in overwritten opcodes
    str r0,[r1]
    add r1,#0xFC
    ldr r0,[r1]
    ldr r4,[r15]
    bx r4 ;@ jump to IRQ handler
    .long 0x37FFB31 ;@ return address ORed with 1 to switch back to Thumb mode

    I am not sure how to hook and switch between modes.
     
  13. habababa

    Newcomer habababa Advanced Member

    Joined:
    Nov 24, 2010
    Messages:
    60
    Country:
    Philippines
    your return address is misaligned.
     
  14. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    No actually I looked at the memory got overwritten. I loaded a byte from the location and it was not the correct value. When people in general hack their nds games and where can they place their code? Do people do it statically?
     
  15. FAST6191

    Reporter FAST6191 Techromancer

    pip
    Joined:
    Nov 21, 2005
    Messages:
    21,703
    Country:
    United Kingdom
    This hooking stuff is almost exclusively the domain of cheats (things that need to sit on top of the game although even those can often be done using the following)- most ASM hacks are one of two things and this is usually there in the very binary from game start (although depending on what needs to be done it can be overwritten as the game progresses). Unless you fancy redoing several binaries (C type languages are big on pointer arithmetic) and possibly an entire rom you can not just add a bytes in the middle of things.

    1) Destructive editing- opcodes are changed (occasionally later ones overwritten although this is rarely the best method) to do what needs to be done. This is usually reserved for simple things like say you found the opcode that subtracts one from your lives when you die, you change a few bytes (or in this case of this example a single bit) and it instead adds a life or perhaps more commonly when dealing with pointers addressing things in memory and located in the binary. You said VFW hack- the crude cousin to this is a narrow font hack wherein you change the draw width/glyph spacing from something large (aimed at Japanese characters) to something more narrow (at least able to be done with Roman characters- although you might have to do something like have W and such as a dual tile affair but that is getting off topic).

    2) Jump to another routine (usually yours) elsewhere in the memory* and jump back at the end of the routine. If you are doing something else not related to the currently running routine (although I would probably want look to interrupts here as it is probably a cheat) then the next opcode that would have normally run but if you say wanted to expand the abilities of an existing routine like a VFW hack on a fixed width game you can jump back at the end of the end of the font/text handling stuff as appropriate.

    *where to stash this is a tricky one. The nicest thing is if there is some free memory somewhere but one a system with resources as limited as the DS it is far from a certainty. Earlier versions of cracker's DSATM had the option to do "deadbeef" padding wherein the rom was told to flood the ram with the hex DEADBEEF at start and then by dumping the ram anything that had DEADBEEF in it after a certain amount of gameplay could be looked at as a possible location to inject your code (although always be prepared to have it used if some odd combination of events happens). At this point I should mention overlays- it is a crude method and one I had not expected to see this side of 1995 but I guess we are dealing with embedded systems reading from static media (homebrew can avoid this by having the SD card to play with so it tends to use alternative methods). The general idea is that a few hundred bytes in the memory can be left blank and then when appropriate a section of code can be put there (one might say overlayed) to do something that is useful but did not need to be in the game all the time, there can be multiple portions of memory given over to use for overlays.
    Getting back on topic if you are not that lucky you can either try to cram your code in the place of the old one, gain some space somehow- games written lazily in C are not a patch on some tightly written ASM code (indeed some cart makers and more notably AKAIO have sped things up or fixed bugs (castlevania portrait of ruin crashing was caused by a bug in the code), granted this is for the GBA but http://www.dwedit.org/dwedit_board/viewtopic.php?id=480 being a nice example) much less a nice tight routine written in THUMB when the last was written in ARM or as mentioned in one of the posts above the binaries are not just opcodes and the things directly associated with them- the other week I pulled images, fonts and more out of the binary and other times we have found text in there but more interestingly there is usually a bunch of error messages associated with wifi sitting in there somewhere (nobody ever said overlays were perfect).

    Nothing stopping you from editing a few opcodes and then jumping when you need some more space either.

    You seem to be co-opting the ARM7 (a good bet as most are so similar between games you can simply replace it with ones from other games and have them work, indeed back when as the ARM7 changed you could even "fix" roms as you were waiting for flash carts to catch up) to overwrite part of the ARM9 binary at runtime which in theory works well enough but in light of the other two methods it comes off as really very long winded. I guess it is quite nice if you want to dodge compression issues (the binaries can be compressed for storage in the rom but will almost invariably be decompressed at runtime) but the binary compression is well known/documented (it is a tweak on the standard LZ type compression used everywhere on the DS)- crystaltile2 and http://code.google.com/p/dsdecmp/ being just two of the tools able to handle compression and decompression).

    Do keep us informed of how things are going- most people stumble when it comes to assembly on things you seem to have fairly well understood already (the ARM/THUMB switching stuff) or get scared at the prospect of having to manually handle memory.
     
  16. rastsan

    Member rastsan 8 baller, Death Wizard

    Joined:
    May 28, 2008
    Messages:
    962
    Location:
    toronto
    Country:
    Canada
    while I was trying to do this and one of the reasons I stopped trying to do this, was that there were just too many errors. I mentioned this earlier (in pm), I am sure 7th dragon uses the r14 (register). there were a number of in game gltiches (errors) related to this register that I needed to go back and fix...

    Several times as you would talk to people in certain towns in emulation and in on flashcarts it would crash. Mainly due to having items or producing items that technically you shouldn't have yet and being someplace that isn't technically unlocked yet. (this was without cheat codes). Also got to mention the screen close open issue which is directly related to the r14 register.
    I am not talking a few errors here a lot.
    IF I remember there are a few places you can safely do this but you are going to need to do the deadbeef method. I had to play for about an hour and a half before I had enough info for what was needed.

    my reason for dual tile encoding:
    Yes before you ask I have deleted almost all of the stuff on this that I had. When I decided to dual tile encode it I just deleted those files as I considered them un-needed and only kept a few screenshots (that I also deleted when I officially gave up on 7th dragon). As it really was easier in my mind to keep the keyboard for entering names and such with dual tile encoded pairs in it than to keep bothering with an asm hack that would also involve fixing the screen close open issue and about 25 other things that could wait until after the translation was done. After I spent more time narrowing down where they were. I even deleted that list... thats how frustrated I was with 7th dragon.


    I guess my priorities were different than there's... Its just that if it isn't broken why are you trying to fix it when you can just work around and with it...
     
  17. Normmatt

    Member Normmatt Former AKAIO Programmer

    Joined:
    Dec 14, 2004
    Messages:
    2,135
    Country:
    New Zealand
    It most safe to use the first 600 or so bytes of the arm9 binary which is generally full of garbage when its been decompressed. Use any decompressor on the extracted arm9 binary and you can safely hook the arm9 binary pretty much anywhere (if you do it correctly) and your code should be safe on most flashcarts if not all. Its how all the third party/dstt anti piracy fixes work by hooking the arm9 and storing their code in that first 600 or so bytes of the arm9 binary.
     
  18. matthewn4444
    OP

    Member matthewn4444 GBAtemp Regular

    Joined:
    Jun 21, 2007
    Messages:
    201
    Country:
    United States
    I'm using dsatm to add deadbeef padding but when resizing the arm7 for this game to 512kb, the game crashes. I know that it only has 4mb of memory so it can only read from 0x2000000 - 0x2400000 but it seems like adding more padding doesnt do anything (or am I missing understanding this).
     

Share This Page