|
17 | 17 | along with Nyxian. If not, see <https://www.gnu.org/licenses/>. |
18 | 18 | */ |
19 | 19 |
|
| 20 | +#import <LindChain/Debugger/MachServer.h> |
20 | 21 | #import <Foundation/Foundation.h> |
21 | 22 | #include <pthread.h> |
22 | 23 | #include <stdio.h> |
@@ -609,145 +610,3 @@ void machServerInit(void) |
609 | 610 | pthread_detach(serverThread); |
610 | 611 | }); |
611 | 612 | } |
612 | | - |
613 | | -#if !JAILBREAK_ENV |
614 | | - |
615 | | -void* ktfp_exception_self_server(void *arg) |
616 | | -{ |
617 | | - // Our task is the target, the exception port as the receive side of the kernel exception messages, the mask is basically controlling to what our exception server reacts to |
618 | | - task_t task = mach_task_self(); |
619 | | - mach_port_t exceptionPort = MACH_PORT_NULL; |
620 | | - exception_mask_t mask = EXC_MASK_BREAKPOINT; |
621 | | - |
622 | | - if(arg == NULL) |
623 | | - { |
624 | | - // Allocating mach port and setting it up with our process |
625 | | - mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &exceptionPort); |
626 | | - mach_port_insert_right(task, exceptionPort, exceptionPort, MACH_MSG_TYPE_MAKE_SEND); |
627 | | - |
628 | | - task_set_exception_ports(task, mask, exceptionPort, EXCEPTION_DEFAULT, ARM_THREAD_STATE64); |
629 | | - |
630 | | - environment_syscall(SYS_handoffep, exceptionPort); |
631 | | - |
632 | | - __builtin_trap(); |
633 | | - |
634 | | - mach_port_deallocate(mach_task_self(), exceptionPort); |
635 | | - task_set_exception_ports(mach_task_self(), EXC_MASK_BAD_ACCESS, MACH_PORT_NULL, EXCEPTION_DEFAULT, THREAD_STATE_NONE); |
636 | | - |
637 | | - return NULL; |
638 | | - } |
639 | | - else |
640 | | - { |
641 | | - exceptionPort = *((mach_port_t*)arg); |
642 | | - } |
643 | | - |
644 | | - // Thanks to microsoft, without you this wouldnt be possible and I wouldnt understand yet what to do. The request is send by the kernel to our mach port |
645 | | - __Request__exception_raise_t *request = NULL; |
646 | | - size_t request_size = round_page(sizeof(*request)); |
647 | | - kern_return_t kr; |
648 | | - mach_msg_return_t mr; |
649 | | - |
650 | | - // Allocating the request structure to have a writing destination |
651 | | - kr = vm_allocate(mach_task_self(), (vm_address_t *) &request, request_size, VM_FLAGS_ANYWHERE); |
652 | | - if(kr != KERN_SUCCESS) |
653 | | - { |
654 | | - // Shouldn't happen ... |
655 | | - fprintf(stderr, "Unexpected error in vm_allocate(): %x\n", kr); |
656 | | - return NULL; |
657 | | - } |
658 | | - |
659 | | - while(1) |
660 | | - { |
661 | | - klog_log(@"machserver", @"listening to %d", exceptionPort); |
662 | | - |
663 | | - // Now requesting the message and waiting on a reply from the kernel.. happens on exception |
664 | | - request->Head.msgh_local_port = exceptionPort; |
665 | | - request->Head.msgh_size = (mach_msg_size_t)request_size; |
666 | | - mr = mach_msg(&request->Head, |
667 | | - MACH_RCV_MSG | MACH_RCV_LARGE, |
668 | | - 0, |
669 | | - request->Head.msgh_size, |
670 | | - exceptionPort, |
671 | | - MACH_MSG_TIMEOUT_NONE, |
672 | | - MACH_PORT_NULL); |
673 | | - |
674 | | - klog_log(@"machserver", @"got answer from %d -> %d", exceptionPort, mr); |
675 | | - |
676 | | - // Microsofts code to handle if the exception message send by the kernel is valid to process |
677 | | - if(mr != MACH_MSG_SUCCESS && mr == MACH_RCV_TOO_LARGE) |
678 | | - { |
679 | | - // Determine the new size (before dropping the buffer) |
680 | | - request_size = round_page(request->Head.msgh_size); |
681 | | - |
682 | | - // Drop the old receive buffer |
683 | | - vm_deallocate(mach_task_self(), (vm_address_t) request, request_size); |
684 | | - |
685 | | - // Re-allocate a larger receive buffer |
686 | | - kr = vm_allocate(mach_task_self(), (vm_address_t *) &request, request_size, VM_FLAGS_ANYWHERE); |
687 | | - if(kr != KERN_SUCCESS) |
688 | | - { |
689 | | - // Shouldn't happen ... |
690 | | - fprintf(stderr, "Unexpected error in vm_allocate(): 0x%x\n", kr); |
691 | | - return NULL; |
692 | | - } |
693 | | - |
694 | | - continue; |
695 | | - |
696 | | - } |
697 | | - else if (mr != MACH_MSG_SUCCESS) |
698 | | - exit(-1); |
699 | | - |
700 | | - // Sanity checks |
701 | | - if(request->Head.msgh_size < sizeof(*request) || request_size - sizeof(*request) < (sizeof(mach_exception_data_type_t) * request->codeCnt)) |
702 | | - exit(-1); |
703 | | - |
704 | | - klog_log(@"machserver", @"exception: %s", exceptionName(request->exception)); |
705 | | - |
706 | | - /* we got it */ |
707 | | - mach_port_mod_refs(mach_task_self(), request->task.name, MACH_PORT_RIGHT_SEND, 1); |
708 | | - *((mach_port_t*)arg) = request->task.name; |
709 | | - |
710 | | - klog_log(@"machserver", @"task: %d | thread: %d", request->task.name, request->thread.name); |
711 | | - |
712 | | - /* now manipulate thread state */ |
713 | | - struct arm64_thread_full_state *state = thread_save_state_arm64(request->thread.name); |
714 | | - state->thread.__pc += 4; |
715 | | - thread_restore_state_arm64(request->thread.name, state); |
716 | | - |
717 | | - kr = KERN_SUCCESS; |
718 | | - |
719 | | - // The faulting thread will be stopped until the reply was send to the kernel |
720 | | - __Reply__exception_raise_t reply; |
721 | | - memset(&reply, 0, sizeof(reply)); |
722 | | - reply.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request->Head.msgh_bits), 0); |
723 | | - reply.Head.msgh_id = request->Head.msgh_id + 100; |
724 | | - reply.Head.msgh_local_port = MACH_PORT_NULL; |
725 | | - reply.Head.msgh_remote_port = request->Head.msgh_remote_port; |
726 | | - reply.Head.msgh_size = sizeof(reply); |
727 | | - reply.NDR = NDR_record; |
728 | | - reply.RetCode = kr; |
729 | | - mr = mach_msg(&reply.Head, MACH_SEND_MSG, reply.Head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); |
730 | | - if(mr != KERN_SUCCESS) |
731 | | - exit(-1); |
732 | | - else |
733 | | - { |
734 | | - return NULL; |
735 | | - } |
736 | | - } |
737 | | -} |
738 | | - |
739 | | -void ktfp_setup(void) |
740 | | -{ |
741 | | - static dispatch_once_t onceToken; |
742 | | - dispatch_once(&onceToken, ^{ |
743 | | - ktfp_exception_self_server(NULL); |
744 | | - }); |
745 | | -} |
746 | | - |
747 | | -task_t obtainTaskPortWithExceptionRecvRight(mach_port_t recv) |
748 | | -{ |
749 | | - ktfp_exception_self_server(&recv); |
750 | | - return recv; |
751 | | -} |
752 | | - |
753 | | -#endif /* !JAILBREAK_ENV */ |
0 commit comments