iOS逆向1024-防護(hù)進(jìn)階

001--反調(diào)試sysctl(代碼防護(hù))

// sysctl:檢測app進(jìn)程是否被附加 (防護(hù)進(jìn)程被調(diào)試) 《程序員的自我修養(yǎng)》

#import "ViewController.h"
#import <sys/sysctl.h>

@interface ViewController ()
@end

static dispatch_source_t timer;

@implementation ViewController

// 1秒鐘檢測一次
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(@"檢測到了!!");
        }else{
            NSLog(@"正常!!");
        }
    });
    dispatch_resume(timer);
}


// 真機(jī)運行 沒有DebuggerServer遏片,所以不會檢測到調(diào)試
// sysctl(int * 控制碼, u_int 字節(jié), void * 查詢結(jié)果, size_t * 結(jié)構(gòu)體, void * 結(jié)構(gòu)體的大小, size_t)
// #define    P_TRACED    0x00000800    /* Debugged process being traced: 跟蹤調(diào)試過程 */

//檢測是否被調(diào)試
BOOL isDebugger(){
    //控制碼
    int name[4];//里面放字節(jié)碼.查詢信息
    name[0] = CTL_KERN;     //內(nèi)核查看
    name[1] = KERN_PROC;    //查詢進(jìn)程
    name[2] = KERN_PROC_PID;//傳遞的參數(shù)是進(jìn)程的ID(PID)   //同:$ ps -A
    name[3] = getpid();     //PID的值告訴(進(jìn)程id)
    
    struct kinfo_proc info; //接受進(jìn)程查詢結(jié)果信息的結(jié)構(gòu)體
    size_t info_size = sizeof(info);//結(jié)構(gòu)體的大小
    //int error = sysctl(name, 4, &info, &info_size, 0, 0);
    int error = sysctl(name, sizeof(name)/sizeof(*name), &info, &info_size, 0, 0);
    assert(error == 0);//0就是沒有錯誤,其他就是錯誤碼
    //1011 1000 1010 1010 1101 0101 1101 0101
    //&
    //0000 0000 0000 1000 0000 0000 0000 0000
    // == 0 ? 沒有、有!!
    return ((info.kp_proc.p_flag & P_TRACED) != 0);  // P_TRACED: 跟蹤調(diào)試過程
}

- (void)viewDidLoad {
    [super viewDidLoad];

    debugCheck();
    
}
@end


002--破解sysctl(攻擊)

創(chuàng)建動態(tài)庫:injectSysctl

image.png

導(dǎo)入fishhook

image.png
#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 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 err;
    }
    return sysctl_p(name, namelen, info, infosize, newinfo, newinfosize);
}

+(void)load
{
    //交換
    rebind_symbols((struct rebinding[1]){{"sysctl",mySysctl,(void *)&sysctl_p}}, 1);
}
@end


003--ptrace&sysctl提前執(zhí)行 (再防護(hù))

創(chuàng)建動態(tài)庫:antiDebug

image.png
image.png

注意:antiDebugCode 防護(hù)在前

#import "antiDebugCode.h"
#import "fishhook.h"
#import "MyPtraceHeader.h"
#import <sys/sysctl.h>

static dispatch_source_t timer;
@implementation antiDebugCode

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(@"檢測到了!!");
        }else{
            NSLog(@"正常!!");
        }
    });
    dispatch_resume(timer);
}


//檢測是否被調(diào)試
BOOL isDebugger(){
    //控制碼
    int name[4];//里面放字節(jié)碼.查詢信息
    name[0] = CTL_KERN;//內(nèi)核查看
    name[1] = KERN_PROC;//查詢進(jìn)程
    name[2] = KERN_PROC_PID;//傳遞的參數(shù)是進(jìn)程的ID(PID)
    name[3] = getpid();//PID的值告訴
    
    struct kinfo_proc info;//接受進(jìn)程查詢結(jié)果信息的結(jié)構(gòu)體
    size_t info_size = sizeof(info);//結(jié)構(gòu)體的大小
    int error = sysctl(name, sizeof(name)/sizeof(*name), &info, &info_size, 0, 0);
    assert(error == 0);//0就是沒有錯誤,其他就是錯誤碼
    
    //1011 1000 1010 1010 1101 0101 1101 0101
    //&
    //0000 0000 0000 1000 0000 0000 0000 0000
    // == 0 ? 沒有  有!!
    return ((info.kp_proc.p_flag & P_TRACED) != 0);
}

void debugerCheck(){
    if (isDebugger()) {
        NSLog(@"進(jìn)程被調(diào)試!!");
    }
    //開啟反調(diào)試
    ptrace(PT_DENY_ATTACH, getpid(), 0, 0);
}

+(void)load
{
    debugerCheck();
}
@end


004--攻防博弈匀借!找到你就贏

loadCommand: 改變原始代碼
ptrace (process trace 進(jìn)程跟蹤)
ptrace 系統(tǒng)函數(shù),是有符號的
查看 ptrace

image.png

下個符號斷點

image.png
image.png
image.png

運行程序蛮粮,立刻進(jìn)入斷點:目的 就是為了看函數(shù)調(diào)用棧

(lldb)bt        // 顯示當(dāng)前線程的調(diào)用堆棧(bt:back stack)
(lldb)image list      // 查看庫
image.png

看不到函數(shù)調(diào)用棧出吹,解決方案:用 Debug 模式

image.png

重新編譯運行

image.png
image.png

Hopper Disassembler 分析MacO文件,找到上面??對應(yīng)的地址

image.png
image.png

快捷鍵:alt + A
同上

image.png

修改MacO文件:跳出 ptrace 方法的執(zhí)行

image.png
image.png

導(dǎo)出 新的MacO文件

image.png

新的MacO 文件 導(dǎo)入MonkeyApp 創(chuàng)建的工程里掂名,運行据沈,可以調(diào)試了!


005--破解懸疑已久的反HOOK

這里涉及到以前的章節(jié):1011- HOOK-代碼的防護(hù)

終端命令:
壓縮成ipa包
zip -ry ZMHook--基本防護(hù).ipa Payload
zip -ry antiHook基本防護(hù).ipa Payload
zip -ry antiHook基本防護(hù)2.ipa Payload
zip -ry antiHook基本防護(hù)exit.ipa Payload

1饺蔑、先加載ZMHook 庫 再加載 ZMHookManager锌介,也就是hook代碼在先,防護(hù)在后膀钠,所以防護(hù)失效
2掏湾、先加載ZMHookManager 庫 再加載 ZMHook,現(xiàn)在防護(hù)肿嘲,再hook 就交互交換不到方法了融击,已經(jīng)被防護(hù)住了
3、對于檢測到對方的hook雳窟,采取的方法式 退出程序 exit W鹄恕匣屡!

#import "ZMHookManager.h"
#import "fishhook.h"
#import <objc/message.h>

@implementation ZMHookManager

//專門HOOK
+(void)load
{
    NSLog(@"ZMHookManager--Load");
    //內(nèi)部用到的交換代碼!
    Method old = class_getInstanceMethod(objc_getClass("ViewController"), @selector(btnClick1:));
    Method new = class_getInstanceMethod(self, @selector(click1Hook:));
    method_exchangeImplementations(old, new);
    
    //基本防護(hù)
    struct rebinding bd;
    bd.name = "method_exchangeImplementations";
    bd.replacement = myExchang;
    bd.replaced = (void *)&exchangeP;
    
//    struct rebinding rebindings[] = {bd};
//    rebind_symbols(rebindings, 1);
    
    
//     method_getImplementation
//     method_setImplementation
    
    struct rebinding bd1;
    bd1.name = "method_getImplementation";
    bd1.replacement = myExchang;
    bd1.replaced = (void *)&getIMP;
    
    struct rebinding bd2;
    bd2.name = "method_setImplementation";
    bd2.replacement = myExchang;
    bd2.replaced = (void *)&setIMP;
    
    struct rebinding rebindings[] = {bd,bd1,bd2};
    rebind_symbols(rebindings, 3);
}

//保留原來的交換函數(shù)
IMP _Nonnull (*setIMP)(Method _Nonnull m, IMP _Nonnull imp);
IMP _Nonnull (*getIMP)(Method _Nonnull m);
void (*exchangeP)(Method _Nonnull m1, Method _Nonnull m2);

//新的函數(shù)
void myExchang(Method _Nonnull m1, Method _Nonnull m2){
    NSLog(@"檢測到了HOOK!!!");
    //強(qiáng)制退出!
    exit(1);
}

-(void)click1Hook:(id)sendr{
    NSLog(@"原來APP的HOOK保留!!");
}
@end

5.1 定位反hook的 退出進(jìn)程的 地方

image.png
image.png

5.2 hopper 查看 MacO 文件

image.png

5.3 hopper 修改內(nèi)存地址,讓防護(hù)的代碼拇涤,找不到要交換的方法捣作,就可以去hook了

image.png
%hook ViewController
- (void)btnClick1:(id)sender {
    NSLog(@"HOOK到了!!");
}
%end



總結(jié):

001--反調(diào)試 sysctl.wmv (防護(hù))

#import <sys/sysctl.h>
// sysctl:檢測app進(jìn)程是否被附加 放在最前面執(zhí)行

002--破解 sysctl.wmv (攻)

創(chuàng)建動態(tài)庫:injectSysctl
導(dǎo)入fishhook
#import "injectCode.h"
#import "fishhook.h"
#import <sys/sysctl.h>
// fishhook 交換 sysctl 方法

003--ptrace&sysctl提前執(zhí)行.wmv (防護(hù))

創(chuàng)建動態(tài)庫:antiDebug
注意:antiDebugCode 防護(hù)在前(MonkeyApp 也進(jìn)攻不了)

  • 反調(diào)試 (上節(jié)課有講解)
    ptrace (process trace 進(jìn)程跟蹤)
    此函數(shù)提供了一個進(jìn)程監(jiān)聽控制另外一個進(jìn)程.并且可以檢測被控制進(jìn)程的內(nèi)存和寄存器里面的數(shù)據(jù)!
    它可以用來實現(xiàn)斷點調(diào)試和系統(tǒng)調(diào)用跟蹤.debugserver就是用的它
    iOS 中沒有提供相關(guān)的頭.
    書籍:<程序員的自我修養(yǎng)>
    */

原理:防護(hù)的代碼執(zhí)行的太早!
導(dǎo)致:我Hook的代碼執(zhí)行在其后鹅士!

004--攻防博弈券躁!找到你就贏.wmv

MacO loadCommand 段:改變原始代碼
ptrace (process trace 進(jìn)程跟蹤)
ptrace 系統(tǒng)函數(shù),是有符號的
下個ptrace符號斷點

運行程序掉盅,立刻進(jìn)入斷點:目的 就是為了看函數(shù)調(diào)用棧
(lldb)bt // 顯示當(dāng)前線程的調(diào)用堆棧(bt:back stack)
(lldb)image list // 查看庫

修改MacO文件:跳出 ptrace 方法的執(zhí)行
導(dǎo)出 新的MacO文件
新的MacO 文件 導(dǎo)入MonkeyApp 創(chuàng)建的工程里也拜,運行,可以調(diào)試了

005--破解懸疑已久的反HOOK.wmv

這里涉及到以前的章節(jié):1011- HOOK-代碼的防護(hù)
1趾痘、先加載ZMHook 庫 再加載 ZMHookManager慢哈,也就是hook代碼在先,防護(hù)在后永票,所以防護(hù)失效
2卵贱、先加載ZMHookManager 庫 再加載 ZMHook,現(xiàn)在防護(hù)侣集,再hook 就交互交換不到方法了键俱,已經(jīng)被防護(hù)住了
3、對于檢測到對方的hook肚吏,采取的方法式 退出程序 exit 7窖!

反hook方案:
5.1 定位反hook的 退出進(jìn)程的 地方
5.2 hopper 查看 MacO 文件
5.3 hopper 修改內(nèi)存地址罚攀,讓防護(hù)的代碼党觅,找不到要交換的方法,就可以去hook了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末斋泄,一起剝皮案震驚了整個濱河市杯瞻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炫掐,老刑警劉巖魁莉,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異募胃,居然都是意外死亡旗唁,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門痹束,熙熙樓的掌柜王于貴愁眉苦臉地迎上來检疫,“玉大人,你說我怎么就攤上這事祷嘶∈合保” “怎么了夺溢?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長烛谊。 經(jīng)常有香客問我风响,道長,這世上最難降的妖魔是什么丹禀? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任状勤,我火速辦了婚禮,結(jié)果婚禮上湃崩,老公的妹妹穿的比我還像新娘荧降。我一直安慰自己,他們只是感情好攒读,可當(dāng)我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著辛友,像睡著了一般薄扁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上废累,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天邓梅,我揣著相機(jī)與錄音,去河邊找鬼邑滨。 笑死日缨,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掖看。 我是一名探鬼主播匣距,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼哎壳!你這毒婦竟也來了毅待?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤归榕,失蹤者是張志新(化名)和其女友劉穎尸红,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刹泄,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡外里,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了特石。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盅蝗。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖县匠,靈堂內(nèi)的尸體忽然破棺而出风科,到底是詐尸還是另有隱情撒轮,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布贼穆,位于F島的核電站题山,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏故痊。R本人自食惡果不足惜顶瞳,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望愕秫。 院中可真熱鬧慨菱,春花似錦、人聲如沸戴甩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽甜孤。三九已至协饲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缴川,已是汗流浹背茉稠。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留把夸,地道東北人而线。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像恋日,于是被迫代替她去往敵國和親膀篮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,914評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,133評論 25 707
  • 上周,因為某天凌晨四點闷营,我媽打來電話烤黍,把我驚醒,結(jié)果只是不小心按到傻盟,但是回完電話我已無法入睡速蕊。于是中午的...
    冰梔櫻閱讀 195評論 0 0
  • 奧黛拉 維護(hù) 保護(hù)的意思, 美國亞特蘭大歷史學(xué)教授 和一個納粹的崇拜者在英國打關(guān)于證偽沒有納粹大屠殺的謊言娘赴。 憤怒...
    我的真諦閱讀 156評論 0 0
  • 數(shù)算十項恩福 1.感恩今天的天氣规哲,不是大太陽也沒有下雨,有少許的微風(fēng)诽表。給人一陣陣涼爽的感覺...
    夏夏Jasmine閱讀 242評論 2 2