Advertisement
M4n0z

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

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