iOS逆向-huolala反除錯
第一步:砸殼
砸殼就不說了,直接frida。
第二步:建立MD工程,開始除錯
首先建立MonkeyDev工程,在AntiAntiDebug.m檔案下斷點,需要斷點的函式有:
my_dlsym,my_ptrace,my_sysctl,my_syscall。
執行,發現在my_dlsym函式中斷了下來, bt列印堆疊看看:
(lldb) bt
* thread #1,queue = 'com.apple.main-thread',stop reason = breakpoint 2.1
* frame #0: 0x000000010468c730 libmylalaDylib.dylib`my_dlsym(__handle=0xfffffffffffffffe,__symbol="dlsym" ) at AntiAntiDebug.m:62:15
frame #1: 0x0000000101c520a8 HLLDriver_Example`___lldb_unnamed_symbol75555$$HLLDriver_Example + 464
frame #2: 0x0000000101c52140 HLLDriver_Example`+[JMSecure440 load] + 16
frame #3: 0x000000022dba1ffc libobjc.A.dylib`call_load_methods + 184
frame #4: 0x000000022dba3e54 libobjc.A.dylib`load_images + 180
frame #5: 0x000000010292a390 dyld`dyld::notifySingle(dyld_image_states,ImageLoader const*,ImageLoader::InitializerTimingList*) + 444
frame #6: 0x000000010293c380 dyld`ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&,unsigned int,char const*,ImageLoader::InitializerTimingList&,ImageLoader::UninitedUpwards&) + 440
frame #7: 0x000000010293b3dc dyld`ImageLoader::processInitializers(ImageLoader::LinkContext const&,ImageLoader::UninitedUpwards&) + 136
frame #8: 0x000000010293b498 dyld`ImageLoader::runInitializers(ImageLoader::LinkContext const&,ImageLoader::InitializerTimingList&) + 84
frame #9: 0x000000010292a6d8 dyld`dyld::initializeMainExecutable() + 220
frame #10: 0x000000010292f2a0 dyld`dyld::_main(macho_header const*,unsigned long,int,char const**,unsigned long*) + 4304
frame #11: 0x0000000102929044 dyld`_dyld_start + 68
(lldb)
複製程式碼
發現 frame 2有個 [JMSecure440 load]方法呼叫,看這名字就像是做防護的, 開啟IDA,搜尋該方法,並搜尋JMSec找到如下類:
JMSecure440
JMSecure423
JMSecure481
JMSecure560
MOBjectmm
複製程式碼
這些類的方法粗看比較難懂,先Hook試試,Hook程式碼如下:
%hook BLYDevice
- (BOOL)isJailbroken
{
return NO;
}
%end
%hook JMSecure440
+ (void)load
{
%log;
}
- (id)init
{
return nil;
}
%end
%hook JMSecure560
- (id)init
{
return nil;
}
%end
%hook SIFViewController
+ (void)JMSecure531
{
%log;
}
%end
複製程式碼
然後執行,發現還是crash,檢視裝置crash日誌,發現有如下堆疊:
Thread 0 Crashed:
0 ??? 000000000000000000 0 + 0
1 HLLDriver_Example 0x0000000101e1db50 -[HLLDriverCoreService powerOn] + 500
2 HLLCoreService 0x0000000102c78a90 __16-[HLLService ON]_block_invoke + 56
3 HLLCoreService 0x0000000102c78c7c -[HLLService appLaunched:] + 140
4 CoreFoundation 0x00000001b2c8421c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
5 CoreFoundation 0x00000001b2c841e8 ___CFXRegistrationPost_block_invoke + 64
6 CoreFoundation 0x00000001b2c836dc _CFXRegistrationPost + 392
7 CoreFoundation 0x00000001b2c83388 ___CFXNotificationPost_block_invoke + 96
8 CoreFoundation 0x00000001b2bfcc54 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1496
9 CoreFoundation 0x00000001b2c82e38 _CFXNotificationPost + 696
10 Foundation 0x00000001b366c1a4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 68
11 UIKitCore 0x00000001df4f9988 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3660
12 UIKitCore 0x00000001df4fefe0 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1540
13 UIKitCore 0x00000001dedc22a4 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke + 776
複製程式碼
從呼叫棧可以看出,在 -[HLLDriverCoreService powerOn] 方法內,發生了crash,通過IDA檢視 該方法的虛擬碼,裡面有保護相關的程式碼,直接hook:
%hook HLLDriverCoreService
- (void)powerOn
{
}
%end
複製程式碼
然後繼續執行,還是斷開除錯,通過檢視裝置crash日誌,日誌如下:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000,0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Application Specific Information:
abort() called
Last Exception Backtrace:
0 CoreFoundation 0x22e9c7180 __exceptionPreprocess + 228
1 libobjc.A.dylib 0x22db9f9f8 objc_exception_throw + 55
2 CoreFoundation 0x22e8e39bc -[NSObject+ 219580 (NSObject) doesNotRecognizeSelector:] + 139
3 CoreFoundation 0x22e9cc9c8 ___forwarding___ + 1407
4 CoreFoundation 0x22e9ce65c _CF_forwarding_prep_0 + 91
5 HLLDriver_Example 0x101f23d58 0x100b54000 + 20774232
6 HLLDriver_Example 0x101f23d34 0x100b54000 + 20774196
7 HLLKit 0x1032ea50c 0x1032dc000 + 58636
8 UIKitCore 0x25b1b6300 -[UIApplication sendAction:to:from:forEvent:] + 95
9 SensorsAnalyticsSDK 0x1040cfa0c 0x104090000 + 260620
10 UIKitCore 0x25ac5f424 -[UIControl sendAction:to:forEvent:] + 79
11 HLLKit 0x1033227e4 0x1032dc000 + 288740
12 UIKitCore 0x25ac5f744 -[UIControl _sendActionsForEvents:withEvent:] + 439
13 UIKitCore 0x25ac5e7b0 -[UIControl touchesEnded:withEvent:] + 567
14 UIKitCore 0x25b1ed5c4 -[UIWindow _sendTouchesForEvent:] + 2107
15 UIKitCore 0x25b1ee7ec -[UIWindow sendEvent:] + 3139
16 UIKitCore 0x25b1ce85c -[UIApplication sendEvent:] + 339
17 UIKitCore 0x25b2949d4 __dispatchPreprocessedEventFromEventQueue + 1767
18 UIKitCore 0x25b297100 __handleEventQueueInternal + 4827
19 UIKitCore 0x25b290330 __handleHIDEventFetcherDrain + 151
20 CoreFoundation 0x22e958f1c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 23
21 CoreFoundation 0x22e958e9c __CFRunLoopDoSource0 + 87
22 CoreFoundation 0x22e958784 __CFRunLoopDoSources0 + 175
23 CoreFoundation 0x22e9536c0 __CFRunLoopRun + 1003
24 CoreFoundation 0x22e952fb4 CFRunLoopRunSpecific + 435
25 GraphicsServices 0x230b5479c GSEventRunModal + 103
26 UIKitCore 0x25b1b4c38 UIApplicationMain + 211
27 HLLDriver_Example 0x100b5a5dc 0x100b54000 + 26076
28 libdyld.dylib 0x22e4168e0 start + 3
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x000000022e5630dc __pthread_kill + 8
1 libsystem_pthread.dylib 0x000000022e5dc094 pthread_kill$VARIANT$mp + 380
2 libsystem_c.dylib 0x000000022e4bbea8 abort + 140
3 libc++abi.dylib 0x000000022db88788 __cxa_bad_cast + 0
4 libc++abi.dylib 0x000000022db94858 std::__terminate(void (*)+ 55384 ()) + 48
5 libc++abi.dylib 0x000000022db94434 __cxa_rethrow + 144
6 libobjc.A.dylib 0x000000022db9fbc8 objc_exception_rethrow + 44
7 CoreFoundation 0x000000022e953020 CFRunLoopRunSpecific + 544
8 GraphicsServices 0x0000000230b5479c GSEventRunModal + 104
9 UIKitCore 0x000000025b1b4c38 UIApplicationMain + 212
10 HLLDriver_Example 0x0000000100b5a5dc 0x100b54000 + 26076
11 libdyld.dylib 0x000000022e4168e0 start + 4
Thread 1 name: JavaScriptCore bmalloc scavenger
Thread 1:
0 libsystem_kernel.dylib 0x000000022e562ee4 __psynch_cvwait + 8
1 libsystem_pthread.dylib 0x000000022e5ddcf8 _pthread_cond_wait$VARIANT$mp + 636
2 libc++.1.dylib 0x000000022db39090 std::__1::condition_variable::wait+ 32912 (std::__1::unique_lock<std::__1::mutex>&) + 24
3 JavaScriptCore 0x0000000235be7de0 void std::__1::condition_variable_any::wait<std::__1::unique_lock<bmalloc::Mutex> >+ 564704 (std::__1::unique_lock<bmalloc::Mutex>&) + 108
4 JavaScriptCore 0x0000000235bebdd4 bmalloc::Scavenger::threadRunLoop+ 581076 () + 176
5 JavaScriptCore 0x0000000235beb54c bmalloc::Scavenger::Scavenger+ 578892 (std::__1::lock_guard<bmalloc::Mutex>&) + 0
6 JavaScriptCore 0x0000000235becf8c std::__1::__thread_specific_ptr<std::__1::__thread_struct>::set_pointer+ 585612 (std::__1::__thread_struct*) + 0
7 libsystem_pthread.dylib 0x000000022e5e52c0 _pthread_body + 128
8 libsystem_pthread.dylib 0x000000022e5e5220 _pthread_start + 44
9 libsystem_pthread.dylib 0x000000022e5e8cdc thread_start + 4
複製程式碼
從日誌標紅的部分可以看到,crash發生在主執行緒,好像並沒有啥可用資訊。 我們首先看下這個地方:
10 HLLDriver_Example 0x0000000100b5a5dc(記憶體實際地址) 0x100b54000(映象基地址) + 26076
複製程式碼
開啟Node,計算出偏移地址:(注意,計算的時候,image映象基地址0x100b54000 只要取低6位就好了,即基地址 = 0xb54000)
然後拿 0x1000065dc 去IDA裡面搜,找到對方的函式,虛擬碼如下:
如圖,原來是在main函式裡面加了個ptrace。 按Tab鍵切換到彙編視窗,找到main函式的基地址:0x0000000100006544 重新執行,Nop掉試試. 1.首先執行,然後在main函式開頭下斷點:
2020-06-12 15:57:22.738042+0800 HLLDriver_Example[1114:124471] LookinServer - Will launch. Framework version: 1.0.0
2020-06-12 15:57:22.911173+0800 HLLDriver_Example[1114:124471] haha
(lldb) im li -o -f HLLDriver_Example
[ 0] 0x000000000136c000 /Users/zzc/Library/Developer/Xcode/DerivedData/mylala-dprymlhjzjchqobznlkzeaqmnlmv/Build/Products/Debug-iphoneos/mylala.app/HLLDriver_Example
(lldb) p/x 0x000000000136c000 + 0x0000000100006544
(long) $0 = 0x0000000101372544
(lldb) b 0x0000000101372544
Breakpoint 5: where = HLLDriver_Example`___lldb_unnamed_symbol1$$HLLDriver_Example,address = 0x0000000101372544
(lldb)
複製程式碼
2.執行,斷在main函式,在彙編14行:
3.Nop該行指令,然後執行即可,即: memory write -s 4 0x101372574 0xd503201f 4.執行,沒有斷開除錯了,非常好。
接下來我們在看看這部分:
同樣的操作:計算偏移地址 = 0x101f23d58 - 0xb54000 = 1013cfd58 通過地址+IDA找到對應方法是:
__int64 __fastcall sub_1013CFD34(__int64 a1)
{
__int64 v1; // x19
void *v2; // x0
void *v3; // x20
void *v4; // x0
void *v5; // x19
v1 = a1;
v2 = objc_msgSend(*(void **)(a1 + 32),"launchImageV");
v3 = (void *)objc_retainAutoreleasedReturnValue(v2);
objc_msgSend(v3,"setAlpha:",0.0);
objc_release(v3);
v4 = objc_msgSend(*(void **)(v1 + 32),"versionLb");
v5 = (void *)objc_retainAutoreleasedReturnValue(v4);
objc_msgSend(v5,0.0);
return objc_release(v5);
}
複製程式碼
然後按X 找到引用該函式的地方,得到下面方法:
void __cdecl -[SplashScreenVC goLoginOrMainPage](SplashScreenVC *self,SEL a2)
{
SplashScreenVC *v2; // x19
void *v3; // x0
__int64 v4; // x21
int v5; // w23
void *v6; // x0
void *v7; // x20
char v8; // w21
char *v9; // x0
id v10; // x0
void *v11; // x20
void *v12; // x0
__int64 v13; // x21
void *v14; // x0
__int64 v15; // x22
void *v16; // x0
__int64 v17; // x23
void *v18; // x0
__int64 v19; // x24
id v20; // x0
void *v21; // x0
void *v22; // x19
void *v23; // x0
__int64 v24; // x0
__int64 v25; // x22
void *v26; // x0
__int64 v27; // x21
void **v28; // [xsp+10h] [xbp-170h]
__int64 v29; // [xsp+18h] [xbp-168h]
__int64 (__fastcall *v30)(); // [xsp+20h] [xbp-160h]
void *v31; // [xsp+28h] [xbp-158h]
SplashScreenVC *v32; // [xsp+30h] [xbp-150h]
void **v33; // [xsp+38h] [xbp-148h]
__int64 v34; // [xsp+40h] [xbp-140h]
__int64 (__fastcall *v35)(__int64); // [xsp+48h] [xbp-138h]
void *v36; // [xsp+50h] [xbp-130h]
SplashScreenVC *v37; // [xsp+58h] [xbp-128h]
Dl_info v38; // [xsp+60h] [xbp-120h]
struct stat v39; // [xsp+80h] [xbp-100h]
const __CFString *v40; // [xsp+110h] [xbp-70h]
const __CFString *v41; // [xsp+118h] [xbp-68h]
__int64 v42; // [xsp+120h] [xbp-60h]
__int64 v43; // [xsp+128h] [xbp-58h]
__int64 v44; // [xsp+130h] [xbp-50h]
//越獄檢測的相關邏輯
v2 = self;
v3 = objc_msgSend(&OBJC_CLASS___NSFileManager,"defaultManager");
v4 = objc_retainAutoreleasedReturnValue(v3);
v5 = (unsigned __int64)objc_msgSend((void *)v4,"fileExistsAtPath:",CFSTR("/Applications/Cydia.app"));
objc_release(v4);
v6 = objc_msgSend(&OBJC_CLASS___NSFileManager,"defaultManager");
v7 = (void *)objc_retainAutoreleasedReturnValue(v6);
LODWORD(v4) = (unsigned __int64)objc_msgSend(v7,CFSTR("/private/var/lib/apt/"));
objc_release(v7);
LODWORD(v4) = v5 | v4 | (stat("/Library/MobileSubstrate/MobileSubstrate.dylib",&v39) == 0);
LOBYTE(v4) = (stat("/Applications/Cydia.app",&v39) == 0) | v4;
LOBYTE(v4) = (stat("/var/lib/cydia/",&v39) == 0) | v4;
v8 = (stat("/var/cache/apt",&v39) == 0) | v4;
if ( dladdr(&_stat,&v38) )
v8 |= strcmp(v38.var0,"/usr/lib/system/libsystem_kernel.dylib") != 0;
v9 = getenv("DYLD_INSERT_LIBRARIES");
if ( v8 & 1 || v9 )
{
v10 = ((id (__cdecl *)(HttpManagerNew_meta *,SEL))objc_msgSend)(
(HttpManagerNew_meta *)&OBJC_CLASS___HttpManagerNew,"getInstance");
v11 = (void *)objc_retainAutoreleasedReturnValue(v10);
v40 = CFSTR("name");
v12 = objc_msgSend(&OBJC_CLASS___NSNumber,"numberWithInt:",20003LL);
v13 = objc_retainAutoreleasedReturnValue(v12);
v41 = CFSTR("info");
v42 = v13;
v14 = objc_msgSend(&OBJC_CLASS___NSNumber,2LL);
v15 = objc_retainAutoreleasedReturnValue(v14);
v43 = v15;
v16 = objc_msgSend(&OBJC_CLASS___NSDictionary,"dictionaryWithObjects:forKeys:count:",&v42,&v40,2LL);
v17 = objc_retainAutoreleasedReturnValue(v16);
v44 = v17;
v18 = objc_msgSend(&OBJC_CLASS___NSArray,"arrayWithObjects:count:",&v44,1LL);
v19 = objc_retainAutoreleasedReturnValue(v18);
objc_msgSend(v11,"mdapReportInfos:",v19);
objc_release(v19);
objc_release(v17);
objc_release(v15);
objc_release(v13);
objc_release(v11);
v20 = ((id (__cdecl *)(AccountManager_meta *,SEL))objc_msgSend)(
(AccountManager_meta *)&OBJC_CLASS___AccountManager,"getInstance");
v21 = (void *)objc_retainAutoreleasedReturnValue(v20);
v22 = v21;
v23 = objc_msgSend(v21,"driver_fid");
v24 = objc_retainAutoreleasedReturnValue(v23);
v25 = v24;
v26 = objc_msgSend(&OBJC_CLASS___NSString,"stringWithFormat:",CFSTR("ios_%@"),v24);
v27 = objc_retainAutoreleasedReturnValue(v26);
+[HttpManagerNew uploadDataWithDriverID:andMark:](
&OBJC_CLASS___HttpManagerNew,"uploadDataWithDriverID:andMark:",v27,&stru_10185DB68);
objc_release(v27);
objc_release(v25);
objc_release(v22);
objc_msgSend(
&OBJC_CLASS___HLLDialog,"showDialogWithTitle:message:confirmTitle:confirmHandler:cancelTitle:cancelHandler:",CFSTR("貨拉拉不支援在越獄系統上執行"),0LL,CFSTR("確定"),&off_101850300,0LL);
}
else
{
v32 = v2;
v33 = _NSConcreteStackBlock;
v34 = 3254779904LL;
v35 = sub_1013CFD34;
v36 = &unk_101849578;
v37 = v2;
v28 = _NSConcreteStackBlock;
v29 = 3254779904LL;
v30 = sub_1013CFDBC;
v31 = &unk_101849A18;
objc_msgSend(&OBJC_CLASS___UIView,"animateWithDuration:animations:completion:",&v33,&v28,0.200000003);
}
}
複製程式碼
從虛擬碼上看,App在這個方法做了越獄檢測。我們直接讓它走else 就好了。 首先得到該函式的基地址: 0x0000001013CF918 然後在這個地址下斷點:
(lldb) p/x 0x000000000136c000 + 0x0000001013CF918
(long) $1 = 0x000000010273b918
(lldb) b 0x000000010273b918
Breakpoint 6: where = HLLDriver_Example`-[SplashScreenVC goLoginOrMainPage],address = 0x000000010273b918
(lldb) c
複製程式碼
斷下來之後,在nop掉下面兩行比較程式碼:
3.Nop該行指令,然後執行即可,即: memory write -s 4 0x10273ba78 0xd503201f memory write -s 4 0x10273ba7c 0xd503201f
然後就可以正常執行咯~ 但是需要登入才可以進去App裡面,註冊又需要一堆堆資料資訊,就不再弄了,不知道上述hook有麼有影響到業務邏輯,從註冊上來看,貌似沒啥影響。