监控线程的 Mach 异常

来源:互联网 发布:淘宝股票行情 编辑:程序博客网 时间:2024/04/30 12:56

xnu 采用了微内核的架构,

因此 Mach Message 与各模块都有着千丝万缕的联系,

异常也不例外。

如果想详细的学习 Mach Exception 是如何工作的,

其与 Unix Signal 的关系,

大家可以去阅读:

《Mac OS X Internals: A Systems Approach》

《Mac OS X and iOS Internals: To The Apple's Core》


这里给出一个监控某个线程 Mach Exception 的代码,

主要用于在发生异常时分析其他线程的状态,

并且可以用来构建基于异常的反调试机制。


#import <mach/mach.h>#import <mach/port.h>#import <mach/exception.h>#import <mach/exception_types.h>#import <mach/task.h>#import <stdio.h>#import <pthread/pthread.h>mach_port_t gExceptionPort = 0;static void *ExceptionHandler(void *ignored){    mach_msg_return_t rc;    printf("--------->Exc handler listening\n");        typedef struct {        mach_msg_header_t Head;        mach_msg_body_t msgh_body;        mach_msg_port_descriptor_t thread;        mach_msg_port_descriptor_t task;        NDR_record_t NDR;        exception_type_t exception;        mach_msg_type_number_t codeCnt;        integer_t code[2];        int flavor;        mach_msg_type_number_t old_stateCnt;        natural_t old_state[144];    } Request;        Request exc;    for(;;) {        rc = mach_msg(&exc.Head,                      MACH_RCV_MSG | MACH_RCV_LARGE,                      0,                      sizeof(Request),                      gExceptionPort,                      MACH_MSG_TIMEOUT_NONE,                      MACH_PORT_NULL);                if(rc != MACH_MSG_SUCCESS) {            return 0;        };                printf("--------->Got Message\n");        exit(1);    }}static void CatchMACHExceptions(){    kern_return_t rc = 0;    exception_mask_t excMask = EXC_MASK_BAD_ACCESS; // !!!这里只是监控了异常读写,实际使用时需要根据需要进行修改!!!        rc = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &gExceptionPort);    if (rc != KERN_SUCCESS) {        fprintf(stderr, "------->Fail to allocate exception port\n");        exit(-1);    }        rc = mach_port_insert_right(mach_task_self(), gExceptionPort, gExceptionPort, MACH_MSG_TYPE_MAKE_SEND);    if (rc != KERN_SUCCESS) {        fprintf(stderr, "-------->Fail to insert right");        exit(-2);    }        rc = thread_set_exception_ports(mach_thread_self(), excMask, gExceptionPort, EXCEPTION_DEFAULT, MACHINE_THREAD_STATE);    if (rc != KERN_SUCCESS) {        fprintf(stderr, "-------->Fail to  set exception\n");        exit(-3);    }        pthread_t thread;    pthread_create(&thread, NULL, ExceptionHandler, NULL);}


0 0