3
3
#include "ps4.h"
4
4
#include "defines.h"
5
5
6
+ #define KERN_XFAST_SYSCALL 0x30EB30
7
+
8
+ #define CTL_KERN 1 /* "high kernel": proc, limits */
9
+ #define KERN_PROC 14 /* struct: process entries */
10
+ #define KERN_PROC_VMMAP 32 /* VM map entries for process */
11
+ #define KERN_PROC_PID 1 /* by process id */
12
+
6
13
extern char kexec [];
7
14
extern unsigned kexec_size ;
8
15
9
16
static int sock ;
10
17
11
18
void usbthing ();
12
19
13
- int _main (void ) {
20
+ unsigned int long long __readmsr (unsigned long __register ) {
21
+ // Loads the contents of a 64-bit model specific register (MSR) specified in
22
+ // the ECX register into registers EDX:EAX. The EDX register is loaded with
23
+ // the high-order 32 bits of the MSR and the EAX register is loaded with the
24
+ // low-order 32 bits. If less than 64 bits are implemented in the MSR being
25
+ // read, the values returned to EDX:EAX in unimplemented bit locations are
26
+ // undefined.
27
+ unsigned long __edx ;
28
+ unsigned long __eax ;
29
+ __asm__ ("rdmsr" : "=d" (__edx ), "=a" (__eax ) : "c" (__register ));
30
+ return (((unsigned int long long )__edx ) << 32 ) | (unsigned int long long )__eax ;
31
+ }
14
32
15
- initKernel ();
16
- initLibc ();
17
- initNetwork ();
33
+ int kpayload (struct thread * td , struct kpayload_args * args ){
18
34
19
- struct sockaddr_in server ;
35
+ printfsocket ( "Starting kpayload...\n" ) ;
20
36
21
- server .sin_len = sizeof (server );
22
- server .sin_family = AF_INET ;
23
- server .sin_addr .s_addr = IP (192 , 168 , 1 , 12 );
24
- server .sin_port = sceNetHtons (9023 );
25
- memset (server .sin_zero , 0 , sizeof (server .sin_zero ));
26
- sock = sceNetSocket ("debug" , AF_INET , SOCK_STREAM , 0 );
27
- sceNetConnect (sock , (struct sockaddr * )& server , sizeof (server ));
28
- int flag = 1 ;
29
- sceNetSetsockopt (sock , IPPROTO_TCP , TCP_NODELAY , (char * )& flag , sizeof (int ));
37
+ struct ucred * cred ;
38
+ struct filedesc * fd ;
39
+
40
+ fd = td -> td_proc -> p_fd ;
41
+ cred = td -> td_proc -> p_ucred ;
42
+
43
+ printfsocket ("Reading kernel_base...\n" );
44
+ void * kernel_base = & ((uint8_t * )__readmsr (0xC0000082 ))[-0x30EB30 ];
45
+ uint8_t * kernel_ptr = (uint8_t * )kernel_base ;
46
+ void * * got_prison0 = (void * * )& kernel_ptr [0xF26010 ];
47
+ void * * got_rootvnode = (void * * )& kernel_ptr [0x206D250 ];
48
+
49
+ printfsocket ("Resolve kernel functions...\n" );
50
+
51
+ int (* copyout )(const void * kaddr , void * uaddr , size_t len ) = (void * )(kernel_base + 0x286d70 );
52
+ int (* printfkernel )(const char * fmt , ...) = (void * )(kernel_base + 0x347580 );
53
+ int (* copyin )(const void * uaddr , void * kaddr , size_t len ) = (void * )(kernel_base + 0x286df0 );
54
+
55
+ cred -> cr_uid = 0 ;
56
+ cred -> cr_ruid = 0 ;
57
+ cred -> cr_rgid = 0 ;
58
+ cred -> cr_groups [0 ] = 0 ;
59
+
60
+ cred -> cr_prison = * got_prison0 ;
61
+ fd -> fd_rdir = fd -> fd_jdir = * got_rootvnode ;
62
+
63
+ printfsocket ("Enabling uart...\n" );
64
+ uint16_t * securityFlags = (uint64_t * )(kernel_base + 0x2001516 );
65
+ * securityFlags = * securityFlags & ~(1 << 15 );
30
66
67
+ printfsocket ("Disabling write protection...\n" );
68
+ uint64_t cr0 = readCr0 ();
69
+ writeCr0 (cr0 & ~X86_CR0_WP );
70
+
71
+ //Kexec
31
72
printfsocket ("Kexec init...\n" );
32
73
33
74
void * DT_HASH_SEGMENT = (void * )0xffffffff82200160 ;
@@ -36,7 +77,7 @@ int _main(void) {
36
77
37
78
printfsocket ("Kexec size [%d]\n" , kexec_size );
38
79
39
- memcpy (DT_HASH_SEGMENT , kexec , kexec_size ); //Fails here
80
+ copyin (DT_HASH_SEGMENT , kexec , kexec_size );
40
81
41
82
printfsocket ("Kexec init [1]\n" );
42
83
@@ -45,26 +86,76 @@ int _main(void) {
45
86
printfsocket ("Kexec init [2]\n" );
46
87
47
88
kexec_init (NULL , NULL );
89
+
90
+ printfsocket ("Kexec inited successfully!\n" );
91
+
92
+ // Say hello and put the kernel base in userland to we can use later
93
+
94
+ printfkernel ("\n\n\nHELLO FROM YOUR KERN DUDE =)\n\n\n" );
95
+
96
+ printfkernel ("kernel base is:0x%016llx\n" , kernel_base );
97
+
98
+ uint64_t uaddr ;
99
+ memcpy (& uaddr ,& args [2 ],8 );
100
+
101
+ printfkernel ("uaddr is:0x%016llx\n" , uaddr );
102
+
103
+ copyout (& kernel_base , uaddr , 8 );
104
+
105
+ return 0 ;
106
+ }
107
+
108
+ int _main (struct thread * td ) {
109
+
110
+ initKernel ();
111
+ initLibc ();
112
+ initNetwork ();
113
+ initPthread ();
114
+
115
+ struct sockaddr_in server ;
116
+
117
+ server .sin_len = sizeof (server );
118
+ server .sin_family = AF_INET ;
119
+ server .sin_addr .s_addr = IP (192 , 168 , 1 , 12 );
120
+ server .sin_port = sceNetHtons (9023 );
121
+ memset (server .sin_zero , 0 , sizeof (server .sin_zero ));
122
+ sock = sceNetSocket ("debug" , AF_INET , SOCK_STREAM , 0 );
123
+ sceNetConnect (sock , (struct sockaddr * )& server , sizeof (server ));
124
+ int flag = 1 ;
125
+ sceNetSetsockopt (sock , IPPROTO_TCP , TCP_NODELAY , (char * )& flag , sizeof (int ));
48
126
127
+ printfsocket ("Connected!\n" );
128
+
129
+ uint64_t * dump = mmap (NULL , 0x1000 , PROT_READ | PROT_WRITE , MAP_ANONYMOUS | MAP_PRIVATE , -1 , 0 );
130
+
131
+ printfsocket ("Starting kernel patch...\n" );
132
+
133
+ int sRet = syscall (11 ,kpayload ,td ,dump );
134
+
135
+ printfsocket ("Kernel patched!\n" );
136
+
49
137
printfsocket ("Starting PS4 Linux Loader\n" );
50
138
51
139
usbthing ();
52
140
53
141
printfsocket ("Done!\n" );
142
+
54
143
sceNetSocketClose (sock );
55
144
56
145
return 0 ;
146
+
57
147
}
58
148
59
149
void usbthing ()
60
150
{
61
- // Open bzImage file from USB
151
+
152
+ printfsocket ("Open bzImage file from USB\n" );
62
153
FILE * fkernel = fopen ("/mnt/usb0/bzImage" , "r" );
63
154
fseek (fkernel , 0L , SEEK_END );
64
155
int kernelsize = ftell (fkernel );
65
156
fseek (fkernel , 0L , SEEK_SET );
66
157
67
- // Open initramfs file from USB
158
+ printfsocket ( " Open initramfs file from USB\n" );
68
159
FILE * finitramfs = fopen ("/mnt/usb0/initramfs.cpio.gz" , "r" );
69
160
fseek (finitramfs , 0L , SEEK_END );
70
161
int initramfssize = ftell (finitramfs );
@@ -73,7 +164,7 @@ void usbthing()
73
164
printfsocket ("kernelsize = %d\n" , kernelsize );
74
165
printfsocket ("initramfssize = %d\n" , initramfssize );
75
166
76
- // Sanity checks
167
+ printfsocket ( "Checks if the files are here\n" );
77
168
if (kernelsize == 0 || initramfssize == 0 ) {
78
169
printfsocket ("no file error im dead" );
79
170
fclose (fkernel );
@@ -98,15 +189,16 @@ void usbthing()
98
189
fclose (fkernel );
99
190
fclose (finitramfs );
100
191
101
- // Call sys_kexec
192
+ printfsocket ( " Call sys_kexec (153 syscall)" );
102
193
syscall (153 , kernel , kernelsize , initramfs , initramfssize , cmd_line );
103
194
104
195
free (kernel );
105
196
free (initramfs );
106
197
107
- // Reboot PS4
198
+ printfsocket ( " Reboot PS4" );
108
199
int evf = syscall (540 , "SceSysCoreReboot" );
109
200
syscall (546 , evf , 0x4000 , 0 );
110
201
syscall (541 , evf );
111
202
syscall (37 , 1 , 30 );
203
+
112
204
}
0 commit comments