Fools2021 notes
Chall3
Hex of the map:
0xD880
00000000000000000000000000000000 D880
0000000000000b0b0b740a0000000000 D890
00000000000000000000000000000f0b D8A0
0f0a0a00000000000000000000000000 D8B0
0000000000000f0f0a0a0b0000000000 D8C0
00000000000000000000000000000f0b D8D0
0a0a0a00000000000000000000000000 D8E0
0000000000000b0b0a0a740000000000 D8F0
00000000000000000000000000000000
0000000000000b0b0b740a0000000000
00000000000000000000000000000f0b
0f0a0a00000000000000000000000000
0000000000000f0f0a0a0b0000000000
00000000000000000000000000000f0b
0a0a0a00000000000000000000000000
0000000000000b0b0a0a740000000000
Possible tiles:
0a ground tyle
0b grass
0f trees
32 2 tree & poke upright
33 2 tree & poke bottomright
34 2 tree & poke upleft
60 2 tree & poke downleft
6c tree up & ground down
6d tree left & ground right
6e tree right & ground left
6f tree down & ground up
74 animated flowers
7a fixed flowers
Byte sequences:
0b0b0b740a
0f0b0f0a0a
0f0f0a0a0b
0f0b0a0a0a
0b0b0a0a74
bruteforce payload:
db 0b0b0b740a ;D3D0
db 0f0b0f0a0a ;D3D8
db 0f0f0a0a0b ;D3E0
db 0f0b0a0a0a ;D3E8
db 0b0b0a0a74 ;D3F0
D3F0 db firstExec
D3F1 db seed3
D3F2 db seed2
D3F3 db seed1
D3F3 db seed0
genNewKey: ;D400
ld a, 10
add a, (hl)
ldd (hl), a
ret nc
inc (hl)
ret nz
dec hl
inc (hl)
ret nz
dec hl
inc (hl)
ret
BruteForcer: ;D410
push af
push bc
push de
push hl
.start: ;D414
ld hl, DABB
push hl
call D400 ; genNewKey ;gen new key. REMEMBER TO SET THE LSB TO 1
.resetKeyBuffer ;D41B
pop hl
xor a ;resets the other buffer
inc hl
ldi (hl), a
ldi (hl), a
ldi (hl), a
ld (hl), a
.resetMapBuffer ;D422
ld hl, fls21_currentMap ;clears the map buffer
ld bc, 0240
ld d, 54
.resetLoop ;D42A
ld (hl), d
inc hl
dec bc
ld a, c
or b
jr nz, D42a :resetLoop
.resetChecknum ;D431
ld hl, fls21_currentChunkLOW ;reset chunkNum
xor a ;nop
ld b, a ;nop
inc a
ldi (hl), a
inc a
ld (hl), b
inc hl
ldi (hl), a
ld (hl), b
.genMapCall: ;D43D
call fls21Func_genMap
.startCheck ;D440
ld hl, D3D0
ld de, D890
ld c, 5 ;sequence equal
ld b, 5 ;charsEqual
push hl
.checkLoop: ;D44B
ld a, (de)
push af
inc de
ld a, e
and a
jr z, D46F; doneCheckLoop
pop af
cp (hl)
jr nz, D469;.wrongCheckLoop
dec c
jr nz, d466;.notDoneCheckLoop:
.doneWord: ;D459
pop hl
ld c, 5
ld a, 8
add a, l
ld l, a
push hl
dec b
jr z, d473; .win
jr D44B;checkLoop ;DONE
.notDoneCheckLoop: ;d466
inc hl
jr D44B; checkLoop
.wrongCheckLoop: D469;
ld c, 5
pop hl
push hl
jr D44B; checkLoop
.doneCheckLoop: ;D46F
pop af
pop hl
jr D414 ;start
.win: ;d473
pop hl
xor a
xor a
ei
.end:
pop hl
pop de
pop bc
pop af
ret
;0A vuoto
;0F alberi
;0B erba
;74 fiori
Symbol table
00:b700 ItemsPicked
00:d800 wOverworldMap
00:dab0 wCurrentBiome
00:dab3 wBattleScratch
00:dab4 wChunkX
00:dab6 wChunkY
00:dab8 wSeed
00:dac5 wInventoryPage
00:dac6 wInventorySelectedItem
00:dac9 wWildSpecies
00:daca wWildLevel
00:dacc wNextEncounterLevelModifier
00:dacd wWildLevelModifier
00:dace wPikachuAttackModifier
00:dad2 wEnemyData
00:dad2 wEnemyPicID
00:dad3 wEncounterTextPtr
00:dad5 wEnemyNamePtr
00:dad7 wEnemyExpYield
00:dad8 wEnemyBaseHP
00:dad9 wEnemyBaseAttack
00:dada wEnemuItemDropChance
00:dadb wEnemyWildItem
00:dadf wPikachuMaxHealth
00:dae0 wPikachuCurrentHealth
00:dae1 wPikachuLevel
00:dae2 wPikachuExperienceLeft
00:dae4 wInventoryCount
00:dae5 wInventory
00:db35 wCurrentSong
00:db36 wSkipSandwichCounter
00:db37 wCurrentVWFEventText
00:db38 wProgressFlags
00:db39 wBossesBeaten
00:db63 LoadHLFromBank3
00:ff96 hCurrentItem
02:a002 InitGame
02:a087 CheckROMIntegrity
02:a142 PrintSeed
02:a23f PrintVWFText
02:a4f8 EchoRAMTest
02:a50b VRAMTest
02:a520 CheckAccuracy
02:a6e1 CheckItemPickup
02:a6f7 PickupItem
02:ab7f GenerateHash
02:ae03 LoadChunkCoords
02:ae76 SummoningChoiceMenu
02:af27 OpenStartMenu
02:af67 GenerateItem
02:afa0 DisplayInventory
02:bae2 DisplayFailedSummoningText
02:b4ec DropItem
02:bcac RunGame
02:bcfa EditSeedMenu
02:b882 ACETarget
02:b8b8 UseInventoryItem
02:b8f1 ItemEffectsTable
02:b917 PotionItemEffect
02:b967 IncreaseHPItemEffect
02:b9b1 NoUseItemEffect
02:b9c6 SkipSandwichItemEffect
02:b9de SummoningSaltItemEffect
02:bb12 TelltaleOrbItemEffect
02:bbfb CrystalItemEffect
02:bc13 DaredevilPotionItemEffect
02:bc40 BraveryPotionItemEffect
02:bc6d IncreaseAttackItemEffect
03:a420 EncountersTable
03:a480 WildMonsTable
Chall4
Writing primitives:
- seed (used in payload)
- items
- pikachu stats
- current and max HP
- attack (unreliable)
- level
- experience
- wild encounters
- species
- level
- item drops
- bosses
- player location
- player X and Y
- current chunk (used in payload)
- biome
- menus
- game options (not probable)
- joypad input
35E3: executes the item, HL points to the code that will be executed
AEC7: item menu input
A1A6: music pointer table (or something about maps)
AB63: hl = hl * 33 + a
A78D: wild encounter loop?
A7C1: wild encounter start
item 0x2D jumps to DAB3, which is fully writable
changing the biome to a glitch one can spawn glitch items
if current page > 9 i can execute glitch items in memory
There’s a possible overflow in wPikachuAttackModifier
Glitch pokemon can drop glitch items
Current plan:
- find a way to spawn glitch item 0x2D
- how does item tracking work? -> uses a bloom table, and it’s not exploitable
- is there any sequence break i can use?
- can i glitch wild encounters?
- is there any issue with the item menu function? -> probably not, it uses the generic menu engine
- maybe the telltale orb can be useful -> no, but there’s a cool easter egg
- check the code of all the other items too -> nothing useful found, maybe should be checked again?
- edit the required memory locations (ez)
- execute 0x2D
Pokemon map addresses:
- 0X: grasslands -> 03:A420
- 1X: steppes -> 03:A430
- 2X: construction -> 03:A450
- 3X: corruption -> 03:A450
Dump:
03:A420 02 04 02 05 02 06 03 04 | 03 05 04 05 04 06 04 04 |................|
03:A430 0e 06 0e 07 0f 06 0f 07 | 10 06 10 07 11 06 11 05 |................|
03:A440 01 06 01 07 01 06 12 06 | 12 07 14 06 14 07 13 06 |................|
03:A450 05 04 05 05 05 06 07 04 | 07 05 08 05 08 04 09 04 |................|
Pokémon table starting at 03:A480
Format: | PicID | Encounter text | Name | Exp | HP | Atk | Drop rate | Item drop |
Dump :
00000000 01 fb bc 24 bf 03 05 04 7f 0b a5 e3 bc 2b bf 03 |.û¼$¿.....¥ã¼+¿.|
00000010 07 03 07 01 24 e3 bc 33 bf 04 09 04 07 01 7c 23 |....$ã¼3¿.....|#|
00000020 bd 3a bf 02 08 01 0c 06 7f e3 bc 42 bf 06 0a 06 |½:¿......ã¼B¿...|
00000030 0c 04 1a 3d bd 4d bf 0a 0b 04 00 00 42 23 bd 55 |...=½M¿.....B#½U|
00000040 bf 04 07 07 0c 05 33 6f bd 5f bf 05 05 09 07 04 |¿.....3o½_¿.....|
00000050 7a 9f bd 66 bf 08 0a 02 e5 0a 5f d2 bd 6b bf 0e |z.½f¿...å._Ò½k¿.|
00000060 0a 05 ff 0e 53 00 be 71 bf 10 0a 06 ff 0f 28 2e |..ÿ.S.¾q¿...ÿ.(.|
00000070 be 7b bf 12 0b 06 ff 10 83 5d be 83 bf 19 0b 08 |¾{¿...ÿ..]¾.¿...|
00000080 00 00 a4 8a be 8a bf 06 07 07 0c 03 23 e3 bc 93 |..¤.¾.¿.....#ã¼.|
00000090 bf 05 06 05 19 11 3c e3 bc 9a bf 06 05 06 19 12 |¿.....<ã¼.¿.....|
000000a0 99 b0 be a1 bf 05 04 05 19 05 a7 e3 bc ab bf 06 |.°¾¡¿.....§ã¼«¿.|
000000b0 03 07 0a 07 84 db be b4 bf 07 08 03 05 04 6a fe |.....Û¾´¿.....jþ|
000000c0 be bc bf 06 05 06 07 02 aa e3 bc c3 bf c8 01 01 |¾¼¿.....ªã¼Ã¿È..|
000000d0 00 00 00 10 0f 14 09 0f 0e 00 13 15 10 05 12 3e |...............>|
000000e0 10 0f 14 09 0f 0e 00 08 19 10 05 12 3e 10 0f 14 |............>...|
000000f0 09 0f 0e 00 12 05 16 09 16 05 12 3e 13 05 05 04 |...........>....|
Formatted:
01 FB BC 24 BF 03 05 04 7F 0B # shydon
A5 E3 BC 2B BF 03 07 03 07 01 # rattata
24 E3 BC 33 BF 04 09 04 07 01 # pidgey
7C 23 BD 3A BF 02 08 01 0C 06 # metapod
7F E3 BC 42 BF 06 0A 06 0C 04 # glitchling
1A 3D BD 4D BF 0A 0B 04 00 00 # scyther
42 23 BD 55 BF 04 07 07 0C 05 # dragonite
33 6F BD 5F BF 05 05 09 07 04 # Magmar
7A 9F BD 66 BF 08 0A 02 E5 0A # TMZ4
5F D2 BD 6B BF 0E 0A 05 FF 0E # ?????
53 00 BE 71 BF 10 0A 06 FF 0F # Ninetales
28 2E BE 7B BF 12 0B 06 FF 10 # Chansey
83 5D BE 83 BF 19 0B 08 00 00 # Mewtwo
Item drop table starting at 03:A460
Dump:
00000000 01 01 07 07 07 08 08 06 |................|
00000008 02 02 03 07 0d 04 04 05 |................|
00000010 02 02 08 08 0c 0d 04 04 |................|
00000018 08 08 0a 0a 0a 0a 04 05 |................|
Item list:
b917 # potion
b917 # super potion
b917 # hyper potion
b9b1 # reviver seed
b967 # life seed
b967 # hardened scale
b9c6 # skip sandwich
b9de # summoning salt
bb12 # telltale orb
b9b1 # glitch shard
b9b1 # shyhorn
bc13 # daredevil potion
bc40 # bravery potion
bbfb # dark crystal
bbfb # amber crystal
bbfb # fluffy crystal
bc6d # sharp beak
bc6d # sharp horn 12
a621 # start of glitch items
01 FB BC 24 BF 03 05 04 7F 0B
A5 E3 BC 2B BF 03 07 03 07 01
24 E3 BC 33 BF 04 09 04 07 01
7C 23 BD 3A BF 02 08 01 0C 06
7F E3 BC 42 BF 06 0A 06 0C 04
1A 3D BD 4D BF 0A 0B 04 00 00
42 23 BD 55 BF 04 07 07 0C 05
33 6F BD 5F BF 05 05 09 07 04
7A 9F BD 66 BF 08 0A 02 E5 0A
5F D2 BD 6B BF 0E 0A 05 FF 0E
53 00 BE 71 BF 10 0A 06 FF 0F
28 2E BE 7B BF 12 0B 06 FF 10
83 5D BE 83 BF 19 0B 08 00 00
Usable tiles:
{'6F', '34', 'F1', '4F', 'FA', '6D', '08', '8E', '7A', '74', '88', 'D9', '60', 'FF', '04', '8D', '33', '31', '8F', '0B', 'EC', '00', '50', '0A', '11', 'CB', '32', 'C9', '0F', 'CA', '6C', '66D', '6E', 'DB', '7F', '93'}
00 nop <---
31 ld sp, d16 <---
33 inc sp <---
C9 ret <---
CA jp z, a16 <---
D9 reti <---
F1 pop af <---
04 inc b
08 ld (a16), sp
0A ld a, (bc)
0B dec bc
0F rrca
11 ld DE, d16
13
32 ldd (hl), a
34 inc (hl)
4E
4D
4F ld c, a
50 ld d, b
51
52
55
60 ld h, b
6C ld l, h
6E ld l, (hl)
6D ld l, l
6F ld l, a
74 ld (hl), h
7A ld a, d
7B
88 adc a, b
8E adc a, (hl)
8D adc a, l
8F adc a, a
93 sub e
CB bitwise operation
DB -
EC -
FA ld a, (a16)
FF rst $38 NOPE
Python code to update set:
string = "DUMP DELLA MAPPA"
set = set()
set.update({'6F', '34', 'F1', '4F', 'FA', '6D', '08', '8E', '7A', '74', '88', 'D9', '60', 'FF', '04', '8D', '33', '31', '8F', '0B', 'EC', '00', '50', '0A', '11', 'CB', '32', 'C9', '0F', 'CA', '6C', '6E', 'DB', '7F', '93'}) #VECCHIO SET
for i in range(0, len(string), 2):
set.add(string[i:i+2])
print(set)
Image of the map to check tiles:

https://i.imgur.com/sIE2AaM.png
TREES = 0x0F
TREES_UP = 0x6C
TREES_DOWN = 0x6F
TREES_LEFT = 0x6E
TREES_RIGHT = 0x6D
GRASS = 0x0A
GRASSIER = 0x7A
GRASSIEST = 0x7B
MEGA_GRASS = 0x31
TALL_GRASS = 0x0B
FLOWER = 0x74
POKE_UP = 0x33
POKE_RIGHT = 0x32
POKE_LEFT = 0x60
POKE_DOWN = 0x34
POKE_GRASS = 0x08
ROAD = 0x55
BARRIER = 0x13
BARRIER_UP = 0x4E
BARRIER_DOWN = 0x4D
BARRIER_LEFT = 0x51
BARRIER_RIGHT = 0x52
GLITCH_C9 = 0xC9
GLITCH_CA = 0xCA
GLITCH_CB = 0xCB
GLITCH_D9 = 0xD9
GLITCH_DB = 0xDB
GLITCH_EC = 0xEC
Possible gadgets
EC50: xor c
Stack:
PAYLOAD #1
db08: inventory
1374: ld b, l; jp bankswitch -> jp (hl)
PAYLOAD #2
db08: inventory
db55: call DB5A -> jp (hl)
Function to use:
Bankswitch
SpritePositionBankswitch (bankswitch)
GetTrainerInformation (bankswitchhome)
CheckForHiddenObjectOrBookchelfOrCardKeyDoor
SeafoamIsIslands1F_h
RocketHideout3BattleTxt
RocketHideout3EndBattleTxt
SilphCoElevator_Script -> SilphCoElevatorWarpMaps (potential call to d502 and jp hl)
fls21Func_callHL
$FB5A
WRONG/OLD PAYLOAD
0b52: pop bc; pop hl; ret
dbfa: hl += bc; ret
db55: call DB5A -> jp (hl)
Current plan:
overflow inventory
change DB74 to $31 (+), item 04
generate password
stack flip on F9D4 (tile data)
there it should be DB0A
exec inventory
decrement DB3C
inventory at DB32 JRs on DB3C, that’s a jp (hl)
Inventory code:
inc c
;DB0A
ld h, 10
ld l, 0a
inc bc
ld b, 54
ld c, 3c
add hl, bc
add hl, bc
dec c
ld e, h
Possible item name pointers (DADD)
A553
A55A
A567
A574
A581
A58B
A59A
A5A8
A5B7
A5C4 (CALL nz, d16)
A5D1 (pop DE)
A5D9 (reti)
A5EA (ld a16, a)
A5F9 (ld sp, hl)
A606 (ld b, d8)
A614
A623 (inc hl)
A62E (ld l, d8)
A639 (add hl, sp)
A63F (ccf)
Fools2021 notes
Chall3
Hex of the map:
0xD880
Byte sequences:
0b0b0b740a
0f0b0f0a0a
0f0f0a0a0b
0f0b0a0a0a
0b0b0a0a74
bruteforce payload:
db 0b0b0b740a ;D3D0 db 0f0b0f0a0a ;D3D8 db 0f0f0a0a0b ;D3E0 db 0f0b0a0a0a ;D3E8 db 0b0b0a0a74 ;D3F0 D3F0 db firstExec D3F1 db seed3 D3F2 db seed2 D3F3 db seed1 D3F3 db seed0 genNewKey: ;D400 ld a, 10 add a, (hl) ldd (hl), a ret nc inc (hl) ret nz dec hl inc (hl) ret nz dec hl inc (hl) ret BruteForcer: ;D410 push af push bc push de push hl .start: ;D414 ld hl, DABB push hl call D400 ; genNewKey ;gen new key. REMEMBER TO SET THE LSB TO 1 .resetKeyBuffer ;D41B pop hl xor a ;resets the other buffer inc hl ldi (hl), a ldi (hl), a ldi (hl), a ld (hl), a .resetMapBuffer ;D422 ld hl, fls21_currentMap ;clears the map buffer ld bc, 0240 ld d, 54 .resetLoop ;D42A ld (hl), d inc hl dec bc ld a, c or b jr nz, D42a :resetLoop .resetChecknum ;D431 ld hl, fls21_currentChunkLOW ;reset chunkNum xor a ;nop ld b, a ;nop inc a ldi (hl), a inc a ld (hl), b inc hl ldi (hl), a ld (hl), b .genMapCall: ;D43D call fls21Func_genMap .startCheck ;D440 ld hl, D3D0 ld de, D890 ld c, 5 ;sequence equal ld b, 5 ;charsEqual push hl .checkLoop: ;D44B ld a, (de) push af inc de ld a, e and a jr z, D46F; doneCheckLoop pop af cp (hl) jr nz, D469;.wrongCheckLoop dec c jr nz, d466;.notDoneCheckLoop: .doneWord: ;D459 pop hl ld c, 5 ld a, 8 add a, l ld l, a push hl dec b jr z, d473; .win jr D44B;checkLoop ;DONE .notDoneCheckLoop: ;d466 inc hl jr D44B; checkLoop .wrongCheckLoop: D469; ld c, 5 pop hl push hl jr D44B; checkLoop .doneCheckLoop: ;D46F pop af pop hl jr D414 ;start .win: ;d473 pop hl xor a xor a ei .end: pop hl pop de pop bc pop af ret;0A vuoto
;0F alberi
;0B erba
;74 fiori
Symbol table
Chall4
Writing primitives:
item 0x2D jumps to DAB3, which is fully writable
changing the biome to a glitch one can spawn glitch items
if current page > 9 i can execute glitch items in memory
There’s a possible overflow in wPikachuAttackModifier
Glitch pokemon can drop glitch items
Current plan:
Pokemon map addresses:
Dump:
Pokémon table starting at 03:A480
Format: | PicID | Encounter text | Name | Exp | HP | Atk | Drop rate | Item drop |
Dump :
Item drop table starting at 03:A460
Dump:
Item list:
Usable tiles:
Python code to update set:
string = "DUMP DELLA MAPPA" set = set() set.update({'6F', '34', 'F1', '4F', 'FA', '6D', '08', '8E', '7A', '74', '88', 'D9', '60', 'FF', '04', '8D', '33', '31', '8F', '0B', 'EC', '00', '50', '0A', '11', 'CB', '32', 'C9', '0F', 'CA', '6C', '6E', 'DB', '7F', '93'}) #VECCHIO SET for i in range(0, len(string), 2): set.add(string[i:i+2]) print(set)Image of the map to check tiles:

https://i.imgur.com/sIE2AaM.png
Possible gadgets
EC50: xor c
Stack:
PAYLOAD #1
db08: inventory
1374: ld b, l; jp bankswitch -> jp (hl)
PAYLOAD #2
db08: inventory
db55: call DB5A -> jp (hl)
Function to use:
Bankswitch
SpritePositionBankswitch (bankswitch)
GetTrainerInformation (bankswitchhome)
CheckForHiddenObjectOrBookchelfOrCardKeyDoor
SeafoamIsIslands1F_h
RocketHideout3BattleTxt
RocketHideout3EndBattleTxt
SilphCoElevator_Script -> SilphCoElevatorWarpMaps (potential call to d502 and jp hl)
fls21Func_callHL
$FB5A
WRONG/OLD PAYLOAD
0b52: pop bc; pop hl; ret
dbfa: hl += bc; ret
db55: call DB5A -> jp (hl)
Current plan:
overflow inventory
change DB74 to $31 (+), item 04
generate password
stack flip on F9D4 (tile data)
there it should be DB0A
exec inventory
decrement DB3C
inventory at DB32 JRs on DB3C, that’s a jp (hl)
Inventory code:
inc c
;DB0A
ld h, 10
ld l, 0a
inc bc
ld b, 54
ld c, 3c
add hl, bc
add hl, bc
dec c
ld e, h
Possible item name pointers (DADD)
A553
A55A
A567
A574
A581
A58B
A59A
A5A8
A5B7
A5C4 (CALL nz, d16)
A5D1 (pop DE)
A5D9 (reti)
A5EA (ld a16, a)
A5F9 (ld sp, hl)
A606 (ld b, d8)
A614
A623 (inc hl)
A62E (ld l, d8)
A639 (add hl, sp)
A63F (ccf)