Advertisement
M4n0z

BlipBlopMenu 2 for Pokemon Yellow EN via Arbitrary Code Execution

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