1. 程式人生 > Android開發 >iOS逆向-huolala反除錯

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有麼有影響到業務邏輯,從註冊上來看,貌似沒啥影響。