Notes from inside your Wii

HackMii header image 2

Korean Wii

September 13th, 2008 by bushing · 26 Comments

With the kind help of naamah31 (author of WUM), James and bigwolf, I have finally gotten my hands on a filesystem dump of a Korean Wii for analysis.  It’s a little anticlimactic, but we finally have some of the answers.

Here are the vitals on its System Menu:

  Versions: 0, CA CRL 0, Signer CRL 0, System 1-40
  Title ID: 00000001-00000002
  Title Type: 1
  Group ID: '\x00\x01'
  Access Rights: 0x00000000
  Title Version: 0x146

(It identifies itself as 3.3K, and it does have the anti-Twilight Hack code.)

For comparison, here is the TMD for v3.3E:

  Versions: 0, CA CRL 0, Signer CRL 0, System 1-30
  Title ID: 00000001-00000002
  Title Type: 1
  Group ID: '\x00\x01'
  Access Rights: 0x00000000
  Title Version: 0x162

What surprised me most was not only that BC & MIOS were present on this unit — but they’re the old, pre-tweezer-hack versions. There goes that theory. (This means that the GameCube support is probably disabled inside the System Menu, but I haven’t dug into that yet.)

On to the subject of the common key! The Korean Wiis ship with IOS versions 4, 9, 21, 37, 40, 41, 43, and 45. The last four are unique to the Korean Wii, and are not available on the Nintendo Update Server, as far as I can tell. (I also have seen no sign of a new update server, so unless I’ve missed something, we will eventually see these appear on the same NUS server.)

As xt5 astutely noted, there is a field in the ticket structure — byte 0x1f1 — that is set to 1 in Korean tickets, and 0 for “normal” tickets. Pulling up IOS40 in IDA Pro, I tried the first thing I could think of — Alt-T, text search for “0x1f1”, and landed on this:

loc_20102DEA                            ; CODE XREF: ES_AddTitleStart+1F4
                LDR     R0, [R5,#8]
                LDR     R3, =0x1F1
                ADD     R3, R8
                LDRB    R3, [R3]
                LSLS    R3, R3, #2
                LDR     R2, =korean_mystery_array
                LDR     R2, [R3,R2]
                MOVS    R3, #0
                STR     R3, [SP,#0x50+var_50]
                MOV     R3, R9
                STR     R3, [SP,#0x50+var_4C]
                MOV     R4, R11
                STR     R4, [SP,#0x50+var_48]
                MOVS    R1, #0
                MOVS    R3, #1
                BL      _ES_GetKey

What’s this? An unbounded index into some mystery array? Tsk, tsk. Jumping to its definition, we see:

korean_mystery_array DCD 4, 11          ; DATA XREF: ES_AddTitleStart:off_20102EC8
                                        ; ES_DiVerifyStuff:off_20105444
                                        ; ES_ImportBoot:off_20106204

Hm… 4, 11… if we compare this to the “normal” IOSes, we see that the corresponding code looks like:

ES:2010237E                 LDR     R0, [R4,#8]
ES:20102380                 STR     R6, [SP,#0x48+var_48]
ES:20102382                 MOV     R3, R9
ES:20102384                 STR     R3, [SP,#0x48+var_44]
ES:20102386                 MOV     R5, R11
ES:20102388                 STR     R5, [SP,#0x48+var_40]
ES:2010238A                 MOVS    R1, #0
ES:2010238C                 MOVS    R2, #4
ES:2010238E                 MOVS    R3, #1
ES:20102390                 BL      _ES_GetKey

So, for traditional Wiis, we’re calling GetKey with an argument of 4, and for Korean Wiis that argument argument is selected from the array [4, 11]. What is this array?

If you look at the source code for xyzzy, you’ll see this definition:

char *key_names[] = {
  /* 0 */ "ECC Priv Key",
  /* 1 */ "Console ID  ",
  /* 2 */ "NAND AES key",
  /* 3 */ "NAND HMAC   ",
  /* 4 */ "Common key  ",
  /* 5 */ "PRNG seed ",
  /* 6 */ "SD key      ",
  /* 7 */ "Unk key 1   ",
  /* 8 */ "Unk key 2   ",
  /* 9 */ "Unk key 3   ",
  /* a */ "Unk key 4  ",

You’ll also see these entries in libogc’s es.h:

#define ES_KEY_COMMON           4
#define ES_KEY_SDCARD           6

So, key 4 is the common key — always used on non-Korean Wiis. There isn’t even an entry for key 11 on this list, because we’ve never seen it before. Looks like a winner to me.

I had hoped at this point that the key might be sitting in the actual IOS binary itself. See, IOS does this silly thing where they have a hard-coded set of default keys:

common_key      DCD 0xEBE42A22, 0x5E8593E4, 0x48D9C545, 0x7381AAF7
                                        ; DATA XREF: read_keys_from_OTP:off_FFFF1BDC
default_ng_id   DCD 0x4A39              ; DATA XREF: get_ng_id:off_FFFF1B4C
default_rng_key DCD 0xC4987385,0xE865ACA4,0x90A4FA2C,0x89A55366
                                        ; DATA XREF: read_rng_key_from_otp:off_FFFF1C14
                DCD 0x94B00000
                DCB    0
                DCB    0
default_ng_cert DCD 3, 2, 0x69D2A2EF, 0x50CC52, 0xDF2217F1, 0xE93EE19D, 0x5BB0E751
                                        ; DATA XREF: get_ng_cert:off_FFFF1D1C
                DCD 0xE5BF4CB, 0xD20B9FA4, 0xF439452B, 0x149B00BD, 0xD5813B42, 0xDD8603AA
                DCD 0xBD5909E, 0x8D5B3ED8, 0x2C575B54, 0xE75A011F, 0x27B8A5F2, 0
                DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
default_korean_key DCD  0, 0, 0, 0      ; DATA XREF: get_korean_key:off_FFFF1D54

If you have a completely blank, unprogrammed Hollywood chip, then it will detect that and use these default keys. You might notice that the default common key above bears a suspicious resemblance to the one we know and love. (This is inexcusable; most crypto implementations go to great lengths to load keys, use them, and then erase them from memory as quickly as possible. I don’t know if anyone ever bothered to actually spell out the rule that you should not hardcode your production keys into your binary, but they should have. Go read Schneier.)

You might also notice that the “Korean key” — key 11 — is all zeroes. Boooo. Let’s dig deeper.

Hiding Keys

There are two places inside the Hollywood package that contain programmable bits — a bank of OTP memory (One-Time Programmable, AKA fuses), and a serial EEPROM (which is actually reprogrammable).

The OTP area is 32 words x 32 bits = 1024 bits, total. This is actually quite a bit for an embedded OTP area — I’ve never seen another chip with that many fuses. (Most chips have more like 16.) The 32 words are organized like so:

 5x32: boot1 SHA1 hash
 4x32: common AES key
 1x32: NG ID
 7x32: NG Private Key
 5x32: NAND HMAC
 4x32: NAND AES key
 4x32: RNG key
 2x32: Unknown
32x32: Total

Whoops, looks like we’re out of room to stash keys in OTP. Even though there are 2 unknown words, we’d need 4 to store a second common key.

What about the sEEPROM? It stores a couple of flags that indicate whether this is a retail or development console (and therefore which set of public keys should be used), and then the certificate issued by Nintendo that is tacked onto your savegames. There are a couple more flags and counters stored there, but still — that’s less than half of the size of the smallest chip they could buy.

Sure enough, some digging reveals:

get_korean_key                          ; CODE XREF: load_all_keys+7C
                                        ; DATA XREF: load_all_keys:off_13A7976C
                PUSH    {R4,R5,LR}
                ADDS    R4, R0, #0
                BL      disable_interrupts
                ADDS    R5, R0, #0
                BL      is_otp_programmed
                CMP     R0, #0
                BEQ     loc_FFFF1D48
                MOVS    R0, #0x3A       ; offset
                ADDS    R1, R4, #0      ; dest
                MOVS    R2, #0x10       ; len
                BL      seeprom_read

loc_FFFF1D3C                            ; CODE XREF: get_korean_key+32
                ADDS    R0, R5, #0
                BL      enable_interrupts
                POP     {R4,R5}
                POP     {R0}
                BX      R0
; ---------------------------------------------------------------------------
loc_FFFF1D48                            ; CODE XREF: get_korean_key+10
                ADDS    R0, R4, #0
                LDR     R1, =default_korean_key
                MOVS    R2, #0x10
                BL      memcpy
                B       loc_FFFF1D3C
; ---------------------------------------------------------------------------
off_FFFF1D54    DCD default_korean_key  ; DATA XREF: get_korean_key+2A
; End of function get_korean_key

This code checks to see if the OTP area is programmed; if not, it assumes it is in the factory and uses the default key (all zeroes). If it is, it reads 0x10 bytes from offset 0x3a of the sEEPROM, and uses those.

63 b8 2b b4 f4 61 4e 2e 13 f2 fe fb ba 4c 9b 7e

Tags: Wii

26 responses so far ↓

  • 1 tona // Sep 13, 2008 at 4:07 pm

    Sounds like it was rather simple, then 😛
    Really appreciate all the background info, though.

    I’m more anxious to find out about all the fun inside the System Menu, though 🙂

  • 2 TheDuck // Sep 13, 2008 at 4:11 pm

    Wow. That was very interesting! I wonder if nammah31 can run trucha-signed disks with using that key to sign it?

  • 3 Kip // Sep 13, 2008 at 5:28 pm

    so that last line is the famous Korean Key?

    another thing, you said the sEEPROM contains some flags to identify if the system is a retail or a development one, so the repair disc screenshot showing a “Install Dev Certificates” just changes those flags?

  • 4 bottmint // Sep 13, 2008 at 6:21 pm

    if i understood code then i would say “sweet stuff this unlocks so many possibilities!!” but i dont so the most i can say is SWEET you finally got a dump of the korean wii.

  • 5 IBNobody // Sep 13, 2008 at 6:55 pm


    So if you wanted to reprogram that serial EEPROM, the Korean common key could be changed.

  • 6 paul1991 // Sep 13, 2008 at 7:00 pm

    It’s great to see some real progress made in the scene. It seems like people are more interested in piracy than progress.

    Sorry about that dvd channel wad I released. I thought it would go over better.

    One question:
    When did you learn so much about Hollywood? I thought nobody had figured out anything about it yet, but you seem to have figured out the save tag, among other things.

  • 7 Zim // Sep 13, 2008 at 7:54 pm

    Very interesting. I hope this information helps you (as well as the rest of us) to better understand the Wii in general. 🙂

  • 8 shickfaced // Sep 13, 2008 at 8:35 pm

    …impressive. I take it that because there is no separate update server and Korean IOS updates cannot be found on the update server we all know and love, that the Korean Wii was distributed after the 3.3 Twilight Fix?

  • 9 bushing // Sep 13, 2008 at 11:44 pm

    @TheDuck: “Trucha signing” doesn’t use a key. As I noted, IOS40 has the same patch that IOS37 and IOS30 received with 3.3 that prevents it from working.

    @Kip: Still not sure what that “install devel certificates” does.

    @IBNobody: Yeah, that key could be changed — say, if you wanted to convert a Wii to NTSC/K. Although it should be perfectly safe, writing to that EEPROM (using a hacked IOS) makes me uncomfortable, so I’d probably just patch IOS40 and replace the all-zero default key with the correct one, and then patch “get_korean_key” to always use the default.

    @paul1991: segher, tmbinc and I did most of the reverse-engineering of the Hollywood last year before the 24c3 presentation; since then, we’ve been joined by others.

    @schickfaced: Yup.

  • 10 jakemaheu // Sep 14, 2008 at 7:45 am

    Not to thread hijack, but speaking of keys, I’m having an issue. I’m trying to use tachtig to decrypt a savegame, and when I run ‘./tachtig’, I get “MD5 Mismatch” in Bash. Any idea what the problem is?

  • 11 Deozaan // Sep 14, 2008 at 4:31 pm

    I have to admit that I don’t understand the majority of what you’re talking about in this blog, but it sure is fascinating!

    Keep up the excellent work bushing and co.

  • 12 QLeap // Sep 14, 2008 at 9:45 pm

    Finally I could make Korean Wii ISO disc on my Japanese Wii.

    I modified partition tickets with re-encrypting Title key with the common-key after decrypting korean key. fill the signature fields with NULL bytes (referred to your patch-mii source — foging ticket part) and padding unused field to SHA1 hash ‘NULL’. (using trucha signing bug)

    Then I launched disc image with gecko-os with language setting Korean, ta-da, it launch Korean disc in Japanese Wii!

  • 13 SquidMan // Sep 16, 2008 at 6:40 pm

    Nice work guise!
    Can’t wait to see what comes out of this (Maybe some interesting behind the scenes things Nintendo did! =D)

  • 14 QLeap // Sep 23, 2008 at 3:28 pm

    IOS 46 is released for Korean Wii, which can be found in Korean Guitar Hero 3 update partition. Of course main partition needs IOS 46 according to the TMD header.

    Well, I have no idea what this version will do though because I have no Korean Wii, possibly will this block latest Twilight hack or Homebrews?

  • 15 svpe // Sep 24, 2008 at 8:20 am

    It does not block the twilight hack because that’s the System Menu’s task (and the Korean one still fails at doing so just like ours).
    All Korean IOS versions are using memcmp instead of strncmp though and therefore come without the “trucha” bug. You can however reload to one of the older IOS versions to get full control again 🙂

  • 16 QLeap // Sep 25, 2008 at 2:51 am

    Korean Wii with modchip can launch twilight princess Japanese version (but not US/EU vertion though) and then can use the twilight hack save, so many Korean Wii users are enjoying homebrews these days.

    Even with GeckoOS, it can lanuch imported DVDs and even NGC discs as well.

  • 17 orwell // Sep 30, 2008 at 11:05 pm

    Woa what good news !
    I came to korea for working and got a korean wii with modchip, but until now it was really difficult to enjoy fully the homebrew scene (the part i’m especially interested). Many of them simply stop after launching the japanese twilight hack.

    Following your post, would it be possible soon to install custom IOS and patching the system to be in another language, zone, or whatever ?

    In any case keep up the good work !

  • 18 guzzard // Oct 5, 2008 at 6:28 am


    I have a Korean Wii with firmware 3.3K and chip D2SUN 3.0 installed. I can boot Untouched Korean backups and some USA games (also have to be untouched), but i cannot get any Homebrew running. I get error messages every time. See pictures below. If anyone knows what I do wrong, or can help me get things running please contact me! Thanks!

    Trying to install HBC8:

    Gecko OS 1.07b (dol):

    Gecko OS 1.07b (elf):

    Trying to install HBC7:

    Trying to start Zelda: TP trough Backup launcher 0.1 (WiiGate):

    WadManager 1.21:

    Custom IOS installer 1.2:

  • 19 guzzard // Oct 7, 2008 at 11:58 am

    How to fix Korean Wii with firmware 3.3K to be able to play KOR/JAP/US/PAL games.


  • 20 orwell // Oct 7, 2008 at 5:43 pm

    guzzard > i have exactly same errors ㅜㅜ (my chip is : Wii Zard 2.03) Its because of our bloody firmware. Poor korean wii user we are.

    But with this post from bushing i have big hope ^^

  • 21 QLeap // Nov 8, 2008 at 12:09 am

    I made a cIOS v6 compliant with Korean Disc Supporting.

    So please check it at:

  • 22 kavid // Nov 10, 2008 at 3:20 am

    Hello,Can I use “software” change korea region to Other region,for examp,Jap,Usa or Europe。I very very hope you release the software.
    Why can Korea wii not play ngc game ?It have no any IOS ,yet hardware is different from other wii?

  • 23 FF1981 // Nov 12, 2008 at 2:40 am

    Please remember us, the korean wii users.

    There are numerous korean wiis in east-asia, especially in china .When you are designing
    software , please don’t forget us. I know korean wii is not as popular as JAP or US wii, but the
    black can be the present of USA ,there is noting we can’t do ! YES ,WE CAN !!!

  • 24 bushing // Nov 12, 2008 at 2:36 pm

    It’s not that we have “forgotten” about Korean Wii users, it’s that

    1) All Korean Wiis come from the factory with System Menu 3.3 (K) installed, which means that the fakesigning bug has been fixed. This means we can’t run any homebrew software from DVDR.

    2) It’s been impossible for me to get a Korean Wii, despite months of trying. Tona tried to add support for Korean Wiis to his AnyRegion Changer, and bricked his Wii in the process; this makes testing difficult.

  • 25 FF1981 // Nov 12, 2008 at 10:09 pm

    Still thanking you for concerning, bushing . I had

    the same situation as Tona. Here is my details if

    you are interested http://gbatemp.net/index.php?showtopic=115154

    I would like to offer my help .Is these any thing

    I can do for you just tell me , anything .
    ZZZFANG2003@yahoo.com.cn is my e-mail

    I am looking forward to your reply

  • 26 Bloodlust // Mar 29, 2009 at 8:41 pm

    If I intend to upgrade the korean Wii which is already softmodded to US firmware to 4.0, is it possible and safe? Does a korean wii on US firmware inherit all the characteristics of a real US set? Like not bricking on certain IOSes etc..

You must log in to post a comment.