Line 1:
Line 1:
β
The STM Release Exploit was used prior to the [[System Menu 4.0]] update to install the [[Homebrew Channel]]. It was obfuscated to prolong it from being patched by Nintendo and/or used for warez.
+
http://www.cartiershop.org/ Cartier Lover Bangles is a symbol of faithful love and they are designed for lovers. For decades, the charm of http://www.cartiershop.org/Cartier-Pendants_37_1.htm Cartier Pendants has always made people fascinated. Beginning with its oval design, the handcuffs design looks like a love sea. Many stars, such as Elizabeth, Taylor, Sophia, http://www.cartiershop.org/Cartier-Love_32_1.htm Cartier Love , have always been wearing Love Bracelet. In the 20th of twentieth century, Louis http://www.cartiershop.org/Cartier-Earrings_30_1.htm Cartier Earrings designed an unique and innovative shape of tricyclic rings for his best friend Jean Cocteau, a famous poet These three gold rings around each other symbolize the Friendship (Platinum), Loyalty (gold) and Love (Rose gold), which are the perfect interpretation for http://www.cartiershop.org/Cartier-Lover_Bangles_33_1.htm Cartier Lover Bangles eternal love. Cartier is now using the above idea on the Cartier Bracelet.
β
β
==Technical Details==
β
This bug was discovered by accident, and in fact it is a real honest-to-goodness software bug that is not only exploitable, but a nuisance during regular use. To understand it, you need to understand how STM works.
β
β
[[IOS#STM|STM]] (State Transition Manager) is the [[IOS]] module in responsible for some hardware functions like handling the fan, βidleβ ([[WiiConnect24]]) mode, the front slot LED (including the blink patterns), and the front-panel buttons. A main function of STM is to provide a way for PowerPC software to get notifications when either the Reset or the Power buttons are pressed. Itβs worth noting that it is unknown why they did this βthe PowerPC already knows about Reset via the legacy GameCube interface, and can be given direct access to Power including IRQ via the shared GPIO system, and IOS doesnβt use these buttons at allβ but they did. It works like this: STM creates two devices, an βimmediateβ device, and an βeventβ device. The immediate device is used to issue commands to STM that take effect immediately, while the event device is the callback mechanism. The PowerPC code issues an IOS_IoctlAsync() call on the βeventβ device, and this call blocks (asynchronously) until there is an event (such as a button press). When this happens, the call returns with the event code, and the PowerPC code reissues it to listen for further events.
β
β
One problem with this approach is that the PowerPC needs a way to shut down the event callback. The IOS [[Hardware/IPC|IPC]] mechanism doesnβt provide a way for the PowerPC to cancel an ongoing request; it must wait until its completion. When PowerPC code needs to hand off execution, it needs to clean up all references and file descriptors to IOS, so it needs a way to get rid of the event call. STM implements this by having a call on the immediate interface that forces the event call to return with a zero event code. So far so good. If youβre interested, check out stm.c on libogc (particularly the functions with EventHook in the name).
β
β
In order to better understand the mechanism, itβs worth looking at the individual messages as they are exchanged with IOS. Hereβs what it might look like:
β
β
{| class="wikitable"
β
|-
β
! PowerPC
β
! IOS
β
|-
β
| colspan="2" style="text-align: center;" | Initializing STM
β
|-
β
| open(path=β/dev/stm/immediateβ)
β
|
β
|-
β
|
β
| open() fd = 1
β
|-
β
| open(path=β/dev/stm/eventhookβ)
β
|
β
|-
β
|
β
|open() fd = 2
β
|-
β
| ioctl(fd=2, num=EVENTHOOK, evbuf=0Γ12345600)
β
|
β
|-
β
| colspan="2" style="text-align: center;" | Time passes, user presses button
β
|-
β
|
β
| Write event code to 0Γ12345600
β
|-
β
|
β
| ioctl(fd=2) result = 0
β
|-
β
| Read event code from 0Γ12345600
β
|
β
|-
β
| ioctl(fd=2, num=EVENTHOOK, evbuf=0Γ12345600)
β
|
β
|-
β
| colspan="2" style="text-align: center;" | Time passes, software decides to shut down STM
β
|-
β
| ioctl(fd=1, num=RELEASE)
β
|
β
|-
β
| Write 0 event code to 0Γ12345600
β
|
β
|-
β
|
β
| ioctl(fd=2) result = 0
β
|-
β
|
β
| ioctl(fd=1) result = 0
β
|-
β
| close(2)
β
|
β
|-
β
|
β
| close(2) result = 0
β
|-
β
| close(1)
β
|
β
|-
β
|
β
| close(1) result = 0
β
|}
β
β
Things didnβt work well when using the [[Twilight Hack]] because Zeldaβs STM eventhook was still active, and STM wonβt let you register a new one. So an STM eventhook release was added to the Twilight Hack. One slight issue is that we canβt know if there was an old eventhook or not, depending on what the state of the machine was (since the Twilight Hack can be relaunched from software, as an SD loader of sorts, and this was popular in the early days), so we just make it attempt to release the eventhook always. This is fine, as the release function will return an error if there is no eventhook active.
β
β
Then IOS started crashing sometimes.
β
β
Looking closely at the release function in STM, hereβs what I found:
β
β
release_eventhook
β
MOV R12, SP
β
STMFD SP!, {R4-R6,R11,R12,LR,PC}
β
LDR R4, =hook_msg
β
MOV R6, R0
β
SUB R11, R12, #4
β
LDR R0, =aRelease
β
BL printf_disabled
β
LDR R3, [R4]
β
MOV R5, #0
β
CMP R3, R5
β
MOVL R1, -6
β
MOV R0, R6
β
BEQ loc_20300C04
β
β
loc_20300BD8
β
STR R5, [R4]
β
MOV R0, R3
β
LDR R3, [R3,#0x18]
β
MOV R1, R5
β
STR R5, [R3]
β
BL AckMessage
β
MOV R0, R6
β
MOV R1, R5
β
BL AckMessage
β
LDMFD SP, {R4-R6,R11,SP,LR}
β
BX LR
β
β
loc_20300C04
β
BL AckMessage
β
LDR R3, [R4]
β
B loc_20300BD8
β
This translates to the following C code:
β
β
struct ios_message {
β
// this isn't exactly right on the IOS side, but it doesn't matter here
β
u32 command; // 0x00 = 6 for ioctl
β
s32 result; // 0x04
β
s32 fd; // 0x08
β
// arguments for ioctl
β
u32 ioctl_number; // 0x0c
β
void *buffer_in; // 0x10
β
u32 in_size; // 0x14
β
void *buffer_out; // 0x18
β
u32 out_size; // 0x1c
β
};
β
β
struct ios_message *hook_msg;
β
β
void release_eventhook(ios_message *imm_msg)
β
{
β
struct ios_message *the_hook_msg = hook_msg;
β
β
printf_disabled("Release\n");
β
if (!the_hook_msg) {
β
AckMessage(imm_msg, -6);
β
}
β
hook_msg = NULL;
β
*(u32*)the_hook_msg->buffer_out = 0;
β
AckMessage(the_hook_msg, 0);
β
AckMessage(imm_msg, 0);
β
}
β
β
Nintendo forgot a return; statement right at the end of the if(!the_hook_msg) block! This means that if there is no callback registered, it will try to ack the immediate message twice (which does nothing), it will try to ack a NULL message (which the kernel catches and does nothing), but most importantly, it will dereference a NULL structure, get a pointer from it, and write 0 to the address pointed to by that pointer. In other words, that line of code becomes **(u32**)0x18 = 0;, as 0Γ18 is the offset of buffer_out inside the structure. And 0Γ18 is an address in low MEM1 that we completely control from the PowerPC. Whoops.
β
β
In the Twilight Hack, this location usually contained some odd value, which caused IOS to crash with an unaligned access exception. We added a workaround in a later release of the Twilight Hack so IOS will no longer crash, which looks like this:
β
β
// STM bug workaround
β
// On attempt to release callback when it's already released
β
// or when it has fired and auto-released, STM dereferences a
β
// member of a NULL IPC structure and then tries to write 0
β
// to outbuf. End result, STM tries to:
β
// **((u32**)0x18) = 0;
β
// so we set 0x18 here to a valid address (0x14) to prevent
β
// a crash.
β
*((u32*)0x80000018) = 0x00000014;
β
sync_after_write((void*)0x80000014, 8);
β
printf("Releasing STM callback...");
β
/* ... */
β
β
The exploit is quite simple: we simply find the address of the stack location that contains the return address for the function (LR), and write it to 0Γ18. Then we release the STM callback twice. The second time around, STM zeroes out the return address and the function returns to execute code at address 0. We place our own code there, and clean up afterwards by jumping to the real return location, so STM keeps on running happily.
β
β
But wait, we need to somehow break into the kernel to disable the signature check. How can we do that? Well, it turns out that Nintendo left behind some useful IOS syscalls. They look like this:
β
β
wtf1
β
MOVS R3, #3
β
STR R3, [R0]
β
MOVS R3, #0
β
STRH R3, [R1]
β
BX LR
β
β
wtf2
β
MOVS R3, #1
β
STR R3, [R0]
β
MOVS R3, #0
β
STRH R3, [R1]
β
BX LR
β
Which translates to:
β
β
void wtf1(u32 *a, u16 *b)
β
{
β
*a = 3;
β
*b = 0;
β
}
β
β
void wtf2(u32 *a, u16 *b)
β
{
β
*a = 1;
β
*b = 0;
β
}
β
These functions appear to be used as configuration for certain global settings, such as whether IOS is monolithic or modular, so they just return constant values by dereferencing their arguments. In any case, there are no permission checks and these calls happily write to any address that you want, with full kernel permissions. We just pass along an address inside the signature check function that we want patched out, and we win.
β
β
Now, this exploit isnβt just caused by the small bug in STM; itβs also a consequence of poor security in IOS in general:
β
β
* IOS should unmap the zero page and cause NULL dereferences to abort.
β
* IOS should NEVER allow or use execute permission for memory controlled by the PowerPC (!!!).
β
* IOS system calls should be code-reviewed and checked for validation of arguments, as they are critical to security.
β
* Nintendo needs to backport security fixes to all IOSes. They had found the syscall bug and fixed it in newer IOS forks, but this is useless without backporting it back to all older IOSes. In fact, changes like that draw attention to the bugs.
β
β
Which of course brings us to the fact that having dozens of forks of security-critical software is a maintenance nightmare and a really really bad idea.
β
Unfortunately, given later exploits and Nintendoβs changes to IOS, it seems they canβt be bothered to do any of the above. They fixed the STM bug and backported the syscall fix from other IOSes, but there are others with similar bugs.
β
β
==History==
β
On October 23rd, 2008, Nintendo released an update that fixed the [[signing bug]] in every publicly-known IOS, disabling any direct methods to install unofficial content on all updated Wiis. Team Twiizers decided to take the opportunity to use one of their stockpiled IOS exploits to get the [[Homebrew Channel]] working with this update. These stockpiled exploits differ from fakesigning in that they directly exploit the IOS runtime, injecting code that lets us take control and disable signatures altogether. Therefore, this was the first released IOS code execution exploit.
β
β
In order to hinder Nintendoβs attempts at fixing it, and to avoid misuse by warez kiddies, sven and I had a lot of fun obfuscating the exploit over a couple afternoons. We decided not to release information about it, hoping it would last long enough to be useful for future installers and BootMii.
β
β
The [[System Menu 4.0]] update eliminated the STM Release Exploit, but it was still left undocumented. Team Twiizers eventually proposed a challenge: the exploit would be documented when someone βbrokeβ the obfuscation and figured out how the exploit works. The intent was to promote reverse engineering and also see just how long it would take people to crack it. An anonymous hacker successfully reverse engineered our layers of obfuscation.
β
β
==Sources==
β
[http://hackmii.com/2010/01/the-stm-release-exploit/ The STM Release Exploit - HackMii]
β
β
[[Category:Exploits]]
β
[[Category:IOS Exploits]]