iOS应用防护

1、背景

iOS应用发布市场之后,可以被动态调式。这样我们的应用代码完全暴露。

2、ptrace防护

创建mac应用,可以查找到以下ptrace源码。

#ifndef    _SYS_PTRACE_H_
#define    _SYS_PTRACE_H_

#include <sys/appleapiopts.h>
#include <sys/cdefs.h>

enum {
    ePtAttachDeprecated __deprecated_enum_msg("PT_ATTACH is deprecated. See PT_ATTACHEXC") = 10
};


#define    PT_TRACE_ME    0    /* 子进程正在被追踪 child declares it's being traced */
#define    PT_READ_I    1    /* read word in child's I space */
#define    PT_READ_D    2    /* read word in child's D space */
#define    PT_READ_U    3    /* read word in child's user structure */
#define    PT_WRITE_I    4    /* write word in child's I space */
#define    PT_WRITE_D    5    /* write word in child's D space */
#define    PT_WRITE_U    6    /* write word in child's user structure */
#define    PT_CONTINUE    7    /* continue the child */
#define    PT_KILL        8    /* kill the child process */
#define    PT_STEP        9    /* single step the child */
#define    PT_ATTACH    ePtAttachDeprecated    /* trace some running process */
#define    PT_DETACH    11    /* stop tracing a process */
#define    PT_SIGEXC    12    /* signals as exceptions for current_proc */
#define PT_THUPDATE    13    /* signal for thread# */
#define PT_ATTACHEXC    14    /* attach to running process with signal exception */

#define    PT_FORCEQUOTA    30    /* Enforce quota for root */
#define    PT_DENY_ATTACH    31

#define    PT_FIRSTMACH    32    /* for machine-specific requests */

__BEGIN_DECLS


int    ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);


__END_DECLS

#endif    /* !_SYS_PTRACE_H_ */

在iOS项目中应用

#import "ViewController.h"
#import "MyPtraceHeader.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor yellowColor];
    
    //  项目拒绝被附加
    ptrace(PT_DENY_ATTACH, 0, 0, 0);
}

@end

这样,项目Xcode调试状态就会直接退出。

3、破解ptrace

创建动态库,使用fishhook来hook系统函数,使得ptrace失效。


截屏2020-12-03 下午11.58.28.png
#import "HookCode.h"
#import "fishhook.h"
#import "MyPtraceHeader.h"

@implementation HookCode

// 定义指针,保存真实的ptrace
int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data);

// 定义一个函数,用来hook ptrace
int myPtrace(int _request, pid_t _pid, caddr_t _addr, int _data){
    
    // 如果不是拒绝附加,继续执行ptrace函数
    if (_request != PT_DENY_ATTACH) {
        return ptrace_p(_request,_pid,_addr,_data);
    }
    // 如果是拒绝附加,直接返回
    return 0;
}

+ (void)load{
    
    // 进行交换
    struct rebinding ptraceBind;
    // 函数的名称
    ptraceBind.name = "ptrace";
    // 新的函数地址
    ptraceBind.replacement = myPtrace;
    // 保存原始函数地址的变量的指针
    ptraceBind.replaced = (void *)&ptrace_p;
    // 定义数组
    struct rebinding rebs[] = {ptraceBind};
    /*
    arg1 : 存放rebinding结构体的数组
    arg2 : 数组的长度
    */
    // 真正交换
    rebind_symbols(rebs, 1);
}

@end

推荐阅读更多精彩内容