[Sebastian Mihai] is a prolific programmer and hacker with a particular focus on retrocomputing and period games, and this latest hack, adding new gameplay elements to Capcom’s Street Fighter II – Champion Edition, is another great one. [Sebastian] was careful to resist changing the game physics, as that’s part of what makes this game ‘feel’ the way it does, but added some fun extra elements, such as the ability to catch birds, lob barrels at the other player, and dodge fire.
The title screen was updated for each of the different versions, so there is no doubt about which was being played. This work was based on their previous hacks to Knights of the Round. Since both games shared the same Capcom CPS-1 hardware, the existing 68000 toolchain could be reused, reducing the overhead for this new series of hacks.
Obviously, without access to the game’s source code, the hacks (all seven of them!) were made by binary modification, first learning about how the original program stores aspects of the game and hacking in a little hand-grafted assembly here and there to sneak in the extra elements without interfering too much with the original code operation.
[Sebastian] stripped out some title screen effects to speed boot time and removed some in-game graphics, such as the score and the ‘insert coin’ images, to free up some graphical tiles to reuse for the new elements. [Sebastian] first needed to understand the game code, which meant disassembly and hand annotation of the entire binary, which was done using the MAME debugger. As the linked article demonstrates, saying this is a big task is somewhat of an understatement.
A simple approach was taken to the mods consisting of three types of binary patches. The first, or ‘short circuit’, are simple NOPs inserted to disable subroutine calls or RTS to force an early return in a subroutine. The second type is a blob of code residing in some unused ROM space and storing state in a spare section of RAM. This is where the main parts of the new code reside. Finally, hooks are injected into the code at key locations, which jump into the binary blob where modified behavior is required. This can do any needed initialization before returning to the main game logic. Making significant changes to the game would be very hard without any spare space in the system, but we guess you could do it by stripping out other game elements, but [Sebastian] didn’t need to go there. If you’re into retro gaming and particularly modding, then going deeper into [Sebastian]’s homepage will reveal an astonishing number of projects and hacks.
Sometimes, our fond memories of games of old are skewed a little over the years, and the gameplay wasn’t that great in reality. So, what can we do? How about a little Redux, Zelda II style? If you’re really down the rabbit hole of retro hardware, then dealing with all those pesky EPROM chips is getting more difficult these days. To help with that, here’s a modern take on the necessary hardware.
Reminds me of the proof of concept backdoor Saleem Rashid inserted into ledger firmware (a popular crypto hardware wallet made by a deeply unpopular company).
Saleem had to make space on the MCU and did this by optimizing the code already used for size so he could insert his own hooks. He goes into it on his Blog link below under Mode of attack 6 years later I still occasionally think about it!
https://saleemrashid.com/2018/03/20/breaking-ledger-security-model/
https://github.com/saleemrashid/ledger-mcu-backdoor
TL;DR compiler intrinsics might end up in multiple places, you can replace a copy with your code. And if someone wants to verify the firmware? We’ll send them over the unparched version by replacing your code with the duplicate intrinsic. The device functions entirely normally externally and even the secure element doesn’t know something’s up.
He also considers literally compressing the firmware which I think would work in multiple settings.
Great hack, thanks. Great article :-)