Glitch City Laboratories Archives

Glitch City Laboratories closed on 1 September 2020 (announcement). This is an archived copy of a thread from Glitch City Laboratories Forums.

You can join Glitch City Research Institute to ask questions or discuss current developments.

You may also download the archive of this forum in .tar.gz, .sql.gz, or .sqlite.gz formats.

Arbitrary Code Execution Discussion

Using 8F to ACE other games - Page 1

Using 8F to ACE other games

Posted by: ISSOtm
Date: 2017-02-11 10:52:57
This is a method to perform ACE on each game frame - provided it uses OAM DMA. I guess all games use it, so, yeah.
It also has the bonus of being cartswap-friendly.
Need no more to be convinced ? Then here is the thing !


This works only on Pokémon Red or Blue.
You need to place the following hex data at the following locations.
Use your favorite emulator's (or BGB if you intend to do cartswap) memory viewer to do that.
Alternatively, you can use an in-game memory editor such as offgao's (see this thread)
Also, make sure all data at FF80 is not executed until it is complete. It's very sensitive data executed on each frame, and you don't wanna crash.
One way to do it is to write a $C9 at $FF80 first, and write the $CD last.

These two pieces of data don't persist after saving and resetting.

At DF00 : (WRITE FIRST !!)
3E76EA65D32146FF3EC3C9

At FF80 : (MAKE SURE YOU HAVE WRITTEN DF00 BEFORE THIS !!)
CD00DF77


Once both pieces of code are in place, go into any house, exit it and o surprise, Hall of Fame !
Tech details are below.


If you want to try the cartswap-based funky badass-showoff version (Pokémon Blue "cartswap wrong warp%"), then set up DF00 and FF80 as above, and then this.

At D163 :
06B0242E22182DFFB00015000014142D0A2D0000B1A00000CD002C00300041002B0032F8E423280000060015000D000B000E000B2400E9

At D31D :
045D010163C33BD501FF

At D53A :
1A21541F110BDF014900CDB5003E10E0FF07E0003DEA36DFEA57DF3E8AEA43DF3EC3EA55DF3EA1EA56DF76003E01E0FF7600C30BDFFF

Now, open your bag (surprise, there's 8F in there), use 8F. The game will then freeze, so use "Load ROM without reset" on BGB and load Pokémon Blue (or Red, works fine too).
Press any direction on the D-Pad, and the game will start. You can then choose to start a new game, and you will soon find out your house leads directly to the Hall of Fame ! Nice.


I attached a BGB save state to be tried on Pokémon Red that has all set up. This was hex edited, but is doable legitimately. You just have to load it in BGB, then use the above method or just close the menus and walk out of your house.





[size=14pt]Tech stuff[/size]
On each LCD frame, the game has to run a small routine in RAM to transfer sprites from a temporary buffer to the location the GB uses. However, we hijack this routine to run custom code.
The trick is simple : hijack usual code flow, run our code, and make sure everything else goes as intended.

At $FF80 is this code :

ld a, $C3
ldh [$FF46], a

which we overwrite with

call $DF00
ld [hl], a


Pokémon R/B/Y allocate $DF00 to $DFFF to be stack space. However, during usual play, I never experienced the game using more than ~100 bytes at once. This leaves us with more than 128 bytes for code storage !

ld a, $76 ; Hall of Fame map ID
ld [$D365], a ; Door mats exit
ld hl, $FF46 ; OAM DMA
ld a, $C3
ret

This code essentially sets all door mats exits to warp Red to the Hall of Fame. Pretty neato, huh ?
This is a half gameshark emulator, because it can't set a value mid-frame. However, it is cartswap-friendly, using for example the following setup :


The data at $D163 and $D31D set up 8F properly, I'll just skip explaining them.

The code at $D53B is a bigger deal.

PartialInit:: ; $D53B
  ld hl, Init
; Real init function. We copy it to RAM for patching.
  ld de, $DF0B
; Routine copy location.
  ld bc, $0049
; How large the target code is : 73 bytes !
; We will append a jump to end it later.
  call CopyData
  ld a, $10
  ldh [$FFFF], a
; Only enable joypad interrupt.
; It should pop instantly, but it doesn't crash, phew !
  rlca
; a = $20
  ldh [$FF00], a
; Select Dpad
  dec a
; a = $1F
; Patch WRAM clear size to not clear $DF00 onwards.
  ld [$DF0B+$2B], a
; Write part of the "return" address.
  ld [$DF0B+$3F], a
  ld a, $8A
; Patch HRAM clear code to not clear patched DMA code.
  ld [$DF0B+$38], a
; It will clear past HRAM, but no problem.
  ld a, $C3
; JP instruction.
  ld [$DF0B+$3D], a
  ld a, $A1
  ld [$DF0B+$3E], a
; Patch DMA writing with returning to ROM code.
  jp $DF0B
; Jump to patched init. Cartswap is complete.

Re: Using 8F to ACE other games

Posted by: MarcinTVP8
Date: 2017-02-11 14:27:28
Sorry, but I don't see an attachment attached here.

Re: Using 8F to ACE other games

Posted by: ISSOtm
Date: 2017-02-11 15:29:46
That's because there were none :D
Now there is one. Thanks for correcting stupid me.