1. 程式人生 > >Android逆向中的常用除錯方法和使用程式碼總結

Android逆向中的常用除錯方法和使用程式碼總結

0x01 smail語言的調式方法 a.動態分析法,利用log日誌輸入或者toast輸出。 利用Toast進行除錯 java程式碼
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程式碼
new Exception("print trace").printStackTrace();
smail程式碼
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 程式碼
android.os.Debug.startMethodTracing("123")
func():
android.os.Debug.stopMethodTracing():
smai程式碼
可以插入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)/4

pediy上的一個例子:

.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)