Android逆向中的常用除錯方法和使用程式碼總結
Toast.makeText(this, "Toast text", 1).show();
smail程式碼
const-string v0, "Toast text" const/4 v1, 0x1 invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; move-result-object v0 invoke-virtual {v0}, Landroid/widget/Toast;->show()V
利用Log日誌輸出 java程式碼
Log.v("android_log","test")
smail程式碼
const-string v0, "test"
const-string v3, "android_log"
invoke-static {v3,v0}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
整數轉字串程式碼
invoke-static {v5}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;
move-result-object v5
log日誌檢視方式 DDMS自動logcat AndroidKiller整合的log工具 adb命令檢視:adb logcat -s android_log:v b.棧跟蹤法,原理輸出執行時的棧的跟蹤資訊。然後檢視棧上的函式呼叫序列來理解方法的執行流程。 java程式碼
smail程式碼new Exception("print trace").printStackTrace();
new-instance v0, Ljava/lang/Exception;
const-string v1, "print trace"
invoke-direct {v0,v1}, Ljava/lang/Exception;-><init>(Ljava/lang/String;)V
invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V
檢視方式
利用log日誌輸出資訊
c.Method Profiling同棧分析法,顯示處各個函式的呼叫資訊。
Method Profiling方法
java 程式碼
smai程式碼android.os.Debug.startMethodTracing("123") func(): android.os.Debug.stopMethodTracing():
可以插入OnCreate()方法中
const-string v0, "123"
invoke-static {v0}, Landroid/os/Debug;->startMethodTracing(Ljava/lang/String;)V
插入OnStop()方法
invoke-static {}, Landroid/os/Debug;->stopMethodTracing()V
注入需要加sd寫入許可權
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
檢視方式 利用adb匯出trace檔案
adb pull /mnt/sdcard/123.trace
在sdk下的tools目錄下利用traceview檢視
traceview 123.trace
0x02.arm語言的修改與調式
靜態調式
arm指令的修改,很多工具在對arm彙編指令修改成相應的十六進位制碼的過程中容易出現錯誤,一般需要我們手動分析進行修改。
首先我們看一下mov指令arm編碼指令的一般格式
下面我們詳細解釋各個區段的含義: 28-31段cond: 指令執行的條件編碼,下面是常見的cond條件和對應二進位制碼。
26-27段:一般是00 25段:如果我們的源運算元是立即數,該位置是1,如果是暫存器,改位置為0. 21-24段:表示的是opcode位
20段:是否帶S標誌位,如果不帶該位為0,指令帶S標誌位為1
16-19段:保留位,一般都設定為0000
12-15段:指令中目的暫存器,根據R0-R15對應0-15比如r1對應為0001,R0對應0000
0-11段:指令的運算元,如果為立即數有十進位制轉換為二進位制程式碼即可,如果是暫存器,同R0-R15對應0-15
例如下面兩個指令
指令一 mov r1, #107
對應機器碼
1110 00 1 1101 0 0000 0001 000001101011
對應十六進位制
E3 A0 10 6B
對應十六進位制編輯器中的值
6B 10 A0 E3
指令二 mov r2,r1
對應機器碼
1110 00 0 1 101 0 0000 0010 000000000001
對應十六進位制
E1 A0 20 01
對應十六進位制編輯器中的值
01 20 A0 E1
下面是arm指令的標準格式如下:
常用的跳轉指令B和機器碼直接的轉換
28-31段cond: 指令執行的條件編碼
25-27段:一般是101 24段:是否帶link跳轉,0不帶連結,1帶連結跳轉 0-23段:存放的是要跳轉的相對地址 地址的機器碼計算方式x=((目的地址-源地址)-8)/4pediy上的一個例子:
.text:00637C80 E5 34 42 EB BL __mulsf3
.text:016C501C EXPORT __mulsf3
BL __mulsf3的機器碼為((0x16C501C-0x637C80)-8)/4=4234E5
BL為帶連線無條件跳轉機器碼為1110 1011 對應16進製為EB故BL __mulsf3對應的機器碼為EB4234E5,在十六進位制編輯器中顯示的情況就是E5 34 42 EB。也就是第一條之類中間的機器碼相同。
動態除錯
利用IDA動態除錯方法(來自:Android軟體安全與逆向分析)
除錯原生程式
1.動態除錯一般的Android原生程式
例項程式:debugnativeapp
在Android裝置中新增、配置android_server程式
先將IDA目錄下的./dbgsrv/android_server程式拷貝到Android裝置下:
adb push ./dbgsrv/android_server /data/local/tmp/
配置檔案許可權屬性,使其為可執行檔案:
adb shell chmod 755/data/local/tmp/android_server
2將例項程式新增到Android裝置
adb push debugnativeapp/data/local/tmp/
adb shell chmod 755/data/local/tmp/debugnativeapp
3啟動除錯服務
adb shell/data/local/tmp/android_server
4進行埠轉發,使PC埠與Android埠可進行互動
adb forward tcp:23946tcp:23946
5啟動IDA,進行程式除錯
啟動IDA的32bit程式,點選:Debugger-Run-RemoteArmLinux/Android debugger,開啟除錯程式的設定對話方塊:
Application:對應除錯程式所在的路徑
Directory:對應除錯程式所在的目錄路徑
HostName:輸入localhost,Port:PC埠
調式動態連結庫
例項:debugjniso.apk
1.將apk安裝在裝置中,執行後介面如下,點選“設定標題”按鈕,便會呼叫動態連結庫libdebugjniso.so中的jniString()方法返回一個修改標題欄的字串。在分析加殼程式的殼時,應以除錯方式來啟動除錯程式(adb shell am start-D -n packagename/activityname)
2.啟動除錯服務,進行埠轉發
adb shell /data/local/tmp/android_server
adb forward tcp:23946 tcp:23946
3.啟動IDA進行程式除錯
點選Debugger-Attach-RemoteArmLinux/Android debugger,開啟設定框
HostName:輸入localhost,Port:對應PC埠
點選OK,便會彈出附加Android程序的對話方塊,選中程序com.droider.debugjniso
4.使用jdb來連線上apk的java層
jdb -connectcom.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8601
5.確定jniString()方法當前的基地址
回到除錯的IDA,使用Ctrl+S快捷鍵開啟段選擇對話方塊,可查詢到libdebugjniso.so當前的基地址為:4B1F2000(隨載入改變)
6.定位到jniString()方法的程式位置
由記憶體地址=基地址+偏移地址(4b1f2000:00000c38),可得當前jniString()方法的記憶體地址為:0x4b1f2c38,使用快捷鍵G開啟地址跳轉框,輸入記憶體地址
7.設定斷點,進行除錯
跳轉在jniString()方法的程式位置,在0x4b1f2c38行設定斷點(F2)