Thursday, April 2, 2020

Help us preserve Great Swordsman!

UPDATE 2020-04-06: we tentatively have enough submissions to decode the ROMs, assuming a few people we know are working on them finish. Thanks to all of those that have submitted and we'll try to post an update in the near future!

Arcade Game: Great Swordsman (1984 Taito) - YouTube

Previously we decapped a few NEC D8041AH MCUs from Great Swordsman in order to better document the game. Unfortunately the images were a little hard to read. However we recently decapped a new AA-016 (C031) and a new AA-017 (C032) and the contrast is much better! Specific cause hasn't been investigated.


Anyway, we are looking for help digitizing the firmware microscope images into bits. This can be done either by manually typing out all 8192 bits or using the rompar utility (preferred)

If you're interested, here is the raw data:

  • AA-016
    • Suggested: nec_8041ah_gswm_aa-016_decap-c031_xpol.jpg
  • AA-017:
    • Suggested: nec_8041ah_gswm_aa-017_decap-c032_xpol.jpg

Specifically:
  • We are especially looking for help with AA-016
  • Multiple people submitting improves accuracy
  • There are some stitching artifacts. If they get in the way of digitizing we can revisit stitching
  • If applicable, please provide rompar project file
  • We will take care of post processing into binary
  • rompar_decap-8_rom_mit20x_xpol is provided as a reference project. Note the image contrast wasn't great, so there were a lot of errors
  • By convention, brighter bits are generally typed as "1" and dark as "0". But we can accept either
  • Advanced rompar users: you can use the reference project as a template, but you'll need to re-align the images. We did this to produce the above rompar image while checking AA-017 results
Please let us know if you have any questions!

Update 2020-04-04


We are starting to process submissions. Thanks to everyone who has submitted so far!

It seems there's some confusion as to where the ROM starts and ends. The above image shows the first 4 rows. When this is exported from rompar it looks like this:

11101011...
01001000...

01101011...
11001101...
...

This is because the the rows are designed in pairs, but the paired bits have some space between them. That is, the bits that actually are adjacent are not from the same pair. This has caused some people to skip the first row:


And give it as:

01001000...
01101011...

11001101...

So with that in mind, we suggest you type it up closer to this if you want to preserve a rough visual layout:

11101011...

01001000...
01101011...

11001101...
...

This won't match rompar output, but this doesn't effect post processing. Hope that helps clarify!

Prologue

Enjoy this post? Please support us on Patreon or follow us on TwitterNote: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.

Monday, December 23, 2019

Dump December: 8051 and lasers

First, we've we've created a Twitter account to help announce blog posts! As always, Patreon supporters get early access, but we'll tweet once they become public.


Anyway, in a previous post we mentioned a new shipment. We've been working it over and have a bunch of updates!



First, there were a few NES 2.0 Mapper 355 PIC16C54 from Block Force (C059) and 3D Block (C060). One of these has been obfuscated by sanding.



These are similar to other PIC16C5X we've done and were dumped using a UV mask roughly around the EPROM.



Next we targeted SemiCom Hatch Catch's Intel 87C52 (246) because we had dumped an Intel 87C51 and it seemed likely we'd be able to extend the attack. However, decapping yielded a surprise:





It's not an 87C52! After a little digging, it's become apparent that Intel 87C52 isn't a real part. Rather, it's a marketing name for the smallest member of the 87C51FX series marketed to people familiar with 8751/8752 differences.

In any case, this wasn't so bad as we heard there was a laser glitch attack against Intel 87C51FA. The basic idea is to randomly flip transistors with a laser until you find one that happens to unlock the chip. After a little prodding (100 mW green, 45 degree angle)...



...we found an area that unlocked the firmware! This resulted in a good dump for SemiCom Hatch Catch without any encryption applied (see for details on 8751 encryption).


Next we checked if we could extend the attack to the Philips 87C52 parts which are in various SemiCom games (ex: CHOKY!CHOKY!, 247). However we once again we encountered shenanigans with chip markings. Here are two chips that are both "P87C52EBPN":




Which are clearly different! Comparing logos:



So a similar scheme as Intel, but even within what should be the same model (P87C52EBPN) we are finding multiple dies. Without being familiar with Philips part numbering it's hard to say exactly why this is, but it's plausible some of these were remarked.

In any case, we explored a UV attack against 87C52 / XSC6644A as used in CHOKY!CHOKY!:


This is a very tight mask very close to data:


But it gets worse. It appears activating security involves row specific security fuses spread throughout the entire configuration section. So to fully unlock the chip you need to erase many fuses across the entire config column! With this in mind, we decided to use something with a naturally straight edge instead of making a tight nail polish mask along the entire column:


And above shows the actual mask used to dump CHOKY!CHOKY!



Next we looked at Philips 87C51RA+ which is used on several games such as SemiCom Dream World (248) and SemiCom Date Quiz GoGo (255). While we might be able to extend the masking attack on Philips 87C52, it was very touchy. With some experience with the Intel 87C51FA laser glitch, we wondered if Philips 87C51RA+ has a similar vulnerability?


And it does! This gave us what looked like encrypted binaries for both of these games. However, upon closer inspection Date Quiz wasn't encrypted, it just had an unusual structure. First, while most MCS51 binaries have a vector jump table at the beginning. Date Quiz immediately begins main() code. Second, most of the ROM is a large random binary. However, between these two it has a 00 filled section, the low entropy which indicates a trivial encryption key. Second, Dream World had a non-trivial key, but was FF filled at the end, which made the key trivial to extract.

Next, we wondered what else might be vulnerable to laser glitching? We tried Atmel AT89C51 and...


Much to our surprise we also found a glitch! We heard this part was likely going to require microprobing which, although not out of the question, was going to make it much harder.


This allowed dumping Quizard 2, German, TAB DN 122 D3 (C054) and Quizard 4, Czech, TS142 CZ1 (C057).

However, C057 has this near the end:

00000910  00 0a 14 02 00 0a 1e 03  00 0a 32 04 00 0f 1e 02  |..........2.....|
00000920  00 ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000930  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000a00  ff ff ff ff ff ff ff ff  ff ff fa ff ff ff ff ff  |................|
00000a10  ff ff fa ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000a20  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000a40  fa ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
00000a50  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000a80  ff ff ff ff ff ff ff ff  ff ff fa ff ff ff ff ff  |................|
00000a90  ff ff ff ff ff ff ff ff  fa ff ff ff ff ff ff ff  |................|
00000aa0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|
*
00000ac0  ff ff ff ff ff ff ff ff  ff ff fb ff ff ff ff ff  |................|
00000ad0  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|

We often seem ROMs end in fill patterns like FF, but they should be solid without bit flips. So why do we think this is correct?

Let's dive a little deeper into our laser glitching approach. First, we program a sample with a known pattern and secure it. Next, we create a script that repeatedly reads the chip, saves the current read, and also displays the current read. While this is running, we sweep a laser around the die, focusing near EPROM, until valid looking data shows up. We then tweak the laser until we get a stable readout. In the case of C057, we held the laser stable and observed 40+ consecutive dumps with the same pattern. While we can't for sure rule out bit flips, this at least gives reasonable confidence the binary is correct. Finally, we also do quick disassembly of dumps to verify assembly looks mostly reasonable.


We also hoped to work on 8752BH, but had issues getting our samples programmed. We suspect they are faulty and have new samples on order. 

So between PIC16C54, Intel 87C51FA (87C52), Philips 87C52 (P87C52EBPN), Philips 87C51RA+ (P87C52EBPN), and Atmel AT89C51 dumps this month, we so far have been 8 dumps in December!


Now for some less good news. We developed a technique to dump EPM5032DC which is used on some Sega System 24 games. Unfortunately we had some issues while decapping Quiz Mekuromeku Story (249) and Quiz Rouka Ni Tattenasai (250). Specifically 249 appears to have been scratched (above), and 250 is under evaluation. We are determining what can be salvaged and, having resolved the decap issue, are looking for replacements if available.


Finally, stay tuned for ROM staining adventures! Part of the Furby ROM can be seen above. On that note, we've seen there are a few good resources on the Furby, scanned source code and a small effort to transcribe it. However, nobody has followed up to convert it into a full .asm for assembling, which would be very interesting to compare to our upcoming capture. We also need to figure out what info and tools are out there on the SPC81A architecture to compile the .asm and disassemble our binary.

Enjoy this post? Please support us on Patreon or follow us on TwitterNote: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.

Thursday, October 24, 2019

C055: changyu2/CYE 87C51

TeamEurope recently asked us to dump an 87C51. We thought we had done this before, but turns out we had only looked at related chips like 8751H and 87C51FA. This adds a few complications:
  • Not known if vulnerable to laser glitching like 87C51FA
  • Don't have a known fuse location like 8751H
  • Not familiar with the XOR encryption scheme


So we procured some sample chips, this time literally marked SAMPLE.


Sample decapped


After a few masking tests, we discover the security fuses are in the location marked above. This makes the project interesting because its rather close to the EPROM. However, we are able to apply masks reasonably precisely, so didn't worry about this too much.



Here is the final mask on C055. Note that the mask was applied pretty heavily to try to minimize edge leakage.

00000000  ec e1 45 b3 09 23 a2 dc  fd bf 76 65 8d 61 20 a3  |..E..#....ve.a .|
00000010  21 54 fc 76 da ef 54 32  44 da bc 30 54 33 35 61  |!T.v..T2D..0T35a|
00000020  12 32 45 83 f4 5d a2 dc  fd bf 76 55 fa c8 12 9e  |.2E..]....vU....|
00000030  51 de b3 b3 66 a0 a3 b8  2b e5 10 92 5b 8f 5a a9  |Q...f...+...[.Z.|
00000040  98 44 ab c4 87 7f 28 a9  13 35 01 16 fa d8 02 28  |.D....(..5.....(|
...
This yields the ROM above!

However, this is encrypted, so we now need to address cracking the XOR table. The basic idea is that there are 0x20 XOR encryption key bytes that are linearly applied, modulo the address. However, since the default key of 0xFF should not change the contents, the result is also inverted. This yields something like this:

for address, pt_byte in enumerate(plaintext):
    encrypted[i] = pt_byte ^ key[address % len(key)] ^ 0xFF

Now with this in mind, note that the key cannot be read out, even if the chip is unprotected. Some options to deal with this:
  • Reprogram the table and XOR out the key from the new ROM readout
  • Guess the key
Guessing the key is probably not too hard as, for example, usually firmware starts with LJMP (0x02). More on this later.

We started by looking at reprogramming the XOR table as a direct extraction technique. Unfortunately, our primary programmer (BP Microsystems) doesn't allow directly programming the table. However, the commercial minipro software did:


We set the key to 0 which yielded this:

00000000  fe d3 00 fd fd 7e 00 00  00 00 00 fd fd fe cd 00  |.....~..........|
00000010  00 00 00 cd 00 00 00 00  00 00 00 cd 00 00 00 00  |................|
00000020  00 00 00 cd 00 00 00 00  00 00 00 cd 8a 57 ff 3d  |.............W.=|
00000030  70 8a 4f 08 bc 4f f7 8a  6f 3f ac 6f 0f bc 6f c8  |p.O..O..o?.o..o.|
00000040  8a 76 ee 8a 73 22 8a 75  ee 8a 77 8e 8a 47 ef 8b  |.v..s".u..w..G..|

Now XOR'ing the two dumps:

00000000  12 32 45 4e f4 5d a2 dc  fd bf 76 98 70 9f ed a3  |.2EN.]....v.p...|
00000010  21 54 fc bb da ef 54 32  44 da bc fd 54 33 35 61  |!T....T2D...T35a|
00000020  12 32 45 4e f4 5d a2 dc  fd bf 76 98 70 9f ed a3  |.2EN.]....v.p...|
00000030  21 54 fc bb da ef 54 32  44 da bc fd 54 33 35 61  |!T....T2D...T35a|
00000040  12 32 45 4e f4 5d a2 dc  fd bf 76 98 70 9f ed a3  |.2EN.]....v.p...|

Which means the encryption key is:

00000000  12 32 45 4e f4 5d a2 dc  fd bf 76 98 70 9f ed a3  |.2EN.]....v.p...|
00000010  21 54 fc bb da ef 54 32  44 da bc fd 54 33 35 61  |!T....T2D...T35a|

Applying the key now to the original dump:

00000000  01 2c ff 02 02 81 ff ff  ff ff ff 02 02 01 32 ff  |.,............2.|
00000010  ff ff ff 32 ff ff ff ff  ff ff ff 32 ff ff ff ff  |...2.......2....|
00000020  ff ff ff 32 ff ff ff ff  ff ff ff 32 75 a8 00 c2  |...2.......2u...|
00000030  8f 75 b0 f7 43 b0 08 75  90 c0 53 90 f0 43 90 37  |.u..C..u..S..C.7|
00000040  75 89 11 75 8c dd 75 8a  11 75 88 71 75 b8 10 74  |u..u..u..u.qu..t|

However, this is suspicious. Usually the first mcs51 instruction is 0x02 (LJMP). However, popping into Ghidra:


Aha! They've just used AJMP instead of LJMP. Additionally we see clean disassembly and familiar register initialization. We have a dump!

Finally, what if we tried guessing the key? Well, we probably undersold just how bad this scheme is. One major flaw is that often people don't use the entire chip and its partly left unprogrammed (ie 0xFF filled). Here's the end of the encrypted dump:

00000fa0  ae cd bc bd f5 82 66 23  04 4c 77 47 ba 60 14 50  |......f#.LwG.`.P|
00000fb0  20 8b 2c 44 23 1c 55 cd  bb 25 43 02 ab cc ca 9e  | .,D#.U..%C.....|
00000fc0  ed cd ba b1 0b a2 5d 23  02 40 89 67 8f 60 12 5c  |......]#.@.g.`.\|
00000fd0  de ab 03 44 25 10 ab cd  bb 25 43 02 ab cc ca 9e  |...D%....%C.....|
00000fe0  ed cd ba b1 0b a2 5d 23  02 40 89 67 8f 60 12 5c  |......]#.@.g.`.\|
00000ff0  de ab 03 44 25 10 ab cd  bb 25 43 02 ab cc ca 9e  |...D%....%C.....|

Where near the end we clearly see a pattern repeated every 0x20 bytes, the telltale sign of filling with 0xFF. So yeah...pretty weak encryption as this is simply inverted to extract the key.


We also recently received a bunch more chips, including a number of 87C5X. So hopefully there will be a follow up soon.

Enjoy this post? Please support us on Patreon! Note: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.

Wednesday, October 2, 2019

AT89C51 glitching


Above: MJ-DFMJ. AT89C51 lower left

We have a number of inherited dumped AT89C51 chips in our inventory as well as a few new undumped ones:

AT89C51 is known to be vulnerable to voltage glitching. Basically there is a race condition when erasing where the security fuse is erased before the main data. If you pull power at just the right time, you clear protection without erasing the data.

However, we had a few concerns approaching this:
  1. If glitching fails, it may erase the part
  2. Concerns over EA damaged to prevent readout
  3. Known microprobing alternate attack

We started by analyzing the chip health to see if they had damaged EA or other issues. While we didn't detect any issues with EA, we did see some odd behavior on C056. When an AT89C51 is protected, the debug interface shuts down and results in the following observations:
  1. Memory is read as 0xFF
  2. Chip ID as 0xFFF00
C056 reported its memory as 0xFF, but the chip ID was reported correctly (0x1E51FF). This implies that the chip is not only unlocked, but its also erased! To confirm this, we did the following:
  1. Create a test pattern of all FF's, except FE on the first byte
  2. Program test pattern, making sure erase is not selected. Programming will likely fail due to first byte not matching
  3. Read back chip. If unprotected, bit 0x01 is cleared on the first byte
When tested on C056 programming did not fail and the first bit was cleared. Unfortunately this is pretty concrete evidence the chip is not protected, and is indeed blank.

Moving on, we still have two chips that we'd like to dump. After some discussion, we decided the best approach was to attempt glitching once. If it fails, fallback to microprobing. Originally we tried implementing the glitch ourselves, but got access to a RunFei commercial voltage glitcher and went with that instead. Unfortunately, C054 did not dump via glitching and will have to be microprobed. 


However, C017 succeeded! It's unfortunate we only got 1/3 dumped so far, but its still good progress that 2/3 of our AT89C51 inventory is processed. We are also investigating using the RunFei for related chips like AT89C2051.

Stay tuned for a post on 87C51!


Enjoy this post? Please support us on Patreon! Note: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.

Lucky HD647180


We previously dumped some HD647180 and TeamEurope asked if we could do a few more.


The new chips are in obscure gambling machines of which little is known other than a little work on Lucky 74. The boards don't even work, but we hope that a successful ROM extraction could be used to learn more about them.



However, these were in the more obscure SDIP90 package. To truly appreciate their massive size, here'ss one with a DIP40.



We've numbered these C050 to C053. They are the same size as a Motorola 68K, but have a 0.07" pitch instead of 0.1". SDIP90 seems rather uncommon and I wonder if there are any other chips that use this package.


Unfortunately, while we both BP Microsystems and Xeltek make SDIP adapters, we've only seen them to 64 pins.


So TeamEurope helped design an SDIP90 to 27C256 EPROM adapter so that we could use a commodity device programmer. Originally we thought we'd have to solder each chip in, but somehow managed to find an SDIP90 socket.


We proceeded to decap a sample SDIP90 part to try to reduce the following risks:

  1. Organic film over chip can be difficult to remove
  2. Some QFN parts have a wire bonding defect (see previous post)
  3. The SDIP adapter was untested
Early testing also revealed the sample was received protected. Interestingly, it had a similar sticker residue (the sticker itself was gone) to the target chips.


Here's some of an organic layer that wasn't fully removed. It must at least be partially removed to expose the security fuse and allow applying a mask to protect the EPROM. We're not sure what its made out of, but its possibly silicone. Its very chemically resistant but is relatively soft and, if the bond pads are strong, can be removed mechanically by gently tugging on it. More chemical treatment seems to soften it more, so is a delicate balance between prolonged acid exposure (weakens material but can weaken pads) and mechanical force applied to the wires. On the sample we used a mix of white fuming nitric acid (WFNA) and H2SO4 at a relatively low temperature based on some previous notes. This seemed to work pretty well and the sample was processed successfully.


No bonding defects were found.


We applied a UV mask like done previously and cleared the security bit. Fortunately the adapter worked we we successfully dumped the sample! Unfortunately, there are no strings in it, so we really aren't sure what it is.

Anyway, the process was then repeated to successfully dump C051 to C053! Sample strings from Lucky 21-D / C051:

000011d0  13 e1 c1 23 23 10 dc cd  08 06 c9 18 43 52 45 44 |...##.......CRED|
000011e0  49 54 20 49 4e 00 18 43  52 45 44 49 54 20 4f 55 |IT IN..CREDIT OU|
000011f0  54 00 18 43 52 45 44 49  54 20 25 00 18 25 00 18 |T..CREDIT %..%..|
00001200  54 4f 54 41 4c 20 42 45  54 00 18 54 4f 54 41 4c |TOTAL BET..TOTAL|
00001210  20 57 49 4e 00 18 57 49  4e 20 25 00 18 25 00 18 | WIN..WIN %..%..|
00001220  50 4c 41 59 20 43 4f 55  4e 54 00 18 25 53 45 54 |PLAY COUNT..%SET|
00001230  20 43 4f 55 4e 54 00 18  50 4f 57 45 52 20 4f 4e | COUNT..POWER ON|
00001240  20 43 4f 55 4e 54 00 10  50 55 53 48 20 53 54 41 | COUNT..PUSH STA|
00001250  52 54 20 53 57 20 46 4f  52 20 51 55 49 54 00 20 |RT SW FOR QUIT. |

However, you may have noticed we omitted C050 (Lucky 25). We were having some issues removing the organic layer and so did a little more H2SO4 acid soak at a relatively low temperature. While this was fine in testing, it resulted in corrosion on C050 pads. We switched to pure WFNA for C051 to C053, which results in more package wear but, when done properly, is gentler on the actual die. We're looking into options to repair the pads. This would be pretty straightforward with a FIB, but unfortunately don't have access to one. There are also some alternatives under investigation.

Special thanks to TeamEurope for both supplying the chips and designing the adapter board! Finally, stay tuned for AT89C51 glitching post!

Enjoy this post? Please support us on Patreon! Note: with the Indiegogo campaign over we unfortunately don't currently have a way to accept one time donations.