Hacking SEEPROM

tueidj

I R Expert
OP
Member
Joined
Jan 8, 2009
Messages
2,569
Trophies
0
Website
Visit site
XP
999
Country
First some background info, followed by a story then some code.

A lot of people know the wii contains a SEEPROM but the purpose of it doesn't seem to be very well understood. It's similar to the OTP area but it's writable; IOS actually writes to it every time it starts. It contains a few things that might (but typically aren't) need to be updated at some point (the MS and CA key IDs, the boot2 version, the NAND generation), some things which are static but don't fit in the OTP (NG specific data, korean key) and one thing that is updated very often (PRNG seed). The korean key is particularly interesting because its presence is the only thing that is different (at a low-level) between a regular wii and a korean wii - it's the cause of the 003 error (we'll come back to this later).
Even though the physical SEEPROM is apparently an embedded part of hollywood/starlet it seems to be functionally identical to an atmel AT93C56 with the ORG pin tied to VCC (16 bit word size). This chip uses a three wire serial interface, which means you talk to it by setting the data input line to the bit value you want to send then toggle the clock line and check the data out line (if you care about the output). These lines along with the chip select line are all exposed via GPIOs which are easy enough to use from Broadway if AHBPROT has been disabled to give access to the right registers. Normally however only starlet/the IOS kernel can talk to the SEEPROM and it normally only happens during IOS startup; the kernel fetches all the required info into RAM and the other parts of IOS can only access/change it via various syscalls (so even if you find an exploit in an IOS module, you won't be able to access the SEEPROM from user mode). There are other very important pieces of information from the atmel spec, such as:
- 16-bit word size, addresses are not in bytes
- self-timed write cycle, so if broadway or starlet crash in the middle of a write it doesn't matter
- no separate erase cycle needed before writing
- command/write timings

Back in 2008 when the korean wiis first appeared, the existing IOSes knew nothing about the existence of the korean key. The first one to acknowledge it was IOS37v2070 which was also the first IOS to have a fixed signature check, DLC support and quite a lot of other security fixes - before it appeared IOS was trivial to exploit because no input validation was performed, it was simple to overwrite memory and hijack code execution. But unfortunately the korean key support introduced a major flaw into their shiny new "secure" IOS. If you've ever compared DLC files from different wiis for songs downloaded in Rock Band 2 or Guitar Hero World Tour, you might notice they're almost identical. They're not actually meant to be; they're supposedly encrypted with the PRNG key which is different for every console but instead are encrypted with a key made up of all zeroes (a NULL key). I figured this out a long time ago and it was what allowed the early versions of RawkSD to create .bin files for custom songs on a PC that had no knowledge about the wii they were going to be used with. It is also what caused those same .bin files to crash when the game was played using wanky's cIOS - it used a different IOS base that used the real PRNG key instead of a NULL key. This IOS code shows the actual cause of the bug:
Code:
LOAD:FFFF1D20 read_korean_key						 ; CODE XREF: load_all_keys+7Cj
LOAD:FFFF1D20										 ; DATA XREF: LOAD:off_13A7976Co
LOAD:FFFF1D20				 PUSH	{R4,R5,LR}
LOAD:FFFF1D22				 ADDS	R4, R0, #0
LOAD:FFFF1D24				 BL	  os_disable_interrupts_thunk
LOAD:FFFF1D28				 ADDS	R5, R0, #0
LOAD:FFFF1D2A				 BL	  init_otp_data
LOAD:FFFF1D2E				 CMP	 R0, #0
LOAD:FFFF1D30				 BEQ	 loc_FFFF1D48
LOAD:FFFF1D32				 MOVS	R0, #0x3A	   ; offset
LOAD:FFFF1D34				 ADDS	R1, R4, #0	  ; dest
LOAD:FFFF1D36				 MOVS	R2, #0x10	   ; word_count
LOAD:FFFF1D38				 BL	  read_seeprom_words
LOAD:FFFF1D3C
LOAD:FFFF1D3C loc_FFFF1D3C							; CODE XREF: read_korean_key+32j
LOAD:FFFF1D3C				 ADDS	R0, R5, #0
LOAD:FFFF1D3E				 BL	  os_enable_interrupts
LOAD:FFFF1D42				 POP	 {R4,R5}
LOAD:FFFF1D44				 POP	 {R0}
LOAD:FFFF1D46				 BX	  R0
LOAD:FFFF1D48 ; ---------------------------------------------------------------------------
LOAD:FFFF1D48
LOAD:FFFF1D48 loc_FFFF1D48							; CODE XREF: read_korean_key+10j
LOAD:FFFF1D48				 ADDS	R0, R4, #0
LOAD:FFFF1D4A				 LDR	 R1, =default_korean_key
LOAD:FFFF1D4C				 MOVS	R2, #0x10
LOAD:FFFF1D4E				 BL	  memcpy_2
LOAD:FFFF1D52				 B	   loc_FFFF1D3C
LOAD:FFFF1D52 ; End of function read_korean_key
The read_seeprom_words function takes three arguments: the offset (in words) of the data to read from the seeprom, the destination in memory where the data will be copied to and the word_count tells how many words to copy. Remember each SEEPROM word is 16-bits (2 bytes) so this code is reading 16*2 = 32 bytes while the korean key is only 16 bytes long. The 16 bytes following the korean key in the SEEPROM are empty but the area in memory that they are being loaded into (16 bytes after dest) is where the console's PRNG key has already been loaded into - so it gets overwritten with zeroes and that is what is used to encrypt/decrypt the songs.
The funny thing is that ninty eventually noticed this mistake and changed word_count to 8 in all future IOSes but that introduced a new problem: thousands of DLC songs had already been downloaded and saved to people's SD cards using the NULL key, fixing the bug would require all those songs to be redownloaded. So they added a hack in the ES module: whenever DLC from Guitar Hero World Tour or Rock Band 2 is loaded from the SD card a NULL key is explicitly used to encrypt/decrypt it instead of the PRNG key. Thus preserving their security breach for future generations.

Getting back to the pesky 003 error: if it's caused by the presence of the korean key why not just erase it from the SEEPROM? This is pretty easy since code to read the seeprom already exists (from MINI) and the missing commands are in the atmel documentation:
Code:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License 2.0 for more details.

#define HW_GPIO1OUT		0x0D8000E0
#define HW_GPIO1IN		0x0D8000E8

enum {
GP_EEP_CS = 0x000400,
GP_EEP_CLK = 0x000800,
GP_EEP_MOSI = 0x001000,
GP_EEP_MISO = 0x002000
};
#define eeprom_delay() usleep(5)

static void seeprom_send_bits(int b, int bits) {
while (bits--) {
if (b & (1 >=1;

// don't interrupt us, this is srs bsns
_CPU_ISR_Disable(level);

mask32(HW_GPIO1OUT, GP_EEP_CLK, 0);
mask32(HW_GPIO1OUT, GP_EEP_CS, 0);
eeprom_delay();

// EWEN - Enable programming commands
mask32(HW_GPIO1OUT, 0, GP_EEP_CS);
seeprom_send_bits(0x4FF, 11);
mask32(HW_GPIO1OUT, GP_EEP_CS, 0);
eeprom_delay();

for (i = 0; i < size; i++) {
send = (ptr[0]
 

SifJar

Not a pirate
Member
Joined
Apr 4, 2009
Messages
6,022
Trophies
0
Website
Visit site
XP
1,175
Country
Very interesting and informative post. Can't say I fully understood all of it, but I got the main concepts. Thanks for sharing.

Hopefully this information will lead to an app to wipe out the korean key, stopping people from installing IOS60 to every SM IOS slot unnecessarily. It can be done relatively simply thanks to HW_AHBPROT, if I'm reading your post correctly?
 

DeadlyFoez

XFlak Fanboy
Banned
Joined
Apr 12, 2009
Messages
5,920
Trophies
0
Website
DeadlyFoez.zzl.org
XP
2,875
Country
United States
Well, just to say, giantpune is a very trustworthy person from my experience. I had asked him about removing the korean key a while back and he told me that he has the code but he is not allowed to share it. Apparently he felt that he was privy to that code and was not supposed to share it with anyone, even someone that he trusts to not further distribute it, like me. Because of that, I have lots of trust in pune. He has told me of many things that he has come across, but because of how he respects other people he decides to not share it. I find that rather honorable of him.

Thank you for this post tueidj. It was very informational. I was not aware that the seeprom could be accessed through the GPIO's. I would love to learn how to do it that way.

Does this info play any part of that bricking app that you had challenged me to try? Would you mind finally letting me in on what that app really does? I'd love to know.

Thanx again man.
 
  • Like
Reactions: 1 person

damysteryman

I am too busy IRL these days...
Member
Joined
Oct 4, 2007
Messages
1,223
Trophies
1
XP
1,026
Country
Antarctica
You know when someone is a madman when:

1. They take their perfectly good, fully functional, hardly used, almost-brand-new-condition Korean Wii, deliberately inflict the nasty Error 003 on it, then test out an untested and potentially unsafe SEEPROM-modifying app to fix it, just because of boredom and curiosity.
2. They film it while putting on a funny voice when narrating it all, and upload it to the internet. :P

Well, enjoy.

[yt]1YGmchNgaP4[/yt]

I am not sure if I should post the compiled binary here.
Should I upload and post it?
Or would it be safer not to?
Tell me what you guys think.
 
  • Like
Reactions: 1 person

damysteryman

I am too busy IRL these days...
Member
Joined
Oct 4, 2007
Messages
1,223
Trophies
1
XP
1,026
Country
Antarctica
I am too. I honestly had no idea if it would or not.

And ok then, that is what I was thinking, hence why I refrained to upload it, and why I asked.

Ok, good to know that it is fixed. Not that it is really a big problem though. :lol:
 

DeadlyFoez

XFlak Fanboy
Banned
Joined
Apr 12, 2009
Messages
5,920
Trophies
0
Website
DeadlyFoez.zzl.org
XP
2,875
Country
United States
I just tested it too, and it works great on adding and removing the korean key. But I will post the compiled program :D

KoreanKii.zip
md5: 0fa3bc1553a407555b2ffaa157750f76

You use this at your own risk!!!

EDIT: This version that is now posted is not the same version that I used in my video, but it should still be fine to use. If you would prefer the version that I used in my video them PM me and I'll give you the link.
Good luck :D
 
  • Like
Reactions: 2 people

JoostinOnline

Certified Crash Test Dummy
Member
Joined
Apr 2, 2011
Messages
11,005
Trophies
1
Location
The Twilight Zone
Website
www.hacksden.com
XP
4,339
Country
United States
@[member='JoostinOnline'],
Good job man. You've certainly come a long way, I remember when everyone was giving you a hard time regarding detecting the korean key, and now you've managed to remove it (with help of course) without even bricking anyone! Kudos!
Well there wasn't any reliable code for detecting it back then. But thanks man. :)

I would like to make it clear that all the hard work was done by tueidj, not me. The code I wrote isn't really anything more than a prompt for running tueidj's code.

PS: If anyone wants to include the seeprom code in their program, they will need to add this to the top:
Code:
#include 
#include 
#include 
#include

@DeadlyFoez I wish you hadn't done that. :(
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Veho @ Veho: https://i.imgur.com/bG1pQld.mp4