127 lines
8.5 KiB
Markdown
127 lines
8.5 KiB
Markdown
# Security Dongle Theory of Operation and Dumping
|
|
|
|
All firebeat games use a Dallas DS1991 iButton connected to the firebeat through
|
|
a DB9 interface as the protection against piracy and as a factory service switch.
|
|
The DS1991 is a small 1-wire non-volatile memory device with three 48-byte
|
|
enclaves that can hold any data. Each enclave is password-protected by an 8-byte
|
|
key and identified with an 8-byte ID. In order to read a secure enclave you must
|
|
provide the correct password. If you don't, the dongle will appear to return
|
|
memory but it will be random data. It is not clear whether the data returned is
|
|
an XOR with the key provided or if the DS1991 generates actual random data when
|
|
the key is wrong. If it is an XOR then we can use knowledge of what should appear
|
|
in the enclaves as a way of brute-forcing the password, but this has not been
|
|
researched. In practice it is not necessary as all known dongle variant passwords
|
|
are extracted.
|
|
|
|
In order to access the security key without forcing the game to be initialized
|
|
and locked to a particular token, each firebeat executable must include the IDs
|
|
and passwords for the three secure enclaves. In practice, they are easy to find
|
|
in the executable as they tend to appear next to factory mode selection strings.
|
|
From examining various games and seeing how they use tokens it appears that
|
|
firebeat games use a similar mechanism for securing themselves with a dongle.
|
|
Games will read all three enclaves using three supplied IDs and passwords
|
|
embedded in the binary.
|
|
|
|
The first enclave is the unique serial number for the copy of the game and
|
|
starts with the 3-letter code for the game (C01 in the case of BeatmaniaIII The
|
|
Final) and is followed by six digits. The game will verify that the 3-letter
|
|
code is a match and reject dongles that do not match, and will display the
|
|
9-digit serial on the boot-up and attract screen. Almost every game will use
|
|
the fourth digit as a region selection switch, comparing it to the cabinet
|
|
ID register. Normally, digits 1, 3 and 7 specify Japan region, 2 and 4 specify
|
|
overseas, and 0 and 9 are reserved. Some games use 9 as a rental code, some
|
|
use 0. It does not appear to validate the rest of the digits so any valid
|
|
displayable ascii string is technically a correct dongle as long as the first
|
|
3 digits match the game code and the fourth digit is correct for the hardware
|
|
you are running on. The rest of the enclave appears to be filled with ascii
|
|
space characters.
|
|
|
|
The second enclave appears to be completely ignored in most games aside from
|
|
verifying that the data itself can be transferred. It appears to be filled
|
|
entirely with ascii space characters. For the few games that do use this
|
|
enclave (Pop'n Music Mickey Tunes, Animelo 1 and 2) this includes additional
|
|
license information. On KeyboardMania 2ndMIX this enclave appears to be filled
|
|
with random data that matches on both Japan and overseas regions so it is possible
|
|
that the enclave password is incorrect or whoever programmed the dongles didn't
|
|
initialize the second enclave properly.
|
|
|
|
The third enclave is the service mode enclave and is normally all ascii
|
|
space characters on a consumer dongle. Various games recognize various
|
|
alternate strings placed into this enclave which enable different modes
|
|
of the game. Some games have recognition for event mode, manufacturer mode,
|
|
service mode, debug mode, easy mode, and others. The game will compare the
|
|
full enclave data against a list of known strings and enable various modes
|
|
depending on which one matches, defaulting to a standard game mode if there
|
|
is no match.
|
|
|
|
There is an additional 8 byte ROM ID that is unique and read-only for each
|
|
DS1991 button. This is completely unused in firebeat games. All games skip
|
|
reading the ID and make no use of it. However, when dumping a dongle it should
|
|
be included in the dump at the end of the file. Fortunately the ROM ID is
|
|
laser engraved on the iButton itself. To retrieve the ROM ID, remove the iButton
|
|
from the DB9 enclosure and flip it over. You'll notice a 2 digit hex number on
|
|
the left, a 2 digit hex number on the right and a 12 digit hex number below
|
|
both of them. The left number is the ROM ID CRC, the right is the product code
|
|
(always 02) and the bottom is the unique serial number. This should be transcribed
|
|
by first noting down the CRC, then the 12 digit serial, and finally the product
|
|
code (02). Then the bytes should be reversed. This can be checked by using the
|
|
`dallas_crc` utility by providing the hex codes for the first seven bytes (after
|
|
reversing them), and you should get a hex CRC value that matches the 8th byte.
|
|
|
|
## Dumping Theory
|
|
|
|
In order to dump the secure enclave of a security iButton, you must know the
|
|
correct ID and password for that enclave and have hardware capable of interfacing
|
|
with the iButton itself. It just so happens that a firebeat has compatible
|
|
hardware for interfacing with an iButton, and the ID and password can be mined out
|
|
of the decompressed executable for each game. Looking at the bootup sequence
|
|
for BeatmaniaIII The Final, the game first sets up a multithreaded environment,
|
|
then kicks off a watchdog thread and then kicks off the main game thread. The
|
|
main game thread performs some basic C runtime initialization and then jumps
|
|
to the hardware init and check code. The check code first prints the checklist
|
|
of all areas to verify and then starts by initializing the IO. Then it reads
|
|
and verifies the dongle before moving on to the rest of the checks. The dongle
|
|
read code first zeros out the serial number global, then performs a secure
|
|
enclave read for each of the three enclaves, and finally verifies the data in
|
|
those enclaves. The first, as documented above, is verified to start with "C01"
|
|
and then the 9 digit serial number is copied to the serial number global. The
|
|
second enclave is ignored, and the third enclave is compared against manufacture
|
|
mode and service mode strings and if found, a manufacture mode global is set.
|
|
Finally, the function returns with a return code that signifies that either the
|
|
dongle was not presesnt, the dongle was present but the serial was bad, or that
|
|
everything was good and to continue booting. The serial global is displayed
|
|
on the startup screen below the game model number and it continues booting.
|
|
|
|
Two things can be gained from this understanding. First, that the game does
|
|
not seem to use the serial number in any way aside from verifying that it is
|
|
in the correct range and matches the cabinet info register's region. This means
|
|
that it is trivial to bypass the security by simply skipping the dongle read
|
|
and jumping directly to the "OK" response. Second, if you have the correct IDs
|
|
and passwords for a dongle in the game's code, it will read all 3 48-byte
|
|
enclaves to a buffer on the stack. This means if you were to modify the serial
|
|
number copy and check code to instead copy the hex values of all 3 enclaves to
|
|
the serial number global before returning you would have a working dongle dump
|
|
utility. This is precisely what the dongledumper.patch modifications achieve.
|
|
The meat of the change is replacing the check and copy with a hex conversion loop
|
|
and resizing the stack for the game's printf implementation so that the very long
|
|
string doesn't blow the stack and cause an exception. The rest of the
|
|
modifications are there to make the output on the screen prettier and to halt the
|
|
game from continuing once it does print the dongle while still petting the
|
|
watchdog. To read the dongle for another game, one must replace the ID and
|
|
password strings with the correct ID and password pairs from that game itself.
|
|
This can be accomplished using the `dongle_dump_utils` utility which already
|
|
contains all of the known passwords. Aside from that, everything works as desired.
|
|
|
|
Once you have all three enclaves output and have noted the ROM ID from the
|
|
iButton itself, you can reconstruct a dongle file for use with MAME or to rewrite
|
|
a new dongle if you have the capability. For MAME, the dongle file should look
|
|
like a raw dump of the entire iButton from the perspective of the iButton
|
|
internals. That means the first ID (8 bytes), then the first password (8 bytes)
|
|
and then the first enclave (48 bytes). Concatenate those, and do the same for
|
|
the second ID, password and enclave, followed by the third. Finally, the 8
|
|
byte ROM ID should follow all 3 enclaves. If done correctly, the resulting file
|
|
should be exactly 200 bytes long. If you have an empty iButton you can program
|
|
the three enclaves by using the ID and passwords followed by a copy of the data
|
|
from another dongle or hand crafted data if you so desire. You can also verify
|
|
that your dump looks correct using the `dongle_dump_utils` utlity.
|