ArcadeHustle / X3_USB_softmod

Taito X3 USB Boot Softmod
7 stars 5 forks source link

What is the X3 Bios password? #4

Open ArcadeHustle opened 4 years ago

ArcadeHustle commented 4 years ago

https://web.archive.org/web/20190113135124/https://arcademachinist.com/

This post would be updated time to time. DISCLAMER Taito X3 is current commercial arcade system, beeing shifted-out by X4, but still. This research is provided for INFORMATIVE AND EDUCATIONAL PURPOSES ONLY. You should legally own the machine, hard drive and matching hardware key. As every X3 owner knows - it comes with a locked BIOS, that just shows you a nice startup fullscreen logo. BIOS Setup has a non-standart hotkey combination Ctrl + Alt + F9 And then you are greeted by very familiar looking AMI bios password prompt. As I have read on different forums - people tried resetting the CMOS to remove the password, and it did not work. Resetting CMOS RAM kills some valuable information, used for ATAsec disk key calculation, but it does not remove the BIOS password. Actually it is not something Taito invented, AMI bios manufacturer toolkit has a configurable option to keep bios setup passwords on cmos reset. So - where it keeps the password? I had to do some self-education to catch up on how modern BIOS works, where it can store things, what is all that UEFI stuff, etc. As this stuff fall out of my interests area, and last time I was playing with BIOS internals was somewhere in i80386 era. So modern BIOSes can store data both in CMOS RAM, which is now part of chipset itself, and is a battery backedup very small memory area of 128 or 256 bytes. Alternative way is to store things in the NVRAM, which is actually a memory area inside SPI flash chip, that holds BIOS image itself (as well as many more stuff like Intel ME, GbE bios, etc).

As we know from other guy's experience of killing his X3 with a CMOS reset - bios password is in the NVRAM, on the SPI flash chip. Looking at the mainboard - you can spot it immediatly, in comes with yellow/green color sticker. I have removed the sticker to discover that the chip is MX25L6406E, which is Macronix 64 Mbit (8Mbytes) SPI flash, with a standart command set.

Before messing with the chip I have decided to try dumping SPI flash chip from NodeMCU clone. It is half the size, but command set and pinout is compatible. I have spent a whole day playing with different combinations of Arduino, level converters and clips. I was able to use FlashROM Tools with an Arduino UNO, programmed with "frser-duino" Do not use under virtual machine - it would not work, because of messed timings As a side note: Adafruit's bidirectional logic level shifter did not work for me, and I have converted my Arduino Uno to 3.3v by replacing voltage regulator. Then it turned out that it is not possible to communicate with SPI chip without removing onboard battery, what we do not want to do for sure, as our precious keys from CMOS ram would be gone.

Had to de-solder the chip from the mainboard. With some damage, as it looks like it was not just soldered to the m/b, but also glued. One trace was damaged and I had to rebuilt it. I really don't get it how people can manually repair stuff like QFP240. Long story short - I was able to completly dump SPI flash chip. Chip contains Intel ME Flash Image. Which can be read and parsed by many different tools like these: Intel ME Flash Tools or UEFITool.

There are tons of interesting stuff inside, and I would return to that later, as ATASec hashing functions are also sitting somewhere there, but for now we need to understand where the BIOS stores it's password. Looking thru the listing you can see it is an AMI Bios. This:

(Original post) was very helpful with confirming that the password is actually stored in AMITSESetup structure. Each character is represented by 2 bytes. Just looking at this data and two passwords (111 and 111111) from that post, I already can see some patterns. Can you? Taito's AMITSESetup looks the same, just first half is zero'ed, as "Administrator" password is not set, only "User" password is active. Still don't see the pattern? Despite AMI BIOS toolkit has all necessary hooks for a manufacturer to implement their own encryption routine - X3 uses AMI's default, with default key. Suprisingly there is not much information about this default alghorithm on the Internet, but in 2013 a manufacturer, called Jetway, accidently leaked AMI BIOS toolchain and partial sources, if you would look carefully thru - you would spot void PasswordEncode(CHAR16 *Password, int MaxSize) that gives you everything you need. The actual password is quite simple, I was expecting some long cryptic string, unique for each machine, or at least for each machine/game combination. But no, it's simplicity suggests - it is the same for all X3s, and may be for other X's.

Unfortunatly there is not much you can do inside the BIOS Setup utility. May be adjust the clock, as mine is 3 days late :) BIOS does see USB drives (as seen in the picture above), but it is impossible to select it for boot, or change boot order in anyway. Only first SATA drive is showing up, nothing else. FUTURE research: ATAsec calculations - where excatly in BIOS are they and how they work. What is the boot block offset? (Even if you sucesfully unlock non-Taito HDD from BIOS - it won't boot, seems BIOS reads non-standart sectors for a boot-block).

tn_X3_AMITSESetup tn_X3_PasswordComparsion

ArcadeHustle commented 4 years ago

You'll need this as mentioned. https://www.techpowerup.com/182484/amibios-source-code-and-amis-uefi-signing-key-leaked

ArcadeHustle commented 4 years ago

https://github.com/raywugithub/zprj/blob/b7c51c9cf4864df6aabb99a1ae843becd577237c/EDK/MiniSetup/PasswordEncode/PasswordEncode.c#L161

VOID PasswordEncode( CHAR16 *Password, UINTN MaxSize) {

if TSE_HASH_PASSWORD

UINTN   ii;
EFI_STATUS Status;
UINTN HashSize = SHA1_DIGEST_SIZE;

if (IsPasswordSupportNonCaseSensitive ())
{
    for ( ii = 0; ii < MaxSize/2; ii++ )
        Password[ii] = ((Password[ii]>=L'a')&&(Password[ii]<=L'z'))?(Password[ii]+L'A'-L'a'):Password[ii];
}

Status = Hash(&gEfiHashAlgorithmSha1Guid, TRUE, (CONST UINT8**)&Password, (CONST UINTN*)&MaxSize, (UINT8*)&HashOutput);

if (!EFI_ERROR (Status)) { MemSet (Password, MaxSize, 0); TseMemCopy ((UINT8)Password, (UINT8)HashOutput, HashSize); }

else

TsePasswordEncodeLocal (Password, MaxSize);

endif