應(yīng)用運(yùn)行時(shí)安全測(cè)試與逆向?qū)崙?zhàn)指南)
1. 為什么移動(dòng)應(yīng)用測(cè)試?yán)@不開(kāi) objection做移動(dòng)端安全測(cè)試和逆向分析的朋友大概率都遇到過(guò)這種情況拿到一個(gè)目標(biāo) App想看看它內(nèi)部有什么敏感操作、有沒(méi)有做證書(shū)校驗(yàn)、能不能動(dòng)態(tài)調(diào)用某個(gè)類的方法結(jié)果抓包工具被 SSL Pinning 擋住反編譯出來(lái)的代碼又看得頭大直接上 Frida 寫(xiě)腳本吧光調(diào)試 hook 點(diǎn)就得折騰半天。我第一次接觸 objection 就是在這種場(chǎng)景下。當(dāng)時(shí)要快速確認(rèn)一個(gè)支付類 App 是否在運(yùn)行時(shí)做了 root 檢測(cè)如果用 Frida 寫(xiě)腳本得先定位檢測(cè)函數(shù)、再寫(xiě) hook 邏輯、還要處理線程問(wèn)題前前后后一晚上沒(méi)了。而 objection 提供了一條現(xiàn)成的命令敲下去直接返回檢測(cè)結(jié)果還能一鍵繞過(guò)。那一刻我就意識(shí)到這類給 Frida 套一層現(xiàn)成工具箱的中間層工具才是實(shí)際干活時(shí)效率最高的方式。objection 不是新的 hook 引擎它本質(zhì)上是一套基于 Frida 的運(yùn)行時(shí)探測(cè)與動(dòng)態(tài)調(diào)試工具包。你不需要寫(xiě)一行業(yè)務(wù)代碼只需要通過(guò)命令行就能完成大量常見(jiàn)的移動(dòng)應(yīng)用測(cè)試動(dòng)作枚舉已加載的類、定位具體類的方法、內(nèi)存搜索、SSL Pinning 繞過(guò)、模擬運(yùn)行環(huán)境繞過(guò) root 檢測(cè)、動(dòng)態(tài)調(diào)用目標(biāo)方法、dump 敏感字符串等。它適用于 Android 和 iOS 兩大平臺(tái)底層對(duì)接 Frida 的注入機(jī)制但把我要寫(xiě)腳本實(shí)現(xiàn)變成了我敲一條命令實(shí)現(xiàn)。這篇文章我會(huì)把 objection 的使用邏輯拆開(kāi)講清楚包括環(huán)境搭建、核心命令背后的原理、實(shí)戰(zhàn)中常見(jiàn)的坑以及它與 Frida 原生腳本的協(xié)作關(guān)系。目標(biāo)是讓還沒(méi)用過(guò)的人能直接上手讓用過(guò)但只停留在會(huì)敲幾條命令階段的人能理解它每個(gè)功能模塊的底層機(jī)制從而在真實(shí)測(cè)試中選對(duì)工具、少走彎路。2. 部署與啟動(dòng)先把 objection 和 Frida 的關(guān)系理順2.1 版本匹配是第一個(gè)容易踩的坑很多人裝 objection 的第一步就栽了原因不是安裝命令出錯(cuò)而是沒(méi)有搞懂 objection、Frida 工具端、frida-server 三者的版本關(guān)系。objection 通過(guò) Python 包管理工具安裝它依賴 Frida 的 Python 綁定而手機(jī)端需要運(yùn)行一個(gè) frida-server 程序才能讓 PC 端的指令真正注入到應(yīng)用進(jìn)程里。我當(dāng)時(shí)在一個(gè)測(cè)試機(jī)上裝的 Frida 是 15.x 版本frida-server 也用的 15.x直接跑 objection 完全沒(méi)問(wèn)題。后來(lái)另一臺(tái)測(cè)試機(jī)刷了一個(gè)老系統(tǒng)鏡像手頭只有 frida-server 12.8 的包結(jié)果 objection 怎么都連不上。排查半天才意識(shí)到Frida Python 包、frida-server、objection 三方之間必須保持一個(gè)大版本兼容否則會(huì)出現(xiàn)連接成功但命令超時(shí)報(bào)錯(cuò) device not foundRPC 調(diào)用失敗等一系列詭異現(xiàn)象。安裝順序建議如下先安裝指定版本的 Frida再安裝 objection最后在測(cè)試設(shè)備端 push 對(duì)應(yīng)版本的 frida-server。命令大致是這樣# 指定版本安裝 Frida避免裝到最新版造成和 frida-server 不匹配 pip install frida15.1.17 pip install objection安裝完成后用objection version查看當(dāng)前工具版本。接著把對(duì)應(yīng)版本的 frida-server 傳到設(shè)備的/data/local/tmp/目錄加執(zhí)行權(quán)限后手動(dòng)啟動(dòng)adb push frida-server /data/local/tmp/ adb shell chmod 755 /data/local/tmp/frida-server adb shell /data/local/tmp/frida-server 2.2 啟動(dòng)方式和普通 Frida 腳本的差異objection 連接應(yīng)用有兩種常見(jiàn)方式一種是直接啟動(dòng)一個(gè)新的應(yīng)用進(jìn)程另一種是附加到已經(jīng)運(yùn)行的進(jìn)程上。從命令上區(qū)分非常直觀# 啟動(dòng)應(yīng)用并立即注入適合冷啟動(dòng)分析 objection -g com.example.target explore # 附加到正在運(yùn)行的進(jìn)程適合動(dòng)態(tài)調(diào)試場(chǎng)景 objection -p 12345 explore這里的explore是進(jìn)入交互式命令界面的關(guān)鍵字進(jìn)去之后你就面對(duì)一個(gè)類似終端的環(huán)境后續(xù)所有操作都在這套命令體系里完成。如果是 iOS 設(shè)備通常還需要加-N參數(shù)指定設(shè)備地址或者通過(guò)--host和--port指定遠(yuǎn)程連接參數(shù)。我建議新手在熟悉階段先不要急著連接真機(jī)而是在模擬器上演練。模擬器環(huán)境下 frida-server 的啟動(dòng)相對(duì)簡(jiǎn)單而且不用擔(dān)心設(shè)備變磚等命令都跑熟了再換到真機(jī)上做完整測(cè)試。注意-g參數(shù)后跟的是包名不是應(yīng)用名稱。很多人第一次運(yùn)行時(shí)把 App 的名字敲進(jìn)去了結(jié)果 tool 報(bào)錯(cuò)找不到目標(biāo)進(jìn)程。3. 核心命令模塊從內(nèi)存搜索到方法鉤子進(jìn)入 explore 交互環(huán)境之后objection 能做的事情就非常多了。我按實(shí)際使用頻率把最核心的功能分成幾個(gè)模塊逐一說(shuō)明。3.1 內(nèi)存搜索與字符串掃描拿到一個(gè)應(yīng)用我最先做的事永遠(yuǎn)是字符串掃描。應(yīng)用里的敏感信息往往直接以字符串形式存在內(nèi)存中比如加密密鑰、API Token、硬編碼的密碼等。memory search api_key這條命令會(huì)在整個(gè)進(jìn)程的堆內(nèi)存中搜索包含api_key的字符串。objection 返回的結(jié)果會(huì)帶上地址和對(duì)應(yīng)的內(nèi)存區(qū)域類型。搜索到目標(biāo)字符串之后可以用memory read來(lái)讀取對(duì)應(yīng)地址附近的內(nèi)容看看到底存了什么。內(nèi)存搜索模塊有一個(gè)細(xì)節(jié)經(jīng)常被忽略——默認(rèn)搜索的是當(dāng)前進(jìn)程的堆區(qū)也就是 Java 層和 Native 層動(dòng)態(tài)分配的內(nèi)存。理論上你可以通過(guò)memory list modules先看進(jìn)程加載了哪些 so 庫(kù)再用memory search在特定模塊的內(nèi)存范圍內(nèi)搜索但這樣的操作對(duì)工具使用者來(lái)說(shuō)要求比較高需要先搞清楚目標(biāo)數(shù)據(jù)可能存在于哪個(gè)區(qū)域。以我個(gè)人的實(shí)踐來(lái)看先全局搜一遍字符串再用結(jié)果反推位置比一開(kāi)始就精確鎖定模塊更高效。3.2 類與方法的運(yùn)行時(shí)探測(cè)這是 objection 最常被使用的功能模塊也是它相對(duì)于手寫(xiě) Frida 腳本最大的優(yōu)勢(shì)。android hooking list classes這條命令會(huì)列出當(dāng)前進(jìn)程中所有已加載的類。如果你對(duì)包名有預(yù)期可以直接用搜索過(guò)濾android hooking list classes -s target.package.name拿到類名之后再列出該類下的所有方法android hooking list class_methods target.package.name.MainActivity這兩條命令的底層機(jī)制其實(shí)依賴于 Frida 對(duì) Java 虛擬機(jī)運(yùn)行時(shí)ART的枚舉能力。objection 把 Frida 的枚舉 API 封裝成了一條條命令你不需要寫(xiě) JavaScript 代碼去遍歷只需要學(xué)會(huì)命令參數(shù)即可。這里有個(gè)比較關(guān)鍵的點(diǎn)list classes列出的類是當(dāng)前時(shí)刻已經(jīng)加載的類不是應(yīng)用 DEX 文件里的所有類。如果一個(gè)類還沒(méi)被創(chuàng)建實(shí)例或被反射調(diào)用它可能不在列表里。所以當(dāng)你發(fā)現(xiàn)某個(gè)目標(biāo)類搜不到時(shí)別急著懷疑命令寫(xiě)錯(cuò)了先在應(yīng)用里多點(diǎn)擊幾個(gè)功能讓更多代碼路徑被執(zhí)行然后再重新枚舉。3.3 動(dòng)態(tài)調(diào)用與 hook 方法類和方法找出來(lái)之后下一步通常是 hook 它、觀察它的調(diào)用時(shí)機(jī)或者干脆直接調(diào)用它。android hooking watch class_method target.package.name.Utils.getKey --dump-args --dump-return這條命令會(huì) hook 指定方法的進(jìn)入和返回打印參數(shù)和返回值。當(dāng)你覺(jué)得某個(gè)方法會(huì)在特定操作中被調(diào)用時(shí)這個(gè)方法非常直觀執(zhí)行一下目標(biāo)操作控制臺(tái)直接打印出入?yún)?、返回值和調(diào)用棧。還有android hooking set method系列命令用于替換方法實(shí)現(xiàn)。它的原理本質(zhì)上就是 Frida 的Java.perform配合overload和implementation屬性只是換成了命令行交互。android hooking set return_value true target.package.name.Utils.isRooted這條命令我?guī)缀趺看味紩?huì)用到尤其是有 root 檢測(cè)邏輯的應(yīng)用。它直接把方法的返回值改成 true 或者 false不需要寫(xiě)任何 hook 代碼。提示如果要 hook 的方法存在多個(gè)重載版本objection 會(huì)提示你指定參數(shù)類型。你可以先用list class_methods查看方法簽名再按--class-loader參數(shù)配好重載類型。3.4 SSL Pinning 繞過(guò)移動(dòng)應(yīng)用測(cè)試中被提到最多的需求應(yīng)該就是 SSL Pinning 繞過(guò)了。很多應(yīng)用使用了證書(shū)校驗(yàn)導(dǎo)致抓包工具看到的全是加密流量。objection 提供了一條相當(dāng)經(jīng)典的命令android sslpinning disable這條命令會(huì)嘗試?yán)@過(guò)應(yīng)用中常見(jiàn)的證書(shū)鎖定邏輯。它的實(shí)現(xiàn)原理是動(dòng)態(tài)替換系統(tǒng)網(wǎng)絡(luò)棧中的驗(yàn)證邏輯比如把 OkHttp 的CertificatePinner、TrustManager 的驗(yàn)證方法等替換為不做校驗(yàn)的實(shí)現(xiàn)版本。但這里有兩點(diǎn)必須提醒第一sslpinning disable不是萬(wàn)能的。它主要覆蓋常見(jiàn)的開(kāi)源網(wǎng)絡(luò)庫(kù)和系統(tǒng)默認(rèn)的網(wǎng)絡(luò)棧如果應(yīng)用內(nèi)部實(shí)現(xiàn)了自定義的證書(shū)校驗(yàn)協(xié)議比如私有協(xié)議加密后做簽名校驗(yàn)這條命令就失效了還是得回到 Frida 腳本針對(duì)具體函數(shù)下手。第二如果應(yīng)用使用了 native 層的證書(shū)校驗(yàn)比如通過(guò) JNI 調(diào)用 C/C 代碼做證書(shū)綁定Java 層的 hook 方式可能完全不起作用。遇到這種情況需要配合android hooking list activities等命令先定位到具體的網(wǎng)絡(luò)模塊再分析它的 native 校驗(yàn)邏輯。3.5 活動(dòng)與服務(wù)組件操作在處理一些需要深鏈路跳轉(zhuǎn)的測(cè)試場(chǎng)景時(shí)直接調(diào)用 Activity 比手動(dòng)操作 UI 高效得多。android activity start -c target.package.name.DeepLinkActivity這條命令可以啟動(dòng)任意 Activity前提是它沒(méi)有被系統(tǒng)限制比如需要特殊權(quán)限才能啟動(dòng)的組件。還有android activity hooking系列命令用于監(jiān)控 Activity 的生命周期回調(diào)。類似的還有android service系列和android broadcast系列可以枚舉和操作服務(wù)與廣播接收器。這些能力從底層看都是利用 Frida 對(duì) Java 層組件的反射調(diào)用objection 只不過(guò)把常用的啟動(dòng)、枚舉、監(jiān)控封裝成了命令行指令幫你省去了大量重復(fù)腳本編寫(xiě)的時(shí)間。4. 運(yùn)行環(huán)境偽裝與安全檢測(cè)對(duì)抗4.1 root 檢測(cè)與模擬器檢測(cè)的繞過(guò)很多應(yīng)用會(huì)在啟動(dòng)階段檢測(cè)運(yùn)行環(huán)境是否被 root 或者是否運(yùn)行在模擬器上一旦檢測(cè)到就直接退出或限制功能。做動(dòng)態(tài)測(cè)試時(shí)這種檢測(cè)會(huì)極大阻礙分析進(jìn)度。objection 提供了環(huán)境偽裝相關(guān)的功能模塊核心命令是android root simulation這條命令的邏輯是對(duì)常見(jiàn)的 root 檢測(cè)點(diǎn)返回假數(shù)據(jù)讓?xiě)?yīng)用認(rèn)為當(dāng)前設(shè)備沒(méi)有 root。類似地android emulator detection相關(guān)命令用于模擬器檢測(cè)的繞過(guò)。但說(shuō)實(shí)話這些統(tǒng)一條命令的實(shí)際效果取決于應(yīng)用時(shí)是怎么寫(xiě)的檢測(cè)邏輯。如果只是檢查Build.TAGS字段或嘗試su文件的路徑這些模擬手段通常有效但如果應(yīng)用在 native 層自己做了文件枚舉或使用了一些比較偏門(mén)的檢測(cè) API單純靠默認(rèn)的模擬命令是不夠的。我的建議是把 objection 自帶的偽裝命令當(dāng)成第一層防線跑完檢測(cè)看應(yīng)用反應(yīng)如果仍然被檢測(cè)到再用android hooking watch class_method去定位具體的檢測(cè)函數(shù)觀察調(diào)用時(shí)機(jī)然后針對(duì)性地做返回值替換。4.2 文件操作與二進(jìn)制導(dǎo)出運(yùn)行時(shí)測(cè)試經(jīng)常會(huì)遇到需要從應(yīng)用私有目錄中提取文件的情況。objection 提供了文件操作模塊file cd /data/data/target.package.name file cat shared_prefs/target.xml file download /data/data/target.package.name/files/test.db /tmp/test.db這三條命令分別對(duì)應(yīng)切換目錄、查看文件內(nèi)容、導(dǎo)出文件到本地。對(duì)測(cè)試最有用的是file download它能直接把應(yīng)用私有目錄下的數(shù)據(jù)庫(kù)、配置文件、緩存文件拉回 PC方便離線分析。這里有一個(gè)安全邊界的理解問(wèn)題objection 之所以能讀取應(yīng)用私有目錄是因?yàn)?Frida 注入的進(jìn)程擁有應(yīng)用本身的 UID 權(quán)限。所以你能讀到的范圍和 App 自身?yè)碛械臋?quán)限一致不能越權(quán)訪問(wèn)其他應(yīng)用的數(shù)據(jù)。這個(gè)概念想清楚就不會(huì)對(duì)著file cat /data/data/other.package/...的報(bào)錯(cuò)一頭霧水了。4.3 敏感信息快速篩查排查 Logcat 日志和剪貼板數(shù)據(jù)是快速發(fā)現(xiàn)敏感泄露的手段之一。android heap search strings android keystore listheap search strings會(huì)遍歷 Java 堆上的字符串對(duì)象輸出所有可讀的字符串常量敏感信息很容易混在里面。比如某個(gè)應(yīng)用在內(nèi)存里拼接 Token 或銀行卡號(hào)這條命令往往能直接撈到。android keystore list則是查看應(yīng)用在 Android Keystore 里存儲(chǔ)的密鑰條目。它不能直接導(dǎo)出私鑰Android Keystore 在硬件級(jí)別保護(hù)私鑰但至少能確認(rèn)應(yīng)用使用了哪些別名和密鑰類型對(duì)于分析密鑰管理流程很有參考價(jià)值。5. 多包聯(lián)動(dòng)與 Frida 腳本的協(xié)作模式5.1 在 objection 中加載自定義腳本objection 滿足不了 100% 的需求尤其是面對(duì)混淆嚴(yán)重的代碼或者私有協(xié)議時(shí)還是離不開(kāi)自定義 Frida 腳本。好消息是 objection 支持加載額外的自定義腳本frida script load /tmp/my_custom_hook.js你可以在交互環(huán)境中動(dòng)態(tài)加載一個(gè)寫(xiě)好的 Frida 腳本它會(huì)在目標(biāo)進(jìn)程里立刻執(zhí)行后續(xù)輸出會(huì)與 objection 的命令行輸出混在一起方便你在同一會(huì)話里同時(shí)使用兩種工具。以我的經(jīng)驗(yàn)推薦的協(xié)作模式是先用 objection 的自動(dòng)化命令做快速偵察明確目標(biāo)方法和調(diào)用邏輯再用 Frida 腳本做精細(xì)化 hook處理混淆函數(shù)、native 層邏輯等 objection 覆蓋不到的場(chǎng)景。兩者的關(guān)系是互補(bǔ)的不是替代的。5.2 多應(yīng)用同時(shí)調(diào)試日常工作中偶爾會(huì)遇到需要同時(shí)分析多個(gè)協(xié)作進(jìn)程的情況。objection 支持-p參數(shù)附加多個(gè)進(jìn)程但實(shí)際操作時(shí)要注意每個(gè) objection 會(huì)話占用一個(gè)終端窗口否則輸出會(huì)互相干擾。多開(kāi)時(shí)建議給每個(gè)會(huì)話打標(biāo)簽區(qū)分objection -p 10001 explore objection -p 10002 explore兩條命令分別開(kāi)兩個(gè)終端即可。從底層來(lái)看每個(gè)會(huì)話都是獨(dú)立的 Frida RPC 通道互相之間沒(méi)有數(shù)據(jù)共享但如果你能理解應(yīng)用之間通過(guò) Binder 或 Socket 的交互邏輯多開(kāi)會(huì)話交叉觀察就能拼出完整的調(diào)用鏈條。6. 一個(gè)典型的實(shí)操排查過(guò)程從定位方法到繞過(guò)檢測(cè)為了把這些命令串起來(lái)我拿一個(gè)模擬的真實(shí)場(chǎng)景走一遍流程幫大家建立完整的操作手感。假設(shè)目標(biāo)應(yīng)用包名是com.example.demo它在啟動(dòng)時(shí)檢測(cè) root檢測(cè)到就退出。第一步附加或啟動(dòng)進(jìn)程進(jìn)入 explore 環(huán)境objection -g com.example.demo explore第二步觀察應(yīng)用行為確認(rèn)它在啟動(dòng)時(shí)直接退出了。此時(shí)我們不確定它用的是哪個(gè)檢測(cè)函數(shù)先枚舉一下與 root 相關(guān)的類android hooking list classes -s root返回結(jié)果里有幾個(gè)可疑的類包括一個(gè)名為com.example.demo.security.SecurityChecker的類。緊接著列出這個(gè)類的方法android hooking list class_methods com.example.demo.security.SecurityChecker可以看到它有一個(gè)isRooted()方法很好那就不用做粗粒度的全盤(pán) hook 了直接針對(duì)這個(gè)方法的返回值下手android hooking set return_value false com.example.demo.security.SecurityChecker.isRooted重新觸發(fā)應(yīng)用的檢測(cè)邏輯觀察是否還能正常進(jìn)入主界面。如果仍然被攔截說(shuō)明還有其他檢測(cè)點(diǎn)繼續(xù)用list classes -s root擴(kuò)大搜索范圍或者用android hooking watch class_method監(jiān)控整個(gè)包的類加載動(dòng)向看它在啟動(dòng)階段到底執(zhí)行了哪些方法。第三步解決完 root 檢測(cè)后用同樣的思路檢查它有沒(méi)有做 SSL Pinningandroid sslpinning disable然后開(kāi) Charles 或 Burp 抓包驗(yàn)證 HTTPS 流量是否可以正常解密查看。這個(gè)流程不算復(fù)雜但它是真實(shí)測(cè)試中最常見(jiàn)的一條主線。掌握這條思路之后很多問(wèn)題都能用類似方法逐步分解掉而不是一頭扎進(jìn)源碼里從零開(kāi)始逆向。7. 實(shí)戰(zhàn)中容易栽的六個(gè)具體問(wèn)題7.1 注入后應(yīng)用崩潰多半是進(jìn)程啟動(dòng)方式不對(duì)使用-g參數(shù)冷啟動(dòng)注入時(shí)如果應(yīng)用自身具有反調(diào)試或 anti-Frida 機(jī)制注入過(guò)程可能被檢測(cè)到導(dǎo)致啟動(dòng)即崩潰。優(yōu)先嘗試附加方式-p也就是先手動(dòng)打開(kāi)應(yīng)用再附加到進(jìn)程。另外檢查應(yīng)用是否有越獄檢測(cè)、Frida 檢測(cè)相關(guān)的代碼路徑如有需要先用環(huán)境偽裝命令處理再注入。7.2 命令執(zhí)行超時(shí)未必是命令錯(cuò)了超時(shí)最常見(jiàn)的原因是進(jìn)程內(nèi)大量類和對(duì)象導(dǎo)致枚舉緩慢尤其是在復(fù)雜的商業(yè) App 中l(wèi)ist classes可能要好幾分鐘。這不算 bug耐心等即可。如果長(zhǎng)時(shí)間無(wú)響應(yīng)還可以用android hooking list activities觀察是否只是某個(gè)功能模塊在阻塞主線程。7.3 抓包失敗確定是 Pinning 還是在 native 層加密sslpinning disable之后抓包還是亂碼先確認(rèn)流量是否走了 SO 層的自定義加密。最直接的驗(yàn)證方式是抓取明文特征比如搜索 HTTP 頭、JSON key 等關(guān)鍵字如果這些關(guān)鍵字也存在且加密說(shuō)明應(yīng)用做了自定義加密封裝和 Pinning 就沒(méi)有關(guān)系了。7.4 文件傳輸失敗檢查寫(xiě)權(quán)限file download導(dǎo)出文件時(shí)目標(biāo)路徑必須擁有當(dāng)前用戶寫(xiě)權(quán)限。如果 PC 端路徑選了一個(gè)沒(méi)有權(quán)限創(chuàng)建的目錄命令會(huì)直接失敗。更常見(jiàn)的失敗原因是應(yīng)用目標(biāo)文件本身被占用或權(quán)限受限比如某些數(shù)據(jù)庫(kù)文件只能由應(yīng)用自身讀寫(xiě)這時(shí)候先在應(yīng)用內(nèi)觸發(fā)一次關(guān)閉數(shù)據(jù)庫(kù)連接再導(dǎo)出。7.5 自動(dòng)化命令覆蓋不了的高混淆代碼有些應(yīng)用做了字符串混淆和類名混淆list class_methods看到的方法名可能完全沒(méi)有意義。這種情況下objection 的自動(dòng)化命令只是輔助定位的作用真正要突破的是通過(guò) Frida 腳本精確指定內(nèi)存地址來(lái) hook 函數(shù)或通過(guò)android hooking watch class_method觀察調(diào)用時(shí)附帶的參數(shù)特征反推邏輯。7.6 模擬器和真機(jī)的行為差異模擬器上的測(cè)試結(jié)果不能代表真機(jī)這個(gè)坑我反復(fù)踩過(guò)。很多應(yīng)用對(duì)模擬器的檢測(cè)比對(duì) root 的檢測(cè)更嚴(yán)格特別是在系統(tǒng)屬性、硬件信息、傳感器數(shù)據(jù)等維度。如果你想在模擬器上跑 objection遇到環(huán)境檢測(cè)嚴(yán)格的應(yīng)用時(shí)優(yōu)先排查模擬器指紋其次才是 root 狀態(tài)。8. 進(jìn)階使用思路objection 在自動(dòng)化巡檢里的位置objection 除了在單次測(cè)試中發(fā)揮作用也可以嵌入到自動(dòng)化的安全巡檢流程里。比如在 CI 環(huán)境里準(zhǔn)備一個(gè)測(cè)試機(jī)每次構(gòu)建出新包后自動(dòng)安裝、自動(dòng)進(jìn)入 explore、自動(dòng)執(zhí)行一組固定的檢查命令枚舉敏感字符串、列出允許導(dǎo)出的組件、檢測(cè)風(fēng)險(xiǎn)方法等從而形成輕量級(jí)的基線巡檢。這個(gè)思路的核心不是讓它替代專業(yè)掃描器而是給測(cè)試團(tuán)隊(duì)提供一個(gè)可以快速執(zhí)行的運(yùn)行時(shí)檢查通道。巡檢結(jié)果輸出為文本日志再配合解析腳本可以自動(dòng)把風(fēng)險(xiǎn)項(xiàng)匯總到工單里。我實(shí)際落地過(guò)一套這樣的流程檢查項(xiàng)大約 20 條執(zhí)行時(shí)間約三分鐘對(duì)于發(fā)布前的快速反饋來(lái)說(shuō)性價(jià)比很高。如果后續(xù)有興趣我還可以寫(xiě)一篇專門(mén)講 objection 配合 CI 做自動(dòng)化巡檢的文章把命令封裝、結(jié)果解析、風(fēng)險(xiǎn)閾值判定這些細(xì)節(jié)都展開(kāi)講清楚。