快手,快影 iOSApp反調試

来源:https://www.cnblogs.com/IOSkf/archive/2020/07/25/13376458.html
-Advertisement-
Play Games

快手,快影的App保護用的是同一套代碼,反調試也很容易,下麵請看過程。 >作為一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流群:761407670 進群密碼‘博客’,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿裡面試題、面試經驗,討論技術, 大家一起交流學習成長! 1. ...


快手,快影的App保護用的是同一套代碼,反調試也很容易,下麵請看過程。

>作為一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流群:761407670 進群密碼‘博客’,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿裡面試題、面試經驗,討論技術, 大家一起交流學習成長!

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, 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, 0, 0, x3, 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進行抓包。

>作為一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流群:761407670 進群密碼‘博客’,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿裡面試題、面試經驗,討論技術, 大家一起交流學習成長!
作者:倒影cc
鏈接:https://juejin.im/post/5ee59de76fb9a047f558d8ed


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 導出數據 導入/導出可以操作的是本地的mongodb伺服器,也可以是遠程的,所以,都有如下通用選項。 利用mongoexport -h host 主機 -port 埠 -d 知名使用的庫 -c 指明要導出的集合 -o 指明要導出的文件名 --csv 指定導出的csv格式 -q 過濾導出 -f fi ...
  • 索引是對資料庫表中一列或多列的值進行排序的一種結構,可以讓我們查詢資料庫變得 更快。MongoDB 的索引幾乎與傳統的關係型資料庫一模一樣,這其中也包括一些基本的查詢優化技巧。 增加檢索的效率. mongodb提供了索引的支持.(越來越傾向於關係型資料庫) 通常建立索引的, 基本要求, 就是文檔的結 ...
  • 許可權概述 在mongodb裡面的用戶是屬於資料庫的,每個資料庫有自己的管理員,管理員登錄後,只能操作所屬的資料庫。 註意:一般在admin資料庫中創建的用戶授予超級管理員許可權,登錄後可以操作任何的資料庫。 創建超級管理員 註意:在開啟許可權管理控制時,一定先要創建一個超級管理員授予超級管理許可權。 (1 ...
  • 添加文檔 語法: db.集合名.insert({k1:"v1", k2:"v2"....}) 註意: (1)文檔就是鍵值對,數據類型是BSON格式,支持的值更加豐富。 比如:db.集合名.insert({name:"bashlog", spc:{weight:100, address:"henan" ...
  • 創建資料庫 語法: use database_name; 註意:如果該資料庫不存在,則創建,如果該資料庫存在,則是切換,如果創建了資料庫,沒有任何操作,則會自動刪除該資料庫。 可以使用db命令查看當前所處的資料庫 查看資料庫 語法: show dbs; 創建集合 語法: db.集合名.insert( ...
  • 報錯信息 無法訪問資料庫 ReportServer。 (ObjectExplorer) 具體錯誤信息: 程式位置: 在 Microsoft.SqlServer.Management.UI.VSIntegration.ObjectExplorer.DatabaseNavigableItem.get_C ...
  • 時光在不經意間,總是過得出奇的快。小暑已過,進入中暑,太陽更加熱烈的綻放著ta的光芒,...在外面被太陽照顧的人們啊,你們都是勤勞與可愛的人啊。在房子里已各種姿勢看我這篇這章的你,既然點了進來,那就由我繼續帶你回顧MySql的知識吧! 回顧練習資料girls庫以及兩張表的腳本: https://pa ...
  • Java事務解析(事務的基本操作+隔離的等級+事務的四大特性+事務的概念) 什麼是事務? 如果一個包含多個步驟的業務操作,這些操作被事務管理,那麼這些操作要麼同時成功要麼同時失敗 事務的四大特性(必須記住): 持久性:當事務回滾或者提交之後,資料庫會持久化數據 一致性:事務操作前後,數據的總量不變 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...