@@ -252,10 +252,10 @@ uint64_t get_dmap_base(void)
252252 return ptrs [0 ] - ptrs [1 ];
253253}
254254
255- uint64_t virt2phys (uintptr_t addr )
255+ uint64_t virt2phys (uintptr_t addr , uint64_t * phys_limit , uint64_t dmap , uint64_t pml )
256256{
257- uint64_t dmap = get_dmap_base ();
258- uint64_t pml = r0gdb_read_cr3 ();
257+ if (! dmap ) dmap = get_dmap_base ();
258+ if (! pml ) pml = r0gdb_read_cr3 ();
259259 for (int i = 39 ; i >= 12 ; i -= 9 )
260260 {
261261 uint64_t inner_pml ;
@@ -266,6 +266,7 @@ uint64_t virt2phys(uintptr_t addr)
266266 {
267267 inner_pml &= (1ull << 52 ) - (1ull << i );
268268 inner_pml |= addr & ((1ull << i ) - 1 );
269+ if (phys_limit ) * phys_limit = (inner_pml | ((1ull << i ) - 1 )) + 1 ;
269270 return inner_pml ;
270271 }
271272 inner_pml &= (1ull << 52 ) - (1ull << 12 );
@@ -274,6 +275,50 @@ uint64_t virt2phys(uintptr_t addr)
274275 //unreachable
275276}
276277
278+ uint64_t kernel_get_proc (uint64_t pid )
279+ {
280+ uint64_t proc = kread8 (offsets .allproc );
281+ while (proc && (int )kread8 (proc + 0xbc ) != pid )
282+ proc = kread8 (proc );
283+ return proc ;
284+ }
285+
286+ int get_proc_cr3 (uint64_t pid , uint64_t * cr3 , uint64_t * dmap_base )
287+ {
288+ uint64_t proc = kernel_get_proc (pid );
289+ if (proc == 0 )
290+ return -1 ;
291+ uint64_t vmspace = kread8 (proc + 0x200 );
292+ // TODO: i dont know when this shifted, may be an earlier fw, also, add this to offsets.c?
293+ uint32_t fwver = r0gdb_get_fw_version () >> 16 ;
294+ uint32_t vmspace_pmap_offset = (fwver >= 0x800 ? 0x2E8 : 0x2E0 );
295+ uint64_t ptrs [2 ] = {0 };
296+ copyout (ptrs , vmspace + vmspace_pmap_offset + 32 , sizeof (ptrs ));
297+ if (cr3 ) * cr3 = ptrs [1 ];
298+ if (dmap_base ) * dmap_base = ptrs [0 ] - ptrs [1 ];
299+ return 0 ;
300+ }
301+
302+ int phys_copyin (uint64_t vaddr , const void * src , uint64_t sz , uint64_t dmap , uint64_t pml )
303+ {
304+ const char * p_src = src ;
305+ uint64_t phys , phys_end ;
306+ while (sz )
307+ {
308+ phys = virt2phys (vaddr , & phys_end , dmap , pml );
309+ if (phys == -1 )
310+ return -1 ;
311+ size_t chk = phys_end - phys ;
312+ if (sz < chk )
313+ chk = sz ;
314+ copyin (dmap + phys , p_src , chk );
315+ vaddr += chk ;
316+ p_src += chk ;
317+ sz -= chk ;
318+ }
319+ return 0 ;
320+ }
321+
277322uint64_t find_empty_pml4_index (int idx )
278323{
279324 uint64_t dmap = get_dmap_base ();
@@ -299,17 +344,17 @@ void build_uelf_cr3(uint64_t uelf_cr3, void* uelf_base[2], uint64_t uelf_virt_ba
299344 kmemcpy ((void * )(pml4_virt + 2048 ), (void * )(dmap + cr3 + 2048 ), 2048 );
300345 uint64_t pml3_virt = uelf_cr3 + 4096 ;
301346 uint64_t pml3_dmap = uelf_cr3 + 16384 ; //user-accessible direct mapping of physical memory
302- copyin (pml4_virt + 8 * ((uelf_virt_base >> 39 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml3_virt ) | 7 }, 8 );
303- copyin (pml4_virt + 8 * ((dmap_virt_base >> 39 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml3_dmap ) | 7 }, 8 );
347+ copyin (pml4_virt + 8 * ((uelf_virt_base >> 39 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml3_virt , 0 , 0 , 0 ) | 7 }, 8 );
348+ copyin (pml4_virt + 8 * ((dmap_virt_base >> 39 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml3_dmap , 0 , 0 , 0 ) | 7 }, 8 );
304349 copyin (pml3_virt , zeros , 4096 );
305350 uint64_t pml2_virt = uelf_cr3 + 8192 ;
306- copyin (pml3_virt + 8 * ((uelf_virt_base >> 30 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml2_virt ) | 7 }, 8 );
351+ copyin (pml3_virt + 8 * ((uelf_virt_base >> 30 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml2_virt , 0 , 0 , 0 ) | 7 }, 8 );
307352 copyin (pml2_virt , zeros , 4096 );
308353 uint64_t pml1_virt = uelf_cr3 + 12288 ;
309- copyin (pml2_virt + 8 * ((uelf_virt_base >> 21 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml1_virt ) | 7 }, 8 );
354+ copyin (pml2_virt + 8 * ((uelf_virt_base >> 21 ) & 511 ), & (uint64_t [1 ]){virt2phys (pml1_virt , 0 , 0 , 0 ) | 7 }, 8 );
310355 copyin (pml1_virt , zeros , 4096 );
311356 for (uint64_t i = 0 ; i * 4096 + user_start < user_end ; i ++ )
312- copyin (pml1_virt + 8 * i , & (uint64_t [1 ]){virt2phys (i * 4096 + user_start ) | 7 }, 8 );
357+ copyin (pml1_virt + 8 * i , & (uint64_t [1 ]){virt2phys (i * 4096 + user_start , 0 , 0 , 0 ) | 7 }, 8 );
313358 for (uint64_t i = 0 ; i < 512 ; i ++ )
314359 copyin (pml3_dmap + 8 * i , & (uint64_t [1 ]){(i <<30 ) | 135 }, 8 );
315360}
@@ -342,6 +387,7 @@ static uint64_t remote_syscall(int pid, int nr, ...)
342387 return kekcall (pid , nr , (uint64_t )args , 0 , 0 , 0 , KEKCALL_REMOTE_SYSCALL );
343388}
344389
390+ #define SYS_mlock 203
345391#define SYS_mdbg_call 573
346392#define SYS_dynlib_get_info_ex 608
347393
@@ -1066,24 +1112,22 @@ static struct shellcore_patch shellcore_patches_761[] = {
10661112};
10671113
10681114static struct shellcore_patch shellcore_patches_800 [] = {
1069- {0xba85ce , "\x52\xeb\x08" , 3 }, //push rdx; jmp 0xBA85D9 **
1070- {0xba85d9 , "\xe8\xe2\xf6\xff\xff\x58\xc3" , 7 }, //call 0xBA7CC0; pop rax; ret **
1071- //{0xba7cb2, "\xe0\x0a\x00\x00", 4},
1072- {0xba7cb1 , "\xe9\xae\xfd\xff\xff" , 5 }, // jmp 0xBA7A64 **
1073- //{0xba8796, "\x31\xc0\x50\xe8\x22\xf5\xff\xff\x58\xc3", 10}, // xor eax,eax; push rax; call 0xBA7CC0; pop rax; ret
1074- {0xba7a64 , "\x31\xc0\x50\xe8\x54\x02\x00\x00\x58\xc3" , 10 }, //xor eax, eax; push rax; call 0xBA7CC0; pop rax; ret **
1075-
1076- {0x6b27bd , "\xeb\x04" , 2 }, //jmp 0x6B27C3 **
1077- {0x2f1a82 , "\xeb\x04" , 2 }, //jmp 0x2F1A88 **
1078- {0x2f1ed2 , "\xeb\x04" , 2 }, //jmp 0x2F1ED8 **
1079- {0x6d1cc1 , "\xeb" , 1 }, //jmp **
1080- {0x6baa05 , "\x90\xe9" , 2 }, //nop; jmp **
1081- {0x6d2a0d , "\xeb" , 1 }, //jmp **
1082-
1083- {0x6d3f89 , "\x61\x01\x00\x00" , 4 }, // 0x6D40EE **
1084- {0x1f7272 , "\xe8\x19\x3c\x5c\x00\x31\xc9\xff\xc1\xe9\xb3\x02\x00\x00" , 14 }, // call 0x7BAE90; xor ecx; inc ecx; jmp 0x1f7533 **
1085- {0x1f7533 , "\x83\xf8\x02\x0f\x43\xc1\xe9\xa7\xfb\xff\xff" , 11 },//cmp eax, 2; cmovae eax, ecx; jmp 0x1F70E5 **
1086- {0x1f6f2e , "\xe9\x3f\x03\x00\x00" , 5 }, // JMP 0x1F7272 **
1115+ {0xba85ce , "\x52\xeb\x08" , 3 }, //push rdx; jmp 0xBA85D9
1116+ {0xba85d9 , "\xe8\xe2\xf6\xff\xff\x58\xc3" , 7 }, //call 0xBA7CC0; pop rax; ret
1117+ {0xba7cb1 , "\xe9\xae\xfd\xff\xff" , 5 }, // jmp 0xBA7A64
1118+ {0xba7a64 , "\x31\xc0\x50\xe8\x54\x02\x00\x00\x58\xc3" , 10 }, //xor eax, eax; push rax; call 0xBA7CC0; pop rax; ret
1119+
1120+ {0x6b27bd , "\xeb\x04" , 2 }, //jmp 0x6B27C3
1121+ {0x2f1a82 , "\xeb\x04" , 2 }, //jmp 0x2F1A88
1122+ {0x2f1ed2 , "\xeb\x04" , 2 }, //jmp 0x2F1ED8
1123+ {0x6d1cc1 , "\xeb" , 1 }, //jmp
1124+ {0x6baa05 , "\x90\xe9" , 2 }, //nop; jmp
1125+ {0x6d2a0d , "\xeb" , 1 }, //jmp
1126+
1127+ {0x6d3f89 , "\x61\x01\x00\x00" , 4 }, // 0x6D40EE
1128+ {0x1f7272 , "\xe8\x19\x3c\x5c\x00\x31\xc9\xff\xc1\xe9\xb3\x02\x00\x00" , 14 }, // call 0x7BAE90; xor ecx; inc ecx; jmp 0x1f7533
1129+ {0x1f7533 , "\x83\xf8\x02\x0f\x43\xc1\xe9\xa7\xfb\xff\xff" , 11 },//cmp eax, 2; cmovae eax, ecx; jmp 0x1F70E5
1130+ {0x1f6f2e , "\xe9\x3f\x03\x00\x00" , 5 }, // JMP 0x1F7272
10871131
10881132 {0x6F08F0 , "\xC3" , 1 }, // callback to sceRifManagerRegisterActivationCallback
10891133
@@ -1301,7 +1345,30 @@ static const struct shellcore_patch* get_shellcore_patches(size_t* n_patches)
13011345 return patches ;
13021346}
13031347
1304- static void patch_shellcore (const struct shellcore_patch * patches , size_t n_patches , uint64_t eh_frame_offset )
1348+ static int patch_shellcore (const struct shellcore_patch * patches , size_t n_patches , uint64_t eh_frame_offset )
1349+ {
1350+ int pid = find_proc ("SceShellCore" );
1351+ struct module_info_ex mod_info ;
1352+ mod_info .st_size = sizeof (mod_info );
1353+ if (remote_syscall (pid , SYS_dynlib_get_info_ex , 0 , 0 , & mod_info ))
1354+ return -1 ;
1355+ uint64_t shellcore_base = mod_info .eh_frame_hdr_addr - eh_frame_offset ;
1356+ uint64_t textsize = mod_info .segments [0 ].size ;
1357+ if (remote_syscall (pid , SYS_mlock , shellcore_base , textsize ))
1358+ return -1 ;
1359+ uint64_t cr3 , dmap ;
1360+ if (get_proc_cr3 (pid , & cr3 , & dmap ))
1361+ return -1 ;
1362+
1363+ for (int i = 0 ; i < n_patches ; i ++ )
1364+ {
1365+ if (phys_copyin (shellcore_base + patches [i ].offset , patches [i ].data , patches [i ].sz , dmap , cr3 ))
1366+ return -1 ;
1367+ }
1368+ return 0 ;
1369+ }
1370+
1371+ static void patch_shellcore_old (const struct shellcore_patch * patches , size_t n_patches , uint64_t eh_frame_offset )
13051372{
13061373 int pid = find_proc ("SceShellCore" );
13071374 struct module_info_ex mod_info ;
@@ -2176,13 +2243,13 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
21762243 kmemzero ((void * )shared_area , 4096 );
21772244 uint64_t uelf_virt_base = (find_empty_pml4_index (0 ) << 39 ) | (-1ull << 48 );
21782245 uint64_t dmem_virt_base = (find_empty_pml4_index (1 ) << 39 ) | (-1ull << 48 );
2179- shared_area = virt2phys (shared_area ) + dmem_virt_base ;
2246+ shared_area = virt2phys (shared_area , 0 , 0 , 0 ) + dmem_virt_base ;
21802247 uint64_t kelf_parasite_desc = (uint64_t )kmalloc (8192 );
21812248 kelf_parasite_desc = ((kelf_parasite_desc - 1 ) | 4095 ) + 1 ;
21822249 for (int i = 0 ; i < desc -> lim_total ; i ++ )
21832250 desc -> parasites [i ].address += kdata_base ;
21842251 kmemcpy ((void * )kelf_parasite_desc , desc , desc_size );
2185- uint64_t uelf_parasite_desc = virt2phys (kelf_parasite_desc ) + dmem_virt_base ;
2252+ uint64_t uelf_parasite_desc = virt2phys (kelf_parasite_desc , 0 , 0 , 0 ) + dmem_virt_base ;
21862253 volatile int zero = 0 ; //hack to force runtime calculation of string pointers
21872254 const char * symbols [] = {
21882255 "comparison_table" + zero ,
@@ -2272,7 +2339,7 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
22722339 uintptr_t uelf_cr3 = (uintptr_t )kmalloc (24576 );
22732340 uelf_cr3 = ((uelf_cr3 + 4095 ) | 4095 ) - 4095 ;
22742341 uelf_cr3s [cpu ] = uelf_cr3 ;
2275- values [uelf_cr3_idx ] = virt2phys (uelf_cr3 );
2342+ values [uelf_cr3_idx ] = virt2phys (uelf_cr3 , 0 , 0 , 0 );
22762343 values [uelf_entry_idx ] = (uintptr_t )uelf_entry - (uintptr_t )uelf_base [0 ] + uelf_virt_base ;
22772344 void * entry = 0 ;
22782345 void * base [2 ] = {0 };
@@ -2334,7 +2401,10 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
23342401 copyin (IDT + 16 * 9 + 5 , "\x8e" , 1 );
23352402 copyin (IDT + 16 * 179 + 5 , "\x8e" , 1 );
23362403 if (!sceKernelIsTestKit ())
2337- patch_shellcore (shellcore_patches , n_shellcore_patches , shellcore_eh_frame_offset );
2404+ {
2405+ if (patch_shellcore (shellcore_patches , n_shellcore_patches , shellcore_eh_frame_offset ))
2406+ notify ("failed to patch shellcore" );
2407+ }
23382408 gdb_remote_syscall ("write" , 3 , 0 , (uintptr_t )1 , (uintptr_t )"done\npatching app.db... " , (uintptr_t )24 );
23392409 #ifndef FIRMWARE_PORTING
23402410 //patch_app_db();
@@ -2347,4 +2417,3 @@ int main(void* ds, int a, int b, uintptr_t c, uintptr_t d)
23472417 asm volatile ("ud2" );
23482418 return 0 ;
23492419}
2350-
0 commit comments