反调试&反反调试 -- 利用sysctl检测调试器是否存在

防护

当一个进程被调试时,该进程会有一个标志位来标记他正在被标记。sysctl函数可用于查看当前进程的信息。

  • 使用该函数,需要导入系统库#import <sys/sysctl.h>

  • 函数介绍

    /*
    函数的返回值若为0时,证明没有错误,其他数字为错误码。
    arg1 传入一个数组,该数组中的第一个元素指定本请求定向到内核的哪个子系统。第二个及其后元素依次细化指定该系统的某个部分。
    arg2 数组中的元素数目
    arg3 一个结构体,指向一个供内核存放该值的缓冲区,存放进程查询结果
    arg4 缓冲区的大小
    arg5/arg6 为了设置某个新值,arg5参数指向一个大小为arg6参数值的缓冲区。如果不准备指定一个新值,那么arg5应为一个空指针,arg6因为0.
    */
    int sysctl(int *, u_int, void *, size_t *, void *, size_t);
    复制代码
  • 函数使用

    int name[4];//存放字节码,查询信息
    name[0] = CTL_KERN;//内核查看
    name[1] = KERN_PROC;//进程查看
    name[2] = KERN_PROC_PID//进程ID
    name[3] = getpid();//获取pid,据说这个可以直接传0???
    
    struct kinfo_proc info;//接受进程查询结果信息的结构体
    size_t info_size = sizeof(info);//结构体的大小
    
    int proc_err = sysctrl(name, sizeof(name)/sizeof(*name), info, info_size, 0, 0);
    assert(proc_err == 0);//出现异常,出发断言
    
    //info.kp_proc.p_flag中存放的是标志位(二进制),在proc.h文件中有p_flag的宏定义,通过&运算可知对应标志位的值是否为0。(若结果值为0则对应标志位为0)。其中P_TRACED为正在跟踪调试过程。
    ((info.kp_proc.p_flag & P_TRACED) != 0)的结果即为是否处于调试状态。
    复制代码

进攻

可以通过fishhook交换掉系统的sysctl函数,源码很少,网上分析很多。关于fishhook的更多东西,具体请百度,这里直接使用。

代码如下:

//函数指针,保存原方法。
int (*sysctl_p)(int *, u_int, void *, size_t *, void *, size_t);
//用来交换的新方法
int mySysctl(int *name, u_int namelen, void *info, size_t *infosize, void *newinfo, size_t newinfosize){
    int err = sysctl_p(name, namelen, info, infosize, newinfo, newinfosize);
    //判断是否是查询进程信息
    if (namelen == 4
        &&name[0] == CTL_KERN
        &&name[1] == KERN_PROC
        &&name[2] == KERN_PROC_PID
        &&info
        &&((int)*infosize == sizeof(struct kinfo_proc))) {
        //接受结果的结构体
        struct kinfo_proc* sys_info = (struct kinfo_proc *)info;
        //通过标志位确认是否为调试状态
        if ((sys_info->kp_proc.p_flag & P_TRACED) != 0) {
            //进行异或运算修改标志位
            sys_info->kp_proc.p_flag ^= P_TRACED;
        }
    }
    return err;
}
复制代码

然后在+(void)load;方法中交换系统的sysctl方法

rebind_symbols((struct rebinding[1]){{"sysctl",mySysctl,(void *)&sysctl_p}}, 1);
复制代码

防护

对于fishhook交换系统函数的进攻方式,我们可以通过将sysctl函数调用放到动态库中,以保证检测函数可以在进攻注入的代码之前执行。动态库的加载顺序为Build Phases下的Link Binary With Libaraies中的排列顺序。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值