安卓動態調試七種武器之長生劍 - Smali Instrumentation

来源:http://www.cnblogs.com/alisecurity/archive/2016/05/25/5526811.html
-Advertisement-
Play Games

安卓動態調試七種武器之長生劍 - Smali Instrumentation 作者:蒸米@阿裡聚安全 0x00 序 隨著移動安全越來越火,各種調試工具也都層出不窮,但因為環境和需求的不同,並沒有工具是萬能的。另外工具是死的,人是活的,如果能搞懂工具的原理再結合上自身的經驗,你也可以創造出屬於自己的調 ...


安卓動態調試七種武器之長生劍 - Smali Instrumentation

作者:蒸米@阿裡聚安全

 

0x00 序

隨著移動安全越來越火,各種調試工具也都層出不窮,但因為環境和需求的不同,並沒有工具是萬能的。另外工具是死的,人是活的,如果能搞懂工具的原理再結合上自身的經驗,你也可以創造出屬於自己的調試武器。因此,筆者將會在這一系列文章中(共7篇)分享一些自己經常用或原創的調試工具以及手段,希望能對國內移動安全的研究起到一些催化劑的作用。

 

0x01 長生劍

長生劍是把神奇的劍,為白玉京所配,劍名取意來自於李白的詩:“仙人撫我頂,結髮受長生。”長生劍是七種武器系列的第一種武器,而筆者接下來所要介紹的調試方法也是我最早學習的調試方法,並且這種方法就像長生劍一樣,簡單並一直都有很好的效果。這種方法就是Smali Instrumentation,又稱Smali插樁。使用這種方法最大的好處就是不需要對手機進行root,不需要指定android的版本,如果結合一些tricks的話還會有意想不到的效果。

 

0x02 Smali/baksmali

做安卓逆向最先接觸到的東西肯定就是smali語言了,smali最早是由Jasmin提出,隨後jesusfreke開發了最有名的smali和baksmali工具將其發揚光大,幾乎dex上所有的靜態分析工具都是在這個項目的基礎上建立的。什麼?你沒聽說過smali和baksmali?你只用過Apktool?如果你仔細閱讀了Apktool官網的說明你就會發現,Apktool其實只是一個將各種工具結合起來的懶人工具而已。並且筆者建議從現在起就拋棄Apktool吧。原因如下:首先,Apktool更新並沒有smali/baksmali頻繁,smali/baksmali更新後要過非長久的時間才會合併到Apktool中,在這之前你可能需要忍受很多詭異的bug。其次,Apktool在反編譯或者重打包dex的時候,如果發生錯誤,僅僅只會提供錯誤的exception信息而已,但如果你使用smali/baksmali,工具會告訴你具體的出錯原因,會對重打包後的調試有巨大的幫助。最後,很多apk為了對付反調試會在資源文件中加入很多junk code從而使得Apktool的解析崩潰掉,造成反編譯失敗或者無法重打包。但如果你僅對classes.dex操作就不會有這些問題了。

學習smali最好的方法就是自己先用java寫好程式,再用baksmali轉換成smali語句,然後對照學習。比如下麵就是java代碼和用baksmali反編譯過後的smali文件的對照分析。

MZLog類主要是用Log.d()輸出調試信息,Java代碼如下:

 

對應的smali代碼如下:

 

最後簡單介紹一下smali常用的數據類型:

 

0x03 Smali插樁

如果僅僅用Smali來分析代碼,效果其實不如用dex2jar和jd-gui更直觀,畢竟看反編譯的java代碼要更容易一些。但Smali強大之處就是可以隨心所欲的進行插樁操作。何為插樁,引用一下wiki的解釋:程式插樁,最早是由J.C. Huang 教授提出的,它是在保證被測程式原有邏輯完整性的基礎上在程式中插入一些探針(又稱為“探測儀”),通過探針的執行並拋出程式運行的特征數據,通過對這些數據的分析,可以獲得程式的控制流和數據流信息,進而得到邏輯覆蓋等動態信息,從而實現測試目的的方法。下麵我就來結合一個例子來講解一下何如進行smali插樁。

 

測試程式是一個簡單的crackme (圖1)。輸入密碼,然後點擊check,如果密碼正確會輸出yes,否則輸出no。

圖1 Crackme1的界面

 

首先我們對crackme這個apk進行解壓,然後反編譯。我們會在MainActivity中看到一個getkey(String,int)函數。這個函數貌似非常複雜,我們暫時不管。我們首先分析一下點下button後的邏輯。我們發現程式會通過getkey("mrkxqcroxqtskx",42)來計算出真正的密碼,然後與我們輸人的密碼進行比較,java代碼如下:

 

 

這時候就是smali插樁大顯身手的時候了,我們可以通過插樁直接獲取getkey("mrkxqcroxqtskx",42)這個函數的返回值,然後Log出來。這樣我們就不需要研究getkey這個函數的實現了。具體過程如下:

1 首先解壓apk然後用baksmali進行反編譯。

 

2 將上一節MZLog類的MZLog.smali文件拷貝到com/mzheng目錄下,這個文件有3個LOG函數,分別可以輸出String的值,Object的值和Object數組的值。註意,如果原程式中沒有com/mzheng這個目錄,你需要自己用mkdir創建一下。拷貝完後,目錄結構如下:

 

3 用文本編輯器打開MainActivity$1.smali文件進行插樁。為什麼是MainActivity$1.smali而不是MainActivity.smali呢?因為主要的判斷邏輯是在OnClickListener這個類里,而這個類是MainActivity的一個內部類,同時我們在實現的時候也沒有給這個類聲明具體的名字,所以這個類用$1表示。加入MZLog.smali這個文件後,我們只需要在MainActivity$1.smali的第71行後面加上一行代碼,invoke-static {v1}, Lcom/mzheng/MZLog;->Log(Ljava/lang/Object;)V,就可以輸出getkey的值了。Invoke是方法調用的指令,因為我們要調用的類是靜態方法,所以使用invoke-static。如果是非靜態方法的話,第一個參數應該是該方法的實例,然後依次是各個參數。具體插入情況如下:

 

4 用smali.jar重新編譯修改後的smali文件,把新編譯的classes.dex覆蓋老的classes.dex,然後再用signapk.jar對apk進行簽名。幾條關鍵指令如下:

 

5 安裝程式到android,隨便輸入點啥,然後點擊check按鈕,隨後在logcat中就可以看到getkey("mrkxqcroxqtskx",42)這個函數的返回值了(圖2)。

enter image description here

圖2 通過logcat獲取getkey的返回值

 

0x03 Smali修改

通過Smali/baksmali工具,我們不光可以插樁,還可以修改apk的邏輯。幾個需要註意點如下:

 

1. if條件判斷以及跳轉語句

在smali中最常見的就是if這個條件判斷跳轉語句了,這個判斷一共有12條指令:

 

 

比如我們在crackme1里判斷密碼是否正確的smali代碼段:

 

如果我們不關心密碼內容,只是希望程式輸出”yes”的話。我們可以把if-eqz v1, :cond_25改成if-nez v1, :cond_25。這樣邏輯就變為:當輸錯密碼的時候,程式反而會輸出”yes”。

 

2. 寄存器問題

修改Smali時有一件很重要的事情就是要註意寄存器。如果亂用寄存器的話可能會導致程式崩潰。每個方法開頭聲明瞭registers的數量,這個數量是參數和本地變數總和。參數統一用P表示。如果是非靜態方法p0代表this,p1-pN代表各個參數。如果是靜態方法的話,p0-pN代表各個參數。本地變數統一用v表示。如果想要增加的新的本地變數,需要在方法開頭的registers數量上增加相應的數值。

比如下麵這個方法:

 

因為這不是靜態方法,所以p0代表this。如果想要增加一個新的本地變數,比如v0。就需要把.registers 1改為.registers 2。

 

3. 給原程式增加大量邏輯的辦法

我非常不建議在程式原有的方法上增加大量邏輯,這樣可能會出現很多寄存器方面的錯誤導致編譯失敗。比較好的方法是:把想要增加的邏輯先用java寫成一個apk,然後把這個apk反編譯成smali文件,隨後把反編譯後的這部分邏輯的smali文件插入到目標程式的smali文件夾中,然後再在原來的方法上採用invoke的方式調用新加入的邏輯。這樣的話不管加入再多的邏輯,也只是修改了原程式的幾行代碼而已。這個思路也是很多重打包病毒慣用的伎倆,確實非常方便好用。

 

0x04 APK簽名Tricks

當我們在實戰中,有時會碰到某些apk在內部實現了自己的簽名檢查。這次我們介紹的Smali Instrumentation方法因為需要重打包,所以會改變原有的簽名。當然,你可以通過修改apk把簽名檢查的邏輯刪掉,但這又費時又費力。筆者在這裡簡單介紹兩種非常方便的方法來解決簽名檢查問題。

 

1. Masterkey

Masterkey漏洞一共有三個,可以影響android 4.4以下版本。利用這個漏洞,我們可以插入新的classes.dex替換掉原有的classes.dex而不需要對apk本身進行重新簽名。如果apk本身有簽名校驗邏輯的話,利用這個漏洞來進行Smali Instrumentation簡直再好不過了。首先,你需要一個android 4.4以下版本的虛擬機或者真機,然後再使用一個masterkey利用工具對apk進行exploit即可。工具下載地址在文章最後,使用的命令如下:

 

orig.apk是原本的apk文件,moddedClassesDex.zip是修改後的classes.dex並壓縮成zip文件,out.apk就是利用Masterkey漏洞生成的新的apk文件。如果成功的話用rar打開文件會看到兩個classes.dex。

enter image description here

圖3 Masterkey生成的apk文件有兩個classes.dex文件

通過masterkey打包後的apk文件簽名並不會有任何變化,這樣也就不用擔心簽名校驗問題了。

 

2. 自定義ROM

簽名的判斷其實是調用了android系統密碼庫的函數,如果我們可以自己定製ROM的話,只需要修改AOSP源碼路徑下的libcore\luni\src\main\java\java\security\MessageDigest.java文件。將isEqual函數中的判斷語句註釋掉:

 

這樣的話,如果在你自定義的ROM上運行apk,無論你怎麼修改classes.dex文件,都不需要關心簽名問題了,系統會永遠返回簽名正確的。

 

0x05 小結

雖然現在越來越多的apk開始使用so文件進行邏輯處理和加固,android 4.4也加入art運行環境,但dalvik永遠是android最經典的東西。如果想要學好android逆向,一定要把這部分知識學好。並且把smali研究透徹以後,會對我們以後要講的自定義dalvik虛擬機有很大幫助。另外文章中所有提到的代碼和工具都可以在我的github下載到,地址是: https://github.com/zhengmin1989/TheSevenWeapons

 

0x06 參考文章

Way of the AndroidCracker http://androidcracking.blogspot.hk/p/way-of-android-cracker-lessons.html

Android Master Key Exploit – Uncovering Android Master Key

https://bluebox.com/technical/uncovering-android-master-key-that-makes-99-of-devices-vulnerable/

https://github.com/Fuzion24/AndroidZipArbitrage

Min Zheng, Patrick P. C. Lee, John C. S. Lui. "ADAM: An Automatic and Extensible Platform to Stress Test Android Anti-Virus Systems", DIMVA 2012

 

作者:蒸米@阿裡聚安全,更多安全技術文章,請訪問阿裡聚安全博客


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

-Advertisement-
Play Games
更多相關文章
  • 地圖篇-03.展示地圖 這一小節是地圖展示,在這一小節要接觸到一個框架:MapKit 1.展示地圖 展示地圖特別簡單,就是調用系統的地圖,有兩種方式,直接上代碼 第一種方式: 導入頭文件 #import <MapKit/MapKit.h> 然後輸入以下代碼: 運行可見: 細心的朋友能開到地圖右下角有 ...
  • Swift數組 OC和Swift數組的比較 OC 只能存放對象 swift 既可以存放對象,又可以存Int,Float等基本數據類型 下麵是swift數組的具體示範 空數組 let arr = [] let arr2 = "Int" let arr3 = Array() 有值數組 let arr4 ...
  • 轉載博客:http://blog.csdn.net/walker02/article/details/8211628 項目開發中遇到的一個問題,對於三星手機在做手機照片選擇時出現圖片顯示不正常,研究後發現應該是手機拍攝的圖片旋轉90度,有的圖片旋轉了180度,有的手機是正常的。在論壇里發現的一個方法 ...
  • 轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/37992017 類似與Android系統為Activity維護一個任務棧,我們也可以通過Activity維護一個回退棧來保存每次Fragment事務發生的變化。如果你將Fragmen ...
  • 存到nsuesrDefault裡面一個可變字典,然後用一個可變字典去接收。 NSMutableDictionary *dic = [[NSUserDefaults standardUserDefaults]valueForKey:@"name"]; 但是你再其賦值的時候 [dic setValue: ...
  • 昨天,花了點時間,把自己的代碼做成framework,但是發現,每次遷移項目或者更新項目都是一件很頭疼的事情,索性,也跟著時尚了一回,把所有代碼都扔到git裡面進行管理,通過cococapods直接安裝即可,下麵是已經創建完.podspec文件後,需要做的步驟: 1.本地測試是否正常 2.git 上 ...
  • 即彈出Tag為CreateOneFragment之上的所有(包括自身)的Fragment。 popBackStackImmediate(name,flag); 第二個參數:只能是 0 或者 1(POP_BACK_STACK_INCLUSIVE); 第一個參數為null時, 第二個參數為0時: 會彈出 ...
  • 每次都逼我翻代碼 這次乾脆寫博客裡面算了 哈哈哈 CGSize maxSize = CGSizeMake(ScreenWith-30,NSIntegerMax); CGSize labelsize = [addressContentLabel.text boundingRectWithSize:ma ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...