【iOS逆向與安全】frida-trace入門

来源:https://www.cnblogs.com/witchan/archive/2022/11/18/16904169.html
-Advertisement-
Play Games

前言 frida-trace是一個用於動態跟蹤函數調用的工具。支持android和ios。安裝教程請參考官網。工欲善其事必先利其器。本文將以某App為示範,演示frida-trace的各種方法在iOS中的應用。 一、目標 讓看文章的你在使用frida-trace時更得心應手。 二、工具 mac系統 ...


前言

frida-trace是一個用於動態跟蹤函數調用的工具。支持android和ios。安裝教程請參考官網。工欲善其事必先利其器。本文將以某App為示範,演示frida-trace的各種方法在iOS中的應用。


一、目標

讓看文章的你在使用frida-trace時更得心應手。

二、工具

  • mac系統
  • frida:動態調試工具
  • 已越獄iOS設備:脫殼及frida調試

三、使用

1.命令格式

frida-trace [options] target

iOS常用的可選參數:

// 設備相關
-D	連接到指定的設備,多個設備時使用。示例:frida-trace -D 555315d66cac2d5849408f53da9eea514a90547e -F 
-U	連接到USB設備,只有一個設備時使用。示例fria-trace -U -F

// 應用程式相關
-f	目標應用包名。spawn模式。示例:frida-trace -U -f com.apple.www
-F	當前正在運行的程式。attach模式示例。示例:frida-trace -U -F或frida-trae -UF
-n	正在運行的程式的名字。attach模式。示例:frida-trace -U -n QQ
-N	正在運行的程式的包名。attach模式。示例:frida-trace -U -N com.apple.www
-p	正在運行的程式的pid。attach模式。示例:frida-trace -U -p 2302
  
// 方法相關,以下參數在一條跟蹤命令中可重覆使用
-I	包含模塊。示例:frida-trace -UF -I "libcommonCrypto*"
-X	不包含模塊。示例:frida-trace -UF -X "libcommonCrypto*"
-i 	包含c函數。示例:frida-trace -UF -i "CC_MD5"
-x 	不包名c函數。示例:frida-trace -UF -i "*MD5" -x "CC_MD5"
-a 	包含模塊+偏移跟蹤。示例:frida-trace -UF -a 模塊名\!0x7B7D48
-m 	包含某個oc方法。示例:frida-trace -UF -m "+[NSURL URLWithString:]"
-M 	不包含某個oc方法。示例:frida-trace -UF -M "+[NSURL URLWithString:]"
  
// 日誌相關
-o	日誌輸出到文件。示例:frida-trace -UF -m "*[* URL*]" -o run.log

2.常用命令

frida-trace中的方法匹配命令支持模糊匹配,星號匹配0個或多個字元,問號匹配1個字元:

-m "-[NSURL *]"	// 匹配NSURL類的所有實例方法
-m "+[NSURL *]"	// 匹配NSURL類的所有類方法
-m "*[NSURL *]" // 匹配NSURL類的所有方法
-m "*[*URL *]"	// 匹配以URL結尾類的所有方法
-m "*[URL* *]" 	// 匹配以URL開頭類的所有方法
-m "*[*URL* *]"	// 匹配包含URL的類的所有方法
-m "*[*URL* *login*]"	// 匹配包含URL的類的帶login的所有方法
-m "*[????? *]"	// 匹配類名只有五個字元的類的所有方法

簡而言之:

當你不確定你要跟蹤的方法是類方法還是實例方法時,用星號代替

當你只知道部分類名時,不確定的地方用星號代替

當你只知道部分方法名時,不確定的地方用星號代替

當你不知道方法名時,直接用星號代替

當你不知道某個字母是大小寫時,用問號代替

frida-trace命令會在當前目錄生成./__handlers__/文件夾內生成對應函數的js代碼。當你需要列印入參,返回值。或修改入參,返回值時,可編輯對應的js文件。

  • 列印或修改OC方法的入參

$ frida-trace -UF -m "-[DetailViewController setObj:]"
Instrumenting...
-[DetailViewController setObj:]: Auto-generated handler at "/Users/witchan/__handlers__/DetailViewController/setObj_.js"
Started tracing 1 function. Press Ctrl+C to stop.

js源碼如下:

{
  onEnter(log, args, state) {
    var self = new ObjC.Object(args[0]);  // 當前對象
    var method = args[1].readUtf8String();  // 當前方法名
    log(`[${self.$className} ${method}]`);

    var isData = false;

    // 字元串
    // var str = ObjC.classes.NSString.stringWithString_("hi wit!")  // 對應的oc語法:NSString *str = [NSString stringWithString:@"hi with!"];
    // args[2] = str  // 修改入參

    // array
    // var 

    // 數組
    // var array = ObjC.classes.NSMutableArray.array();  // 對應的oc語法:NSMutableArray array = [NSMutablearray array];
    // array.addObject_("item1");  // 對應的oc語法:[array addObject:@"item1"];
    // array.addObject_("item2");  // 對應的oc語法:[array addObject:@"item2"];
    // args[2] = array; // 修改入參

    // 字典
    // var dictionary = ObjC.classes.NSMutableDictionary.dictionary(); // 對應的oc語法:NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
    // dictionary.setObject_forKey_("value1", "key1"); // 對應的oc語法:[dictionary setObject:@"value1" forKey:@"key1"]
    // dictionary.setObject_forKey_("value2", "key2"); // 對應的oc語法:[dictionary setObject:@"value2" forKey:@"key2"]
    // args[2] = dictionary; // 修改入參

    // 位元組
    var data = ObjC.classes.NSMutableData.data(); // 對應的oc語法:NSMutableData *data = [NSMutableData data];
    var str = ObjC.classes.NSString.stringWithString_("hi wit!")  // 獲取一個字元串。 對應的oc語法:NSString *str = [NSString stringWithString:@"hi with!"];
    var subData = str.dataUsingEncoding_(4);  // 將str轉換為data,編碼為utf-8。對應的oc語法:NSData *subData = [str dataUsingEncoding:NSUTF8StringEncoding];
    data.appendData_(subData);  // 將subData添加到data。對應的oc語法:[data appendData:subData];
    args[2] = data; // 修改入參
    isData = true;

    // 更多數據類型:https://developer.apple.com/documentation/foundation

    var before = args[2];

    // 註意,日誌輸出請直接使用log函數。不要使用console.log()
    if (isData) {
    	// 列印byte對象
      var after = new ObjC.Object(args[2]); // 列印NSData
      var outValue = after.bytes().readUtf8String(after.length()) // 將data轉換為string
      log(`before:=${before}=`);
      log(`after:=${outValue}=`);
    } else {
    	// 列印字元串、數組、欄位
      var after = new ObjC.Object(args[2]); // 列印出來是個指針時,請用該方式轉換後再列印
      log(`before:=${before}=`);
      log(`after:=${after}=`);
    }

    // 如果是自定義對象時,使用以上方法無法列印時,請使用以下方法:
    // var customObj = new ObjC.Object(args[0]); // 自定義對象
    // // 列印該對象所有屬性
    // var ivarList = customObj.$ivars;
    // for (key in ivarList) {
    //   log(`key${key}=${ivarList[key]}=`);
    // }

    // // 列印該對象所有方法
    // var methodList = customObj.$methods;
    // for (var i=0; i<methodList.length; i++) {
    //   log(`method=${methodList[i]}=`);
    // }
  },
  onLeave(log, retval, state) {

  }
}

  • 修改OC方法的返回值

$ frida-trace -UF -m "-[DetailViewController obj]"
Instrumenting...
-[DetailViewController obj]: Loaded handler at "/Users/witchan/__handlers__/DetailViewController/obj.js"
Started tracing 1 function. Press Ctrl+C to stop.

js源碼如下:

{
  onEnter(log, args, state) {

  },
  onLeave(log, retval, state) {
    // 字元串
    var str = ObjC.classes.NSString.stringWithString_("hi wit!")  // 對應的oc語法:NSString *str = [NSString stringWithString:@"hi with!"];
    retval.replace(str)  // 修改返回值
    var after = new ObjC.Object(retval); // 列印出來是個指針時,請用該方式轉換後再列印
    log(`before:=${retval}=`);
    log(`after:=${after}=`);

    // 其他數據類型,請往上看
  }
}
  • 列印C函數的入參和返回值

$ frida-trace -UF -i "CC_MD5"
Instrumenting...
CC_MD5: Loaded handler at "/Users/witchan/__handlers__/libcommonCrypto.dylib/CC_MD5.js"
Started tracing 1 function. Press Ctrl+C to stop.

js源碼如下:

{
  onEnter(log, args, state) {
    // 註意。c方法里的參數直接從下標0開始
    this.args0 = args[0];	
    this.args2 = args[2];
    this.backtrace = 'CC_MD5 called from:\n' +
        Thread.backtrace(this.context, Backtracer.ACCURATE)
        .map(DebugSymbol.fromAddress).join('\n') + '\n';
  },
  onLeave(log, retval, state) {
    
    var ByteArray = Memory.readByteArray(this.args2, 16);
    var uint8Array = new Uint8Array(ByteArray);

    var str = "";
    for(var i = 0; i < uint8Array.length; i++) {
        var hextemp = (uint8Array[i].toString(16))
        if(hextemp.length == 1){
            hextemp = "0" + hextemp
        }
        str += hextemp;
    }
    log(`CC_MD5(${this.args0.readUtf8String()})`);   
    log(`CC_MD5()=${str}=`);
    log(this.backtrace);	// 列印函數調用棧
  }
}
  • 常用frida-trace命令

跟蹤單個方法:frida-trace -UF -m "-[DetailViewController obj]"

跟蹤多個方法:frida-trace -UF -m "-[DetailViewController obj]" -m "+[NSURL URLWithString:]"

跟蹤某個類的所有方法:frida-trace -UF -m "*[DetailViewController *]"

跟蹤某個類的所有方法併排除viewDidLoad方法:frida-trace -UF -m "*[DetailViewController *]" -M "-[DetailViewController viewDidLoad]"

跟蹤整個App中包含sendMsg關鍵詞的所有方法:frida-trace -UF -m "*[* *sendMsg*]"

需要忽略某個字母的大小寫,請使用?代替sendMsg中的M:frida-trace -UF -m "*[* *send?sg*]"

日誌過多時,可保存到文件:frida-trace -UF -m "*[* *sendMsg*]" -o run.log

跟蹤某個動態庫:frida-trace -UF -I "libcommonCrypto*"

跟蹤某個c函數:frida-trace -UF -i "CC_MD5"

跟蹤sub_1007B7D48函數:frida-trace -UF -a xxxxx\!0x7B7D48

總結

以上就是關於frida-trace的基本使用,希望能幫助到大家。同時也建議大家閱讀官方文檔:https://frida.re/docs/frida-trace/

提示:閱讀此文檔的過程中遇到任何問題,請關註公眾號【移動端Android和iOS開發技術分享】或加QQ群【812546729

IMG_4048


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

-Advertisement-
Play Games
更多相關文章
  • 作用:隨時修改代碼 (在函數或類定義完成之後,再去修改函數的實現過程) """類似猴子補丁在函數定義好之後,再去更改他的行為"""import typesclass Valley: def func(self): return "等待宣告"def common(self): return "只有永不 ...
  • 1. 擴容方案剖析 1.1 擴容問題 在項目初期,我們部署了三個資料庫A、B、C,此時資料庫的規模可以滿足我們的業務需求。為了將數據做到平均分配,我們在Service服務層使用uid%3進行取模分片,從而將數據平均分配到三個資料庫中。 如圖所示: 後期隨著用戶量的增加,用戶產生的數據信息被源源不斷的 ...
  • 上文介紹了命令行方式來對文件進行加解密操作。本文將繼續在此基礎上,實現一個快速簡易的GUI界面方便操作,先上代碼看效果。 ...
  • aspnetcore上傳圖片也就是上傳文件有兩種方式,一種是通過form-data,一種是binary。 先介紹第一種form-data: 該方式需要顯示指定一個IFormFile類型,該組件會動態通過打開一個windows視窗選擇文件 及圖片。 postman演示如上,代碼如下: [HttpPos ...
  • FreeRtos操作系統 首先,應該介紹什麼是FreeRtos,他於單片機而言就是一個管理器,作為管理者管理嵌入式晶元中的任務,堆棧,中斷,隊列等等資源,對於操作系統而言,又分為實時操作系統和非實時操作系統,實時操作系統代表任務或者某個功能必須在指定的運行時間內完成,保證設備想要執行的功能能立即得到 ...
  • 摘要:先通過OPS確認節點狀態是否已經恢復,或登錄後臺執行cm_ctl query -Cv確認集群是否已經Normal。 本文分享自華為雲社區《【實例狀態】GaussDB CN服務異常》,作者:酷哥。 確認節點狀態 先通過OPS確認節點狀態是否已經恢復,或登錄後臺執行cm_ctl query -Cv ...
  • 一、前言 ChunJun(原FlinkX)是一個基於 Flink 提供易用、穩定、高效的批流統一的數據集成工具,既可以採集靜態的數據,比如 MySQL,HDFS 等,也可以採集實時變化的數據,比如 binlog,Kafka等。同時 ChunJun 也是一個支持原生 FlinkSql所有語法和特性的計 ...
  • 學會 MongoDB 的增刪改查只能算得上是“初窺門徑”,瞭解、熟練掌握索引才能算得上“融會貫通”。基本可以認為資料庫的索引知識是一個初級開發向中級開發轉變所必備的知識。 ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...