[Android 脫殼] 使用 IDA 進行簡單的脫殼
0x00 摘要
Apk脫殼方法有兩種:
(1)使用脫殼神器ZjDroid進行脫殼(現在此方法不是很好使,因為很多應用都同步更新自己的防禦機制,個人覺得熟練脫殼還是得使用 IDA 進行操練)。
(2)使用 IDA Pro 在 dvmDexFileOpenPartial 這個函式下斷點進行脫殼。(大殺技)
加殼能防止原始碼被偷窺,但是這隻能防止靜態分析,無法防止動態除錯。不管怎麼加殼保護,原始的classes.dex在App執行時都要載入到記憶體中。所以如果在App載入classes.dex處下個斷點,然後再把classes.dex對應記憶體中的內容摳出來還原成原始的classes.dex檔案,就能達到脫殼的目的了。
0x01 實驗
(1)以第1屆Alictf的EvilApk300(如圖0所示)為例,簡單介紹一下使用IDA Pro 進行脫殼的步驟
- step 1:將手機連線電腦
[Bash shell] 純文字檢視 複製程式碼
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 |
/size ]
/size ]
|
如果成功,手機上 app 會彈出 “Waiting For Debugger”
- step 2:操作 IDA
依次點選”Debbuger -> Attach -> Remote ARMLinux/Android debugger”啟動IDA Pro中的Android Debbuger
然後在彈出的對話方塊中點選”Debug options”按鈕,將“Suspend on process entry point”,“Suspend on thread start/exit”,“Suspend on library load/unload”這幾個選項勾選上,再將Hostname配置為localhost,埠:23946
注意:Ctrl + F 方便查詢
- step 3:繼續 IDA
脫殼的時候重點關注:dvmDexFileOpenPartial 函式(在該函式處下斷點)
依次點選“Debugger -> Debugger windows -> Module list”,找到so檔案列表
在Module list中找到libdvm.so這個檔案(注意:Ctrl + F 方便查詢)
雙擊libdvm.so,在彈出的函式列表中找到dvmDexFileOpenPartial函式,然後雙擊該函式就看到dvmDexFileOpenPartial函式的具體實現
在dvmDexFileOpenPartial函式處下斷點(F2 下斷點)
- step 4:使用jdb命令動態除錯Apk
點選 ida 左上角的綠色執行按鈕(F9)
開啟 DDMS 工具(android-sdk\sdk\tools\ddms.bat)
使用jdb命令進行除錯時,一般選擇8700埠,因為8700是預設的除錯埠;開啟終端視窗,輸入:
[Bash shell] 純文字檢視 複製程式碼
1 2 3 |
|
此時 IDA 會彈出 ”Add map…” 視窗(點選 cancel 按鈕即可):
此時程序就執行到了dvmDexOpenPartial函式斷點處,dvmDexOpenPartial 函式的定義:
[C++] 純文字檢視 複製程式碼
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
dvmDexFileOpenPartial 函式的原型如下所示:
int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)
其中 addr表示Dex檔案在記憶體中的起始地址,
len 表示Dex檔案的大小,
ppDvmDex是一個指向DvmDex型別的二級指標,具體表示什麼,我也不知道
脫殼只用到 addr 和 len 這兩個引數,所以需要獲取 R0 和 R1 暫存器的值(ARM的傳遞引數機制規定 R0 儲存著函式從左至右的第一個引數,R1 儲存著函式從左至右的第二個引數),可以檢視到暫存器列表中的內容如圖所示:
- step 5:在 IDA 中編寫idc指令碼dump記憶體還原dex檔案
選擇 File -> Script command…
稍等片刻,即可以把 dump 出來的 dex 檔案儲存在 C 盤根目錄
IDC指令碼:
[C] 純文字檢視 複製程式碼
1 2 3 4 5 |
|
- step 6:使用 JEB 分析dump 出來的 dex 檔案[此處內容請參考原文]
本文脫殼核心思想:在 dvmDexFileOpenPartial 函式處下斷點,然後動態除錯 Apk,待App 執行到斷點處後,寫一個 idc 指令碼將 dex 檔案所對應的記憶體 dump 出來,然後還原成 dex 檔案就完成脫殼操作了,最後再分析反編譯 dex 所得到的 smali 檔案。 |
- 參考文獻
[1] 聽鬼哥說ZJDROID脫殼的簡單使用:http://blog.csdn.net/guiguzi1110/article/details/38727753
[2] 安卓逆向學習筆記(9)- 使用IDA Pro進行簡單的脫殼 :http://blog.csdn.net/pengyan0812/article/details/46275317
[3] Android應用方法隱藏及反除錯技術淺析:http://www.kuqin.com/shuoit/20151012/348473.html0x00 摘要
Apk脫殼方法有兩種:
(1)使用脫殼神器ZjDroid進行脫殼(現在此方法不是很好使,因為很多應用都同步更新自己的防禦機制,個人覺得熟練脫殼還是得使用 IDA 進行操練)。
(2)使用 IDA Pro 在 dvmDexFileOpenPartial 這個函式下斷點進行脫殼。(大殺技)
加殼能防止原始碼被偷窺,但是這隻能防止靜態分析,無法防止動態除錯。不管怎麼加殼保護,原始的classes.dex在App執行時都要載入到記憶體中。所以如果在App載入classes.dex處下個斷點,然後再把classes.dex對應記憶體中的內容摳出來還原成原始的classes.dex檔案,就能達到脫殼的目的了。
0x01 實驗
(1)以第1屆Alictf的EvilApk300(如圖0所示)為例,簡單介紹一下使用IDA Pro 進行脫殼的步驟
- step 1:將手機連線電腦
[Bash shell] 純文字檢視 複製程式碼
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 |
|
如果成功,手機上 app 會彈出 “Waiting For Debugger”
- step 2:操作 IDA
依次點選”Debbuger -> Attach -> Remote ARMLinux/Android debugger”啟動IDA Pro中的Android Debbuger
然後在彈出的對話方塊中點選”Debug options”按鈕,將“Suspend on process entry point”,“Suspend on thread start/exit”,“Suspend on library load/unload”這幾個選項勾選上,再將Hostname配置為localhost,埠:23946
注意:Ctrl + F 方便查詢
- step 3:繼續 IDA
脫殼的時候重點關注:dvmDexFileOpenPartial 函式(在該函式處下斷點)
依次點選“Debugger -> Debugger windows -> Module list”,找到so檔案列表
在Module list中找到libdvm.so這個檔案(注意:Ctrl + F 方便查詢)
雙擊libdvm.so,在彈出的函式列表中找到dvmDexFileOpenPartial函式,然後雙擊該函式就看到dvmDexFileOpenPartial函式的具體實現
在dvmDexFileOpenPartial函式處下斷點(F2 下斷點)
- step 4:使用jdb命令動態除錯Apk
點選 ida 左上角的綠色執行按鈕(F9)
開啟 DDMS 工具(android-sdk\sdk\tools\ddms.bat)
使用jdb命令進行除錯時,一般選擇8700埠,因為8700是預設的除錯埠;開啟終端視窗,輸入:
[Bash shell] 純文字檢視 複製程式碼
1 2 3 |
|
此時 IDA 會彈出 ”Add map…” 視窗(點選 cancel 按鈕即可):
此時程序就執行到了dvmDexOpenPartial函式斷點處,dvmDexOpenPartial 函式的定義:
[C++] 純文字檢視 複製程式碼
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
dvmDexFileOpenPartial 函式的原型如下所示:
int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)
其中 addr表示Dex檔案在記憶體中的起始地址,
len 表示Dex檔案的大小,
ppDvmDex是一個指向DvmDex型別的二級指標,具體表示什麼,我也不知道
脫殼只用到 addr 和 len 這兩個引數,所以需要獲取 R0 和 R1 暫存器的值(ARM的傳遞引數機制規定 R0 儲存著函式從左至右的第一個引數,R1 儲存著函式從左至右的第二個引數),可以檢視到暫存器列表中的內容如圖所示:
- step 5:在 IDA 中編寫idc指令碼dump記憶體還原dex檔案
選擇 File -> Script command…
稍等片刻,即可以把 dump 出來的 dex 檔案儲存在 C 盤根目錄
IDC指令碼:
[C] 純文字檢視 複製程式碼
1 2 3 4 5 |
|
- step 6:使用 JEB 分析dump 出來的 dex 檔案[此處內容請參考原文]
本文脫殼核心思想:在 dvmDexFileOpenPartial 函式處下斷點,然後動態除錯 Apk,待App 執行到斷點處後,寫一個 idc 指令碼將 dex 檔案所對應的記憶體 dump 出來,然後還原成 dex 檔案就完成脫殼操作了,最後再分析反編譯 dex 所得到的 smali 檔案。 |
- 參考文獻
[1] 聽鬼哥說ZJDROID脫殼的簡單使用:http://blog.csdn.net/guiguzi1110/article/details/38727753
[2] 安卓逆向學習筆記(9)- 使用IDA Pro進行簡單的脫殼 :http://blog.csdn.net/pengyan0812/article/details/46275317
[3] Android應用方法隱藏及反除錯技術淺析:http://www.kuqin.com/shuoit/20151012/348473.html