Skip to content

Instantly share code, notes, and snippets.

@stek29
Created February 25, 2018 14:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stek29/cdff84cdb0e51dc7f6770af1915be02d to your computer and use it in GitHub Desktop.
Save stek29/cdff84cdb0e51dc7f6770af1915be02d to your computer and use it in GitHub Desktop.
#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