▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ ░▒▓█ rapid1337.com █▓▒░ ╓──────────────────────────────────────────╖ ║ Bubble Bobble ║ ╟──────────────────────────────────────────╢ ║ You?ll need following: ║ ╟──────────────────────────────────────────╢ ║ ·· security/bubble-bobble.html ·· ║ ╙──────────────────────────────────────────╜ ============================================================================ Title ..: Bubble Bobble Author .: staff Date ...: 2005-01-15 Section : Security ============================================================================ Bubble Bobble ? Taito Corp. 1987 ![1.gif](../assets/img/tutorials/bubble-bobble/1.gif) ? You?ll need following: 1. Original game ? find on emunova.net 2. An Amiga or WINUAE 3. Action Replay or ROM image 4. Pencil and paper Isn?t this just nostalgic? Start by making a copy of original game. You?ll notice an error on track 0, probably a good old copylock protection. Boot copy of game to see how the protection behaves. Track counter moves to 0 at the title screen (copylock check), but game continues short after. You can actually play level one with no problems. After level one, the game will start to behave strangely. It might hang on level two, start over and over again at level one, we can?t have that, can we? Boot original game and enter AR when the track counter moves to 0 (at the title pic). Copylock?s usually start with a ? PEA $$$$$ ?, search for the opcodes: F 48 7A. AR will only return one address; 54B8C. ![2.gif](../assets/img/tutorials/bubble-bobble/2.gif) Disassemble address 54B8C and hit enter a few times. You?ll see typically signs of a copylock, like the PEA and ILLEGAL instruction. Continue disassembling until you reach end of copylock: ![3.gif](../assets/img/tutorials/bubble-bobble/3.gif) Copylock seems to end around address 5505A. Stick a breakpoint to this address and exit AR. AR will then pop up, when address 5505A are reached. BS 5505A. When AR pops up, see registers with R. Looks like we have the key in D0. Elderly copylocks often returned the key at address 24, besides D0. See address 24 with M 24. So, we have to return the key both in D0 + address 24. ![4.gif](../assets/img/tutorials/bubble-bobble/4.gif) The copylock is located in a file called ? snd ? ? tricky thing to do . Insert copy of game and load it into memory, starting at address 30000: LM SND,30000. File is located between 30000 305CC. ![5.gif](../assets/img/tutorials/bubble-bobble/5.gif) Disassemble address 30000 and hit enter a few times. Notice the BRA 300DC at address 30020, disassemble address 300DC and hit enter a few times. Bingo, 300DC is start of the copylock. Assemble address 300DC and insert following code: 300DC; MOVE.L #2DAAB0BD,D0; wire correct key to D0 300E2; MOVE.L #D0,24.S; copy key from D0 to address 24 300E6; RTS; return ![6.gif](../assets/img/tutorials/bubble-bobble/6.gif) Save memory back as a file called ? snd?, overwriting the old one: SM SND,30000 305CC. To test your new crack, wouldn?t it be nice with unlimited life? Let?s add a little trainer, giving player 1 & 2 unlimited life. Assuming you are at start of level one, and still got all four lives, enter AR and start trainer: TS 4. When it?s finished searching, exit AR and loose ONE life. ![8.gif](../assets/img/tutorials/bubble-bobble/8.gif) Enter AR again and continue trainer: T 3. AR will return two addresses and game stores count value in the first one. Check what game does with this address: FA 1EBAE. ![9.gif](../assets/img/tutorials/bubble-bobble/9.gif) You?ll receive lot?s of references, but we are only interested in address 24B80. This address subtracts 1 from the life count. Disassemble address 24B80 and hit enter a few times: ![10.gif](../assets/img/tutorials/bubble-bobble/10.gif) Besides address 24B80, also notice address 24B98. This instruction also subtracts 1 from an address. This is the counter for player two. Notice that there are $18 between the two addresses ( 24B98-24B80=18), as we shall use this information later on. We?ll train the game, by simply NOP?ing out these two instructions, and life count address will newer decrease. We want to patch the game, so it halts upon boot and gives us a visual information about choosing trainer or not. This will require a little trainer patch, which we?ll located at address 100. Take note of the opcodes for the first instruction we?ll remove: M 24B80. Take note of opcodes marked with red. We?ll need them, to find the instruction later on. ![11.gif](../assets/img/tutorials/bubble-bobble/11.gif) Main loader is called ? BOOT ? and load a file into memory called ? BUBBLE ?. This game does not use fixed address for data, but relative. This means, that we have to use one of the registers as an offset, to locate which part of memory to patch. Load file ? BOOT ? into memory, starting at address 30000: LM BOOT,30000. File is located between address 30000 ? 300BC. Disassemble address 30000 and hit enter a few times: ![12.gif](../assets/img/tutorials/bubble-bobble/12.gif) Loader ends at address 30072. Change the ? RTS ? to a loop routine and save file back to disk, see picture above. Reboot game and wait for it to hang. When it hangs, file ? bubble ? has been loaded into memory, but isn?t executed, due to due loop routine. Enter AR and press ? R ? to see registers. A3 points to address 1D2D4, check contents of address by typing N 1D2D4 and hit enter a few times. A3 seems to be pointing to the main loader. We can then use A3 as an offset, to calculate which addresses to patch. ![13.gif](../assets/img/tutorials/bubble-bobble/13.gif) Search for the opcodes for the ? SUBI.B ? instruction: F 04 39 00. AR returns a punch of addresses, but we are only interested in 24B80. We wish to alter address 24B80 and player two?s counter was located $18 away, at address 24B98, remember? Use AR to calculate the number to add to A3, to make A3 point to the first address we want to change: ? 24B80-1D2D4=78AC. ![14.gif](../assets/img/tutorials/bubble-bobble/14.gif) Read boot block into memory, starting at address 70000: RT 0 1 70000. Check for spare bytes for our trainer: N 70000. Seems like we have plenty of space here for our trainer. Before we code the trainer, we have to alter the main loader, so it calls our trainer, before executing the game. Load file ? BOOT ? into memory, starting at address 30000: LM BOOT,30000. Disassemble address 30020 and hit enter ``` a few times: ``` ![15.gif](../assets/img/tutorials/bubble-bobble/15.gif) We have the loop routine at address 30072, and we want to alter it to a ? ``` JMP 100.S ?. But our changes is 2 bytes longer ``` than the original code, so we have to put the jump at address 3006E instead. This will overwrite some of the game code, so we have to replace it in our trainer patch. Take note of the opcodes for the instruction at 3006E, see picture above. Assemble 3006E and insert a ? JMP 100.S ?: ![16.gif](../assets/img/tutorials/bubble-bobble/16.gif) Save file back: SM BOOT,30000 300BC. Assemble offset $100 (70100) on boot block and code the trainer: ![17.gif](../assets/img/tutorials/bubble-bobble/17.gif) You can?t assemble the first line using AR, so insert the opcodes instead, see picture above. Comments for the code: 70100; Restore code we removed in loader 70104; Set CLI colour to green 7010C; Check for left mouse 70114; If pressed, branch to 70122 and train game 70116; Check for right mouse 7011E; If pressed, branch to 7011E and start normal game 70120; loop routine, until mouse is pressed 70122; Add #78AC to A3, make it point to the first long word, in the first instruction we want to NOP out (player 1) 70128; NOP out first long word 7012E; NOP out second long word 70136; Add #18 to A3, make it point to player two?s energy count down instruction 7013C; NOP out first long word (player 2) 70142; NOP out second long word (player 2) 7014A; Subtract #78C4 (78AC+18=78C4) from A3, restoring it to it?s original value 70150; Return (start game) When game boot?s, it load a while and CLI screen will flash green. If you press Right mouse, normal game will start, if Left mouse is pressed, the ? SUBI.B ? instructions will be NOP?ed out and you?ll have unlimited life. Next step, is getting the trainer into address 100. We do this, by adding a little copy routine, moving the trainer from offset $100 on boot block into address 100. Disassemble 7000C (start of boot code) and hit enter a few times. Take note of the line and change it to ? BSR 700C0 ?. We?ll the put the copy routine at 700C0, and boot block will call it upon game boot. ![18.gif](../assets/img/tutorials/bubble-bobble/18.gif) Assemble 700C0 and code the copy routine, see picture above. Comments: 700C0; Dest. address 100 for trainer 700C6; Copy from offset $100 on disk 700CA; Copy $200, size to copy 700CE; Copy 700D0; Copy 700D4; Restore code we removed in start of boot block 700D8; Return to original boot code. Correct boot block checksum: BOOTCHK 70000 ![19.gif](../assets/img/tutorials/bubble-bobble/19.gif) Write boot block back: WT 0 1 70000. ![7.gif](../assets/img/tutorials/bubble-bobble/7.gif) Dedicated to the cutest girlie on earth, Victoria. Rob ---------------------------------------------------------------------------- -- rapid1337.com -- The dumping ground for all things tech // knowledge is the weapon --