userclient_hv_trap.m 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. @import Darwin;
  2. @import Foundation;
  3. typedef io_object_t io_connect_t;
  4. kern_return_t IOConnectTrap6(io_connect_t connect, uint32_t index, uintptr_t p1, uintptr_t p2,
  5. uintptr_t p3, uintptr_t p4, uintptr_t p5, uintptr_t p6);
  6. static mach_port_t gUserClient;
  7. static uint64_t gCodePtrs[14];
  8. static uint64_t gDiscriminant;
  9. static int init_hv_trap() {
  10. NSError* nserror = nil;
  11. NSString* inStr = [NSString stringWithContentsOfFile:@"/tmp/zhuowei_portinfo"
  12. encoding:NSUTF8StringEncoding
  13. error:&nserror];
  14. if (!inStr) {
  15. NSLog(@"Error opening portinfo: %@", nserror);
  16. return 1;
  17. }
  18. NSArray<NSString*>* parts = [inStr componentsSeparatedByString:@"\n"];
  19. int target_pid = parts[0].intValue;
  20. mach_port_t target_task = 0;
  21. kern_return_t err;
  22. err = task_for_pid(mach_task_self_, target_pid, &target_task);
  23. if (err) {
  24. fprintf(stderr, "Failed to get task port: %s\n", mach_error_string(err));
  25. return 1;
  26. }
  27. if (target_task == MACH_PORT_NULL) {
  28. fprintf(stderr, "Can't get task port for pid %d\n", target_pid);
  29. return 1;
  30. }
  31. mach_port_name_t remote_port_id = parts[1].intValue;
  32. mach_port_t user_client = 0;
  33. mach_msg_type_name_t user_client_type = 0;
  34. err = mach_port_extract_right(target_task, remote_port_id, MACH_MSG_TYPE_COPY_SEND, &user_client,
  35. &user_client_type);
  36. if (err) {
  37. fprintf(stderr, "Failed to extract user client port: %s\n", mach_error_string(err));
  38. return 1;
  39. }
  40. NSLog(@"ok port = %u", user_client);
  41. gDiscriminant = strtoull(parts[2].UTF8String, nil, 0x10);
  42. for (int i = 0; i < 14; i++) {
  43. gCodePtrs[i] = strtoull(parts[3 + i].UTF8String, nil, 0x10);
  44. }
  45. gUserClient = user_client;
  46. return 0;
  47. }
  48. kern_return_t hv_trap(unsigned int hv_call, void* hv_arg) {
  49. static dispatch_once_t init_token;
  50. dispatch_once(&init_token, ^{
  51. init_hv_trap();
  52. });
  53. if (gUserClient == 0) {
  54. // TODO(zhuowei): make an error code??
  55. return 0x1337;
  56. }
  57. uint64_t signed_code_ptr = gCodePtrs[hv_call];
  58. return IOConnectTrap6(gUserClient, /*index=*/0, /*arg1*/ hv_arg, /*arg2*/ 0, signed_code_ptr,
  59. gDiscriminant, 0, 0);
  60. }