iOS 反反调试之sysctl

前几天在调试某被注入过dylib的WX时,由于本人刚刚接触逆向,对该方面知识不够,碰到了点问题被困扰了两天,现已解决,特此分享给新手供参考。

先说说遇到的问题现象:

  • 在正常状态下该ipa包能正常安装正常运行,且会一直停留在登录界面让输入授权码。
  • debugserver 能正常附加,lldb也能正常连接,但是在连接成功后再c后过大约5s后app崩溃。lldb输出:Process 11155 exited with status = 10 (0x0000000a)
    如下:
(lldb) process connect connect://0000000:1234
Process 11155 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x00000001819c8fd8 libsystem_kernel.dylib`mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
->  0x1819c8fd8 <+8>: ret    

libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x1819c8fdc <+0>: mov    x16, #-0x20
    0x1819c8fe0 <+4>: svc    #0x80
    0x1819c8fe4 <+8>: ret    
(lldb) c
Process 11155 resuming
Process 11155 exited with status = 10 (0x0000000a) 

系统 log输出如下:

May  7 19:55:27 iPhone WeChat[11484] <Error>: +[MicroMessengerAppDelegate application:didRegisterForRemoteNotificationsWithDeciceToken:]: unrecognized selector sent to class 0x103b37ce0
May  7 19:55:28 iPhone mediaserverd[5349] <Notice>: '' com.cjwj.xin(pid = 11484) setting DiscoveryMode = DiscoveryMode_None, currentDiscoveryMode = DiscoveryMode_None
May  7 19:55:28 iPhone SpringBoard[11461] <Warning>: UNNotificationSchedulerConnectionListener connection invalidated
May  7 19:55:28 iPhone SpringBoard[11461] <Warning>: UNNotificationRegistrarConnectionListener connection invalidated
May  7 19:55:28 iPhone SpringBoard[11461] <Warning>: HW kbd: Failed to set (null) as keyboard focus
May  7 19:55:28 iPhone com.apple.xpc.launchd[1] (UIKitApplication:com.cjwj.xin[0x77fd][11484]) <Warning>: Service exited with abnormal code: 10
May  7 19:55:28 iPhone com.apple.debugserver-@(#)PROGRAM:debugserver  PROJECT:debugserver-340.3.124
    [11487] <Warning>: 1 +0.000000 sec [2cdf/3b03]: error: ::read ( 6, 0x16e35ea38, 1024 ) => -1 err = Bad file descriptor (0x00000009)
May  7 19:55:28 iPhone SpringBoard[11461] <Warning>: Application 'UIKitApplication:com.cjwj.xin[0x77fd]' exited voluntarily.
May  7 19:55:28 iPhone UserEventAgent[456] <Warning>: 14334655851519: id=com.cjwj.xin pid=11484, state=0
May  7 19:55:37 iPhone kernel[0] <Notice>: AppleHDQGasGauge:stats num_clients=1,num_entries=617313,dl_skip=0,dl_cali=0,dl_over=0,dl_drain=27 ops=3615206,collated=0,bfailures=2,collate_error=0,ioerr=0,timeouts=97 retry16=210,chf16=29
May  7 19:55:37 iPhone kernel[0] <Notice>: AppleHDQGasGauge:clientLog ld=593121808/d28 le=593122346/e30
May  7 19:55:37 iPhone kernel[0] <Notice>: AppleHDQGasGauge:clientLog 495657400/T20 495657400/C20 495657667/S27 566137324/T26 566137324/d26 566137324/C26 566137857/S28 566137857/e28 566661472/T27
May  7 19:55:37 iPhone kernel[0] <Notice>: AppleHDQGasGauge:clientLog 566661472/C27 566661717/S29 593121808/T28 593121808/d28 593121808/C28 593122346/S30 593122346/e30

分析

正常运行的时候没问题,一连接lldb就崩溃,这种情况一般都是加了反调试。但是作为逆向菜鸟的我来说之前只听说过ptrace反调试,但是加了ptrace断点后并没有发现,所以可以排除ptrace了。然后通过各种google 百度后发现了另一种反调试方法:sysctl。下断点,运行,断在了sysctl,再看下调用栈,的确是注入的dylib调用的:

(lldb) process connect connect://20.20.20.20:1234
Process 11611 stopped
* thread #1, stop reason = signal SIGSTOP
    frame #0: 0x00000001819c8fd8 libsystem_kernel.dylib`mach_msg_trap + 8
libsystem_kernel.dylib`mach_msg_trap:
->  0x1819c8fd8 <+8>: ret    

libsystem_kernel.dylib`mach_msg_overwrite_trap:
    0x1819c8fdc <+0>: mov    x16, #-0x20
    0x1819c8fe0 <+4>: svc    #0x80
    0x1819c8fe4 <+8>: ret    
(lldb) b sysctl
Breakpoint 1: where = libsystem_c.dylib`sysctl, address = 0x00000001818f6a3c
(lldb) c
Process 11611 resuming
Process 11611 stopped
* thread #4, stop reason = breakpoint 1.1
    frame #0: 0x00000001818f6a3c libsystem_c.dylib`sysctl
libsystem_c.dylib`sysctl:
->  0x1818f6a3c <+0>:  stp    x29, x30, [sp, #-0x10]!
    0x1818f6a40 <+4>:  mov    x29, sp
    0x1818f6a44 <+8>:  ldr    w8, [x0]
    0x1818f6a48 <+12>: cmp    w8, #0x8                  ; =0x8 
(lldb) bt
* thread #4, stop reason = breakpoint 1.1
  * frame #0: 0x00000001818f6a3c libsystem_c.dylib`sysctl
    frame #1: 0x0000000106387f1c libwsp.dylib`_bookIn + 146376
    frame #2: 0x0000000106394698 libwsp.dylib`_bookIn + 197444
    frame #3: 0x00000001818954bc libdispatch.dylib`_dispatch_call_block_and_release + 24
    frame #4: 0x000000018189547c libdispatch.dylib`_dispatch_client_callout + 16
    frame #5: 0x00000001818a14c0 libdispatch.dylib`_dispatch_queue_drain + 864
    frame #6: 0x0000000181898f80 libdispatch.dylib`_dispatch_queue_invoke + 464
    frame #7: 0x000000018189547c libdispatch.dylib`_dispatch_client_callout + 16
    frame #8: 0x00000001818a3914 libdispatch.dylib`_dispatch_root_queue_drain + 2140
    frame #9: 0x00000001818a30b0 libdispatch.dylib`_dispatch_worker_thread3 + 112
    frame #10: 0x0000000181aad470 libsystem_pthread.dylib`_pthread_wqthread + 1092
    frame #11: 0x0000000181aad020 libsystem_pthread.dylib`start_wqthread + 4
(lldb) 

接下来就是编写tweak干掉反调试,如下:

#import <sys/sysctl.h>
#import <sys/proc.h>
#import <substrate.h>

 int (*old__sysctl)(int *name, u_int num, void* buffer, size_t *bufferSize, void *set0, size_t set1);

 int new_sysctl(int *name, u_int num, void* buffer, size_t *bufferSize, void *set0, size_t set1) {
    NSLog(@"========================new_sysctl");
    int result =  old__sysctl(name, num, buffer, bufferSize, set0, set1);
    size_t info_size = sizeof(struct kinfo_proc);
    if(info_size == *bufferSize){
        NSLog(@"info_size == buffer_size");
        int * flag = (int*)buffer+(0x20/sizeof(int));
        *flag = ~P_TRACED;
    }
    return result;
}


%ctor {
        MSHookFunction((void *)sysctl, (void *)&new_sysctl, (void **)&old__sysctl);
}

编译打包安装,再连接lldb,一切正常运行。完工!

下面再补充下上面tweak中0x20的来源:

sysctl反调试是利用sysctl函数查看内核进程状态标志,判断是否是被调试状态,当进程被调试的时候info.kp_proc.p_flag会变成P_TRACED,所以就可以通过sysctl查询进程相应的kinfo_proc信息就可以判断是否是在被调试状态,我们只需要在函数返回时修改p_flag = ~P_TRACED就可以让sysctl返回未在调试状态。

0x20是内核进程状态标志(p_flag)相对于内核进程状态模型(struct kinfo_proc) 的偏移。可以通过下面方法获取:

  • 首先在Xcode中输入下面一行,然后打个断点


    1.png
  • 当断点住下后用lldb打印:


    2.png
  • $1 - $0 = 0x20

如有错误欢迎评论指正。

参考:

http://bbs.iosre.com/t/sysctl-lldb-gdb/1953
https://coredump.gr/articles/ios-anti-debugging-protections-part-2/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容