IDA 調試 Android 方法及簡單的脫殼實現
IDA 調試 Android 方法及簡單的脫殼實現
標簽: android原創逆向調試dalvik 2016-05-24 14:24 9286人閱讀 評論(3) 收藏 舉報 分類:版權聲明:本文為博主原創文章,未經博主允許不得轉載。
目錄(?)[+]
本文參考了一些網絡文章,對大大們的技術分享表示感謝。小弟剛剛開始深入去搞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…】。輸入以下代碼:
- 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 方法及簡單的脫殼實現