iOS逆向安防从入门到秃头--基础防御 & 破解

小谷秃头合集xcode

  • 今天小谷分享几种 基础的 防御手段。— 固然,也说下如何破解

1. 白名单防御

  • 这个防御目前应该是用的最少的,缘由是这个误伤比较大

思前想后,仍是先要说下这种防御手段服务器

  • 原理: 白名单防御手段的原理主要是防止动态库的插入

也就是把全部可能用到的动态库收集起来。若是检测到多余的动态库,就能够作相应的防御技巧markdown

  • 第一步: 获取执行所须要的全部库
//获取image 个数
int count = _dyld_image_count();
//把本身的macho镜像去掉
for (int i = 1; i < count; i++) {
    //打印全部image name,用,隔开
    printf("%s,",_dyld_get_image_name(i));
}
复制代码
  • 第二步: 把输出的logcopy

1.png

若是之后真的用到了,绝对不能写在客户端。(其实就算写在服务器请求误伤仍是很大!)函数

  • 第三步: 判断应用加载进入的时候,是否有不包含的库(这里若是存在,就视为注入的库)
int count = _dyld_image_count();
    //把本身的macho镜像去掉
    for (int i = 1; i < count; i++) {
// printf("%s,",_dyld_get_image_name(i));
        if (!strstr(libStr, _dyld_get_image_name(i))) {
            //若是不包含,视为注入库!
            NSLog(@"注入库。采起防御措施~!");
        }
    }
复制代码
  • 总结下
      1. 白名单防御误伤太大
      1. 如今基本没有啥应用会这么作。维护成本过高
      1. 若是系统升级,或者每一个机型的系统库不同。就要一直改变兼容
      1. 就算写成服务器存储。也可能不是第一瞬间判断的

不推荐这种防御!,可是经过白名单防御,可能会有不少延伸的思想。兄弟们能够考虑下~post

2. Ptrace

很早以前支付宝就是用的这个~ui

2.1. Ptrace防御

  • 咱们逆向APP的时候,有时候不单单是静态分析,还可能会动态调试spa

  • 咱们的动态调试,不管是终端调试,仍是Xcode附加。都是经过debugserver监测进程作到的!debug

  • Ptrace就是经过限制进程阻止附加调试指针

  • 先来个Ptrace的例子调试

//点击事件来一波
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"ptrace 防调试!");
    ptrace(PT_DENY_ATTACH, 0, 0, 0);//这个就是Ptrace防御调试
    NSLog(@"难道没有防御住?");
}
复制代码
  • 咱们点击一下

2.png

发现以后就不走了!

Ptrace特色:调试闪退,可是点击APP正常运行

2.2. Ptrace破解

防御办法就有破解办法

  • 若是你肯定是Ptrace防御了。那么咱们能够hook这个符号试试~
//定义函数指针!
int  (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data);

+(void)load
{
    //交换
    struct rebinding ptraceBd;
    ptraceBd.name ="ptrace";
    ptraceBd.replacement = my_ptrace;
    ptraceBd.replaced = (void *)&ptrace_p;
    
    struct rebinding bds[] = {ptraceBd};
    rebind_symbols(bds, 1);
}
//自定义
int  my_ptrace (int _request, pid_t _pid, caddr_t _addr, int _data){
    if (_request != PT_DENY_ATTACH) {//若是不是拒绝附加,保持调用!
        return ptrace_p(_request,_pid,_addr,_data);
    }
    return 0;
}
复制代码

利用fishhook符号重绑定就搞定了~

3. sysctl

3.1. sysctl防御

这个目前仍是挺厉害的~ 抖音就是用的这个,不过他除了这个还作了别的防御(改天我玩一下,而后写一篇博客,😆)

  • 写一下他的防御代码
#import <sys/sysctl.h>
bool isDebugServer(){
    //控制码
    int name[4];//放字节码-查询信息
    name[0] = CTL_KERN;//内核查看
    name[1] = KERN_PROC;//查询进程
    name[2] = KERN_PROC_PID; //经过进程id查进程
    name[3] = getpid();//拿到本身进程的id
    //查询结果
    struct kinfo_proc info;//进程查询信息结果
    size_t info_size = sizeof(info);//结构体大小
    int error = sysctl(name, sizeof(name)/sizeof(*name), &info, &info_size, 0, 0);
    assert(error == 0);//0就是没有错误,设置个断言
    //结果解析 p_flag的第12位为1就是有调试
    //p_flag 与 P_TRACED =0 就是有调试
    return ((info.kp_proc.p_flag & P_TRACED) !=0);
}
- (void)viewDidLoad {
    [super viewDidLoad];
    if (isDebugServer()) {
        NSLog(@"在debugserver调试状态!");
        //自行处理
    }else{
        NSLog(@"在正常运行状态!");
    }
}
复制代码
  • 当我Xcode 运行

3.png

  • 当我断开xcode,本身运行时

4.png

说明检测到了

3.2. sysctl破解

也是用的fishhook符号重绑定

  • 这里我就写重绑定以后的实现
//自定义函数
int mySysctl(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
        && (int)*infosize == sizeof(struct kinfo_proc))
    {
        int err = sysctl_p(name, namelen, info, infosize, newinfo, newinfosize);
        //拿出info作判断
        struct kinfo_proc * myInfo = (struct kinfo_proc *)info;
        if((myInfo->kp_proc.p_flag & P_TRACED) != 0){
            //使用异或取反
            myInfo->kp_proc.p_flag ^= P_TRACED;
        }
        return 0;
    }
    return sysctl_p(name, namelen, info, infosize, newinfo, newinfosize);
}
复制代码

4. 总结

  • 白名单防御是一种思惟手段,这种防御误伤很大,慎用!!

  • Ptracesysctl如今用的还挺多的,你要想办法作到神不知鬼不觉~

  • 你们能够用到工程试上一下~ 😆。

相关文章
相关标签/搜索