Created
February 25, 2018 14:53
-
-
Save stek29/cdff84cdb0e51dc7f6770af1915be02d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <mach/mach.h> | |
#include <xpc/xpc.h> | |
/* dlsym-like function that uses (private API) CoreSymbolication to get unexported symbols. | |
C functions use their C name, without the underscore prefix. C++ functions use their | |
demangled names, e.g. "MYClass::function(int, void *)" */ | |
void *get_symbol(const char *name); | |
kern_return_t bootstrap_look_up3(mach_port_t bp, const char *service_name, mach_port_name_t *sp, int64_t target_pid, const unsigned char *instance_uuid, uint64_t flags); | |
kern_return_t bootstrap_look_up(mach_port_t bp, const char* service_name, mach_port_t *sp); | |
mach_port_t xpc_mach_send_get_right(xpc_object_t obj); | |
void xpc_dictionary_set_mach_send(xpc_object_t, const char*, mach_port_t); | |
kern_return_t (*_Xxpc_bootstrap_routine)(unsigned int type, xpc_object_t req, xpc_object_t* ret); | |
// this is somewhere from newosxbook.com i guess | |
extern struct _os_alloc_once_s { | |
long once; | |
void *ptr; | |
} _os_alloc_once_table[]; | |
struct xpc_global_data { | |
uint64_t a; | |
uint64_t xpc_flags; | |
mach_port_t task_bootstrap_port; /* 0x10 */ | |
#ifndef __LP64__ | |
uint32_t padding; | |
#endif | |
xpc_object_t xpc_bootstrap_pipe; /* 0x18 */ | |
// and there's more, but you'll have to wait for MOXiI 2 for those... | |
// ... | |
}; | |
__attribute__((constructor)) | |
static void ctor(void) {; | |
_Xxpc_bootstrap_routine = (void*) get_symbol("_xpc_bootstrap_routine"); | |
}; | |
extern void *_xpc_type_mach_send; | |
#define XPC_TYPE_MACH_SEND _xpc_type_mach_send | |
xpc_object_t Xbootstrap_create_request(mach_port_t bp) { | |
xpc_object_t v1; | |
v1 = xpc_dictionary_create(NULL, NULL, 0); | |
xpc_dictionary_set_uint64(v1, "type", 7); | |
xpc_dictionary_set_uint64(v1, "handle", 0); | |
xpc_dictionary_set_mach_send(v1, "domain-port", bp); | |
return v1; | |
} | |
kern_return_t _xpc_mach_port_retain_send(mach_port_name_t name){ | |
return mach_port_mod_refs(mach_task_self(), name, MACH_PORT_RIGHT_SEND, 1); | |
} | |
kern_return_t _xpc_interface_routine(uint64_t subsystem, uint64_t routine_id, xpc_object_t req, xpc_object_t* resp) { | |
xpc_dictionary_set_uint64(req, "subsystem", subsystem); | |
xpc_dictionary_set_uint64(req, "routine", routine_id); | |
// xpc_dictionary_set_bool(req, "pre-exec", 1); | |
xpc_pipe_routine() | |
} | |
kern_return_t _xpc_bootstrap_routine(uint64_t routine_id, xpc_object_t req, xpc_object_t *resp) { | |
return _xpc_interface_routine(5, routine_id, req, resp); | |
} | |
kern_return_t Xbootstrap_look_up3(mach_port_t bp, const char *service_name, mach_port_name_t *sp, int64_t target_pid, const unsigned char *instance_uuid, uint64_t flags) { | |
xpc_object_t req = Xbootstrap_create_request(bp); | |
xpc_dictionary_set_string(req, "name", service_name); | |
xpc_dictionary_set_int64(req, "targetpid", target_pid); | |
xpc_dictionary_set_uuid(req, "instance", instance_uuid); | |
xpc_dictionary_set_uint64(req, "flags", flags); | |
kern_return_t ret = KERN_SUCCESS; | |
xpc_object_t resp = NULL; | |
ret = _Xxpc_bootstrap_routine(0xCF, req, &resp); | |
if (ret != KERN_SUCCESS) { | |
if (ret == 0x8D) { | |
// (ipc/send) invalid destination port | |
ret = 0x10000003; | |
} | |
xpc_release(req); | |
return ret; | |
} | |
xpc_object_t port_obj = xpc_dictionary_get_value(resp, "port"); | |
if (port_obj != NULL) { | |
// no need to check type -- xpc_mach_send_get_right checks it | |
mach_port_t port = xpc_mach_send_get_right(port_obj); | |
if (port != MACH_PORT_NULL) { | |
ret = _xpc_mach_port_retain_send(port); | |
*sp = port; | |
} | |
} | |
xpc_release(resp); | |
xpc_release(req); | |
return ret; | |
} | |
kern_return_t Xbootstrap_look_up(mach_port_t bp, const char* service_name, mach_port_t *sp) { | |
uuid_t v4; | |
return Xbootstrap_look_up3(bp, service_name, sp, 0, v4, 0); | |
} | |
mach_port_t getbp(void) { | |
mach_port_t bp = MACH_PORT_NULL; | |
if (task_get_bootstrap_port(mach_task_self(), &bp) != KERN_SUCCESS) { | |
bp = MACH_PORT_NULL; | |
} | |
return bp; | |
} | |
int main(void) { | |
mach_port_t bp = getbp(); | |
printf("BP: 0x%x\n", bp); | |
mach_port_t p0, p1; | |
p0 = p1 = MACH_PORT_NULL; | |
const char* serv = "com.apple.iohideventsystem"; | |
int ret; | |
ret = Xbootstrap_look_up(bp, serv, &p1); | |
printf("Xbootstrap_look_up: 0x%x (%s)\n", ret, mach_error_string(ret)); | |
printf("port1: 0x%x\n", p1); | |
ret = bootstrap_look_up(bp, serv, &p0); | |
printf("bootstrap_look_up: 0x%x (%s)\n", ret, mach_error_string(ret)); | |
printf("port0: 0x%x\n", p0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment