Merge branch 'main' of https://github.com/Nazky/PSFree-Kame
This commit is contained in:
@@ -4,9 +4,11 @@ Lapse Kex ported to 9.00 - Still WIP
|
||||
|
||||
Very fast and reliable but can KP :P
|
||||
|
||||
Warning: This repository is a work in progress. Do not use it by default—or better yet, don’t use it at all—until I and/or someone else declare it stable. There are issues with certain games, such as black screens, problems with save data, and multiple kernel panics. The offsets for PS4 9.00 still need to be verified. If you choose to use it, do so at your own risk.
|
||||
|
||||
TODO:
|
||||
- Needs a bin loader on Port 9020.
|
||||
- Some performance Tweaks??.
|
||||
- Add sysveri Patch
|
||||
|
||||
PR are welcome
|
||||
|
||||
@@ -17,13 +19,12 @@ repo is for the PS4 but we try to make things portable to PS5.
|
||||
* PSFree: src/psfree.mjs
|
||||
* Lapse (kernel): src/scripts/lapse.mjs
|
||||
|
||||
Donation (Monero/XMR):
|
||||
Donation [abc developer] (Monero/XMR):
|
||||
86Fk3X9AE94EGKidzRbvyiVgGNYD3qZnuKNq1ZbsomFWXHYm6TtAgz9GNGitPWadkS3Wr9uXoT29U1SfdMtJ7QNKQpW1CVS
|
||||
|
||||
# COPYRIGHT AND AUTHORS:
|
||||
AGPL-3.0-or-later (see src/COPYING). This repo belongs to the group
|
||||
`anonymous`. We refer to anonymous contributors as "anonymous" as well.
|
||||
|
||||
# CREDITS:
|
||||
* anonymous for PS4 firmware kernel dumps
|
||||
* Check the appropriate files for any **extra** contributors. Unless otherwise
|
||||
|
||||
+115
-43
@@ -16,6 +16,7 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "utils.h"
|
||||
@@ -57,52 +58,123 @@ void do_patch(void) {
|
||||
void * const kbase = (void *)rdmsr(0xC0000082) - off_fast_syscall;
|
||||
|
||||
disable_cr0_wp();
|
||||
//ChendoChap Patches For 900
|
||||
const size_t KERNEL_enable_syscalls_1 = 0x490;
|
||||
const size_t KERNEL_enable_syscalls_2 = 0x4B5;
|
||||
const size_t KERNEL_enable_syscalls_3 = 0x4B9;
|
||||
const size_t KERNEL_enable_syscalls_4 = 0x4C2;
|
||||
const size_t KERNEL_mprotect = 0x80B8D;
|
||||
const size_t KERNEL_prx = 0x23AEC4;
|
||||
const size_t KERNEL_mmap_1 = 0x16632A;
|
||||
const size_t KERNEL_mmap_2 = 0x16632D;
|
||||
const size_t KERNEL_dlsym_1 = 0x23B67F;
|
||||
const size_t KERNEL_dlsym_2 = 0x221b40;
|
||||
const size_t KERNEL_setuid = 0x1A06;
|
||||
const size_t KERNEL_bzero = 0x2713FD;
|
||||
const size_t KERNEL_pagezero = 0x271441;
|
||||
const size_t KERNEL_memcpy = 0x2714BD;
|
||||
const size_t KERNEL_pagecopy = 0x271501;
|
||||
const size_t KERNEL_copyin = 0x2716AD;
|
||||
const size_t KERNEL_copyinstr = 0x271B5D;
|
||||
const size_t KERNEL_copystr = 0x271C2D;
|
||||
const size_t KERNEL_veriPatch = 0x626874;
|
||||
const size_t KERNEL_setcr0_patch = 0x3ade3B;
|
||||
write32(kbase, KERNEL_enable_syscalls_1, 0);
|
||||
write16(kbase, KERNEL_enable_syscalls_2, 0x9090);
|
||||
write16(kbase, KERNEL_enable_syscalls_3, 0x9090);
|
||||
write8(kbase, KERNEL_enable_syscalls_4, 0xEB);
|
||||
write8(kbase, KERNEL_mmap_1, 0x37);
|
||||
write8(kbase, KERNEL_mmap_2, 0x37);
|
||||
write32(kbase, KERNEL_mprotect, 0);
|
||||
write8(kbase, KERNEL_dlsym_1, 0xEB);
|
||||
write32(kbase, KERNEL_dlsym_2, 0xC3C03148);
|
||||
write8(kbase, KERNEL_setuid, 0xEB);
|
||||
write16(kbase, KERNEL_prx, 0xE990);
|
||||
write8(kbase, KERNEL_bzero, 0xEB);
|
||||
write8(kbase, KERNEL_pagezero, 0xEB);
|
||||
write8(kbase, KERNEL_memcpy, 0xEB);
|
||||
write8(kbase, KERNEL_pagecopy, 0xEB);
|
||||
write8(kbase, KERNEL_copyin, 0xEB);
|
||||
write8(kbase, KERNEL_copyinstr, 0xEB);
|
||||
write8(kbase, KERNEL_copystr, 0xEB);
|
||||
write16(kbase, KERNEL_veriPatch, 0x9090);
|
||||
write32(kbase, KERNEL_setcr0_patch, 0xC3C7220F);
|
||||
|
||||
|
||||
// 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.
|
||||
write16(kbase, 0x4b5, 0x9090);
|
||||
write16(kbase, 0x4b9, 0x9090);
|
||||
write8(kbase, 0x4c2, 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);
|
||||
|
||||
// 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);
|
||||
// }
|
||||
write32(kbase, 0x80b8d, 0);
|
||||
|
||||
// patch sys_dynlib_dlsym() to allow dynamic symbol resolution everywhere
|
||||
|
||||
// call ...
|
||||
// mov r14, qword [rbp - 0xad0]
|
||||
// cmp eax, 0x4000000
|
||||
// jb ... ; patch jb to jmp
|
||||
write8(kbase, 0x23B67F, 0xeb);
|
||||
// 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, 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 sysveri to prevent delayed panics
|
||||
write16(kbase, 0x626874, 0x9090);
|
||||
|
||||
// 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]");
|
||||
// }
|
||||
|
||||
// sysent[11]
|
||||
const size_t offset_sysent_11 = 0x1100520;
|
||||
// .sy_narg = 6
|
||||
write32(kbase, offset_sysent_11, 6);
|
||||
// .sy_call = gadgets['jmp qword ptr [rsi]']
|
||||
write64(kbase, offset_sysent_11 + 8, kbase + 0x4c7ad);
|
||||
write32(kbase, offset_sysent_11 + 0x2c, 1);
|
||||
// .sy_thrcnt = SY_THR_STATIC
|
||||
write32(kbase, offset_sysent_11 + 0x2c, 1);
|
||||
|
||||
enable_cr0_wp();
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user