#include <stdio.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <bootstrap.h> // for bootstrap * #include <mach/mach_port.h> // for mach_port*, ipc_space #include <mach/mach_init.h> // for mach_task_self #include <stdlib.h> int main(int argc, char **argv, char **envp, char **apple) { extern mach_port_t bootstrap_port; // defined in libsystem_kernel.dylib printf("My BS Port (SEND RIGHT) - is 0x%x\n", bootstrap_port); char *mach_error_string(int); // in some header, whatever #ifdef LOOKUP mach_port_t server_p = MACH_PORT_NULL; kern_return_t kr = bootstrap_look_up (bootstrap_port, // from bootstrap.h argv[1], &server_p); if (KERN_SUCCESS == kr) { printf("SERVER P is 0x%x\n", server_p);} else { fprintf(stderr,"bootstrap_look_up: %s\n" , mach_error_string(kr)); } #endif // LOOKUP #ifdef ENUM ipc_space_t target = mach_task_self(); // given representing MOI. kern_return_t kr = task_for_pid(mach_task_self(), atoi(argv[1]), &target); if (kr != KERN_SUCCESS) { fprintf(stderr," FOOL! You cannot unleash the dark magicks! Away with thee! (%s)\n", mach_error_string(kr)); exit(1); } mach_port_t myEphPort = MACH_PORT_NULL; // unallocated constant #define MAX_PORTS_FOR_FUN 1 for (int i = 0; i < MAX_PORTS_FOR_FUN; i++) { kr = mach_port_allocate (target, // ipc_space_t task, MACH_PORT_RIGHT_RECEIVE , // mach_port_right_t right, &myEphPort); // mach_port_name_t *name); mach_port_insert_right (target, myEphPort, myEphPort, MACH_MSG_TYPE_MAKE_SEND); (void) kr; // @@TODO: check me. Should be KERN_SUCCESS printf("My Eph port is 0x%x\n", myEphPort); } // There are more port (rights) in my space than I necessarily know. // and - there is some API to ENUMERATE. ipc_info_space_t space_info; ipc_info_name_array_t table_info; mach_msg_type_number_t table_infoCnt; ipc_info_tree_name_array_t tree_info; mach_msg_type_number_t tree_infoCnt; kern_return_t kr1 = mach_port_space_info (target, // ipc_space_read_t space, &space_info, // ipc_info_space_t *space_info, &table_info , // ipc_info_name_array_t *table_info, &table_infoCnt, // mach_msg_type_number_t *table_infoCnt, &tree_info, // ipc_info_tree_name_array_t *tree_info, // IRRELEVANT (unused) &tree_infoCnt); // mach_msg_type_number_t *tree_infoCnt // IRRELEVANT (unused) if (KERN_SUCCESS != kr1) { fprintf(stderr," mach_port_space_info: %s\n", mach_error_string(kr1)); exit(1); } printf("Table count: %d\n", table_infoCnt); int p = 0; for (p = 0; p < table_infoCnt; p++) { #if 0 typedef struct ipc_info_name { mach_port_name_t iin_name; /* port name, including gen number */ /*boolean_t*/ integer_t iin_collision; /* collision at this entry? */ mach_port_type_t iin_type; /* straight port type */ mach_port_urefs_t iin_urefs; /* user-references */ natural_t iin_object; /* object pointer/identifier */ natural_t iin_next; /* marequest/next in free list */ natural_t iin_hash; /* hash index */ } ipc_info_name_t; #endif printf("%d: name 0x%x type 0x%x obj 0x%x\n" , p, table_info[p].iin_name, table_info[p].iin_type, table_info[p].iin_object); }// end p #endif // ENUM } // end main