原創,轉載請注明出處。
一般java ide(如eclipse、idea)都可用來進行smali的動態調試,這里選擇IDEA。
第1步:使用apktool反編譯apk
java -jar apktool_2.0.0rc4.jar d -d 123.apk -o out
注意:
apktool的版本問題,有的版本沒有-d選項
-d選項代表反編譯出來后綴是.java而不是.smali,但也不是真正的java代碼,這樣是讓IDEA識別出java文件然后使用JDWP進行遠程調試,如下:

第2步:更改debug屬性及在入口添加waitDebug
2.1
更改AndroidManifest.xml中的android:debuggable=”true”
2.2
找到入口Activity,在其onCreate方法開始處添加android.os.Debug.waitForDebugger();
對應的smali代碼為:
invoke-static {}, Landroid/os/Debug;->waitForDebugger()V

第3步:重打包並簽名
java -jar apktool_2.0.0rc4.jar b -d out -o debug.apk
java -jar signapk.jar pub.pem prv.pk8 debug.apk signed.apk
第4步:新建java工程,導入smali代碼,並在關鍵位置下斷
4.1
新建java項目,項目位置填為之前反編譯出的out目錄

4.2
找到關鍵位置下斷點,這個“關鍵位置“就具體情況具體分析了。
這里以示例apk為例下在onClick函數處。

第5步:遠程調試
5.1
打開ddms,然后運行程序。
手機會出現對話框或白屏來等待調試
ddms出現如下情景:

紅色小蟲代表此進程正等待調試
29954為pid
8600為此進程的遠程機器調試端口號,8700為通用備用端口號
5.2
配置遠程調試選項
Host:localhost
Port:8600
調試模式:Attach
項目:out
這里說一下調試模式Attach和listen的區別,Attach是調試服務端(被調試程序運行的機器)啟動一個端口等待我們(調試客戶端)去連接,Listen是我們(調試客戶端)監聽一個端口,當調試服務端准備好了就會連接進行調試。一般習慣選擇Attach。

5.3
開始調試
這里介紹一下JDWP協議,JDB Client(被調試程序)在被調試時會啟動jdwp線程通過JDWP協議與JDB Server(調試端)進行通信,JDWP協議用於傳輸調試的行號及局部變量等信息,這個就是為什么一開始反編譯為java文件也可以調試的原因了。
當開始調試時紅色小蟲會變為綠色,說明已經連接上遠程調試服務端了。

輸入用戶名admin和密碼abc123

然后在下方就可以看到,左側為程序的方法調用棧區,顯示了程序執行到斷點處所調用過的方法,越下面的方法被調用的越早。右側為方法的變量及值,可以右鍵更改。可以看到剛剛輸入的用戶名admin和密碼abc123。
使用F8單步調試,F7單步跳入,shift+F8單步跳出

接下來就不多說了。
總結:
這篇文章也是初步的介紹了一下apk的動態調試方法,然而調試、反調試、反反調試處於不斷的對抗當中,了解java及android中調試系統的原理以及破除反調試的方法才能從容面對各種坑。
動態分析一般會比靜態分析效率更高,但是現在一般程序也不會這么輕易就能調試起來,比如設各種坑讓人難以調試,核心算法逐漸寫到so里(可以使用ida動態調)。在逆向分析時,還得動靜結合,多思考,多學習。
