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如今用的還挺多的,你要想辦法作到神不知鬼不覺~

  • 你們能夠用到工程試上一下~ 😆。

相關文章
相關標籤/搜索