Sunday 28 December 2014

Capcom Kabuki CPU - Part 5

Welcome to the sixth and final post in the Capcom Kabuki reverse engineering series, you can find all previous posts here:

Reprograming Kabuki

Last week's journey under the microscope gave us a better understanding of all the Kabuki internals. In this week's final post we will learn all of its reprograming secrets. 





Kabuki is no longer a secret, thank you for watching and I hope you enjoyed this journey as much as I did. See you again in 2015!


Monday 22 December 2014

Capcom Kabuki CPU - Part 4

Welcome to the fifth post in the Capcom Kabuki reverse engineering series, you can find any previous posts over here:

A Hardware Attack on Kabuki

Ready for a journey under the microscope? This week's post is a video, let's dive in and see who really Kabuki is.





Liked the video? See the next and final part here: Reprograming Kabuki


Saturday 13 December 2014

Capcom Kabuki CPU - Part 3

Welcome to the fourth post in the Capcom Kabuki reverse engineering series, if you missed any of the previous readings you can find them here:

A Better Pang Desuicide

Are you familiar with this mess?


If you do then it means that at some point you have desuicided some sort of arcade game, most probably a Capcom title.

To me this is actually how this journey started the day I got hold of a dead Capcom/Mitchell Pang game motherboard. Like many of you went straight to the usual arcade forum and asked the community for advice, and this is when you most probably got introduced to the Dead Battery Society website.

Yup, you have a look and it seems like you can get you game to work by doing X, Y and Z, hack your board, add new pieces, cables and even cut physical tracks and a few other tricks.

The Dead Battery Society web page

The result? You have a working game but not the original thing anymore, you required tools, skills, and the whole process isn't exempt of the risk of damaging your game. To some people this is ok but I don't think anyone can deny the appeal of having truly original hardware in our hands and the pain involved in having to hack our boards, we are passionate collectors after all.

Refusing the idea of having to do this with my own suicided Pang board I went on and researched for better ways of reviving Kabuki powered game titles.

As your know from the previous post I explored the effort of trying to take control of Kabuki via software, something that successfully allowed me to identify what happens inside Kabuki when the battery runs out, but also led me to the discovery that something else than just the encryption keys prevents us from reviving the games with software alone.

The next logical frontier was planning a hardware attack, a lengthy, skillful and complicated process that requires plenty of education and preparation. But in the meantime and with the help of some of the tools created for the software attack on Kabuki I went on and decided to make a simpler Pang desuicide method.

Pang playing in the Barcelona stage, my hometown. And no, there isn't such river in front of the Sagrada Familia ;)


The Existing Desuicide Method

The current popular desuicide method described by the Arcade Battery Society requires an important amount of tools, installing new double size roms as well as wiring, soldering, and forcing Kabuki in Z80 mode, etc... This existing hack exploits the fact that game unencrypted code can be obtained thanks the efforts of Icer Addis and the driver incorporated by the Mame team. 

The requirement for double size roms comes from how Kabuki's encryption operates, if you remember from previous posts, Kabuki features different encryption for Opcodes, than Opcode parameters and Data.

I won't get into much detail but knowing where exactly each byte goes into is a very difficult task and the only way of knowing so is by following the program execution byte by byte as it gets interpreted by the cpu. 

For this reason existing hacks require two unencrypted sets of the same data, one that has been processed with the decryption for Opcodes, and another set that has been processed with the decryption for Data and Opcode arguments.

The way this is put together is by using half of the double size rom for the first unencrypted data set and the second half for the data second set, all is then wired together to the higher address pin of the double size roms and the M1 signal of the Kabuki in Z80 mode or any other Z80 replacement compatible cpu.

The M1 pin of Z80 compatible cpus signals when the cpu is reading an Opcode, or an Opcode parameter or Data. This signal is the key to the hack as it allows us to know with digital precision what data to serve the cpu as M1 goes high or low.

A typical Pang desuicide

A way of simplifying this process both in the resources and skills required is to obtain a valid unified unencrypted set that fits into the original roms. Let's look into it.


Hands on

Using a similar approach to what I explained on my previous post with the software attack, we need a Pang mask file that can help us produce the definitive rom set. Think of a mask file as a map that tells us where Opcodes and Opcode arguments and Data should be places on a rom

Pang program roms consist of two roms labeled as Rom 6 and Rom 7. Number 6 is a 32k byte (256k bit) rom, and number 7 is the larger rom with 128k (1024k bit) worth of code.  In total combined they feature 160k bytes. 

Trying to trace 160k bytes worth of program code can be almost mission impossible if we tried to do this manually, so we must get an ally on our side that helps us speed up the process as much as possible, and this where once again Mame becomes a god sent. 

Mame features a collection of CPU drivers that emulate a variety of platforms, and among them the Z80 cpu, we can use these drivers to help us achieve our goal by modifying them to get the data we need as is processed by the emulated cpu.

Mame source code files - the Z80 driver

In my case what I wanted is to simply be able to modify the Z80 driver to fast track the identification of all opcodes and data bytes within the Pang code, and the best of all, you get this data by playing the game!

The way this is done, is by hacking the existing Z80 driver code and incorporate new code parts needed for dumping the mask information we seek. For example the different read types performed by the cpu:

case 1: byte8[0] = 0xFF; break; /* op code */   <--- Writes an 0xFF when the cpu reads an opcode
case 2: byte8[0] = 0xAA; break; /* op code argument */  <--- Writes 0xAA when data is read 
case 7: byte16[0] = 0xAAAA; break; /* op code argument16 bits */ <--- Etc...
case 3: byte8[0] = 0x22; break; /* memory read */
case 4: byte8[0] = 0x55; break; /* memory write */
case 5: byte16[0] = 0x2222break; /* memory read16 bits */
case 6: byte16[0] = 0x5555break; /* memory write16 bits  */

Or also assembling the rom bank structure used by the game, a fundamental part of the Kabuki encryption scheme:

case 0: PC = PC - banked_region[0]; break; /* 00000-03fff */
case 1: PC = PC - (banked_region[0] /2); break; /* 04000-0bfff */
case 2: ; break; /* 8000 - bfff */
case 3: PC = PC + (banked_region[0] /2); break; /* 0c000-0ffff */
case 4: PC = PC + (banked_region[0]); break; /* 10000-13fff */
case 5: PC = PC + (banked_region[0] *1.5); break; /* 14000-17fff */
case 6: PC = PC + (banked_region[0] *2);  break; /* 18000-1bfff */
case 7: PC = PC + (banked_region[0] *2.5);; break; /* 1c000-1ffff */

In summary, what we do with this modified driver is tap on all the interesting cpu operations, and the most tricky part is making sure we trap all opcode arguments correctly as they can get a bit complex (remember, opcodes and arguments and encrypted differently).

In order to use the driver we must recompile Mame and execute it with our favorite z80 powered game. While you play the game the driver saves to disk all the byte information on two separate files, z80.log (the main code region 0x0000-0x7FFF) and z80-banks.log (a dynamic region consisting in 8 banks in the 0x8000 to 0xBFFF region).

Portion of Pang's rom 6 mask file produced with Mame

Here's a copy of the modified Z80 driver, feel free to hack it and reuse it as much as you want and sorry for the lack of programing "etiquette", i'm just an amateur not a pro coder. Remember that it probably requires modification if to be used with games different than Pang or Buster Bros. It should compile fine as part of Mame 0.153.

Once we have played the game extensively, all screens, both single and two player.... and used all options available we should have a very consistent set of mask files that should be ready to put to test by using Masker, the program I shared on my previous post. Using Masker we can input both unencrypted (opcode and data) files together with the mask files produced by our Mame driver and get a final single romset that fits the original roms and requires not motherboard hacking.

Truth is this isn't as easy as playing and having all the work done, extensive testing and manual finishing of rom areas never accessed by the game program is necessary and this requires understanding of the byte-code, dedication and a considerable time investment. Consider this process mostly a handcraft.


Pang - The Unencrypted set

And here's the result, a complete functional unencrypted romset of Pang, click to download. 

What this means is you can get back to life your suicided Pang games by simply burning new code on the existing roms and not having to use new eprom pieces, wiring or hacking your board. 

The only requirement besides burning the new code is that you leave Kabuki's pin 28 hanging outside of the cpu socket unconnected (ignore this if your board is already desuicided and no power is being supplied to pin 28).

Pin 28 overhangs the cpu socket so it doesn't make contact


Next week

Thanks for reading and stay tuned for what's coming next week: A hardware attack on Kabuki. At this point in time i'm not entirely sure how many more posts  I will dedicate to Kabuki but expect at least one more fully dedicated to a journey under the microscope and exposing its reprograming secrets.

Until that time comes here's nice teaser of what's coming, enjoy and thanks again for following.

Kabuki under the microscope



Sunday 7 December 2014

Capcom Kabuki CPU - Part 2

Welcome to the third post in the series, you can access the previous posts here:

A Software Attack on Kabuki

As explained on part one, Kabuki presumably uses an internal memory where it keeps the keys used for program and data code decryption. We know this from the fact that whenever the cpu loses power input on pin 28 those memory contents are lost and the cpu stops being able to run games, forever.


But let's look for a minute at what's going on here...


If Kabuki uses an internal memory for storage then this storage must be of CMOS type, thanks to one of the manufacturer product catalogs (VTI) we already know that the Kabuki Z80 core is a CMOS part.


In theory bits of CMOS memory or registers must default to an specific value after a power loss has occurred. Normally this should be 0, but let's play and get wild by assuming internal inverters are at work and the memory output default value could also be 1. 


In either case, and unless the designers of Kabuki randomized ram/register contents as part of a paranoid approach, then we could be in safe grounds when assuming that Kabuki's ram must get back a known state after a power loss has occurred. 


Could we try running code encrypted with keys whose bit values are all 0's or 1's? Could recovering a dead Kabuki game be so simple just requiring the burning a new set of roms encrypted with those default values? 


Let's look into this.


Planning the Attack


First of all, if we want to run code encrypted with different keys then we must know how to encrypt new valid code. Thanks to Icer Addis and the Mame team we know how to decode code for games using Kabuki but as expected, not a word about encoding code as it has never been a need to emulate existing games.


Secondly, we will need a piece of Z80 code that allows us to validate the experiment. Creating a "Hello World" piece of code that works on Capcom hardware is a project on its own. 

Writing a Hello World



Pang rom "Hello World" code running under Mame 




















Digging around Pang and using an standard disassembler I produced the following code that creates a functional Hello World test, the unencrypted code works perfectly under Mame by replacing rom number 6:


  .data:0x00000000f3di
  .data:0x00000001ed56im 1
  .data:0x000000033e00ld a,0x00
  .data:0x00000005d302out (0x02),a
  .data:0x000000073e40ld a,0x40
  .data:0x00000009d300out (0x00),a
; char* src = arg[1]
  .data:0x0000000b213cd8ld hl,0xd83c
  .data:0x0000000e011eccld bc,0xcc1e
  .data:0x00000011112500ld de,0x0025
  .data:0x000000141ald a,(de)
; dst[i] = c
  .data:0x00000015a7and a
  .data:0x00000016ca0000jp z,0x0000
  .data:0x0000001977ld (hl),a
  .data:0x0000001a2cinc l
  .data:0x0000001b3600ld (hl),0x00
; while (c != 0)
  .data:0x0000001d2cinc l
  .data:0x0000001e3e10ld a,0x10
  .data:0x0000002002ld (bc),a
  .data:0x0000002113inc de
  .data:0x000000220cinc c
  .data:0x0000002318efjr 0x0014
  .data:0x0000002548454C4C4F21HELLO!


Encrypting Kabuki compatible code

Now the harder part...

We need a set of tools to allow us encrypt our program, I won't get into much detail but writing the encoder required hard work (thanks to ASR and DR for the help) and I ended creating the following programs:

Kabuki Encode - Encrypts a file with a set of keys. Generates separated encrypted opcodes and data as required by Kabuki.
Kabuki Decode - Decrypts a Kabuki encrypted file using a set of keys provided.
Masker - This tool mixes encrypted opcodes and data generated by Kabuki Encode, takes a mask file as input.

Use this link to download a zip file including source code, binaries compiled for Mac OS, and also the Hello World program shown above. 

All three programs present a help output when ran with no arguments:

./kabuki_encode
Kabuki Encode by Eduardo Cruz http://arcadehacker.blogspot.com

usage: ./kabuki_encode <inputfile_opcode> <inputfile_data> <outputfile_opcodes> <outputfile_data> <baseaddress> <lenght> <swapkey1> <swapkey2> <addresskey> <xorkey> Optional: <numberofbanks>


In order to produce valid encrypted code for our Hello World test program we first need to encrypt it using Kabuki Encode by running the following command:


./kabuki_encode helloworld.bin helloworld.bin helloworld.bin_opcodes helloworld.bin_data 0x0000 0x30 0x00000000 0x00000000 0x0000 0x00 0
Wrote 48 (0x30) bytes

As you can observe in the example above all keys are intentionally set to 0, this is because we want to test if Kabuki's default keys after losing power default to 0.

Kabuki Encode has created for us two different files "helloworld.bin_opcodes" and "helloworld.bin_data". Kabuki handles opcodes and data bytes differently and this requires different encryption for both as explained on my previous post. 

Next is merging the resulting opcode and data files. 

This is when the tool Masker becomes handy, it helps us merge the files generated by Kabuki Encode into a single file, but before being able to use it we need to create a mask file that will tell Masker how the final resulting file should be combined.


Mask file for Hello World

Notice the file is full of FF and AA bytes, FF tells Masker to place on that position a byte from the opcode encrypted file, and AA tells it to place a byte from the data file instead. A mask file needs to be created manually and this requires that you know your program, you need to differentiate opcodes from data bytes (arguments of opcodes are data bytes too).

Let's run Masker:


./masker helloworld.bin.mask  helloworld.bin_opcodes helloworld.bin_data  helloworld.bin.final

Wrote 48 (0x30) bytes

Finally we have our final encrypted code "helloworld.bin.final". This is now ready to burn into a 27256 type eprom and off to test it on a real Pang board.


Hello World, the results

With a great amount of excitement I tested this new code encrypted with encryption keys set to 0 but I was soon faced with a reality check, it didn't work... and the same went for code tested with all encryption bits set to 1. A total fail.

Back to the drawing board

What could be going on here? Our encrypted code is totally valid and Mame is able to run it. Could there be differences in the real hardware vs the Mame emulation? We are clearly missing something here...

Time to go back to hardware and plug the logic analyzer, we need to understand exactly what's going on with Kabuki. This time we will use the original roms of the game Pang to understand the running differences of the real hardware in encrypted (pin 28 high) and non encrypted mode (pin 28 low). 

Using the method described before and with the help of our new tools I created a Pang romset encrypted with all bits set to 0 and ran it.


Pang code running encrypted on the left and unencrypted on the right

The Z80 code shown above represents a timeline of execution, the program starts at 0x58 and first takes the order to call/jump to a different code location (0x13A), before doing so it stores the address of the byte that it was supposed to execute next if there wasn't such call/jump order (0x5B).

After that it continues at the call address 0x13A and soon encounters an order to return back at 0x13E. The program recovers the address where it should execute next from the stack: 0x5B.

In the case of Kabuki running unencrypted (right side) the address recovered, 0x5B, is interpreted correctly as 0x5B. Kabuki running encrypted mode (left side) also reads 0x5B but it interprets wrongly as 0xAD therefore returning code execution to a wrong place.

Bingo! As identified with the help of a logic analyzer we can see that our suicided Kabuki (left side) is trying to decode memory ram reads and not just rom reads... What this means is that any bytes stored in memory during execution are handled as encrypted bytes when read back. This causes all programs that use memory to malfunction.

The good: This finding explains why our Hello World didn't work and confirms that indeed Kabuki defaults to 0 all encryption keys when suicided. 

The bad: We have hit ourselves with a massive stop wall... There's a new element at play not taken into account before, Kabuki must feature an additional configuration setting inside its memory that decides when to decode and not to decode byte reads, this setting probably sets which address spaces must be ignored eg: do not decode anything from 0xC000 to 0xFFFF (Pang's ram space). 

When Kabuki suicides besides losing the encryption keys it also loses this address decoding setting and leaves the cpu practically unusable. With this discovery our dream to recover dead Kabuki games with new rom code is vanished, but we have just lost a battle, not the entire war.

This is all for this week, thanks for reading and stay tuned for my next post in the Kabuki series: A better Pang desuicide.