1. 程式人生 > Android開發 >快手,快影 iOSApp反除錯

快手,快影 iOSApp反除錯

快手,快影的App保護用的是同一套程式碼,反除錯也很容易,下面請看過程。

1.快手App去反除錯

直接frida砸殼,然後建立MonkeyDev工程,並在antiAntiDebug.m檔案的相關函式下斷點,然後執行。

App執行起來後,將在my_dlsym函式斷下來,然後bt列印呼叫棧:

然後在棧1地址處下斷, 即: b 0x00000001054c3430,按C執行。 在0x00000001054c3430 處斷下來之後, 修改返回值 x0 = 0,即: register write $x0 0

在彙編55行:

nop該行指令,然後執行即可,命令如下: memory write -s 4 0x1028c09f4 0xd503201f

2.快影App去反除錯

砸殼快影,然後建立MonkeyDev工程, 執行,閃退。 看下日誌,列印如下: [AntiAntiDebug] - dlsym get ptrace symbol [AntiAntiDebug] - ptrace request is PT_DENY_ATTACH 在antiAntiDebug的my_ptrace和my_dlsym處下斷點。

去反除錯 函式1:0x000000010265c920,
彙編55行: nop掉改行彙編指令即可正常執行,命令如下:
memory write -s 4 0x102e089f4 0xd503201f

2.1 快影App sign的計算邏輯

首先通過IDA靜態分析,我們得到如下關鍵方法:

id __cdecl +[KSMWPassportSecurityTools hmac:withKeyData:](KSMWPassportSecurityTools_meta *self,SEL a2,id a3,id a4)
{
  id v4; // x19
  id v5; // x20
  __int64 v6; // x21
  __int64 v7; // x1
  __int64 v8; // x22
  void *v9; // x0
  const char *v10; // x20
  void *v11; // x19
  void *v12; // x21
  void *v13; // x19
  size_t v14; // x0
char v16; // [xsp+8h] [xbp-48h] v4 = a4; v5 = a3; v6 = objc_retain(a3,a2); v8 = objc_retain(v4,v7); v9 = (void *)objc_retainAutorelease(v5); v10 = (const char *)objc_msgSend(v9,"cStringUsingEncoding:",4LL); objc_release(v6); v11 = (void *)objc_retainAutorelease(v4); v12 = objc_msgSend(v11,"bytes"); v13 = objc_msgSend(v11,"length"); objc_release(v8); v14 = strlen(v10); CCHmac(2LL,v12,v13,v10,v14,&v16); // 2 = kCCHmacAlgSHA256 return (id)objc_msgSend(&OBJC_CLASS___NSData,"dataWithBytes:length:",&v16,32LL); } 複製程式碼

其完整的sign計算邏輯為:

[KSMWPassportSecurityTools createSignWithStringNonce:ssecurity:longValue: value]
    |
    +[KSMWPassportSecurityTools hmac:withKeyData:] = resultData
        |
        CCHmac(2LL,0,x3,101,resultBuf); 
    |
    data = bswap32(value)
    |
    [data appendData: resultData]
    |
    [KSMWPassportSecurityTools base64Encode:]


複製程式碼

於是對[KSMWPassportSecurityTools createSignWithStringNonce:ssecurity:longValue: value]方法下斷,然後點選獲取驗證碼,其呼叫棧如下:

thread #1,queue = 'com.apple.main-thread',stop reason = breakpoint 18.1
frame #0: 0x0000000101856fb0 KwaiYDelux`+[KSMWPassportSecurityTools createSignWithStringNonce:ssecurity:longValue:]
frame #1: 0x0000000101856c30 KwaiYDelux`+[KSMWPassportSecurityTools signOnURLPath:method:requestParams:] + 364
frame #2: 0x0000000101855910 KwaiYDelux`-[KSMWNetworkOperation url:method:parameters:cookies:completionHandler:] + 212
frame #3: 0x0000000101863a14 KwaiYDelux`-[KWPassportAPI POST:bodyParams:completionHandler:] + 280
frame #4: 0x00000001018607f8 KwaiYDelux`-[KWPassportAPI requestSMSCode:countryCode:type:completion:] + 412
frame #5: 0x000000010185f25c KwaiYDelux`-[KWPassport requestSMSCode:countryCode:type:completion:] + 132
frame #6: 0x00000001026799dc KwaiYDelux`-[KWAccountChannelService_Imp sendSMSWithRequest:handler:] + 264
frame #7: 0x000000018deea800 CoreFoundation`__invoking___ + 144
frame #8: 0x000000018ddcc3c0 CoreFoundation`-[NSInvocation invoke] + 292
frame #9: 0x000000010259659c KwaiYDelux`___lldb_unnamed_symbol58737$$KwaiYDelux + 1180
frame #10: 0x000000010817e7fc Flutter`__45-[FlutterMethodChannel setMethodCallHandler:]_block_invoke + 116
frame #11: 0x000000010811d6d0 Flutter`flutter::PlatformViewIOS::HandlePlatformMessage(fml::RefPtr<flutter::PlatformMessage>) + 680
frame #12: 0x0000000108170048 Flutter`std::__1::__function::__func<flutter::Shell::OnEngineHandlePlatformMessage(fml::RefPtr<flutter::PlatformMessage>)::$_32,std::__1::allocator<flutter::Shell::OnEngineHandlePlatformMessage(fml::RefPtr<flutter::PlatformMessage>)::$_32>,void ()>::operator()() + 80
frame #13: 0x000000010812a988 Flutter`fml::MessageLoopImpl::FlushTasks(fml::FlushType) + 96
frame #14: 0x000000010812ef0c Flutter`fml::MessageLoopDarwin::OnTimerFire(__CFRunLoopTimer*,fml::MessageLoopDarwin*) + 32
frame #15: 0x000000018de75554 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 28
frame #16: 0x000000018de75284 CoreFoundation`__CFRunLoopDoTimer + 864
frame #17: 0x000000018de74ab8 CoreFoundation`__CFRunLoopDoTimers + 248
frame #18: 0x000000018de6fa08 CoreFoundation`__CFRunLoopRun + 1844
frame #19: 0x000000018de6efb4 CoreFoundation`CFRunLoopRunSpecific + 436
frame #20: 0x000000019007079c GraphicsServices`GSEventRunModal + 104
frame #21: 0x00000001ba6d0c38 UIKitCore`UIApplicationMain + 212
frame #22: 0x0000000100e0c028 KwaiYDelux`___lldb_unnamed_symbol1343$$KwaiYDelux + 100
frame #23: 0x000000018d9328e0 libdyld.dylib`start + 4

複製程式碼

呼叫+[KSMWPassportSecurityTools hmac:withKeyData:]
其中hmac=POST&/pass/ky/sms/code&countryCode=+86&phone=ZTSP__R2oN18L5Ilx8weM__ZTSP&type=395&8951850021377611294
data = 空

彙編50行,呼叫 CCHmac(2LL,101,resultBuf); // 2 = kCCHmacAlgSHA256, CC_SHA256_DIGEST_LENGTH = 32, 即加密返回長度=32

(lldb) x/50xg $x3,長度=101,即=POST&/pass/ky/sms/code&countryCode=+86&phone=ZTSP__R2oN18L5Ilx8weM__ZTSP&type=395&8951850021377611294

記憶體資料如下:

0x2823ace91: 0x61702f2654534f50 0x6d732f796b2f7373      
0x2823acea1: 0x632665646f632f73 0x6f437972746e756f      
0x2823aceb1: 0x702636382b3d6564 0x53545a3d656e6f68      
0x2823acec1: 0x314e6f32525f5f50 0x7738786c49354c38
0x2823aced1: 0x5053545a5f5f4d65 0x39333d6570797426
0x2823acee1: 0x3538313539382635 0x3637373331323030
0x2823acef1: 0x0000003439323131 0x0000000000000000
0x2823acf01: 0x0000000000000000 0x0000000000000000
複製程式碼

(lldb) x/50xg $x5 -> 加密結果

0x16f1290c8: 0x35da8aa020e5bd2f 0xf6fc50b2b2c85841
0x16f1290d8: 0x2e00c9df95a02ada 0x17325b620c1cd33f
複製程式碼

將data<7c3b5c2a 5ec9161e> append 加密結果,得到:

<7c3b5c2a 5ec9161e 2fbde520 a08ada35 4158c8b2 b250fcf6 da2aa095 dfc9002e 3fd31c0c 625b3217>
複製程式碼

然後呼叫 [KSMWPassportSecurityTools base64Encode:],傳入上面的data。 得到:
fDtcKl7JFh4vveUgoIraNUFYyLKyUPz22iqgld/JAC4/0xwMYlsyFw==

這就是最終的sign,可以通過抓包進行對比。

由於快影App 大部分業務介面都是flutter開發的,目前還沒有能力進行逆向,flutter頁面的介面請求也沒有走Native,沒辦法進行抓包。

wireshark只能抓到https加密包,它的本質就是把經過網路卡的資料包複製一份,而不是像charles在手機系統上起一個代理伺服器,對App的網路請求進行代理請求。

據網上說,可以通過代理(fan qiang)工具進行代理,然後再使用charles進行抓包。