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.

Video Games Discussion

The CartSwap ACE - Using Pokémon to ACE / credits warp other games - Page 1

The CartSwap ACE - Using Pokémon to ACE / credits warp other games

Posted by: ISSOtm
Date: 2016-12-02 15:22:15
[size=18pt]The CartSwap ACE[/size]
This is a Proof of Concept (or PoC) that we can use Pokémon Red, Blue and Yellow to manipulate other games.

The principle is extremely simple :


This PoC limits itself to rebooting the cartridge, but a more useful application would be modifying save files, stuff like that. This exploit just proves this is possible.


[size=18pt]How to do this ?[/size]
First, you'll need Pokémon Red, Blue or Yellow, and a Game Boy Color. I insist on GBC, because it won't work on any GBA model.
It may or may not work on black&white GBs, but nobody tested it yet.
For obvious reasons, this cannot be done on emulators.

Once you are running R/B/Y on your GBC, you need to acquire 8F/ws m arbitrary code execution. Visit our wiki article.
That is, obtain the item, and set up the bootstrap accordingly.

Then, you need to setup your inventory exactly like this, starting from the first item :

(V  Warning, these panels scroll  V)

8F / ws m
Any item x[any qty]
Ice Heal x243
Protein x99
Antidote x106
Awakening x240
Escape Rope x27
Poké Ball x122
Great Ball x179
TM06 x255
Super Repel x247
Fresh Water x4
Burn Heal x177
Fire Stone x241
Lemonade x1
TM33 x[whatever]
[the rest of the item pack doesn't matter]


Here is a method to get all of this :

(For newbies, "MissingNo-duplicate" means "encounter or capture MissingNo with the item you wish to duplicate in the sixth slot of your item pack")

I then recommend that you save. You're going to pull your cartridge out, anyway, so it's a good idea to save this hard work :D
If your item pack doesn't match what is described above, I take no responsibility from what happens next, including crashes, corruptions and loss of save data. YOU HAVE BEEN WARNED.

Then use 8F / ws m. If the game just freezes, you probably got it right. If not, that's where you'll be happy you saved.
You now have like ten seconds to pull your Pokémon game out of the Game Boy and place another cartridge in.
Then the game in place now will start, but it will believe it is running on a black & white GB instead of a GBC. Yep.

That's what this exploit does : start a game without going through the "Game Boy" script, and thus you could, for example, edit your save file !


[size=18pt]Tech details[/size]
When pulling the cartridge out of the socket, the CPU doesn't hang, reset or anything. What happens is all reads from ROM return hex:FF.
Strangely, it appears that the GBC boot ROM may actually be ran again. I don't know why this doesn't work 100% of the time.

The thing is, Furrtek proved it was possible to remove the cartridge and have the CPU still run. (See TheZZAZZGlitch's post below).
As such, the idea was to prevent the CPU from running anything ROM while cartridges were being swapped.
This implied two things.
First, disabling interrupts. Because all reads from ROM return $FF, this would result in constant rst 38h, and as such, a stack overflow that would erase all RAM.
Second, running code from a memory location NOT in ROM nor SRAM.
We were left with VRAM, WRAM (and Echo RAM, but that's essentially the same :P), OAM and HRAM.
WRAM was the good candidate, since all ACE exploits ran code from WRAM.

We thus needed to disable interrupts, temporarily hang the CPU while in RAM, and resume once the cartridge was back in.
I first tried a code that first waited to read a $FF from ROM, then boot back up as it read no more $FF. It got a 12% success rate, probably from badly engaged pins.
Then TheZZAZZGlitch suggested a code that just waited for a set amount of time. After many mistakes, I finally made the code ! And here it is.


Here is the GBz80 assembly code that is actually ran by the exploit, very dirty and hackish, but what matters are the items :D

dec c ; padding
di
inc h ; padding
ld h, e ; $0122
dec bc ; padding
ld l, d ; hl = $0100
ld c, $F0 ; adjust this for delay : the more there are, the less you'll wait. 240 give ~12 seconds of delay.
dec e ; de = $0000

.delayCartReboot
dec de
inc b ; padding
ld a, d
inc bc ; padding ; won't affect C since this is run 256 times
or e ; a = $00 if and only if de = $0000. Also resets the C flag, so the next op will really be an "add".
adc a, $FF ; will overflow unless a = $00, ie de = $0000
jr c, delayCartReboot

inc a ; a becomes $00 (it was $FF)
inc b ; padding
inc c ; we need C to be zero
or c ; A = $00 at this point, so essentially this is "ld a, c" but this updates the Z flag
jr nz, delayCartReboot

ld a, $01
jp (hl)

This code is full of padding instructions, intended to make the code "viable" as items, because some values are represented by invalid items, or some we can't the quantity of.
They are intended to not trash sensible data (RAM and important registers) and not lock execution.

Step-by-step explanation :
First, we have the instruction that disables interrupts. It could have replaced the "inc b" instruction sandwiched between the "inc a" and "inc c" in the later part of the code, saving one slot, but this would be dangerous.
Then, I use the fact that, when this code starts, register DE's value is hex:0001. As such, I make H equal E ($00) and L equal D ($01), that gives HL = $0100, the memory address the Game Boy boot ROM jumps to when it gives control to the game. We will preserve this value during the whole process as to make the final jump a simple "jp (hl)".
We then decrement E to make DE equal $0000, the value required for all entries in the following loop.

We then enter the two intricate loops, marked each by their jr instruction.
The inside one simply decrements DE, and ends when the bitwise OR of D and E plus $FF doesn't trigger overflow.
This only happens when D OR E = 0, ie when D = E = 0, ie when DE = $0000. Tests gave that these 65536 cycles (due to overflow) took roughly a tenth of a second.
This complicated pattern of recognizing D = E = 0 was done because circumstances restricted us to only the NZ, Z and C conditions of the JR instruction, and NZ was needed by both. So we figured this setup could translate a NZ into a C !
Note that even though the C register is very precious, it is modified through every iteration by the "inc bc". Yet, it is incremented 65536 = 256 * 256 times… so, the value before entry and after exit will be the same.

The extern loop increments C (which was trashed so much it was preserved :P), and returns when it is 0. As such, the higher C is set in the preamble, the less this extern loop re-loops. And there you go !

Then, the last two instructions. The jp (hl) jumps to $0100 (preserved from the preamble), performing the "reboot", while A is set to 1 The reason for this is that games functioning for both GB and GBC use the value of register A to determine the console they are being played on. $11 indicates GBC, and usually all other value are treated as B&W GB. (The GB ouputs a $1, which was also convenient, so I chose 1).
Because Pokémon R/B make the GBC boot in "B&W compatibility", we need games to boot as if on a GB.




[size=18pt]Original post[/size]

I was browsing Twitter, and then I found this. https://www.youtube.com/watch?v=xayxmTLljr8

Now, I'm wondering : what if we ran a 8F payload that did this :
1. Disable ALL interrupts
2. Loop forever until something occurs (button press, I think)
3. Do some more stuff (enabling interrupts and whatnot :P)
And then, during step 2, we pulled off the Pokémon R/B/Y cartridge and plugged some other cart inside ?

I don't see why the console would crash, no I/O seems to R/W/J/X from ROM… soooo it just might be possible to transfer ACE's between games ! That'd be hella sweet.
But I don't know if there isn't a protection that freezes the CPU when the cartridge is removed ! That's the deal.

Ideas :
1. If it works, we'd just need to make two payloads and transfer one to a part of memory where it won't be overwritten… but first we need to know if this can theoretically work.
2. If the console stops, enable the Joypad interrupt ONLY, then run a STOP and trigger the interrupt once cartridges have been stop'n'swop'd. Since the Joypad interrupt points to a reti in R/B(/Y?), this should be fine.

8F setup that might work :

8F
Item x[qty]
TM43 x4
Escape Rope x29
Repel x15
Lemonade x16
Hyper Potion x118
[More stuff]

Registers on startup :
af = 6300 [a=63, f=00]
bc = 22B8 [b=22, c=B8]
de= 0001 [d=00, e=01]
hl= D322 [h=D3, l=22]
All flags reset

di ; prevent bad code from being executed. Interrupts will stack requests in FFFF, but meh.
inc b ; filler
dec e ; de = $0000
dec de ; de = $FFFF
ld e, $0F ; de = $FF0F
ld a, $10
ld (de), a
halt
; return to game code, perform ACE, write something to VRAM ?

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: TheZZAZZGlitch
Date: 2016-12-03 05:07:48
Through some random Google searches I discovered this video. It showcases that the CPU still runs after swapping the cartridge, provided that the instruction pointer isn't in ROM. There's also a comment from a person who claims they were able to do this successfully by executing code from RAM.
So indeed, "bringing" ACE to other games should be possible.
I'd imagine something like this would work:

Copy the code to RAM and jump there (this step is unnecessary if we're using an 8F script, since ACE causes the code to run from RAM anyways)
Disable all interrupts (interrupt handlers are in ROM)
Give the user a chance to swap the cartridge. We could have a mechanism that reacts on button presses and so on, but the simplest, most compact way to do it would be having a very long loop that delays the execution, giving the user a few seconds to do the swapping
Now we're executing code in the context of the newly inserted cartridge. We can do whatever we want at this point, then jump to $0100 to run the game!

There are some problems with this. Most importantly, because the cart isn't actually running when we're executing our code, we can't really influence the game's state.
We can't just modify RAM, since the game will most likely initialize variables with its own values after starting. There are some ways we could avoid this:

Just edit the SRAM. We can wreak some havoc with that too. My first Gen III HoF warp exploit only used SRAM writes to do its job, for the same reason as we have here (both the game and its state are completely trashed long before the code is executed)
Exploit some game-specific quirks in RAM initialization. Gen I Pokemon games like to completely zero out WRAM during initialization, but a lot of games didn't bother to do that (like Magi-Nation). There is a chance that some code in the game uses this uninitialized data. For example, the NES classic Super Mario Bros has a Continue option that will happily read from unitialized data, which makes this glitch possible.
Don't make the game run its RAM initialization. For Pokemon games, jumping in the middle of the Init subroutine just after the RAM initialization code should do the trick. Or even better, don't let the game decide how it should be initialized. Do the initialization exactly how you want it, set up all RAM values you want, set up registers and resume the game in its running state (for Pokemon this would be in the overworld loop) - in other words, implement savestates in real hardware.
If the game does at least a part of its initialization with interrupts enabled, and prepares its RAM before it initializes DMA, we can try another trick: before launching the game, set a custom DMA handler that sets some RAM address to a given value and enable interrupts. There's a good chance that the DMA handler will be called before it gets overwritten by init code, but after the RAM initialization code is executed, giving us a persistent RAM change.

Once we're able to do any of these things, chances are we have already won. Many games don't expect invalid values in their internal variables, so most likely we can trigger a different ACE bug in a more convenient place and do all of the wonderful things.

In other words, by having a special Pokemon cartridge we could potentially ACE any game we want (or at least dump/write save files to it). But I still need confirmation whether or not this will happen on all consoles (GB, GBC, SGB). The 'completely legit random video I found on the internetz' suggests that it works at least for GBC.

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-03 13:35:08
[size=18pt]DISCLAIMER[/size]
This "exploit" uses obscure and heavily unintended hardware behavior. NEVER deviate from any instruction given here, otherwise you could corrupt your save data from either cartridge, corrupt the program from either cartridge, or damage your Game Boy.
If you didn't follow the steps listed here and something went wrong, don't complain.
If you did but something went wrong, or you think you found out something new/interesting, post something about it. We love that. Also, we are active on this forum, and do our best to answer quickly.

Also please, read the first three sections before doing anything. You'll be at risk to miss some info or additional features (yep there are).

Now, please enjoy your stay.




[size=18pt]Proof Of Concept "Game Re-boot" 8F Setup & Method[/size]
Here is a setup based on a mix of TheZZAZZGlitch's ideas and my previous post.

This is a PoC item pack setup that should be used like so :
1. Plug Pokémon R/B in a GBC
2. Run 8F setup
3. Remove cartridge. Nothing should happen.
4. Plug any other cartridge. It should boot right away !

Here is the 8F setup, starting from the first item in the inventory pack. WARNING ! This setup relies on the value of register DE. See comment below.
Quantities noted in parentheses are ways to obtain those required ; a "+ 128" means "duplicate using MissingNo", a "- XX" means "toss XX of it".

8F
Item x[qty]
TM43 x99
Antidote x106 (= 1 + 128 - 23)
Escape Rope x26
Soda Pop x60
Fire Stone x251 (= 1 + 128 - 6 + 128)
Poké Ball x26
Fresh Water x61
Rare Candy x251
Lemonade x17
TM33 x[any qty] / Great Ball x233 (= 1 + 128 - 24 + 128)
; Nope, this is not TM33 ACE, guys.





[size=18pt]Things to note[/size]





[size=18pt]Value of A / Number of Lemonades : Changing Consoles[/size]
This will let you change the "model" of Game Boy you will be using, provided the game you use cares.
An example of this is Pokémon Gold, Silver and Crystal, which behave differently on GBs and GBC/As.

Here are the values the register A usually holds when the GBx leaves control to the game :
$01  SGB or Normal Gameboy (DMG)
$FF  SGB2 or Pocket Gameboy
$11  CGB or GBA

However, some games (such as Shantae and, apparently, Zelda Oracle of Ages/Seasons, see ROM0:0158 for "bit 0, b" or this disassembly) differentiate GBC and GBA by checking Bit 0 (parity) of the B register.
This bit is cleared by the GBC boot ROM, whereas the GBA sets it.
The above setup leaves this bit undefined. (Technical details below)
What you can do to force either GBC or GBA is :



[size=14pt]Effects of "faking" a console[/size]
This has yet to be tested, since Pokémon Red and Blue make GBCs boot into "DMG (grey GB) mode", which removes GBC features. Effects will differ with Pokémon Yellow, which has GBC compatibility (check ROM0:0143, where $00 means "No GBC", $80 means "Maybe GBC", and $C0 means "GBC only")

When a game detects GBA, it usually applies different color palettes to compensate for a skewed color mixing (red tones are different on GBC and GBA).
Sometimes exclusive content is sometimes unlocked ; for example, Shantae gives you the Tinkerbat form only if you are playing on a GBA (Source)


[size=14pt]Undefined B[/size]
The problem is that 8F setups usually modify B, and as such, B's value upon starting the new game will depend on the setup, but only on the setup.

So, B's value is undefined, yet consistent : it will be that same every time you run the script.
The Bicycle x1 sets B to 1, which has bit 0 set ; the Burn / Ice Heals x4 increment B, setting it to 2, which has bit 0 clear (whereas x5 decrements it, still clearing bit 0)




[size=18pt]GBz80 code[/size]
When this code begins, register DE should equal $0001. If a setup is used that modifies DE… this won't work. The current 5- and 6-Pokémon setups work fine.

; We NEED to disable interrupts because they run from ROM.
; Servicing an interrupt before the cartridge is pulled will result in ROM being executed (and that's exactly what we're trying to avoid)
; Servicing an interrupt after the cartridge is pulled will result in execution NOP-sliding into VRAM. And we [i]definitely[/i] don't want that.
di

; It is a pain to execute any "jp $xxxx" because of the three consecutive bytes and uncooperative item translations, so we will do a "jp (hl)" instead.
; As such, we need to set hl up.
; This one setup is smaller than one padding instruction, then loading a value into H and another into L, then modifying DE,
; *probably* saving one item slot.
ld h, e ; hl = $0122
dec bc ; Padding byte (harmless)
ld l, d ; hl = $0100, where the GB leaves execution after startup (usually a NOP followed by a JP to the game's bootstrap)
dec e ; de = $0000, which will be our "reference byte" address, which we will constantly poll to

; Now, we need to wait until a new cartridge is inserted.
; To do so, we first read the byte at ($0000), which is $FF in Pokémon Red/Blue.
; We will simply wait until it's not the case anymore.
.waitCartRemoved
ld a,(de)
dec a
inc a ; don't modify A, but update the Z flag
jr nz, waitCartRemoved (@-4, @+$FC)

inc b ; Padding byte

; Assuming all reads from ROM
.waitCartInserted
ld a,(de)
inc a
dec a
jr z, waitCardInserted

ld a, $11 ; games use this value to identify GBC (see G/S/C Glitch Dimension)

( dec bc ) ; if Great Ball
jp (hl) ; We jump to the memory location the GB gives control to at startup

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: Yeniaul
Date: 2016-12-03 13:51:48
NEVER deviate from any instruction given here, otherwise you could corrupt your save data from either cartridge, [size=18pt]corrupt the program from either cartridge[/size], or damage your Game Boy.

What does ROM stand for again?

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-03 14:00:39
Read-Only Memory. But plugging cartridges in and out may damage components such as the MBC (the component responsible for switching ROM banks) or the ROM chip. I grouped that under "corrupt cartridge program" for simplicity.

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: Yeniaul
Date: 2016-12-03 15:42:45

Read-Only Memory. But plugging cartridges in and out may damage components such as the MBC (the component responsible for switching ROM banks) or the ROM chip. I grouped that under "corrupt cartridge program" for simplicity.

If anything the MBC and the pins are the only vulnerable parts of the cart (although a surge to ROM might be possible…)

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-03 16:27:55


Read-Only Memory. But plugging cartridges in and out may damage components such as the MBC (the component responsible for switching ROM banks) or the ROM chip. I grouped that under "corrupt cartridge program" for simplicity.

If anything the MBC and the pins are the only vulnerable parts of the cart (although a surge to ROM might be possible…)

I was thinking about the surge, at least on DMGs, where the GND pin is as large as the others (and be disconnected before alimentation), but more to the MBC than to the ROM (although unlikely it's still possible)

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-07 09:58:55
Okay, for two reasons the previous setup did NOT work. So here is the FINAL setup that will work.
I thus deleted the previous message.

8F
Does not x[matter at all]
Ice Heal x243
Protein x99
Antidote x106
Awakening x240
Escape Rope x27
Poké Ball x122
Great Ball x179
TM06 x255
Super Repel x247
Fresh Water x4
Burn Heal x177
Fire Stone x241
Lemonade x1
TM33 x[nobody cares]


To get the items :


GBz80 assembly code, very dirty and hackish, but what matters are the items :D

dec c ; padding
di
inc h ; padding
ld h, e ; $0122
dec bc ; padding
ld l, d ; hl = $0100
ld c, $F0 ; adjust this for delay : the more there are, the less you'll wait. 240 give ~12 seconds of delay.
dec e ; de = $0000

.delayCartReboot
dec de
inc b ; padding
ld a, d
inc bc ; padding ; won't affect C since this is run 256 times
or e ; a = $00 if and only if de = $0000. Also resets the C flag, so the next op will really be an "add".
adc a, $FF ; will overflow unless a = $00, ie de = $0000
jr c, delayCartReboot

inc a ; a becomes $00 (it was $FF)
inc b ; padding
inc c ; we need C to be zero
or c ; A = $00 at this point, so essentially this is "ld a, c" but this updates the Z flag
jr nz, delayCartReboot

ld a, $01
jp (hl)


This has been tested on BGB, and has yet to be confirmed to work on GBC.
Also, I got a Pocket GB to try out with.

I don't have a DMG and probably won't in the near future, so I ask anyone that has a GB if they can try this. Thanks !

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: Cryo
Date: 2016-12-09 14:30:09
I just tried this setup on my CGB, but it crashed and burned.

Looking at the items again, shouldn't TM07 ([font=courier]CF = rst 08h; FF = rst 38h[/font]) be HM03 ([font=courier]C6 FF = add a,$FF[/font])?

After testing out the change from TM07 to HM03 on a physical CGB, the game softlocked as if it'd gone into STOP mode. It didn't annihilate the graphics though, so at least that's something! :P

Re: Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-10 05:15:32
Yeah, I messed up somewhere while "compiling" the instructions into items.
We need to turn this TM07 into a TM06, that'd make an "adc a, $FF" thingy.
Sadly you need to have defeated Koga and kept the TM, so I'm trying to make a substitution.

I didn't mention something about this setup : it does freeze the console… only for a while. I does some decrementations while running code in RAM.
And when it waited long enough by doing absolutely nothing (gotta call this the "Luigi Exploit"), then it runs the cart again.

However, this will depend on how many Awakenings you have.
With 99 Awakenings on BGB, it froze for like two minutes. So that's why your game did this :P

I need to fix the setup, but thanks for testing ! I have done a few nervous breakdowns this week and couldn't test that myself è_é

Edited the previous message. It SHOULD work, but I left my console out of reach for the week-end.

Re: The Luigi Exploit - Could Pokémon be used to ACE / credits warp other games ?

Posted by: Stackout
Date: 2016-12-11 08:27:50

If you don't know about "Luigi wins by doing absolutely nothing", then check this out.


You screwed up your link, I think you meant this.

Re: The Luigi Exploit - Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-11 08:44:42
Thanks, I edited it.

Now I'm wondering about uses for this thing.

Re: The Luigi Exploit - Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-12 10:17:00
I think some god hates me.

After I successfully performed the exploit yesterday, a result of several weeks of failures, long Skype discussions and heavy debugging, I went to bed - it was late, and I had to work for the physics test that happened today. (I fared better than usual, even though that's completely off-topic.) This morning, I tried again - with success. I was quite happy and relieved. I planned to record some footage in the afternoon, when I would have time to.

Now, as of December the 12th 2016, I have to officially declare the SRAM battery of my Pokémon Red cartridge deceased at 12:54am today.


I think some god hates me.

Re: The Luigi Exploit - Could Pokémon be used to ACE / credits warp other games ?

Posted by: Yeniaul
Date: 2016-12-12 10:40:28
SRAM batteries are easily replaced with the proper screwdriver, a spudger or knife, a soldering iron and a CR2032, and hotglue, in that order. I've even had this process save my data… somehow.

Re: The Luigi Exploit - Could Pokémon be used to ACE / credits warp other games ?

Posted by: ISSOtm
Date: 2016-12-12 11:14:07
I don't have the
courage/patience/resources/will to buy them
to do that. I'll make my Everdrive GB useful (and for once I'll use it legally ! o/)