美文网首页
逆向防护

逆向防护

作者: 昵称是乱起的 | 来源:发表于2019-04-17 18:41 被阅读0次

1. 禁止附加进程Ptrace

ptrace是在iOS项目中不能直接使用,需要去命令行项目下拷贝出头文件,才能使用,#import <sys/ptrace.h>后进去拷贝

#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

//_request是要做的事情,_pid是进程id,_addr,_data取决于第一个参数  
int     ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);


__END_DECLS

#endif  /* !_SYS_PTRACE_H_ */
1.1 ptrace禁止附加进程

ptrace(PT_DENY_ATTACH, 0, 0, 0);

ptrace 防护的一个特点:
1、重签名(Xcode)运行之后闪退!
2、手动打开正常运行!

1.2 反ptrace

道理很简单,就是利用fishhook重绑定

#import "fishhook.h"
#import "MyPtraceHeader.h"

@implementation insertDylib

//定义指针,保存原来的函数地址
int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data);

//自己的的ptrace
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
    return 0;
}

+(void)load
{
    struct rebinding ptraceBd;
    ptraceBd.name = "ptrace";
    ptraceBd.replacement = my_ptrace;
    ptraceBd.replaced = (void *)&ptrace_p;
    struct rebinding binds[] = {ptraceBd};
    rebind_symbols(binds, 1);
}

2. 反调试sysctl

2.1 sysctl可以查询是否是debug状态,代码如下:
BOOL isDebug(){
    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);
}
2.2 反sysctl
#import "fishhook.h"
#import <sys/sysctl.h>

@implementation InjectCode

//原始函数指针
int  (*sysctl_p)(int *, u_int, void *, size_t *, void *, size_t);

//新函数地址
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
        && (int)*infosize == sizeof(struct kinfo_proc)) {
        
        int err = sysctl_p(name,namelen,info,infosize,newInfo,newInfoSize);
        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 err;
    }
    return sysctl_p(name,namelen,info,infosize,newInfo,newInfoSize);
}

+(void)load
{
    rebind_symbols((struct rebinding[1]){{"sysctl",my_sysctl,(void *)&sysctl_p}}, 1);
}

3. 反fishhook

通过dlopen查找ptrace真正的函数地址

#import "MyPtraceHeader.h"
#import <dlfcn.h>

- (void)viewDidLoad {
    [super viewDidLoad];
    //拼接一个 ptrace
    unsigned char funcStr[] = {
        ('a' ^ 'p'),
        ('a' ^ 't'),
        ('a' ^ 'r'),
        ('a' ^ 'a'),
        ('a' ^ 'c'),
        ('a' ^ 'e'),
        ('a' ^ '\0'),
    };
    unsigned char * p = funcStr;
    while (((*p) ^= 'a') != '\0') p++;
    
    //通过dlopen拿到句柄
    void * handle = dlopen("/usr/lib/system/libsystem_kernel.dylib", RTLD_LAZY);
    //定义函数指针
    int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data);
    
    if (handle) {
        ptrace_p = dlsym(handle, (const char *)funcStr);
        if (ptrace_p) {
            ptrace_p(PT_DENY_ATTACH, 0, 0, 0 );
        }
    }
    
}
上面还是可以通过```fishhook dlsym```来破解,

4. syscall

4.1 syscall直接调用系统函数
//第一个参数是函数的编号,函数编号可以在#import <sys/syscall.h>里找到
//第二个开始是函数的参数,有几个就写几个
syscall(SYS_ptrace, PT_DENY_ATTACH, 0, 0);
4.2 通过内联汇编调用函数

volatile是防止代码被编译器优化掉,先调用syscall,间接调用ptrace

asm volatile(
                     "mov x0,#26\n"
                     "mov x1,#31\n"
                     "mov x2,#0\n"
                     "mov x3,#0\n"
                     "mov x16,#0\n"//中断根据x16 里面的值,跳转syscall
                     "svc #0x80\n"//这条指令就是触发中断(系统级别的跳转!)
        );

也可以直接通过软汇编直接调用ptrace

asm volatile(
                     "mov x0,#31\n"
                     "mov x1,#0\n"
                     "mov x2,#0\n"
                     "mov x3,#0\n"
                     "mov x16,#26\n"//中断根据x16 里面的值,跳转ptrace
                     "svc #0x80\n"//这条指令就是触发中断(系统级别的跳转!)
                     );
}

5. 越狱检测

//越狱检测
    char * dlname = getenv("DYLD_INSERT_LIBRARIES");
    if (dlname) {
        NSLog(@"越狱手机,关闭部分功能");
    }else{
        NSLog(@"正常手机!");
    }

相关文章

  • 逆向防护

    1. 禁止附加进程Ptrace ptrace是在iOS项目中不能直接使用,需要去命令行项目下拷贝出头文件,才能使...

  • 逆向防护

    简单的查看项目是否被调试之 sysctl函数 1.资料准备,破解的ipa 包 2.创建与ipa 同名的空工程,ip...

  • Android逆向分析

    生死看淡,不服就干! Android应用安全防护和逆向分析

  • iOS 逆向防护(一)

    1、DYLD_INSERT_LIBRARIES 注意:该方法只支持iOS10以下系统并且只防护动态库插入的形式,在...

  • iOS 逆向防护(二)

    白名单检测 上一篇文章中我们解决了iOS10以下系统的防止动态库注入的方式,这篇文章我们通过白名单检测的方式来防止...

  • iOS逆向之文件系统结构

    上一篇文章地址:iOS逆向之介绍 上一篇文章中,介绍了iOS逆向做了些什么,需要怎样的防护,逆向的流程,提到的工具...

  • iOS逆向之旅(防护篇) — 防护Tweak插件

    Tweak的原理 要防护某种技术,首先你得知道这种技术是通过什么原理实现的 Tweak 在Make package...

  • iOS逆向工程 - 基本防护

    知道了 HOOK 的原理,接下来我们就可以做一些代码的基本防护了。我们今天基本防护要达到的目的是:自己的 Meth...

  • iOS应用之逆向防护

    iOS的逆向步骤一般为: 脱壳可执行文件 使用IDE或Hopper反编译分析代码逻辑 使用class-dump加l...

  • iOS 逆向 -- 动态调试防护

    ptrace debugserver通过ptrace函数调试app ptrace是系统函数,此函数提供一个进程去监...

网友评论

      本文标题:逆向防护

      本文链接:https://www.haomeiwen.com/subject/tdtiwqtx.html