1+ #include <stdint.h>
2+ #include <string.h>
3+ #include <malloc.h>
4+ #include <unistd.h>
5+
6+ // libogc files
7+ #include <ogc/machine/processor.h>
8+ #include <ogc/ipc.h>
9+ #include <ogc/cache.h>
10+
11+ // Local Files
12+ #include "globals.h"
13+
14+ const uint8_t disable_ahbprot_payload [] = {
15+ 0xF0 , 0x00 , 0xF8 , 0x02 , // bl #8
16+ 0xE7 , 0xFE , // b #0, keep looping main thread
17+ 0x00 , 0x00 , // padding
18+ // actual disabling. it loads, and stores the value in 0xd800064 or'ed with 0x80000dfe
19+ // this gives the PPC access to the starlet's AHB devices
20+ 0x4A , 0x06 , // ldr r2, [DAT_00000024] = 0x0d800064
21+ 0x4B , 0x07 , // ldr r3, [DAT_00000028] = 0x80000dfe
22+ 0x68 , 0x11 , // ldr r1, [r2,#0x0] => 0x0d800064
23+ 0x43 , 0x0B , // orrs r3, r1
24+ 0x60 , 0x13 , // str r3, [r2,#0x0] => 0x0d800064
25+ // disable HW_MEMMIRR (0xd800060) by orring with 0x00000008
26+ 0x4A , 0x06 , // ldr r2, [DAT_0000002c] = 0x0d800060
27+ 0x23 , 0x08 , // movs r3, #0x8
28+ 0x68 , 0x11 , // ldr r1, [r2,#0x0] => 0x0d800060
29+ 0x43 , 0x0B , // orrs r3, r1
30+ 0x60 , 0x13 , // str r3, [r2,#0x0] => 0x0d800060
31+ // and finish up with setting MEM_PROT_REG(0xd804202)
32+ 0x4B , 0x04 , // ldr r3, [DAT_00008030] = 0x0d804202
33+ 0x22 , 0x00 , // movs r2, #0x0
34+ 0x80 , 0x1A , // strh r2, [r3,#0x0] => 0x0d804202
35+ 0x47 , 0x70 , // bx lr
36+ // data used by above code
37+ 0x0D , 0x80 , 0x00 , 0x64 , // DAT_00000024
38+ 0x80 , 0x00 , 0x0D , 0xFE , // DAT_00000028
39+ 0x0D , 0x80 , 0x00 , 0x60 , // DAT_0000002c
40+ 0x0D , 0x80 , 0x42 , 0x02 // DAT_00000030
41+ };
42+
43+ #define DISABLE_AHBPROT_PAYLOAD_SIZE (sizeof(disable_ahbprot_payload) / sizeof(disable_ahbprot_payload[0]))
44+
45+ bool is_dolphin ()
46+ {
47+ // /dev/dolphin will never exist in an official IOS
48+ s32 fd = IOS_Open ("/dev/dolphin" , 0 );
49+ if (fd >= 0 )
50+ {
51+ IOS_Close (fd );
52+ return true;
53+ }
54+ return false;
55+ }
56+
57+ // time to exploit /dev/sha!
58+ bool disable_ahbprot ()
59+ {
60+ if (AHBPROT_DISABLED || is_dolphin ()) {
61+ return true; // AHBPROT is already disabled, likely via launching through HBC or the user is using Dolphin. Dolphin always has it disabled however :)
62+ }
63+
64+ // We proceed to exploit /dev/sha
65+ // Good amount of this is from Priiloader but ported to C from C++ lol
66+ s32 fd = -1 ;
67+ ioctlv * params = NULL ;
68+
69+ fd = IOS_Open ("/dev/sha" , 0 );
70+ if (fd < 0 )
71+ return false;
72+
73+ params = (ioctlv * )memalign (sizeof (ioctlv ) * 4 , 32 );
74+ if (params == NULL )
75+ return false;
76+
77+ // Overwrite the thread 0 state with address 0 (0x80000000)
78+ memset (params , 0 , sizeof (ioctlv ) * 4 );
79+ params [1 ].data = (void * )0xFFFE0028 ;
80+ params [1 ].len = 0 ;
81+ DCFlushRange (params , sizeof (ioctlv ) * 4 );
82+
83+ // Set code to disable AHBPROT and stay in loop
84+
85+ memcpy ((void * )0x80000000 , disable_ahbprot_payload , DISABLE_AHBPROT_PAYLOAD_SIZE );
86+ DCFlushRange ((void * )0x80000000 , DISABLE_AHBPROT_PAYLOAD_SIZE );
87+ ICInvalidateRange ((void * )0x80000000 , DISABLE_AHBPROT_PAYLOAD_SIZE );
88+
89+ s32 callRet = IOS_Ioctlv (fd , 0x00 , 1 , 2 , params );
90+ if (callRet < 0 )
91+ return false;
92+
93+ // wait for it to have processed the sha init and given a timeslice to the mainthread :)
94+ usleep (50000 );
95+ return true;
96+ }
0 commit comments