Advertisement
M4n0z

BlipBlopMenu 2 for Pokemon Red and Blue EN via Arbitrary Code Execution

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