Save restoreation with 8F
Posted by: likebeingawesome
Date: 2017-06-27 20:12:11
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.
Where'd you hear that? The most they can do is ban you from online services. As long as you do it right, they don't even fucking know you did it.
sense Nintendo will destroy it if I hack
Lemonade x28 (hex:1C)
Poké Ball x6 (hex:06)
Parlyz Heal x205 (hex:CD)
TM17 x53 (hex:35)
Fresh Water x62 (hex:3E)
Moon Stone x234 (hex:EA)
Great Ball x1 (hex:01)
Lemonade x2 (hex:02)
Soda Pop x234 (hex:EA)
Antidote x64 (hex:40)
Carbos x165 (hex:A5)
X Accuracy x152 (hex:98)
Awakening x139 (hex:8B)
TM05 x58 (hex:3A)
TM13 x[Any qty]
Max Potion x71 (hex:47)
TM13 x213 (hex:D5)
Lemonade x123 (hex:7B)
TM45 x209 (hex:D1)
Repel x159 (hex:9F)
Soda Pop x213 (hex:D5)
TM01 x234 (hex:EA)
HP Up x181 (hex:B5)
Poké Ball x195 (hex:C3)
Master Ball x1 (hex:01)
Commented source code :
@ 1:D321 :
ld a, $1C
inc b ; Padding
ld b, $0F ; Carried over to the ROP chain
call $35D9 ; BankswitchHome
inc a ; Padding
ld a, $0A
ld [$0103], a ; Enable SRAM
ld a, 2
dec a ; ld a, 1
ld [$400B], a ; Switch to bank 1
ld h, $A5
ld l, $98
ld c, $8B
call $D53A ; Jump to part 2 (it never returns)
@ 1:D53A :
ld de, $D53A ; Part 3
push de
ld a, $7B
push af
pop de ; ld d, $7B , backwardest-way (c)ISSOtm 2017 :D
ld e, $9F ; de points to checksum function
dec a ; Padding
push de
ret ; Enable ROP chain
ld [$B523], a ; sMainDataCheckSum
inc b ; Padding
jp $0101 ; Jump to game init to avoid losing SRAM
Tech explanation :
1. We switch to ROM bank $1C because that's where all save functions are stuffed
2. We open SRAM for writing
3. We switch to SRAM bank 1
4. We set the parameters for the later checksumming
5. We *call* the second part, without a RET (you'll see why)
Obviously both bytes of each parameter won't compile as valid items so I'm going at it the most backwards way possible (notice how b is set at the beginning of the whole thing...)
6. The checksum function's address is a b***h, and hl is locked-up, so we HAVE to use a ROP chain. Yay. Starting by pushing Part 3's address
7. We can't change anything but a and d, and we must load it when both `ld d, XX` and `$7B` compile to invalid items :/
Thus, GVHFWDéfFZ (to sum up)
8. We "return" to the checksum function, correct parameters and all, then to Part 3.
9. We set the stored checksum to match the calculated sum, thus "uncorrupting" the file
10. We'd have to close SRAM, switch to the correct ROM bank and let the user reset the game. However that'd be fairly heavy, and you're aware that users are stupid, so they will power cycle their console and lose data. We address both issues by resetting ourselves
(Note : 0100 is a NOP, so 0101 does reset the game. Plus it avoids that nasty 00 byte.)
I just came up with a setup that does the job. Probably the most bloated I ever created, and definitely not worth it.
But I tested it, and it works !
Surely a genius will come after me and squeeze it. But for now…
In your bag, starting from item #3 :
Lemonade x28 (hex:1C)
Poké Ball x6 (hex:06)
Parlyz Heal x205 (hex:CD)
TM17 x53 (hex:35)
Fresh Water x62 (hex:3E)
Moon Stone x234 (hex:EA)
Great Ball x1 (hex:01)
Lemonade x2 (hex:02)
Soda Pop x234 (hex:EA)
Antidote x64 (hex:40)
Carbos x165 (hex:A5)
X Accuracy x152 (hex:98)
Awakening x139 (hex:8B)
TM05 x58 (hex:3A)
TM13 x[Any qty]
In your item PC :
Max Potion x71 (hex:47)
TM13 x213 (hex:D5)
Lemonade x123 (hex:7B)
TM45 x209 (hex:D1)
Repel x159 (hex:9F)
Soda Pop x213 (hex:D5)
TM01 x234 (hex:EA)
HP Up x181 (hex:B5)
Poké Ball x195 (hex:C3)
Master Ball x1 (hex:01)
Once you're set up, use ws m and the game will reset with glitched palettes (unless your save file is *exactly* right, but whatever). Until you loaded your save, DON'T SHUT THE CONSOLE DOWN THE SLIGHTEST BIT. You might lose save data !!
Now, your save file will be uncorrupted :D So load it ! What are you waiting for ?
(You don't need to save after it's uncorrupted, but you can :)
Commented source code :
@ 1:D321 :
ld a, $1C
inc b ; Padding
ld b, $0F ; Carried over to the ROP chain
call $35D9 ; BankswitchHome
inc a ; Padding
ld a, $0A
ld [$0103], a ; Enable SRAM
ld a, 2
dec a ; ld a, 1
ld [$400B], a ; Switch to bank 1
ld h, $A5
ld l, $98
ld c, $8B
call $D53A ; Jump to part 2 (it never returns)
@ 1:D53A :
ld de, $D53A ; Part 3
push de
ld a, $7B
push af
pop de ; ld d, $7B , backwardest-way (c)ISSOtm 2017 :D
ld e, $9F ; de points to checksum function
dec a ; Padding
push de
ret ; Enable ROP chain
ld [$B523], a ; sMainDataCheckSum
inc b ; Padding
jp $0101 ; Jump to game init to avoid losing SRAM
Tech explanation :
1. We switch to ROM bank $1C because that's where all save functions are stuffed
2. We open SRAM for writing
3. We switch to SRAM bank 1
4. We set the parameters for the later checksumming
5. We *call* the second part, without a RET (you'll see why)
Obviously both bytes of each parameter won't compile as valid items so I'm going at it the most backwards way possible (notice how b is set at the beginning of the whole thing...)
6. The checksum function's address is a b***h, and hl is locked-up, so we HAVE to use a ROP chain. Yay. Starting by pushing Part 3's address
7. We can't change anything but a and d, and we must load it when both `ld d, XX` and `$7B` compile to invalid items :/
Thus, GVHFWDéfFZ (to sum up)
8. We "return" to the checksum function, correct parameters and all, then to Part 3.
9. We set the stored checksum to match the calculated sum, thus "uncorrupting" the file
10. We'd have to close SRAM, switch to the correct ROM bank and let the user reset the game. However that'd be fairly heavy, and you're aware that users are stupid, so they will power cycle their console and lose data. We address both issues by resetting ourselves
(Note : 0100 is a NOP, so 0101 does reset the game. Plus it avoids that nasty 00 byte.)