測試環境:
偵錯程式: IDA6.5
手機及系統版本:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_yvkp2s1tduw7u8jc.png)
.SO層脫殼
一:.如何到達殼入口點?
1.我是透過對dvmLoadNativeCode函式下斷,分析它執行流程最後到達殼入口(如果您有更好的辦法還請告知,感謝中...),函式dvmLoadNativeCode是執行載入so檔案的操作。(2.3系統是這個名字),2.3以上系統被名稱粉碎了,不過在2.3以上系統中可以在libdvm.so中搜尋函式名也是可以找到的,(我當前系統函式名為:_Z17dvmLoadNativeCodePKcP6ObjectPPc)如下圖所示:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_nti01tox32i9yrwr.png)
2.對dvmLoadNativeCode函式進行下斷有些小技巧,前後下斷點,等殼執行完成後反回就斷在這裡,如下圖所示:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_muygzqjrozyguphr.png)
3.跟進這libdvm.so:4087B900 BLX unk_4083F694 函式後,分析其流程就可以發現有so的載入基址為0x5B97C000,如下圖:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_9qalhcecgx3qvb4u.png)
4.得到so在記憶體中基址後就可以用ReadELF -a xx.so來檢視so檔案的INIT_ARRAY檔案偏移,如下圖執行 ReadELF -a libprotectClass.so 命令後
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_8gxkzoxje5a3j7co.png)
5.我們用IDA靜態反編譯libprotectClass.so檔案,然後去0xfd98地址去看看,是一個函式地址,如下圖
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_bswtse0x1qd71omj.png)
該函式為:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_zasgtd36x2utlgkh.png)
6.得到了libprotectClass.so在記憶體中基址與INIT_ARRAY檔案偏移,將它們相加即可得到so殼入口了0x5B97EF5C,去記憶體中看看,如下圖:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_ooimo0p7f7wz8gmt.png)
是不是與__gnu_armfini_26函式很像呢?然後我們在該函下個斷點,F9執行以這兒就可以接著分析so殼程式碼了。
二:so如何脫殼?
1.到達殼入口後我們單步跟蹤看看,到修改程式碼屬性這裡
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_p2nr5ghii2r0br7h.png)
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_jpwefdv650dxkkzv.png)
R0為要修改的開始地址
2.準備解密程式碼,跟進該函式。
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_com1uvf0uomjxeu8.png)
在該函式里做解密程式碼操作,首先是複製0xA長度的金鑰,如下圖,然後初始化金鑰
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_c1qjwx3iay5v7bsl.png)
3.從初始化金鑰函式來看,應該使用的是RC4演算法,接著就是解密了。
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_2k1k0pqxnb93wdvw.png)
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_fjwf5nac2b5toug5.png)
R0為要解密的Buffer, R1為Buffer的大小, R3為初始化後的金鑰。
4.演算法 金鑰 都知道了,我們可以寫個程式來解密so了,如下圖解密前後JNI_OnLoad對比。
解密前為:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_v09zfv9pyl45kfkw.png)
解密後為:(程式碼己正常)
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_uybmeznug6vq4kcd.png)
到此可以靜態分析了,其它的小夥伴們自己去玩吧(^_^), 解密演算法RC4_so己放在附件中。
DEX 記憶體dump
1.接著上面so程式碼解密完成後,反回到這裡, libdvm.so:4087B904 MOV R1, R6
這時可以在JNI_OnLoad函式下斷點了,如下圖:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_i47d26maerqr3uek.png)
F9來到JNI_OnLoad函式,接著就是慢長的分析了。
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_m2jpgru75jc37857.png)
詳細的分析流程我就不細說了,想了解的現在可以自己動態與靜態結合分析了,我們這次的目的是記憶體中dump完整的DEX。
到JNI_OnLoad函式後,到下面libprotectClass.so:5B88A22C BLX R4下好斷點。如下圖
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_1pkra4fq3jsqiwe4.png)
3.F9到這裡後,F7跟進,然後在 mmap函式下斷點, F9執行,當LR的地址為程式領空時反回下好斷點(一定要是程式領空才有效,因為mmap會被多次呼叫),F9執行。
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_7g8bhp2e8xz9tyzl.png)
接下來R0將會存放解密後的Dex,然後F8走,直到該函式執行完成後,開始解密DEX開頭0x70個字,解密完成後就可dump出來了,如下圖:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_ky9r1tbca45soo1t.png)
到此完整的DEX己經出來了,下面我們Dump出來,打包反編譯。
開始地址為0x5BC35000, 大小為0x005EDBA4, 結束地址為0x5C222BA4
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_s5cdjdwy7h8icvwt.png)
4.將dump出來的dex重新打包並能成功反編,如下圖:
![](https://zhuanlan.kanxue.com/upload/attach/201711/536985_c8wd7cc9az6a8r7l.png)
5.到此整個過程就完成了,下面該做些什麼小夥伴們自己發輝吧,我就不知道了。(^_^)。(樣本就是上傳了,想玩玩的去XX加固保官網下載去吧)
資料下載
http://yunpan.cn/cAFzDYcB6weWY (提取碼:6e74)