27-逆向防護(上)

前言

本篇文章繼續(xù)討論App的安全防護的原理塌碌,主要講解關于動態(tài)調試的防護。我們知道旬盯,App可以被lldb動態(tài)調試台妆,因為App被設備中的debugserver附加進程翎猛,它會跟蹤我們的應用進程(trace process),我們可以利用這點接剩,動態(tài)的修改App進程中的數(shù)據(jù)切厘,達到我們想要的結果,而這一過程利用的就是ptrace函數(shù)懊缺。

一疫稿、ptrace防護

接著上篇文章26-越獄防護的末尾,我們知道????

  1. ptrace(process trace)其實是系統(tǒng)內核函數(shù)鹃两,系統(tǒng)提供一個進程監(jiān)察和控制另一個進程遗座,并且還能讀取和修改被控制的進程的內存和寄存器里的數(shù)據(jù),因此它可以決定應用能否被debugserver附加俊扳。
  2. 如果我們在項目中途蒋,調用ptrace函數(shù),將程序設置為拒絕附加拣度,即可對lldb動態(tài)調試進行有效的防護碎绎。

1.1 防護代碼示例

  1. 搭建App項目antiDebug
  2. 導入MyPtraceHeader.h頭文件????
/*
 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. The rights granted to you under the License
 * may not be used to create, or enable the creation or redistribution of,
 * unlawful or unlicensed copies of an Apple operating system, or to
 * circumvent, violate, or enable the circumvention or violation of, any
 * terms of an Apple operating system software license agreement.
 *
 * Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 */
/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
/*-
 * Copyright (c) 1984, 1993
 *    The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    This product includes software developed by the University of
 *    California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *    @(#)ptrace.h    8.2 (Berkeley) 1/4/94
 */

#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_ */

  1. 打開ViewController.m文件,寫入以下代碼????
#import "ViewController.h"
#import "MyPtraceHeader.h"

@implementation ViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   ptrace(PT_DENY_ATTACH, 0, 0, 0);
}

@end
  1. Xcode運行項目抗果,啟動后立即退出筋帖。使用ptrace設置為拒絕附加,只能手動啟動App冤馏。
    也就是說日麸,用戶在使用App時一切正常,不會有任何影響逮光。一旦被debugserver附加代箭,就會閃退
越獄情況

以上是非越獄手機涕刚,如果在越獄機上進行debugserver附加呢嗡综?

  1. 找到antiDebug進程????
ps -A | grep antiDebug
  1. 手動對App進行debugserver附加
debugserver localhost:12346 -a 15289
-------------------------
debugserver-@(#)PROGRAM:LLDB  PROJECT:lldb-900.3.87
for arm64.
Attaching to process 15289...
Segmentation fault: 11

附加失敗,無論以何種方式杜漠,都會被ptrace函數(shù)阻止极景。

1.2 破解ptrace 防護

ptrace是系統(tǒng)內核函數(shù),被開發(fā)者所熟知驾茴。ptrace的防護痕跡也很明顯 ???? 手動運行程序正常盼樟,Xcode運行程序閃退

因此锈至,我們在逆向一款App時晨缴,遇到上述情況,第一時間就會想到ptrace防護峡捡。那么怎么破解這個呢击碗?

  1. 從MachO符號角度思考筑悴,由于ptrace是系統(tǒng)函數(shù),需要間接符號表延都,我們可以試探性的下一個ptrace的符號斷點????
  1. 運行雷猪,ptrace的斷點命中????

上圖驗證了我們的想法,現(xiàn)在確定了對方的防護手段晰房,想要破解并非難事。

  1. 針對antiDebug項目射沟,模擬應用重簽名殊者,注入動態(tài)庫
  • 創(chuàng)建Inject動態(tài)庫,創(chuàng)建InjectCode類
  • Inject動態(tài)庫中验夯,導入fishhook猖吴,導入MyPtraceHeader.h頭文件
  • 打開InjectCode.m文件,寫入以下代碼????
#import "InjectCode.h"
#import "MyPtraceHeader.h"
#import "fishhook.h"

@implementation InjectCode

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

int (*sys_ptrace)(int _request, pid_t _pid, caddr_t _addr, int _data);

int my_ptrace(int _request, pid_t _pid, caddr_t _addr, int _data){
   
   if(_request==PT_DENY_ATTACH){
       return 0;
   }
   
   return sys_ptrace(_request, _pid, _addr, _data);
}

@end

ptrace_my函數(shù)中挥转,如果是PT_DENY_ATTACH枚舉值海蔽,直接return返回。如果是其他類型绑谣,系統(tǒng)有特定的作用党窜,需要執(zhí)行ptrace原始函數(shù)

  1. 運行項目借宵,進入lldb動態(tài)調試幌衣,ptrace破解成功!??????????

二壤玫、sysctl

由于系統(tǒng)并沒有公開ptrace函數(shù)豁护,使用的時候需額外手動引入頭文件,該頭文件還不是系統(tǒng)公開的欲间,這點就比較麻煩楚里,那有沒有別的函數(shù)可以直接使用進行防護呢?當然有猎贴,接下來班缎,介紹另一個系統(tǒng)內核函數(shù)sysctl

2.1 sysctl定義

首先來看看該函數(shù)的定義 ????

??注意:使用前需引入系統(tǒng)的頭文件 ???? #import <sys/sysctl.h>

int  sysctl(int *, u_int, void *, size_t *, void *, size_t);

明顯可見有6個參數(shù)嘱能,分別如下????

  1. 查詢信息的數(shù)組吝梅,給它的指針
  2. 數(shù)組中元素的數(shù)據(jù)類型的大小
  3. 接收信息結構體的指針
  4. 接收信息結構體的大小的指針
  5. 第5個和第6個參數(shù) ???? 直接寫0就行

接下來我們來解釋下這幾個參數(shù)具體的含義。

第一個參數(shù)int *

因為是int *類型惹骂,所以該數(shù)組的元素是int類型苏携,代表字節(jié)碼的意思,存儲的就是調用方需要查詢的信息对粪。例如可以這么寫????

int name[4];//里面放字節(jié)碼右冻。查詢的信息
name[0] = CTL_KERN;//內核查詢
name[1] = KERN_PROC;//查詢進程
name[2] = KERN_PROC_PID;//傳遞的參數(shù)是進程的ID
name[3] = getpid();//PID的值
第二個參數(shù)u_int

u_int是無符號整型装蓬,可以這么計算 ???? sizeof(name)/sizeof(*name)

第三個參數(shù)void *

代表一個接收信息的結構體指針,一般使用kinfo_proc結構體????

struct kinfo_proc {
    struct  extern_proc kp_proc;                    /* proc structure */
    struct  eproc {
        struct  proc *e_paddr;          /* address of proc */
        struct  session *e_sess;        /* session pointer */
        struct  _pcred e_pcred;         /* process credentials */
        struct  _ucred e_ucred;         /* current credentials */
        struct   vmspace e_vm;          /* address space */
        pid_t   e_ppid;                 /* parent process id */
        pid_t   e_pgid;                 /* process group id */
        short   e_jobc;                 /* job control counter */
        dev_t   e_tdev;                 /* controlling tty dev */
        pid_t   e_tpgid;                /* tty process group id */
        struct  session *e_tsess;       /* tty session pointer */
#define WMESGLEN        7
        char    e_wmesg[WMESGLEN + 1];    /* wchan message */
        segsz_t e_xsize;                /* text size */
        short   e_xrssize;              /* text rss */
        short   e_xccount;              /* text references */
        short   e_xswrss;
        int32_t e_flag;
#define EPROC_CTTY      0x01    /* controlling tty vnode active */
#define EPROC_SLEADER   0x02    /* session leader */
#define COMAPT_MAXLOGNAME       12
        char    e_login[COMAPT_MAXLOGNAME];     /* short setlogin() name */
        int32_t e_spare[4];
    } kp_eproc;
};

其中纱扭,我們需要重點關注一個flag參數(shù)牍帚,在extern_proc結構體中????

有哪些定義呢?往下翻到155行????

上圖紅框處的P_TRACED乳蛾,看注釋就知道暗赶,是debug調試跟蹤進程信息的,這個就是我們想要的肃叶。而且它的值是0x800蹂随,其它的類似0x100,0x200因惭,0x400岳锁,一看就知道是按照byte(位)定義的枚舉類型,可以多種狀態(tài)疊加蹦魔。

使用的時候采用&與操作符激率。例如????

struct kinfo_proc info;//接受查詢結果的結構體
(info.kp_proc.p_flag & P_TRACED) != 0 //判斷結果中是否包含了P_TRACED狀態(tài),即當前App是否正在被第三方動態(tài)調試
第四個參數(shù)size_t *
size_t info_size = sizeof(info);

??注意:是size_t *勿决,所以使用的時候是&info_size乒躺。

完整的使用示例
BOOL isDebugger(){
    int name[4];//里面放字節(jié)碼。查詢的信息
    name[0] = CTL_KERN;//內核查詢
    name[1] = KERN_PROC;//查詢進程
    name[2] = KERN_PROC_PID;//傳遞的參數(shù)是進程的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聪蘸,表示調試狀態(tài)。
   //(info.kp_proc.p_flag & P_TRACED)
    
    return ((info.kp_proc.p_flag & P_TRACED) != 0);
}

調用處????

- (void)viewDidLoad {
    [super viewDidLoad];
    
    if (isDebugger()) {
        NSLog(@"檢測到有調試表制!");
    } else {
        NSLog(@"沒有調試健爬!");
    }
}
進階版

上面在viewDidLoad中,只能執(zhí)行一次么介,我們更希望定時檢查娜遵,所以可以這么改,采用dispatch_source_t的定時器方式????

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(@"調試狀態(tài)H蓝獭设拟!");
        }else{
            NSLog(@"正常!");
        }
    });
    dispatch_resume(timer);
}

然后調用處????

- (void)viewDidLoad {
    [super viewDidLoad];
   
    debugCheck();
}

運行????

當然久脯,也不用一直開啟定時器檢查纳胧,在App啟動的時候檢查一段時間即可!

與ptrace的不同
  • ptrace的特點:
    1. 重簽名(Xcode)運行之后閃退帘撰!
    2. 手動打開正常運行跑慕!
  • sysctl ???? 可擴展性更強,檢測到調試后,可以做自己想做的事核行。

2.2 破解sysctl

因為sysctl是系統(tǒng)的內核函數(shù)牢硅,所以我們很自然就想到 ???? fishHook,因此這么做????

  1. 創(chuàng)建一個動態(tài)庫inject.framework芝雪,再創(chuàng)建一個類InjectCode减余,專門用來hooksysctl????
  1. 實現(xiàn)hooksysctl????
#import "InjectCode.h"
#import "fishhook.h"
#import <sys/sysctl.h>


@implementation InjectCode

//原始函數(shù)指針
int  (*sysctl_p)(int *, u_int, void *, size_t *, void *, size_t);

//新函數(shù)地址
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);
}

@end

run????

三、破解

現(xiàn)在我們知道惩系,使用ptracesysctl2種方式都能檢測到當前App是否被調試位岔,那有沒有方法能破解這些檢測呢?當然可以蛆挫。

3.1 動態(tài)注入破解

首先赃承,我們要清楚,之所以能檢測到被調試悴侵,是因為我們在動態(tài)庫中使用fishHook,替換了sysctl的方式實現(xiàn)拭嫁,核心在于時機 ???? 動態(tài)庫的load方法肯定比主工程的執(zhí)行可免! 只要我們的破解比這個更早,是不是就能實現(xiàn)了做粤?接下來我們用代碼來驗證????

  1. 同樣的浇借,新建一個工程antiDebug,在工程中新建動態(tài)庫antiDebug.framework
  2. 引入ptracesysctl
    • 引入頭文件MyPtraceHeader.h
    • 新建類antiDebugCode
#import "antiDebugCode.h"
#import <sys/sysctl.h>
#import "MyPtraceHeader.h"
#import <mach-o/dyld.h>
#import <mach-o/loader.h>

@implementation antiDebugCode
//檢測是否存在調試
BOOL isDebugger(){
    int name[4];//里面放字節(jié)碼怕品。查詢的信息
    name[0] = CTL_KERN;//內核查詢
    name[1] = KERN_PROC;//查詢進程
    name[2] = KERN_PROC_PID;//傳遞的參數(shù)是進程的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,表示調試狀態(tài)肉康。
    //(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, ^{
        printf("檢查INSERT:%s\n",getenv("DYLD_INSERT_LIBREARIES"));
        if (isDebugger()) {
//            NSLog(@"調試狀態(tài)4彻馈!");
        }else{
//            NSLog(@"正常吼和!");
        }
    });
    dispatch_resume(timer);
}



+(void)load
{
    debugCheck();
    //不允許調試附加!
//    ptrace(PT_DENY_ATTACH, 0, 0, 0);
    
    //檢查Cycript
    int count = _dyld_image_count();
    for (int i = 0; i < count; i++) {
        printf("%s\n",_dyld_get_image_name(i));
    }
    
}
  1. 新建一個MonkeyApp工程MonkeyDemo涨薪,使用上面的antiDebug工程生成的app包進行重簽名,例如????
  1. 打開MonkeyApp中sysctl的檢測功能????
  1. run ????

上圖可見炫乓,sysctl的檢測功能已被破解刚夺!????????????

?? 綜上所述,所有的防護手段的關鍵點在于 ???? 提前執(zhí)行末捣!

3.2 靜態(tài)破解

接著上面的例子繼續(xù)侠姑,既然App中已經提前預防了ptracesysctl,那么我們所有的想以注入的方式去修改代碼的這條路肯定就走不通了箩做,不論是動態(tài)庫注入還是靜態(tài)庫注入莽红,因為你的時機點不可能比App中的還早,是吧卒茬!

那有沒有別的方式去破防呢船老?當然也有 ???? 靜態(tài)破解咖熟!我們嘗試直接修改它的Mach-O文件(即修改二進制)。

3.2.1 ptrace靜態(tài)破解

接下來我們示例演示一下柳畔,如何靜態(tài)調試App中使用的ptrace檢測馍管。

  1. 首先,我們把上述工程antiDebug中的ptrace檢測的注釋放開????
  1. 重新編譯生成新的app包001--antiDebug薪韩,當做我們要破解的App????
  1. 新建Monkey工程确沸,取名test,重簽名app包001--antiDebug ????

此時俘陷,直接run罗捎,肯定無法動態(tài)調試,會直接崩潰(每次finish running 就會自動斷開調試)????

  1. 此時我們猜測拉盾,是否是ptrace防護了桨菜?于是添加符號斷點????

再次run,果然斷住了????

根據(jù)調用棧信息捉偏,是在[antiDebugCode load] 之中調用的倒得,因為我們本地電腦有antiDebug的工程源碼,并且源碼工程并沒有去符號,所以能查看到。真實的情況下备燃,是沒有源碼的,我們可以通過lldb指令來查看 ???? bt查看調用棧????

一樣能找到[antiDebugCode load], 是在動態(tài)庫antiDebug中菩彬,還有動態(tài)庫的地址0x000000010431fd20,這個是虛擬地址潮梯,包含了偏移量的地址骗灶,那如何得到偏移前的地址呢????? image list指令得到首地址來計算酷麦!????

得到了首地址0x0000000104318000矿卑,然后相減得到偏移量0x7D20

  1. 使用hopper打開antiDebug.framework的Mach-O二進制文件沃饶,搜索偏移量0x7D20????

?? 注意:將antiDebug拷貝出來母廷,方便查看。

找到了糊肤!

  1. 接著修改該匯編指令 ???? option + A????

修改成nop空指令的意思琴昆。

  1. 導出生成新的二進制???? (需要將Hopper升級為正版)

替換原有的antiDebug.framework的Mach-O二進制文件,再次runtest工程馆揉,就不會斷開調試了业舍!

以上就是通過修改Mach-O文件的方式,靜態(tài)暴力破解ptrace

3.2.2 sysctl靜態(tài)破解

接下來就輪到sysctl了舷暮,還是一樣态罪,先打符號斷點,看看????

bt查看調用棧信息????

上圖可見下面,在gcd的block之中复颈,,看不到任何的調用的觸發(fā)點等信息沥割,無法繼續(xù)往下深究了耗啦。

換一種思路,從原始App包入手机杜,Hopper看看Mach-O文件中帜讲,搜索sysctl????

直接搜索,在真實的工程中這是一個很耗時的過程椒拗,因為我們是demo似将,所以很快就能知道。

主工程找不到就找動態(tài)庫????

上圖就找到了蚀苛,我們繼續(xù)往下翻玩郊,找到debugCheck函數(shù)????

繼續(xù)往下翻,找到___debugCheck_block_invoke枉阵,就是調用sysctl的地方????

?? 注意:但是此時還是在GCD的block之中,我們還是無法確定App之中是哪個方法調用的sysctl预茄。

3.3 破解防護與block

上述sysctl破解過程中兴溜,我們也發(fā)現(xiàn)了個好處????

防護代碼寫到GCD的block中執(zhí)行,即使第三方破解能拿到地址耻陕,也只是block_invoke調用處的地址拙徽,并不是真正的調用的地址,仍然無法繼續(xù)斷點跟進诗宣,難以破防膘怕,除非你對GCD的源碼流程了如指掌。

總結

  • ptrace
    • 可阻止Appdebugserver附加
    • 在iOS系統(tǒng)中召庞,無法直接使用岛心,需要導入頭文件
    • ptrace函數(shù)的定義
      ? int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
    • 破解ptrace
      ? 使用ptrace符號斷點試探
      ? 使用fishhookptrace函數(shù)HOOK
      ? 是PT_DENY_ATTACH枚舉值,直接返回篮灼。其他類型忘古,執(zhí)行原始函數(shù)
  • sysctl
    • 使用前需引入系統(tǒng)的頭文件 ???? #import <sys/sysctl.h>
    • sysctl函數(shù) ???? int sysctl(int *, u_int, void *, size_t *, void *, size_t);
      ? 查詢信息的數(shù)組,給它的指針
      ? 數(shù)組中元素的數(shù)據(jù)類型的大小
      ? 接收信息結構體的指針 ???? kinfo_proc結構體指針诅诱,其中重點關注p_flag參數(shù)髓堪,在extern_proc結構體中
      ? 接收信息結構體的大小的指針
      ? 第5個和第6個參數(shù) ???? 直接寫0就行
    • 與ptrace的不同
      ? ptrace特點 ???? 重簽名(Xcode)運行之后閃退手動打開正常運行!
      ? sysctl???? 可擴展性更強干旁,檢測到調試后驶沼,可以做自己想做的事。
    • 破解sysctl
      ? 同樣在framework中使用fishhook進行方法交換
      ? 判斷查詢信息的數(shù)組中各個元素的條件是否是追蹤當前進程
      ? kinfo_proc結構體的判斷 ???? (p_flag & P_TRACED) != 0p_flag ^= P_TRACED異或取反
  • 破解
    • 動態(tài)注入破解 ???? 在framework中新建類争群,在load方法中進行ptracesysctl的防護
    • 靜態(tài)破解
      • ptrace靜態(tài)破解
        ? 符號斷點得到ptrace偏移后的地址回怜,image list得到庫的首地址,計算偏移地址offsetAddress
        ? 使用hopper打開Mach-O二進制文件祭阀,搜索offsetAddress鹉戚,并將其對應的匯編指令修改為nop空指令,導出新的Mach-O专控,替換原有的
      • sysctl靜態(tài)破解 ???? 如果在GCD的Block中執(zhí)行抹凳,則很難破解,因為block_invoke的地址即使知道伦腐,但不清楚GCD底層的調用邏輯
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末赢底,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子柏蘑,更是在濱河造成了極大的恐慌幸冻,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咳焚,死亡現(xiàn)場離奇詭異洽损,居然都是意外死亡,警方通過查閱死者的電腦和手機革半,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門碑定,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人又官,你說我怎么就攤上這事延刘。” “怎么了六敬?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵碘赖,是天一觀的道長。 經常有香客問我外构,道長普泡,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任典勇,我火速辦了婚禮劫哼,結果婚禮上,老公的妹妹穿的比我還像新娘割笙。我一直安慰自己权烧,他們只是感情好眯亦,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著般码,像睡著了一般妻率。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上板祝,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天宫静,我揣著相機與錄音,去河邊找鬼券时。 笑死孤里,一個胖子當著我的面吹牛,可吹牛的內容都是我干的橘洞。 我是一名探鬼主播捌袜,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼炸枣!你這毒婦竟也來了虏等?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤适肠,失蹤者是張志新(化名)和其女友劉穎霍衫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侯养,經...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡敦跌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逛揩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峰髓。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖息尺,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情疾掰,我是刑警寧澤搂誉,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站静檬,受9級特大地震影響炭懊,放射性物質發(fā)生泄漏。R本人自食惡果不足惜拂檩,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一侮腹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧稻励,春花似錦父阻、人聲如沸愈涩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽履婉。三九已至,卻和暖如春斟览,著一層夾襖步出監(jiān)牢的瞬間毁腿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工苛茂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留已烤,地道東北人。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓妓羊,卻偏偏與公主長得像胯究,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子侍瑟,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內容