diff --git a/payloads/sources/ps4-kpatches-src/1250.c b/payloads/sources/ps4-kpatches-src/1250.c new file mode 100644 index 0000000..d4ef0a5 --- /dev/null +++ b/payloads/sources/ps4-kpatches-src/1250.c @@ -0,0 +1,171 @@ + +/* Copyright (C) 2024-2025 anonymous + * + * This file is part of PSFree. + * + * PSFree is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * PSFree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ + +// 12.50, 12.52 + +#include "types.h" +#include "utils.h" + +static inline void do_patch(void *kbase); + +__attribute__((section (".text.start"))) +int kpatch(void *td) { + const u64 xfast_syscall_off = 0x1c0; + void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; + + do_patch(kbase); + + return 0; +} + +__attribute__((always_inline)) +static inline void do_patch(void *kbase) { + disable_cr0_wp(); + + // LightningMods's additional dlsym patches from PPPwn + write16(kbase, 0x1B76E3, 0x04eb); // skip check 1 + write16(kbase, 0x1B76F3, 0x04eb); // skip check 2 + write16(kbase, 0x1B7713, 0xe990); // nop + jmp + + // ChendoChap's patches from pOOBs4 + write16(kbase, 0x627B34, 0x00eb); // veriPatch + write8(kbase, 0xacd, 0xeb); // bcopy + write8(kbase, 0x2BD40D, 0xeb); // bzero + write8(kbase, 0x2BD451, 0xeb); // pagezero + write8(kbase, 0x2BD4CD, 0xeb); // memcpy + write8(kbase, 0x2BD511, 0xeb); // pagecopy + write8(kbase, 0x2BD6D6, 0xeb); // copyin + write8(kbase, 0x2BDB86, 0xeb); // copyinstr + write8(kbase, 0x2BDC3D, 0xeb); // copystr + + // stop sysVeri from causing a delayed panic on suspend + write16(kbase, 0x62841F, 0x00eb); + + // 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 + // + // // check the calling code if it looks like one of the syscall stubs at a + // // libkernel library and check if the syscall number correponds to the + // // proper stub + // if ((code & 0xff0000000000ffff) != 0x890000000000c0c7 + // || sa.code != (u32)(code >> 0x10) + // ) { + // // patch this to " = 0" instead + // is_invalid_syscall = -1; + // } + write32(kbase, 0x490, 0); + // these code corresponds to the check that ensures that the caller's + // instruction pointer is inside the libkernel library's memory range + // + // // patch the check to always go to the "goto do_syscall;" line + // void *code = td->td_frame->tf_rip; + // if (libkernel->start <= code && code < libkernel->end + // && is_invalid_syscall == 0 + // ) { + // goto do_syscall; + // } + // + // do_syscall: + // ... + // lea rsi, [rbp - 0x78] + // mov rdi, rbx + // mov rax, qword [rbp - 0x80] + // call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args) + // + // sy_call() is the function that will execute the requested syscall. + write8(kbase, 0x4c2, 0xeb); + write16(kbase, 0x4b9, 0x00eb); + write16(kbase, 0x4b5, 0x00eb); + + // 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, 0x391526, 0xeb); + + // patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings + // + // this check is skipped after the patch + // + // if ((new_prot & current->max_protection) != new_prot) { + // vm_map_unlock(map); + // return (KERN_PROTECTION_FAILURE); + // } + write16(kbase, 0x2FC12C, 0x04eb); + + // TODO: Description of this patch. patch sys_dynlib_load_prx() + write16(kbase, 0x1B71A4, 0xe990); + + // patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere + // call ... + // mov r14, qword [rbp - 0xad0] + // cmp eax, 0x4000000 + // jb ... ; patch jb to jmp + write32(kbase, 0x1B7758, 0x013ce990); + // patch called function to always return 0 + // + // sys_dynlib_dlsym: + // ... + // mov edi, 0x10 ; 16 + // call patched_function ; kernel_base + 0x951c0 + // test eax, eax + // je ... + // mov rax, qword [rbp - 0xad8] + // ... + // patched_function: ; patch to "xor eax, eax; ret" + // push rbp + // mov rbp, rsp + // ... + write32(kbase, 0x3BD8A0, 0xc3c03148); + + // 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, 0x1FA75A, 0x37); + write8(kbase, 0x1FA75D, 0x37); + + // overwrite the entry of syscall 11 (unimplemented) in sysent + // + // struct args { + // u64 rdi; + // u64 rsi; + // u64 rdx; + // u64 rcx; + // u64 r8; + // u64 r9; + // }; + // + // int sys_kexec(struct thread td, struct args *uap) { + // asm("jmp qword ptr [rsi]"); + // } + const u64 sysent_11_off = 0x1102d80; + // .sy_narg = 2 + write32(kbase, sysent_11_off, 2); + // .sy_call = gadgets['jmp qword ptr [rsi]'] + write64(kbase, sysent_11_off + 8, kbase + 0x47b31); + // .sy_thrcnt = SY_THR_STATIC + write32(kbase, sysent_11_off + 0x2c, 1); + + enable_cr0_wp(); +} diff --git a/payloads/sources/ps4-kpatches-src/1300.c b/payloads/sources/ps4-kpatches-src/1300.c new file mode 100644 index 0000000..6da455f --- /dev/null +++ b/payloads/sources/ps4-kpatches-src/1300.c @@ -0,0 +1,171 @@ +/* Copyright (C) 2024-2025 anonymous + * + * This file is part of PSFree. + * + * PSFree is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * PSFree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ + +// 13.00 + +#include "types.h" +#include "utils.h" + +static inline void do_patch(void *kbase); + +__attribute__((section (".text.start"))) +int kpatch(void *td) { + const u64 xfast_syscall_off = 0x1c0; + void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; + + do_patch(kbase); + + return 0; +} + +__attribute__((always_inline)) +static inline void do_patch(void *kbase) { + disable_cr0_wp(); + + // LightningMods's additional dlsym patches from PPPwn + write16(kbase, 0x1B76E3, 0x04eb); // skip check 1 + write16(kbase, 0x1B76F3, 0x04eb); // skip check 2 + write16(kbase, 0x1B7713, 0xe990); // nop + jmp + + // ChendoChap's patches from pOOBs4 + write16(kbase, 0x627B84, 0x00eb); // veriPatch + write8(kbase, 0xacd, 0xeb); // bcopy + write8(kbase, 0x2BD42D, 0xeb); // bzero + write8(kbase, 0x2BD471, 0xeb); // pagezero + write8(kbase, 0x2BD4ED, 0xeb); // memcpy + write8(kbase, 0x2BD531, 0xeb); // pagecopy + write8(kbase, 0x2BD6DD, 0xeb); // copyin + write8(kbase, 0x2BDB8D, 0xeb); // copyinstr + write8(kbase, 0x2BDC5D, 0xeb); // copystr + + // stop sysVeri from causing a delayed panic on suspend + write16(kbase, 0x62846F, 0x00eb); + + // 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 + // + // // check the calling code if it looks like one of the syscall stubs at a + // // libkernel library and check if the syscall number correponds to the + // // proper stub + // if ((code & 0xff0000000000ffff) != 0x890000000000c0c7 + // || sa.code != (u32)(code >> 0x10) + // ) { + // // patch this to " = 0" instead + // is_invalid_syscall = -1; + // } + write32(kbase, 0x490, 0); + // these code corresponds to the check that ensures that the caller's + // instruction pointer is inside the libkernel library's memory range + // + // // patch the check to always go to the "goto do_syscall;" line + // void *code = td->td_frame->tf_rip; + // if (libkernel->start <= code && code < libkernel->end + // && is_invalid_syscall == 0 + // ) { + // goto do_syscall; + // } + // + // do_syscall: + // ... + // lea rsi, [rbp - 0x78] + // mov rdi, rbx + // mov rax, qword [rbp - 0x80] + // call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args) + // + // sy_call() is the function that will execute the requested syscall. + write8(kbase, 0x4c2, 0xeb); + write16(kbase, 0x4b9, 0x00eb); + write16(kbase, 0x4b5, 0x00eb); + + // 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, 0x391546, 0xeb); + + // patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings + // + // this check is skipped after the patch + // + // if ((new_prot & current->max_protection) != new_prot) { + // vm_map_unlock(map); + // return (KERN_PROTECTION_FAILURE); + // } + write16(kbase, 0x2FC14C, 0x04eb); + + // TODO: Description of this patch. patch sys_dynlib_load_prx() + write16(kbase, 0x1B71A4, 0xe990); + + // patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere + // call ... + // mov r14, qword [rbp - 0xad0] + // cmp eax, 0x4000000 + // jb ... ; patch jb to jmp + write32(kbase, 0x1B7758, 0x013ce990); + // patch called function to always return 0 + // + // sys_dynlib_dlsym: + // ... + // mov edi, 0x10 ; 16 + // call patched_function ; kernel_base + 0x951c0 + // test eax, eax + // je ... + // mov rax, qword [rbp - 0xad8] + // ... + // patched_function: ; patch to "xor eax, eax; ret" + // push rbp + // mov rbp, rsp + // ... + write32(kbase, 0x3BD8C0, 0xc3c03148); + + // 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, 0x1FA77A, 0x37); + write8(kbase, 0x1FA77D, 0x37); + + // overwrite the entry of syscall 11 (unimplemented) in sysent + // + // struct args { + // u64 rdi; + // u64 rsi; + // u64 rdx; + // u64 rcx; + // u64 r8; + // u64 r9; + // }; + // + // int sys_kexec(struct thread td, struct args *uap) { + // asm("jmp qword ptr [rsi]"); + // } + const u64 sysent_11_off = 0x1102d80; + // .sy_narg = 2 + write32(kbase, sysent_11_off, 2); + // .sy_call = gadgets['jmp qword ptr [rsi]'] + write64(kbase, sysent_11_off + 8, kbase + 0x47b31); + // .sy_thrcnt = SY_THR_STATIC + write32(kbase, sysent_11_off + 0x2c, 1); + + enable_cr0_wp(); +} + diff --git a/payloads/sources/ps4-kpatches-src/1302.c b/payloads/sources/ps4-kpatches-src/1302.c new file mode 100644 index 0000000..c1274b9 --- /dev/null +++ b/payloads/sources/ps4-kpatches-src/1302.c @@ -0,0 +1,171 @@ +/* Copyright (C) 2024-2025 anonymous + * + * This file is part of PSFree. + * + * PSFree is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * PSFree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ + +// 13.02 13.04 + +#include "types.h" +#include "utils.h" + +static inline void do_patch(void *kbase); + +__attribute__((section (".text.start"))) +int kpatch(void *td) { + const u64 xfast_syscall_off = 0x1c0; + void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; + + do_patch(kbase); + + return 0; +} + +__attribute__((always_inline)) +static inline void do_patch(void *kbase) { + disable_cr0_wp(); + + // LightningMods's additional dlsym patches from PPPwn + write16(kbase, 0x1B76F3, 0x04eb); // skip check 1 + write16(kbase, 0x1B7703, 0x04eb); // skip check 2 + write16(kbase, 0x1B7723, 0xe990); // nop + jmp + + // ChendoChap's patches from pOOBs4 + write16(kbase, 0x627B84, 0x00eb); // veriPatch + write8(kbase, 0xacd, 0xeb); // bcopy + write8(kbase, 0x2BD43D, 0xeb); // bzero + write8(kbase, 0x2BD481, 0xeb); // pagezero + write8(kbase, 0x2BD4FD, 0xeb); // memcpy + write8(kbase, 0x2BD541, 0xeb); // pagecopy + write8(kbase, 0x2BD6ED, 0xeb); // copyin + write8(kbase, 0x2BDB9D, 0xeb); // copyinstr + write8(kbase, 0x2BDC6D, 0xeb); // copystr + + // stop sysVeri from causing a delayed panic on suspend + write16(kbase, 0x62846F, 0x00eb); + + // 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 + // + // // check the calling code if it looks like one of the syscall stubs at a + // // libkernel library and check if the syscall number correponds to the + // // proper stub + // if ((code & 0xff0000000000ffff) != 0x890000000000c0c7 + // || sa.code != (u32)(code >> 0x10) + // ) { + // // patch this to " = 0" instead + // is_invalid_syscall = -1; + // } + write32(kbase, 0x490, 0); + // these code corresponds to the check that ensures that the caller's + // instruction pointer is inside the libkernel library's memory range + // + // // patch the check to always go to the "goto do_syscall;" line + // void *code = td->td_frame->tf_rip; + // if (libkernel->start <= code && code < libkernel->end + // && is_invalid_syscall == 0 + // ) { + // goto do_syscall; + // } + // + // do_syscall: + // ... + // lea rsi, [rbp - 0x78] + // mov rdi, rbx + // mov rax, qword [rbp - 0x80] + // call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args) + // + // sy_call() is the function that will execute the requested syscall. + write8(kbase, 0x4c2, 0xeb); + write16(kbase, 0x4b9, 0x00eb); + write16(kbase, 0x4b5, 0x00eb); + + // 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, 0x391556, 0xeb); + + // patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings + // + // this check is skipped after the patch + // + // if ((new_prot & current->max_protection) != new_prot) { + // vm_map_unlock(map); + // return (KERN_PROTECTION_FAILURE); + // } + write16(kbase, 0x2FC15C, 0x04eb); + + // TODO: Description of this patch. patch sys_dynlib_load_prx() + write16(kbase, 0x1B71B4, 0xe990); + + // patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere + // call ... + // mov r14, qword [rbp - 0xad0] + // cmp eax, 0x4000000 + // jb ... ; patch jb to jmp + write32(kbase, 0x1B7768, 0x013ce990); + // patch called function to always return 0 + // + // sys_dynlib_dlsym: + // ... + // mov edi, 0x10 ; 16 + // call patched_function ; kernel_base + 0x951c0 + // test eax, eax + // je ... + // mov rax, qword [rbp - 0xad8] + // ... + // patched_function: ; patch to "xor eax, eax; ret" + // push rbp + // mov rbp, rsp + // ... + write32(kbase, 0x3BD8D0, 0xc3c03148); + + // 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, 0x1FA78A, 0x37); + write8(kbase, 0x1FA78D, 0x37); + + // overwrite the entry of syscall 11 (unimplemented) in sysent + // + // struct args { + // u64 rdi; + // u64 rsi; + // u64 rdx; + // u64 rcx; + // u64 r8; + // u64 r9; + // }; + // + // int sys_kexec(struct thread td, struct args *uap) { + // asm("jmp qword ptr [rsi]"); + // } + const u64 sysent_11_off = 0x1102d80; + // .sy_narg = 2 + write32(kbase, sysent_11_off, 2); + // .sy_call = gadgets['jmp qword ptr [rsi]'] + write64(kbase, sysent_11_off + 8, kbase + 0x47b31); + // .sy_thrcnt = SY_THR_STATIC + write32(kbase, sysent_11_off + 0x2c, 1); + + enable_cr0_wp(); +} + diff --git a/payloads/sources/ps4-kpatches-src/1350.c b/payloads/sources/ps4-kpatches-src/1350.c new file mode 100644 index 0000000..0566038 --- /dev/null +++ b/payloads/sources/ps4-kpatches-src/1350.c @@ -0,0 +1,171 @@ +/* Copyright (C) 2024-2025 anonymous + * + * This file is part of PSFree. + * + * PSFree is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * PSFree is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . */ + +// 13.50 + +#include "types.h" +#include "utils.h" + +static inline void do_patch(void *kbase); + +__attribute__((section (".text.start"))) +int kpatch(void *td) { + const u64 xfast_syscall_off = 0x1c0; + void * const kbase = (void *)rdmsr(0xc0000082) - xfast_syscall_off; + + do_patch(kbase); + + return 0; +} + +__attribute__((always_inline)) +static inline void do_patch(void *kbase) { + disable_cr0_wp(); + + // LightningMods's additional dlsym patches from PPPwn + write16(kbase, 0x1B7703, 0x04eb); // skip check 1 + write16(kbase, 0x1B7713, 0x04eb); // skip check 2 + write16(kbase, 0x1B7733, 0xe990); // nop + jmp + + // ChendoChap's patches from pOOBs4 + write16(kbase, 0x627FC4, 0x00eb); // veriPatch + write8(kbase, 0xacd, 0xeb); // bcopy + write8(kbase, 0x2BD44D, 0xeb); // bzero + write8(kbase, 0x2BD491, 0xeb); // pagezero + write8(kbase, 0x2BD50D, 0xeb); // memcpy + write8(kbase, 0x2BD551, 0xeb); // pagecopy + write8(kbase, 0x2BD6FD, 0xeb); // copyin + write8(kbase, 0x2BDBAD, 0xeb); // copyinstr + write8(kbase, 0x2BDC7D, 0xeb); // copystr + + // stop sysVeri from causing a delayed panic on suspend + write16(kbase, 0x6288AF, 0x00eb); + + // 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 + // + // // check the calling code if it looks like one of the syscall stubs at a + // // libkernel library and check if the syscall number correponds to the + // // proper stub + // if ((code & 0xff0000000000ffff) != 0x890000000000c0c7 + // || sa.code != (u32)(code >> 0x10) + // ) { + // // patch this to " = 0" instead + // is_invalid_syscall = -1; + // } + write32(kbase, 0x490, 0); + // these code corresponds to the check that ensures that the caller's + // instruction pointer is inside the libkernel library's memory range + // + // // patch the check to always go to the "goto do_syscall;" line + // void *code = td->td_frame->tf_rip; + // if (libkernel->start <= code && code < libkernel->end + // && is_invalid_syscall == 0 + // ) { + // goto do_syscall; + // } + // + // do_syscall: + // ... + // lea rsi, [rbp - 0x78] + // mov rdi, rbx + // mov rax, qword [rbp - 0x80] + // call qword [rax + 8] ; error = (sa->callp->sy_call)(td, sa->args) + // + // sy_call() is the function that will execute the requested syscall. + write8(kbase, 0x4c2, 0xeb); + write16(kbase, 0x4b9, 0x00eb); + write16(kbase, 0x4b5, 0x00eb); + + // 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, 0x391916, 0xeb); + + // patch vm_map_protect() (called by sys_mprotect()) to allow rwx mappings + // + // this check is skipped after the patch + // + // if ((new_prot & current->max_protection) != new_prot) { + // vm_map_unlock(map); + // return (KERN_PROTECTION_FAILURE); + // } + write16(kbase, 0x2FC4AC, 0x04eb); + + // TODO: Description of this patch. patch sys_dynlib_load_prx() + write16(kbase, 0x1B71C4, 0xe990); + + // patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere + // call ... + // mov r14, qword [rbp - 0xad0] + // cmp eax, 0x4000000 + // jb ... ; patch jb to jmp + write32(kbase, 0x1B7778, 0x013ce990); + // patch called function to always return 0 + // + // sys_dynlib_dlsym: + // ... + // mov edi, 0x10 ; 16 + // call patched_function ; kernel_base + 0x951c0 + // test eax, eax + // je ... + // mov rax, qword [rbp - 0xad8] + // ... + // patched_function: ; patch to "xor eax, eax; ret" + // push rbp + // mov rbp, rsp + // ... + write32(kbase, 0x3BDD10, 0xc3c03148); + + // 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, 0x1FA79A, 0x37); + write8(kbase, 0x1FA79D, 0x37); + + // overwrite the entry of syscall 11 (unimplemented) in sysent + // + // struct args { + // u64 rdi; + // u64 rsi; + // u64 rdx; + // u64 rcx; + // u64 r8; + // u64 r9; + // }; + // + // int sys_kexec(struct thread td, struct args *uap) { + // asm("jmp qword ptr [rsi]"); + // } + const u64 sysent_11_off = 0x1102d80; + // .sy_narg = 2 + write32(kbase, sysent_11_off, 2); + // .sy_call = gadgets['jmp qword ptr [rsi]'] + write64(kbase, sysent_11_off + 8, kbase + 0x47b31); + // .sy_thrcnt = SY_THR_STATIC + write32(kbase, sysent_11_off + 0x2c, 1); + + enable_cr0_wp(); +} + diff --git a/payloads/sources/ps4-kpatches-src/Makefile b/payloads/sources/ps4-kpatches-src/Makefile index 8060319..b96d7f9 100644 --- a/payloads/sources/ps4-kpatches-src/Makefile +++ b/payloads/sources/ps4-kpatches-src/Makefile @@ -1,4 +1,4 @@ -TARGET_VERSIONS = 900 903 950 1000 1050 1100 1102 1150 1200 +TARGET_VERSIONS = 900 903 950 1000 1050 1100 1102 1150 1200 1250 1300 1302 1350 CC = gcc OBJCOPY = objcopy diff --git a/savedata/kernel_offset.lua b/savedata/kernel_offset.lua index 5d1633b..2548f86 100644 --- a/savedata/kernel_offset.lua +++ b/savedata/kernel_offset.lua @@ -327,7 +327,31 @@ ps4_kernel_offset_list = { TARGET_ID_OFFSET = 0x21cc60d, SYSENT_661_OFFSET = 0x110a760, JMP_RSI_GADGET = 0x47b31 - } + }, + [{ "12.50", "12.52"}] { + EVF_OFFSET = 0x784858, + PRISON0 = 0x111fa18, + ROOTVNODE = 0x2136e90, + TARGET_ID_OFFSET = 0x21cc60d, + SYSENT_661_OFFSET = 0x110a760, + JMP_RSI_GADGET = 0x47b31 + }, + [{ "13.00", "13.02", "13.04" }] = { + EVF_OFFSET = 0x7849D8, + PRISON0 = 0x111fa18, + ROOTVNODE = 0x2136e90, + TARGET_ID_OFFSET = 0x21cc60d, + SYSENT_661_OFFSET = 0x110a760, + JMP_RSI_GADGET = 0x47b31 + }, + [{ "13.50" }] = { + EVF_OFFSET = 0x784E18, + PRISON0 = 0x111fa18, + ROOTVNODE = 0x2136e90, + TARGET_ID_OFFSET = 0x21cc60d, + SYSENT_661_OFFSET = 0x110a760, + JMP_RSI_GADGET = 0x47b31 + }, } function get_ps5_kernel_offset() diff --git a/savedata/kernel_patches_ps4.lua b/savedata/kernel_patches_ps4.lua index 6867203..fc7a030 100644 --- a/savedata/kernel_patches_ps4.lua +++ b/savedata/kernel_patches_ps4.lua @@ -40,6 +40,14 @@ local shellcode_1150 = "b9820000c00f3248c1e22089c04809c2488d8a40feffff0f20c04825 local shellcode_1200 = "b9820000c00f3248c1e22089c04809c2488d8a40feffff0f20c04825fffffeff0f22c0b8eb040000beeb040000bf90e9ffff41b8eb000000668981a3761b00b8eb04000041b9eb00000041baeb000000668981ecc02f0041bbeb000000b890e9ffff4881c2717904006689b1b3761b006689b9d3761b0066448981f47a6200c681cd0a0000ebc681cdd32b00ebc68111d42b00ebc6818dd42b00ebc681d1d42b00ebc6817dd62b00ebc6812ddb2b00ebc681fddb2b00eb66448989df836200c7819004000000000000c681c2040000eb66448991b904000066448999b5040000c681e6143900eb66898164711b00c78118771b0090e93c01c78160d83b004831c0c3c6811aa71f0037c6811da71f0037c781802d100102000000488991882d1001c781ac2d1001010000000f20c0480d000001000f22c031c0c3" +local shellcode_1250 = "b9820000c00f3248c1e22089c04809c20f20c04825fffffeff0f22c0b8eb040000b9eb040000be90e9ffffbfeb00000066898223751b00b890e9ffff41b8eb00000041b9eb000000668982e46f1b0041baeb00000041bbeb040000488d827179040066898a33751b006689b253751b006689ba74796200c6820d090000ebc6824dd22b00ebc68291d22b00ebc6820dd32b00ebc68251d32b00ebc68216d52b00ebc682c6d92b00ebc6827dda2b00eb664489825f826200c782d002000000000000c68202030000eb6644898af902000066448992f5020000c68266133900eb6644899a6cbf2f00c78298751b0090e93c01c782e0d63b004831c0c3c6829aa51f0037c6829da51f0037c782c02b100102000000488982c82b1001c782ec2b1001010000000f20c0480d000001000f22c031c0c3" + +local shellcode_1300 = "b9820000c00f3248c1e22089c04809c20f20c04825fffffeff0f22c0b8eb040000b9eb040000be90e9ffffbfeb00000066898223751b00b890e9ffff41b8eb00000041b9eb000000668982e46f1b0041baeb00000041bbeb040000488d827179040066898a33751b006689b253751b006689bac4796200c6820d090000ebc6826dd22b00ebc682b1d22b00ebc6822dd32b00ebc68271d32b00ebc6821dd52b00ebc682cdd92b00ebc6829dda2b00eb66448982af826200c782d002000000000000c68202030000eb6644898af902000066448992f5020000c68286133900eb6644899a8cbf2f00c78298751b0090e93c01c78200d73b004831c0c3c682baa51f0037c682bda51f0037c782c02b100102000000488982c82b1001c782ec2b1001010000000f20c0480d000001000f22c031c0c3" + +local shellcode_1302 = "b9820000c00f3248c1e22089c04809c20f20c04825fffffeff0f22c0b8eb040000b9eb040000be90e9ffffbfeb00000066898233751b00b890e9ffff41b8eb00000041b9eb000000668982f46f1b0041baeb00000041bbeb040000488d827179040066898a43751b006689b263751b006689bac4796200c6820d090000ebc6827dd22b00ebc682c1d22b00ebc6823dd32b00ebc68281d32b00ebc6822dd52b00ebc682ddd92b00ebc682adda2b00eb66448982af826200c782d002000000000000c68202030000eb6644898af902000066448992f5020000c68296133900eb6644899a9cbf2f00c782a8751b0090e93c01c78210d73b004831c0c3c682caa51f0037c682cda51f0037c782c02b100102000000488982c82b1001c782ec2b1001010000000f20c0480d000001000f22c031c0c3" + +local shellcode_1350 = "b9820000c00f3248c1e22089c04809c20f20c04825fffffeff0f22c0b8eb040000b9eb040000be90e9ffffbfeb00000066898243751b00b890e9ffff41b8eb00000041b9eb00000066898204701b0041baeb00000041bbeb040000488d827179040066898a53751b006689b273751b006689ba047e6200c6820d090000ebc6828dd22b00ebc682d1d22b00ebc6824dd32b00ebc68291d32b00ebc6823dd52b00ebc682edd92b00ebc682bdda2b00eb66448982ef866200c782d002000000000000c68202030000eb6644898af902000066448992f5020000c68256173900eb6644899aecc22f00c782b8751b0090e93c01c78250db3b004831c0c3c682daa51f0037c682dda51f0037c782c02b100102000000488982c82b1001c782ec2b1001010000000f20c0480d000001000f22c031c0c3" + function get_kernel_patches_shellcode() local shellcode = "" if FW_VERSION == "9.00" then @@ -60,6 +68,14 @@ function get_kernel_patches_shellcode() shellcode = shellcode_1150 elseif FW_VERSION == "12.00" or FW_VERSION == "12.02" then shellcode = shellcode_1200 + elseif FW_VERSION == "12.50" or FW_VERSION == "12.52" then + shellcode = shellcode_1250 + elseif FW_VERSION == "13.00" then + shellcode = shellcode_1300 + elseif FW_VERSION == "13.02" or FW_VERSION == "13.04" then + shellcode = shellcode_1302 + elseif FW_VERSION == "13.50" then + shellcode = shellcode_1350 end if #shellcode == 0 then return ""