M4n0z

BlipBlopMenu 2 for Pokemon Yellow EN via Arbitrary Code Execution

Dec 4th, 2024 (edited)
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ASM (NASM) 12.27 KB | Source Code | 0 0
  1. /*
  2.  
  3. BlipBlopMenu 2 - Compatible with EN Yellow ONLY
  4.  
  5.  
  6. Description
  7.  
  8. BlipBlopMenu 2 allows the TimOS selector to be accessed simply by pressing the Select button while in the overworld.
  9. This eliminates the need to use a glitch item and restores the functionality of the Daycare.
  10.  
  11. In addition, three scripts are installed, providing the following effects:
  12. #3. Repeller: When active, it permanently avoids any wild battle.
  13. #4. Trespasser: By holding B button, all collisions are disabled.
  14. #5. Motorbike: New! By holding A button, super speed is activated.
  15.  
  16.  
  17. Prerequirements
  18. - TimoVM's gen 1 ACE setup with a clean TimOS installation from:
  19.  https://glitchcity.wiki/wiki/Guides:SRAM_Glitch_ACE_Setups_(EN_Yellow)
  20.  
  21. Instructions
  22. 1)  - Installation on actual hardware or emulator: You can use TimoVM's NicknameConverter and NicknameWriter from the above page.
  23.     - Installation on emulator with debugging features: Just copy and paste the HEX code into address $d8b4.
  24. 2) Run the code from NicknameWriter.
  25. 3) While in overworld, by pressing Select button TimOS selector pops up.
  26. 4) Confirm everything works correctly by testing the three new scripts and then save the game.
  27.  
  28. Attention! Activating Trespasser and walking outside the game's borders will guarantee a crash. Proceed with caution!
  29.  
  30.  
  31.  
  32. Code:
  33.  
  34. 3e 02 cd 99 3e 01 41 00 11 57  
  35. c8 21 69 d6 e5 cd b1 00 0e 86  
  36. d1 21 fb d8 cd b1 00 0e 12 11  
  37. 9c d4 cd b1 00 0e 18 1e 7a cd  
  38. b1 00 0e 4c 11 11 bb cd b1 00  
  39. 0e 08 11 bd c7 cd b1 00 0e 19  
  40. 11 98 c8 cd b1 00 3e 05 ea e9  
  41. c6 fa 5c df fe 7c 28 2f f3 3e  
  42. 02 cd 99 3e 01 04 00 11 80 ff  
  43. 21 11 bb cd b1 00 0e 48 11 15  
  44. df cd b1 00 cd a9 3e 21 5d d3  
  45. 7e fe 0b 20 09 36 76 04 21 83  
  46. 5c cd 84 3e fb cd 15 df c3 ed  
  47. d6 21 6e d3 11 a4 d6 7a be 28  
  48. 1a 01 5d d3 0a fe 76 20 09 fa  
  49. 57 d3 a7 20 0c 3e 0b 02 3a 12  
  50. 1b 7e 12 3e 69 22 72 21 ee d6  
  51. cb 46 28 04 7d ea 3b d1 cb 4e  
  52. 28 03 cd 9c d4 cb 56 28 0a 2e  
  53. ff af be 20 01 34 cd 7a d4 0e  
  54. 46 3e c3 c9 00 fa 2f d7 a7 c0  
  55. f0 b4 cb 4f 3e 00 28 01 3c ea  
  56. 38 cd c9 fa 5d d3 fe 1c c8 f0  
  57. b4 cb 47 c8 fa c4 cf fe 07 d0  
  58. a7 c8 cd 7f 0b 18 f3 cd a5 d6  
  59. e2 f0 b3 cb 57 c8 f0 b8 f5 cd  
  60. 2d df 21 27 df e5 cd d8 28 f1  
  61. e0 b8 c3 6b 21 cd 0f 37 21 90  
  62. cf 36 94 af ea 93 cf cd 33 22  
  63. 0e 1f 3e 9d cd 11 22 21 39 6f  
  64. cd 17 39 3e 1c cd 92 3e 06 03  
  65. 21 53 ba 11 e8 c6 e5 d5 c5 d5  
  66. cd 58 7c 57 c8 a1 c8 98 c8 ad  
  67. c8 06 02 21 ee d6 7e a8 77 c9  
  68. 06 01 cd 9a c8 a0 c0 af ea 3b  
  69. d1 c9 06 04 18 e9  
  70.  
  71. Total Bytes: 356
  72.  
  73.  
  74. Extra Scripts for BlipBlopMenu 2 for Pokemon Yellow EN also available here:
  75. https://pastebin.com/r2LNqbGp
  76.  
  77.  
  78. ************ Logic ************
  79.  
  80. Part 1 - Installer ($d8b4-$da17)
  81. After the code is written and executed, installer manages to transfer:
  82. - NicknameWriter from unused WRAM ($d669) to TimOS area ($c857).
  83. - Main payload (MSP Manipulator and OAM payloads) to unused memory ($d669).
  84. - Script payloads to unused memory ($d47a and $d49c).
  85. - OAM DMA hijack and TimOS Loader splitted payload to SRAM Bank 2 ($bb11)
  86. - Script pointers in TimOS selector ($c7bd).
  87. - Script enablers inside TimOS area ($c898).
  88.  
  89. Part 2 - Map Script payload ($d669-$d6a4)
  90. After installation and every time the game starts, MSP targets custom MSP payload.
  91. - MSP payload checks for active TimOS payload ($df5c).
  92. - If stack corrupts payload or OAM is not hijacked, it sets up the hijack ($ff80) and copies TimOS Loader payload at the top of the stack ($df15).
  93. - After setting up OAM hijack, current active room is checked. If unused room $0b is detected, manual map reset is performed to get out of HoF.
  94. - TimOS Loader payload's check is executed ($df15).
  95. - Jump to original MSP happens and the game continues to its normal state.
  96.  
  97. Part 3 - OAM DMA payloads ($d6a5-$d6ee)
  98. After OAM DMA hijack is set, the following routine is executed in every frame.
  99. - MapScriptPointer manipulator payload is executed, which checks if MSP is hijacked.
  100. - If not, current room is checked. If HoF is detected, it waits for the active dialogs to close and replaces room id with an unused one.
  101. - Afterwards, original MSP is copied to the end of this routine, and a custom one replaces it.
  102. - OAM DMA payloads are execuded, according to the payload bits set from TimOS.
  103. - Proper registers are set and OAM DMA routine continues its normal execution.
  104.  
  105. Part 4 - TimOS Loader payload ($df15)
  106. - In every non moving overworld frame, Select button is checked (hJoyPressed - $ffb3).
  107. - If the above checks are true, TimOS Loader is triggered, setting up some environment values and launching TimOS payload.
  108. - After TimOS closes, execution continues from a payload closer to the top of the stack, so to avoid any potential crash caused by a stack overflow.
  109. - In case stack overflows and destrys TimOS payload, the check in MS payload rebuilts it during the next overworld frame.
  110.  
  111.  
  112.  
  113. ************ Memory map ************
  114.  
  115. SRAM2
  116. bb11-bb14: OAM DMA hijack payload
  117. bb15-bb5c: TimOS Loader
  118.  
  119. WRAM0
  120. d47a-d491: Motorbike payload
  121. d49c-d4ad: Trespasser payload
  122. d669-d6a2: MSP payload
  123. d6a3-d6a4: MSP backup address
  124. d6a5-d6ed: OAM DMA payloads
  125. d6ee: OAM DMA payload flags
  126. df15-df5c: TimOS loader copied from SRAM2 $bb15
  127.  
  128. HRAM
  129. ff80-ff83: OAM DMA hijack, copies from $bb11
  130.  
  131.  
  132.  
  133. Source to be compiled with RGBDS
  134. */
  135.  
  136.  
  137. SECTION "BlipBlopMenu2", ROM0
  138.  
  139. start:
  140.  
  141. ;;;;;;;;;;;; Installer payload ;;;;;;;;;;;;
  142.  
  143. ld a, $02
  144. call $3e99          ; Open SRAM2
  145.  
  146. ; move NicknameWriter into TimOS
  147. ld bc, $0041        ; 65 bytes
  148. ld de, $c857        ; destination
  149. ld hl, $d669        ; origin
  150. push hl
  151. call $00b1          ; CopyData
  152.  
  153. ; move main payload in unused memory $d669
  154. ld c, $86           ; 134 bytes
  155. pop de
  156. ld hl, $d8fb        ; origin
  157. call $00b1          ; CopyData
  158.  
  159. ; move scripts in unused memory
  160. ; copy trespassing to d49c
  161. ld c, $12           ; 18 bytes
  162. ld de, $d49c        ; to unused memory
  163. call $00b1          ; CopyData - due to previous copyData, de points correctly
  164. ; copy motorbike to d47a
  165. ld c, $18           ; 24 bytes
  166. ld e, $7a           ; to unused memory
  167. call $00b1          ; CopyData - due to previous copyData, de points correctly
  168.  
  169. ; move OAM hijack + TimOS Loader into SRAM Bank 2
  170. ld c, $4c           ; 76 bytes
  171. ld de, $bb11        ; destination
  172. call $00b1          ; CopyData
  173.  
  174. ; move TimOS pointer
  175. ld c, $08           ; 8 bytes
  176. ld de, $c7bd        ; destination
  177. call $00b1          ; CopyData
  178.  
  179. ; move TimOS enablers
  180. ld c, $19           ; 25 bytes
  181. ld de, $c898        ; destination
  182. call $00b1          ; CopyData
  183.  
  184. ld a, $05           ; set no of scripts
  185. ld [$c6e9], a
  186.  
  187.  
  188. ;;;;;;;;;;;; Executed by MSP hijack ;;;;;;;;;;;;
  189.  
  190. ; $d669 - executed by MapScript after loading the game
  191. ; it checks if TimOS Loader payload is present
  192. ld a, [$df5c]       ; last byte of TimOS payload, so if it gets corrupted to be rebuilt together with OAM DMA hijack
  193. cp a, $7c
  194. jr z, .timoscheck
  195.  
  196. ; if DMA is unset
  197. di
  198. ; opens SRAM2
  199. ld a, $02
  200. call $3e99          ; OpenSRAM to bank 02
  201.  
  202. ; copy 4 bytes to hijack dma
  203. ld bc, $0004        ; 4 bytes to be copied to ff80 earlier set to de
  204. ld de, $ff80        ; destination
  205. ld hl, $bb11        ; from SRAM 2
  206. call $00b1          ; CopyData - the stored version of .OAMDMApayload.
  207.  
  208. ; copy timos loader to df15
  209. ld c, $48           ; 72 bytes
  210. ld de, $df15        ; to the top of the stack
  211. call $00b1          ; CopyData - due to previous copyData, de points towards TimOS loader payload
  212.  
  213. ; closes SRAM
  214. call $3ea9          ; CloseSRAM
  215.  
  216. ; checks and initialises map if unused room is detected in place of HoF
  217. ld hl, $d35d        ; wCurMap: 00=Pallet town, 76=HoF room, 0b=unused
  218. ld a, [hl]
  219. cp a, $0b           ; if unused room is detected
  220. jr nz, .endcp  
  221. ld [hl], $76        ; set room back to HoF
  222. inc b               ; bank 1 : b=0 from previous use
  223. ld hl, $5c83        ; run MainMenu.pressedA, as it is intended by the game
  224. call $3e84          ; Bankswitch
  225.  
  226. .endcp
  227. ei
  228.  
  229. .timoscheck
  230. call $df15          ; TimOS loader checks
  231.  
  232. .curmsp
  233. jp $d6ed            ; a safe address to be replaced automatically by msp manipulator
  234.    
  235.    
  236.    
  237. ;;;;;;;;;;;; Executed by OAM DMA hijack ;;;;;;;;;;;;
  238.  
  239. ; $d6a5
  240. ; MSP Manipulator - It checks and sets Map Script Pointer after backing up the original one
  241.  
  242. ; Preload addresses
  243. ld hl, $d36e        ; wCurMapScriptPtr+1
  244. ld de, $d6a4        ; Original MSP backup address+1
  245.  
  246. ; checks if MSP is hijacked
  247. ld a, d             ; Custom wCurMapScriptPtr high byte check
  248. cp a, [hl]          ; Compares current to custom pointer
  249. jr z, .payload1
  250.  
  251. ; room checking to bypass HoF reset
  252. ld bc, $d35d        ; wCurMap: 00=Pallet town, 76=HoF room, 0b=unused
  253. ld a, [bc]
  254. cp a, $76           ; if wCurMap = HoF
  255. jr nz, .backup
  256. ld a, [$d357]       ; wLetterPrintingDelayFlags
  257. and a               ; check if text is active
  258. jr nz, .payload1    ; if 0 do following
  259. ld a, $0b           ; set wCurMap to unused id
  260. ld [bc], a
  261.  
  262. ; hijacks MSP
  263. .backup
  264. ld a, [hl-]
  265. ld [de], a
  266. dec de
  267. ld a, [hl]
  268. ld [de], a
  269. ld a, $69
  270. ld [hl+], a
  271. ld [hl], d          ; d669
  272.  
  273. ; if scriptflag's bit0=0, skip leavemealone script
  274. .payload1           ; Always ignore encounters
  275. ld hl, $d6ee
  276. bit 0, [hl]
  277. jr z, .payload2
  278. ld a, l             ; a!=0
  279. ld [$d13b], a       ; wNumberOfNoRandomBattleStepsLeft
  280.  
  281. ; if scriptflag's bit1=0, skip trespassing script
  282. .payload2
  283. bit 1, [hl]
  284. jr z, .payload3    
  285. call $d49c          ; trespassing script
  286.  
  287. ; if scriptstate's bit2=0, skip parkour script
  288. .payload3
  289. bit 2, [hl]
  290. jr z, .endoam
  291. ; if walking activates bike
  292. ld l, $ff           ; hl = d6ff [wWalkBikeSurfState]
  293. xor a
  294. cp a, [hl]
  295. jr nz, .checkb
  296. inc [hl]
  297. .checkb
  298. call $d47a          ; Motorbike script
  299.  
  300. ; setting return values for OAM DMA routine
  301. .endoam
  302. ld c, $46
  303. ld a, $c3
  304. ret
  305.  
  306.  
  307. ;;;;;;;;;;;; Temporary data ;;;;;;;;;;;;
  308. db $00              ;  Flags initialisation
  309.  
  310.  
  311.  
  312. ;;;;;;;;;;;; Trespassing payload ;;;;;;;;;;;;
  313. ; -> d49c - 18 bytes
  314. ld a, [$d72f]       ; spin check
  315. and a
  316. ret nz
  317. ldh a, [$b4]        ; If Pressed
  318. bit 1, a            ; B Button
  319. ld a, $00           ; we cannot use xor a, since it will reset z
  320. jr z, .trespass
  321. inc a
  322. .trespass
  323. ld [$cd38], a       ; Loads Walk Type
  324. ret
  325.  
  326. ;;;;;;;;;;;; Splitted Motorbike payload ;;;;;;;;;;;;
  327. ; -> d47a - 24 bytes
  328. ; checks for cycling road
  329. ld a, [$d35d]
  330. cp a, $1c
  331. ret z
  332.  
  333. ; checks button A pressed
  334. ldh a, [$b4]
  335. bit 0, a
  336. ret z
  337.  
  338. ; script activates at 6th moving frame and loops until it hits 0
  339. .loop
  340. ld a, [$cfc4]       ; wWalkCounter
  341. cp a, $07
  342. ret nc
  343. and a
  344. ret z
  345. call $0b7f          ; AdvancePlayerSprite
  346. jr .loop
  347.  
  348.  
  349.  
  350. ;;;;;;;;;;;; OAM hijack payload ;;;;;;;;;;;;
  351. call $d6a5          ; if initial payload changes, change address acordingly
  352. ld [c], a           ; setup to trigger stock OAM payload
  353.  
  354.  
  355. ;;;;;;;;;;;; TimOS Loader payload ;;;;;;;;;;;;
  356. ; timos loader - 74
  357. ; Loaded from $bb15 to $df15 automatically with map script pointer
  358.  
  359. ; Read select button state - It automatically skips false positives like it happens in start menu
  360. ldh a, [$b3]        ; Read buttons [hJoyPressed]
  361. bit 2, a            ; Compare to select button [bit2]
  362. ret z               ; If select not pressed, stop executing
  363.  
  364. ldh a, [$b8]        ; Saves hLoadedROMBank
  365. push af
  366.  
  367. call $df2d          ; .tempdata
  368.  
  369. ;;;;;;;;;;;; After TimOS loader ;;;;;;;;;;;;
  370. ; safedata - this part should not be overwritten while timos is active, otherwise it will crash
  371. ld hl, $df27        ; We set hl to static address to continue execution after CloseTextDisplay
  372. push hl
  373. call $28d8          ; CloseTextDisplay
  374.  
  375. pop af              ; Restores saved rom bank
  376. ldh [$b8], a
  377.  
  378. jp $216b            ; PlayDefaultMusic
  379.  
  380. ;;;;;;;;;;;; TimOS loader ;;;;;;;;;;;;
  381. ; tempdata ($df32) - - this part can be overwritten safely while timos is active
  382. call $370f          ; SaveScreenTilesToBuffer1
  383.  
  384. ld hl, $cf90        ; wCurPartySpecies
  385. ld [hl], $94        ; Change nickname pokemon to Abra, so we avoid random missigno names crashing the game
  386. xor a
  387. ld [$cf93], a       ; wListMenuID
  388.  
  389. call $2233          ; StopMusic
  390. ld c, $1f           ; Bank with sound
  391. ld a, $9d           ; BlipBlop sound
  392. call $2211          ; PlayMusic
  393.  
  394. ld hl, $6f39        ; To execute DisplayTextIDInit.drawTextBoxBorder after bankswitch
  395. call $3917          ; Bankswitch hardcoded to bank 1
  396.  
  397. ;;;;;;;;;;;; TimOS payload ;;;;;;;;;;;;
  398. ; timos - 20 bytes
  399. ld a, $1c           ; ROM bank number
  400. call $3e92          ; Bankswitch+14
  401. ld b, $03           ; SRAM bank number
  402. ld hl, $ba53        ; Origin/destination
  403. ld de, $c6e8        ; Destination/origin
  404. push hl
  405. push de
  406. push bc
  407. push de
  408. call $7c58          ; CopyBoxToOrFromSRAM+1
  409.  
  410.  
  411.  
  412. ;;;;;;;;;;;; Payload pointers ;;;;;;;;;;;;
  413. db $57, $c8, $a1, $c8, $98, $c8, $ad, $c8
  414.  
  415.  
  416. ;;;;;;;;;;;; Bit Enablers pointers ;;;;;;;;;;;;
  417. ; Trespasser - 2 bytes
  418. ld b, $02
  419.  
  420. ; common function - 7 bytes
  421. .common
  422. ld hl, $d6ee
  423. ld a, [hl]
  424. xor a, b
  425. ld [hl], a
  426. ret
  427.  
  428. ; Repeller - 12 bytes
  429. ld b, $01
  430. call $c89a      ; .common
  431. and a, b
  432. ret nz
  433. xor a
  434. ld [$d13b], a       ; wNumberOfNoRandomBattleStepsLeft
  435. ret
  436.  
  437. ; Motorbike - 4 bytes
  438. ld b, $04
  439. jr .common      ; .common
  440.  
  441.  
Add Comment
Please, Sign In to add comment