iOS应用攻防-sysctl

2,079 阅读2分钟

上次讲到ptrace 的问题, 其实系统对于应用防护有几点

  • ptrace_ptr_t

  • dlsym_ptr_t

  • syscall_ptr_t

  • sysctl_ptr_t

今天这里介绍sysctl  先看看其方法定义:

int     sysctl(int *, u_int, void *, size_t *, void *, size_t);int     sysctlbyname(const char *, void *, size_t *, void *, size_t);int     sysctlnametomib(const char *, int *, size_t *);

要想知道应用是否处于调试状态 看他的第三个参数kinfo_proc里面的kp_proc.p_flag 的第12位。如果为1,表示调试状态。

现在直接上防护代码:

//检测调试

BOOL isDebugger(){    int name[4];//里面放字节码。查询的信息    name[0] = CTL_KERN;//内核查询    name[1] = KERN_PROC;//查询进程    name[2] = KERN_PROC_PID;//传递的参数是进程的ID    name[3] = getpid();//PID的值        struct kinfo_proc info;//接受查询结果的结构体    size_t info_size = sizeof(info);    if(sysctl(name, 4, &info, &info_size, 0, 0)){        NSLog(@"查询失败");        return NO;    }    //看info.kp_proc.p_flag 的第12位。如果为1,表示调试状态。    //(info.kp_proc.p_flag & P_TRACED)    return ((info.kp_proc.p_flag & P_TRACED) != 0);}static dispatch_source_t timer;void debugCheck(){    timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);    dispatch_source_set_event_handler(timer, ^{        if (isDebugger()) {            NSLog(@"调试状态!!");        }else{            NSLog(@"正常!");

        }    });    dispatch_resume(timer);}

防护代码直接来monkey 的

#if TARGET_OS_SIMULATOR
#error Do not support the simulator, please use the real iPhone Device.
#endif

#import "fishhook.h"
#import <Foundation/Foundation.h>
#import <sys/sysctl.h>

typedef int (*ptrace_ptr_t)(int _request,pid_t _pid, caddr_t _addr,int _data);
typedef void* (*dlsym_ptr_t)(void * __handle, const char* __symbol);
typedef int (*syscall_ptr_t)(int, ...);
typedef int (*sysctl_ptr_t)(int *,u_int, void*, size_t*,void*, size_t);


static ptrace_ptr_t orig_ptrace = NULL;
static dlsym_ptr_t orig_dlsym = NULL;
static sysctl_ptr_t orig_sysctl = NULL;
static syscall_ptr_t orig_syscall = NULL;

int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
void* my_dlsym(void* __handle, const char* __symbol);
int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize);
int my_syscall(int code, va_list args);

int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data){
    if(_request != 31){
        return orig_ptrace(_request,_pid,_addr,_data);
    }
    
    NSLog(@"[AntiAntiDebug] - ptrace request is PT_DENY_ATTACH");
    
    return 0;
}

void* my_dlsym(void* __handle, const char* __symbol){
    if(strcmp(__symbol, "ptrace") != 0){
        return orig_dlsym(__handle, __symbol);
    }
    
    NSLog(@"[AntiAntiDebug] - dlsym get ptrace symbol");
    
    return my_ptrace;
}

typedef struct kinfo_proc _kinfo_proc;

int my_sysctl(int * name, u_int namelen, void * info, size_t * infosize, void * newinfo, size_t newinfosize){
    if(namelen == 4 && name[0] == CTL_KERN && name[1] == KERN_PROC && name[2] == KERN_PROC_PID && info && infosize && ((int)*infosize == sizeof(_kinfo_proc))){
        int ret = orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize);
        struct kinfo_proc *info_ptr = (struct kinfo_proc *)info;
        if(info_ptr && (info_ptr->kp_proc.p_flag & P_TRACED) != 0){
            NSLog(@"[AntiAntiDebug] - sysctl query trace status.");
            info_ptr->kp_proc.p_flag ^= P_TRACED;
            if((info_ptr->kp_proc.p_flag & P_TRACED) == 0){
                NSLog(@"trace status reomve success!");
            }
        }
        return ret;
    }
    return orig_sysctl(name, namelen, info, infosize, newinfo, newinfosize);
}

int my_syscall(int code, va_list args){
    int request;
    va_list newArgs;
    va_copy(newArgs, args);
    if(code == 26){
#ifdef __LP64__
        __asm__(
                "ldr %w[result], [fp, #0x10]\n"
                : [result] "=r" (request)
                :
                :
                );
#else
        request = va_arg(args, int);
#endif
        if(request == 31){
            NSLog(@"[AntiAntiDebug] - syscall call ptrace, and request is PT_DENY_ATTACH");
            return 0;
        }
    }
    return orig_syscall(code, newArgs);
}

__attribute__((constructor)) static void entry(){
    NSLog(@"[AntiAntiDebug Init]");
    
    rebind_symbols((struct rebinding[1]){{"ptrace", my_ptrace, (void*)&orig_ptrace}},1);
    
    rebind_symbols((struct rebinding[1]){{"dlsym", my_dlsym, (void*)&orig_dlsym}},1);
    
    //some app will crash with _dyld_debugger_notification
    // rebind_symbols((struct rebinding[1]){{"sysctl", my_sysctl, (void*)&orig_sysctl}},1);
    
    rebind_symbols((struct rebinding[1]){{"syscall", my_syscall, (void*)&orig_syscall}},1);
}