天天看點

Android APP動态調試的三種Smali注入小技巧

作者:橙留香Park

也許每個人出生的時候都以為這世界都是為他一個人而存在的,當他發現自己錯的時候,他便開始長大

少走了彎路,也就錯過了風景,無論如何,感謝經曆

本篇文章遇到排版混亂的地方,可點選文末閱讀原文或前往該位址:https://orangey.blog.csdn.net/article/details/126219891

更多關于Android安全的知識,可前往:https://blog.csdn.net/ananasorangey/category11955914.html

Android APP動态調試的三種Smali注入小技巧

0x01 前言

動态調試是在沒有軟體源代碼的情況下,通過調試程式來跟蹤分析彙編代碼,檢視寄存器的值,了解軟體的執行流程,回報程式執行時的中間結果

動态調試一般與靜态分析結合使用,尤其是在靜态分析難以取得突破時,需要使用動态調試進行輔助分析。主流調試工具包括DDMS、IDA Pro、AndBug、gdb等,主要涉及兩種調試方法:

  • 通過方法跟蹤的方式,對Android SDK開發的Java層程式進行動态調試
  • 通過附加程序的方式,對Android NDK開發的原生動态連結庫進行調試

1.2 動态分析技巧

列印Log法:

  • 設定應用可調試
  • 插入Log
  • 回編譯并安裝運作
  • 檢視Log資訊

棧跟蹤法:

  • 在關鍵位置插入代碼
  • logcat中檢視資訊

Method Profiling:

  • 運作Device Monitor
  • 監控方法

UI檢視:

  • adb指令檢視
  • Device Monitor檢視

1.2.1 資訊回報法( 資源id / 字元串 )

所謂資訊回報法,是指先運作目标程式,然後根據程式運作時給出的回報資訊作為突破口尋找關鍵代碼。例如運作目标程式并輸入錯誤的注冊碼時,會彈出提示“無效使用者名或注冊碼”,這就是程式回報給我們的資訊。通常情況下,程式中用到的字元串會存儲在String.xml檔案或者寫死到程式代碼中,如果是前者的話,字元串在程式中會以id 的形式通路,隻需在反彙編代碼中搜尋字元串的id 值即可找到調用代碼處;如果是後者的話,在反彙編代碼中直接搜尋字元串即可。

如果想快速找到某一個按鈕或者某個界面的相關代碼,即仍舊是找到ID值,再通過JEB等工具進行查找,那麼如何找到id值,這裡可以使用工具uiautomatorviewer.bat(SDK)

通俗的來說就是,根據程式正常運作的提示資訊進行定位,例如:錯誤提示,運作提示等等。可以在程式中直接搜尋字元串,當提示資訊在 String.xml 資源檔案中的時候,可以根據 R.java 的映射檔案,查找對應的資源id,然後在 smali 或者在 ida 視窗中進行搜尋

1.2.2 特征函數法( api 函數 )

這種定位代碼的方法與資訊回報法類似。在資訊回報法中,無論程式給出什麼樣的回報資訊,終究是需要調用Android SDK 中提供的相關API 函數來完成的。比如,彈出注冊碼錯誤的提示資訊就需要調用Toast.MakeText().Show()方法,在反彙編代碼中直接搜尋Toast應該很快就能定位到調用代碼,如果 Toast在程式中有多處的話,可能需要分析人員逐個甄别

通俗的來說就是,根據程式提示資訊的方法,在對應的 Android 的 API 下斷點,通過 API 來檢索相關的代碼

1.2.3 順序檢視法(分析程式執行流程 / 病毒分析)

順序檢視法是指從軟體的啟動代碼開始,逐行的向下分析,掌握軟體的執行流程,這種分析方法在病毒分析時經常用到

通俗的來說就是,從 AndroidManifest.xml 中找到 主 Activity 界面,然後順序分析代碼,通常在分析病毒軟體時使用。( 通過 UI 進行分析, adb shell dumpsys activity top )

1.2.4 代碼注入法( 動态調試 / 插入log / 檢視logcat / 分析加解密 )

動态調試,又叫插樁,即在關鍵反彙編代碼處插入可以輸出 logcat 調試資訊的代碼

例如,smali代碼注入或者動态修改程式,一般都可歸結為代碼注入

1.2.5 棧跟蹤法( 動态調試 / 函數調用流程 )

棧跟蹤法屬于動态調試的方法,原理是輸出運作時棧調用跟蹤資訊,然後檢視函數調用序列來了解方法的執行流程

通俗的來說就是,利用輸出時的棧跟蹤資訊,通過檢視棧上的函數調用序列來了解方法的執行流程

1.2.6 Method Profiling( 動态調試 / 熱點分析 / 函數調用流程 )

Method Profiling 動态調試方法,主要用于熱點分析和性能優化。除了可以記錄每個函數趙勇的CPU時間外,還可以跟蹤所有的函數調用關系,并提供比棧跟蹤法更詳細的函數調用序列報告

Method Profiling 動态調試方法,主要是使用ptrace來進行,相應的有hook等等技術

0x02 工具+環境

常見環境:

  • apktool+eclipse/idea/android studio/netbeans

IDA pro + DDMS 主要用來調試so檔案,當然也可以調試dex檔案

linux環境:

  • andbug/gdb+gdb_server

其他:

  • gikdbg/cygwin+ndk-gdb

Hook技術:

  • Xposed
  • Cydia Substrate
  • Frida
  • 自定義hook

0x03 什麼是Smali注入?

Smali注入又稱Smali插樁(Smali Instrumentation),WIKI解釋:它是在保證被測程式原有邏輯完整性的基礎上在程式中插入一些探針(又稱為“探測儀”),通過探針的執行并抛出程式運作的特征資料,通過對這些資料的分析,可以獲得程式的控制流和資料流資訊,進而得到邏輯覆寫等動态資訊,進而實作測試目的的方法。這幾個詞(保證程式原有邏輯性、插入探針、抛出特征資料)也是samli注入需要關注的幾個關鍵點所在

0x04 什麼是Log類?

SDK提供Android.util.Log 類輸出調試資訊,總共有五種調試方法(v(),d(),i(),w(),e()) ,六種調試狀态(verbose,debug,info,warning,error,assert) 。在插入時可以插入對應的方法進行調試,如果僅是輸出對象的值,可以是v或者d()方法,這裡需要注意,六種調試狀态存在等級之分,依順序排序,高一級的狀态會覆寫低級的狀态,這個如果對java語言比較熟悉的話,可以類比java語言的exception異常類

Android中的日志工具類是Log(android.util.Log),這個類中提供了如下5個方法列印日志:

  • Log.v():調試顔色為黑色的,任何消息都會輸出。用于列印那些最為瑣碎的、意義最小的日志資訊。對應級别verbose,是Android日志裡面級别最低的一種
  • Log.d():輸出顔色是藍色的,僅輸出debug調試的意思,但他會輸出上層的資訊,過濾起來可以通過DDMS的Logcat标簽來選擇。用于列印一些調試資訊,這些資訊對你調試程式和分析問題應該是有幫助的。對應級别debug,比verbose高一級
  • Log.i():輸出為綠色,一般提示性的消息information,它不會輸出Log.v和Log.d的資訊,但會顯示i、w和e的資訊。用于列印一些比較重要的資料,這些資料應該是你非常想看到的、可以幫你分析使用者行為資料。對應級别info,比debug高一級
  • Log.w():輸出為橙色,可以看作為warning警告,一般需要我們注意優化Android代碼,同時選擇它後還會輸出Log.e的資訊。用于列印一些警告資訊,提示程式在這個地方可能會有潛在的風險,最好去修複一下這些出現警告的地方。對應級别warn,比info高一級
  • Log.e():輸出為紅色,可以想到error錯誤,這裡僅顯示紅色的錯誤資訊,這些錯誤就需要我們認真的分析,檢視棧的資訊了。用于列印程式中的錯誤資訊,比如程式進入到了catch語句當中。當有錯誤資訊列印出來的時候,一般都代表你的程式出現嚴重問題了,必須盡快修複。對應級别error,比warn高一級

0x05 插入Log類的動态調試方法

5.1 直接插入

  • 直接在smali代碼插入log類,尋找到需要插入的代碼
  • 缺點:直接插入smali代碼的話,簡單的邏輯可能對寄存器沒有什麼嚴格的要求,如果是複雜的邏輯結構,或者程式本身使用的寄存器比較少,那麼可能沒法使用該方法

5.1.1 Android Studio建立APK demo

  • Android Studio建立一個簡單的項目(Enpty Activity),然後建立一個class,将其命名為MyCrackTest,添加如下代碼
package com.example.mytest;

import android.util.Log;

public class MyCrackTest {
    public static void Logd(String v0){
        Log.d ("hash", "testtest"+v0);
    }
}

           

PS:要用static進行修飾,之後我們反編譯代碼後會在onCreate中進行調用,如下smali:

const-string v0, "The Orangey blog welcomes you!!!-test"

invoke-static {v0}, LMyCrackTest;->Logd(Ljava/lang/String;)V
           

smali對應的java代碼如下:

MyCrackTest.Logl("The Orangey blog welcomes you!!!-test");
           
  • Android Studio打包成APK(自動會簽名),我們先來運作下沒有改動之前的APK,在打開logcat的情況下搜尋hash 這個關鍵字是沒有看到的我們想要的資訊的,接下來我們會在smali插入代碼來達到調用對應輸出資訊的目的
Android APP動态調試的三種Smali注入小技巧
Android APP動态調試的三種Smali注入小技巧

5.1.2 反編譯APK

  • 用apktool将APK進行反編譯,反編譯成功後會得到app-debug 檔案
java -jar apktool.jar d -f app-debug.apk -o app-debug
           

5.1.3 插入smali代碼

  • 進入app-debug檔案的app-debug\smali\com\example\mytest下,将MyCrackTest.smali放到smali根目錄下
Android APP動态調試的三種Smali注入小技巧
Android APP動态調試的三種Smali注入小技巧
  • MyCrackTest.smali 在onCreate 裡面添加調試的smali代碼
Android APP動态調試的三種Smali注入小技巧

5.1.4 回編譯APK并簽名

java -jar apktool_2.6.1.jar b app-debug -o app-debug1.apk
           
java -jar  signapk.jar testkey.x509.pem testkey.pk8 app-debug1.apk app-debug_qm.apk
           
  • 開啟logcat,然後丢到模拟器運作
adb logcat
           

運作結果如下:

Android APP動态調試的三種Smali注入小技巧

5.2 增加寄存器法

  • 一般在方法的前面都會聲明寄存器的個數。例如,隻要增加一個寄存器,即.local 11那麼就可以使用v10寄存器來代替上面的v8寄存器
  • 優點:不需要考慮使用哪個寄存器來做tag,減少了對程式的幹擾
  • 缺點:仍舊對程式産生一定幹擾

案例APK下載下傳:https://www.wandoujia.com/apps/280375/history_v100991744

5.2.1 反編譯APK

将下載下傳好的APK重命名為bd.apk

java -jar apktool.jar d -f bd.apk -o bd
           
Android APP動态調試的三種Smali注入小技巧

打開AndroidManifest.xml檔案,找到App最先啟動的Activity

Android APP動态調試的三種Smali注入小技巧

通過檢視AndroidManifest.xml中的Activity的配置資訊,可以判定LogoActivity就是最先啟動的Activity,也就是後面我們所需要修改的歡迎界面

那麼,如何判斷是否為最先啟動的呢?可以看有沒有如下内容:

<intent-filter>
    <action android:name="android.intent.action.MAIN"/>
    <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
           
# 決定應用的入口Activity,也就是我們啟動應用時首先顯示哪一個Activity
android.intent.action.MAIN

# 表示activity應該被列入系統的啟動器(launcher)(允許使用者啟動它)
# Launcher是安卓系統中的桌面啟動器,是桌面UI的統稱
android.intent.category.LAUNCHER
           

intent-filter 标簽中這兩個值:

  • android.intent.action.MAIN
  • android.intent.category.LAUNCHER

intent-filter 标簽中(MAIN和LAUNCHER)具體作用如下:

  • MAIN指定了應用入口位址
  • LAUNCHER是應用在手機桌面上的圖示
  • 如果隻設定MAIN,沒有設定LAUNCHER,應用可以被安裝到手機,但是在桌面看不到APP的圖示,是以就無法啟動APP
  • 如果隻設定了LAUNCHER,而沒有設定MAIN,系統不知道應用從哪個Activity啟動,是以也就不會在桌面顯示圖示
  • 如果給多個Activity設定了MAIN和LAUNCHER,桌面會顯示多個APP圖示,點選圖示會分别進入設定的Activity中

5.2.2 定位LogoActivity的onCreate方法進行代碼注入

打開\smali\com\baidu\tieba\LogoActivity.smali檔案,定位到onCreate方法

Android APP動态調試的三種Smali注入小技巧
  • 修改onCreate方法中的本地寄存器的個數

為什麼要修改呢?因為smali是基于寄存器的,所有的操作都要經過寄存器,是以在進行smali代碼注入時首先要适當修改寄存器的個數。因為構造和顯示Toast函數至少需要3個寄存器,是以我們應該先将onCreate方法中的.locals值由7修改為10

android.widget.Toast 是android提供的一個用于快顯資訊的類
           
Android APP動态調試的三種Smali注入小技巧
  • 在onCreate方法中注入Toast代碼,需要定位到invoke-super{p0,p1},Lcom/baidu/tbadk/BaseActivity;->onCreate(Landroid/os/Bundle;)V 這條語句後面添加構造和顯示Toast的代碼
invoke-super {p0, p1}, Lcom/baidu/tbadk/BaseActivity;->onCreate(Landroid/os/Bundle;)V
    
const-string v7, "The Orangey blog welcomes you!!!" # 構造toast顯示的字元串 
    
const/4 v8, 0x1   # 構造Toast 的顯示時間,0表示Toast.LENGTH_SHORT;1表示Toast.LENGTH_LONG
    
invoke-static {p0, v7, v8}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; # 調用Toast.makeText方法

move-result-object v9   # 将前面的Toast.makeText方法的傳回值儲存到v9寄存器中

invoke-virtual {v9}, Landroid/widget/Toast;->show()V  # 調用Toast.show方法彈出Toast資訊
           
Android APP動态調試的三種Smali注入小技巧

5.2.3 回編譯APK并簽名

apktool b out -o 3.apk

java -jar apktool.jar b bd -o bd_log1.apk

Android APP動态調試的三種Smali注入小技巧

java -jar .\sign\signapk.jar .\sign\testkey.x509.pem .\sign\testkey.pk8 bd_log1.apk bd_log1_qm.apk

Android APP動态調試的三種Smali注入小技巧
Android APP動态調試的三種Smali注入小技巧

丢到模拟器安裝

Android APP動态調試的三種Smali注入小技巧
Android APP動态調試的三種Smali注入小技巧

5.3 自定義log類

編寫自定義的log類的samli代碼,然後隻要将其放入smali檔案的根目錄檔案夾下,然後,在smali代碼中插入一句調用代碼即可(步驟跟上面說的Android Studio 差不多,隻是多了個編寫log類的APK反編譯後把log類的smali代碼放到我們需要插入log類代碼的APK的smali檔案下)

具體内容,請前往之前寫的文章有介紹:

[免費專欄] Android安全之靜态方式逆向APK應用淺析【手動注入smali+】+【IDA Pro靜态分析so檔案】+【IDA Pro基礎使用講解】:https://orangey.blog.csdn.net/article/details/126219913

參考連結:

https://blog.csdn.net/pengyan0812/article/details/44568147

http://www.tasfa.cn/index.php/2016/05/18/smali-instrumentation/

你以為你有很多路可以選擇,其實你隻有一條路可以走

繼續閱讀