Skip to content

Commit 2bff5d6

Browse files
authored
Added Full Support 8.40/8.60
Fixed Shellcore Patching 8.40+ Thanks @idlesauce
1 parent a5b35a6 commit 2bff5d6

1 file changed

Lines changed: 101 additions & 32 deletions

File tree

ps5-kstuff/main.c

Lines changed: 101 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
277322
uint64_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

10681114
static 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

Comments
 (0)