前幾天在調(diào)試某被注入過dylib的WX時,由于本人剛剛接觸逆向,對該方面知識不夠,碰到了點問題被困擾了兩天,現(xiàn)已解決,特此分享給新手供參考。
先說說遇到的問題現(xiàn)象:
- 在正常狀態(tài)下該ipa包能正常安裝正常運行,且會一直停留在登錄界面讓輸入授權(quán)碼。
- 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)
系統(tǒng) 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就崩潰,這種情況一般都是加了反調(diào)試。但是作為逆向菜鳥的我來說之前只聽說過ptrace反調(diào)試,但是加了ptrace斷點后并沒有發(fā)現(xiàn),所以可以排除ptrace了。然后通過各種google 百度后發(fā)現(xiàn)了另一種反調(diào)試方法:sysctl。下斷點,運行,斷在了sysctl,再看下調(diào)用棧,的確是注入的dylib調(diào)用的:
(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干掉反調(diào)試,如下:
#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反調(diào)試是利用sysctl函數(shù)查看內(nèi)核進程狀態(tài)標志,判斷是否是被調(diào)試狀態(tài),當進程被調(diào)試的時候info.kp_proc.p_flag會變成P_TRACED,所以就可以通過sysctl查詢進程相應(yīng)的kinfo_proc信息就可以判斷是否是在被調(diào)試狀態(tài),我們只需要在函數(shù)返回時修改p_flag = ~P_TRACED就可以讓sysctl返回未在調(diào)試狀態(tài)。
0x20是內(nèi)核進程狀態(tài)標志(p_flag)相對于內(nèi)核進程狀態(tài)模型(struct kinfo_proc) 的偏移??梢酝ㄟ^下面方法獲?。?/p>
-
首先在Xcode中輸入下面一行,然后打個斷點
1.png -
當斷點住下后用lldb打?。?/p>
2.png - $1 - $0 = 0x20
如有錯誤歡迎評論指正。
參考:
http://bbs.iosre.com/t/sysctl-lldb-gdb/1953
https://coredump.gr/articles/ios-anti-debugging-protections-part-2/

