Skip to content

Instantly share code, notes, and snippets.

@mach-kernel
Created June 7, 2021 20:49
Show Gist options
  • Select an option

  • Save mach-kernel/5c0f78e18def295d7251ffd41083920a to your computer and use it in GitHub Desktop.

Select an option

Save mach-kernel/5c0f78e18def295d7251ffd41083920a to your computer and use it in GitHub Desktop.

Revisions

  1. mach-kernel created this gist Jun 7, 2021.
    66 changes: 66 additions & 0 deletions xpc_test.rs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,66 @@
    use std::os::raw::{c_void, c_int, c_char};
    use std::ptr::{null_mut, null};
    use std::ffi::{CStr, CString};

    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

    extern "C" {
    pub fn xpc_pipe_create_from_port(port: mach_port_t, flags: u64) -> xpc_pipe_t;
    pub fn xpc_pipe_routine_with_flags(
    pipe: xpc_pipe_t,
    msg: xpc_object_t,
    reply: *mut xpc_object_t,
    flags: u64,
    ) -> c_int;

    pub fn xpc_dictionary_set_mach_send(
    object: xpc_object_t,
    name: *const c_char,
    port: mach_port_t,
    );
    }

    pub type xpc_pipe_t = *mut c_void;

    fn main() {
    let argv: Vec<String> = std::env::args().collect();

    if argv.len() < 2 {
    println!("Usage: {}", argv[0]);
    std::process::exit(1);
    }

    let bootstrap_pipe: xpc_pipe_t = unsafe {
    xpc_pipe_create_from_port(bootstrap_port, 4)
    };

    let list_request: xpc_object_t = unsafe {
    xpc_dictionary_create(null(), null_mut(), 0)
    };

    unsafe {
    xpc_dictionary_set_uint64(list_request, CString::new("subsystem").unwrap().as_ptr(), 3);
    xpc_dictionary_set_uint64(list_request, CString::new("handle").unwrap().as_ptr(), 0);
    xpc_dictionary_set_uint64(list_request, CString::new("routine").unwrap().as_ptr(), 815);
    xpc_dictionary_set_string(list_request, CString::new("name").unwrap().as_ptr(), CString::new(argv[1].clone()).unwrap().as_ptr());
    xpc_dictionary_set_uint64(list_request, CString::new("type").unwrap().as_ptr(), 7);
    xpc_dictionary_set_bool(list_request, CString::new("legacy").unwrap().as_ptr(), true);
    xpc_dictionary_set_mach_send(list_request, CString::new("domain-port").unwrap().as_ptr(), bootstrap_port);
    }

    let mut reply: xpc_object_t = null_mut();

    let err = unsafe {
    xpc_pipe_routine_with_flags(bootstrap_pipe, list_request, &mut reply, 0)
    };

    if err == 0 {
    let desc = unsafe {
    CStr::from_ptr(xpc_copy_description(reply))
    };

    println!("XPC Response\n{}", desc.to_string_lossy())
    } else {
    println!("Error: {}", err)
    }
    }