標籤:記錄 dump 展開 add title text hostname 錯誤 附加
IDA 調試 Android 方法及簡單的脫殼實現 標籤: android原創逆向調試dalvik 2016-05-24 14:24 9286人閱讀 評論(3) 收藏 舉報 分類: 原創
(25) Android
(5) 學習
(9) 逆向
(4)
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
目錄(?)[+]
本文參考了一些網路文章,對大大們的技術分享表示感謝。小弟剛剛開始深入去搞Android的逆向不久,寫一下學習筆記,希望能拋磚引玉,給新手同學們帶來方便。文筆比較爛,這不重要,重要的是按自己思路整理出來的資料以後自己看起來快一些。文中如有不對的地方還請留言指正。
前置環境
JDK,IDA PRO,Android NDK,Android Killer,JEB,Root並開啟開發人員模式USB調試的手機
動態啟動調試
Android Killer 反編譯 x.apk,取出 classes.dex Dalvik檔案,記錄包名和啟動類名。
修改 AndroidManifest.xml 檔案,在<application>標籤裡添加屬性 android:debuggable="true" 這一步越早修改越好,防止忘記改。
可以查看一下AndroidManifest.xml 他們的對應關係,加深理解。
用AndroidKiller 重新編譯修改過的x_fix.apk。
adb install x_fix.apk 安裝到手機
將 IDA 安裝目錄 dbgsrv 目錄下的 android_server 檔案拷入手機
adb push dbgsrv\android_server /data/data/android_server
接著執行
adb shell chmod 655 /data/data/android_server添加可執行許可權
adb shell /data/data/android_server 將其運行起來
在實際環境中可能會遇到中的一些錯誤,圖中也給出瞭解決方法。
需要額外說明的是,當 adb root 失敗時,需要在手機中安裝一下“超級adbd”開啟應用選擇啟用超級adbd ,再執行adb root 就可以了。
運行後可以看到 Listening on port #23946 … 字樣就說明 server 運行成功了,並且已經開啟了手機端的 23946 連接埠等待接收命令。
為了方便PC端IDA 串連調試手機,可以在本機做連接埠轉寄。另起一個cmd,輸入:
adb forward tcp:23946 tcp:23946
將之前儲存出的 classes.dex 托入 IDA。在IDA菜單中選擇 【Debugger】-> 【Debugger Options…】添加以下選項
再點擊 Set specific options,添加adb 路徑及剛剛儲存的包名和入口名,
【Debugger】-> 【Process Options…】的配置
接下來就可以按IDA上的啟動鍵,啟動手機端的APP進行調試了,
你可以在【View】->【open subviews】->【functions】調出函數列表,再配合Android killer 或 JEB 分析的代碼位置進行下斷調試了。
動態附加調試正常流程
在手機端運行程式後,按的步驟直接附加就可以了。
如果出現 Bogus or irresponsive remote server 的錯誤提示
修改 SELinux安全性原則限制
adb shell su -c setenforce 0
再重新運行 android_server 重新轉寄,再試。
反調試/解密函數運行前進行動態調試
很多程式加入了反調試機制,或者是偽dex檔案在程式運行時解密真正的dex檔案以殼的方式保護APP。針對此兩種方法可採用在程式運行前掛起程式,再用IDA掛載,在關鍵位置下斷,來破解類此防護。
舉一個網上的例子。
下載 ori.apk 按之前的操作記錄包名等,加入Debug屬性,安裝到手機
運行調試啟動命令
adb shell am start –D –n loading.androidmanual/loading.androidmanual.BeginningActivity
這時程式會被掛起,等待調試器接入。
用IDA 載入,調試選項如下
載入時可記錄一下該應用的pid 之後會用到,忘記記錄也沒關係,附加後在IDA 的輸出log裡可以找到pid的資訊
運行 adb forward tcp:7788 jdwp:977 命令,轉寄要調試的進程到連接埠7788(隨便寫),
運行 jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=7788 使用jdb 載入調試。
此時程式處於阻塞狀態,沒關係,返回IDA,在Modules視窗尋找libdvm.so,雙擊進入Module: libdvm.so 視窗,尋找_Z21dvmDexFileOpenPartialPKviPP6DvmDex 函數,雙擊定位過去,在函數頭部下斷。
因為要Load Dex 檔案都要經過此函數就像 LoadLibrary同樣的道理。
接下來點擊IDA繼續運行程式就會在此斷點斷下來。
R0 寄存器中的地址就是 Dex 的起始地址。點擊旁邊的斷行符號表徵圖跳轉到相應的位置。在 View-PC 視窗中右鍵,選擇Jump in a new hex window 可以更好的觀察記憶體中的資訊
這就是殼中釋放出來的程式真正的dex檔案了。根據Dex 檔案結構,我們知道從起始位置位移0x20位元組是這個檔案的大小,在這裡也就是 0x0FAEB4。有了起始位置和檔案大小就可以Dump了。我們直接寫IDA 的指令碼來dump。【file】->【Script Command…】。輸入以下代碼:
[cpp] view plain copy
- auto fp, dexAddress ,endAddr;
- dexAddress = 0x54d4c41c; //起始地址
- endAddr = 0x54E472D0; //結束位址=起始地址+檔案大小
- fp = fopen("d:\\dump.dex", "wb"); //開啟檔案
- for (; dexAddress < endAddr; dexAddress++) //迴圈寫入
- fputc(Byte(dexAddress), fp);
- fclose(fp);
Dex檔案儲存後就可以丟進JEB進行分析了……
如果是反調試機制,那麼就從一開始載入的so檔案入手進行分析。同樣用IDA掛載起來
按照上面的步驟找到JNI_OnLoad函數並下斷,F9運行起來後就可以跟蹤分析了。
IDA 調試 Android 方法及簡單的脫殼實現