測試環境:
調試器: IDA6.5
手機及系統版本:
.SO層脫殼
一:.如何到達殼入口點?
1.我是通過對dvmLoadNativeCode函數下斷,分析它執行流程最后到達殼入口(如果您有更好的辦法還請告知,感謝中...),函數dvmLoadNativeCode是執行加載so文件的操作。(2.3系統是這個名字),2.3以上系統被名稱粉碎了,不過在2.3以上系統中可以在libdvm.so中搜索函數名也是可以找到的,(我當前系統函數名為:_Z17dvmLoadNativeCodePKcP6ObjectPPc)如下圖所示:
2.對dvmLoadNativeCode函數進行下斷有些小技巧,前后下斷點,等殼執行完成后反回就斷在這里,如下圖所示:
3.跟進這libdvm.so:4087B900 BLX unk_4083F694 函數后,分析其流程就可以發現有so的加載基址為0x5B97C000,如下圖:
4.得到so在內存中基址后就可以用ReadELF -a xx.so來查看so文件的INIT_ARRAY文件偏移,如下圖執行 ReadELF -a libprotectClass.so 命令后
5.我們用IDA靜態反編譯libprotectClass.so文件,然后去0xfd98地址去看看,是一個函數地址,如下圖
該函數為:
6.得到了libprotectClass.so在內存中基址與INIT_ARRAY文件偏移,將它們相加即可得到so殼入口了0x5B97EF5C,去內存中看看,如下圖:
是不是與__gnu_armfini_26函數很像呢?然后我們在該函下個斷點,F9執行以這兒就可以接着分析so殼代碼了。
二:so如何脫殼?
1.到達殼入口后我們單步跟蹤看看,到修改代碼屬性這里
R0為要修改的開始地址
2.准備解密代碼,跟進該函數。
在該函數里做解密代碼操作,首先是拷貝0xA長度的密鑰,如下圖,然后初始化密鑰
3.從初始化密鑰函數來看,應該使用的是RC4算法,接着就是解密了。
R0為要解密的Buffer, R1為Buffer的大小, R3為初始化后的密鑰。
4.算法 密鑰 都知道了,我們可以寫個程序來解密so了,如下圖解密前后JNI_OnLoad對比。
解密前為:
解密后為:(代碼己正常)
到此可以靜態分析了,其它的小伙伴們自己去玩吧(^_^), 解密算法RC4_so己放在附件中。
DEX 內存dump
1.接着上面so代碼解密完成后,反回到這里, libdvm.so:4087B904 MOV R1, R6
這時可以在JNI_OnLoad函數下斷點了,如下圖:
F9來到JNI_OnLoad函數,接着就是慢長的分析了。
詳細的分析流程我就不細說了,想了解的現在可以自己動態與靜態結合分析了,我們這次的目的是內存中dump完整的DEX。
到JNI_OnLoad函數后,到下面libprotectClass.so:5B88A22C BLX R4下好斷點。如下圖
3.F9到這里后,F7跟進,然后在 mmap函數下斷點, F9執行,當LR的地址為程序領空時反回下好斷點(一定要是程序領空才有效,因為mmap會被多次調用),F9執行。
接下來R0將會存放解密后的Dex,然后F8走,直到該函數執行完成后,開始解密DEX開頭0x70個字,解密完成后就可dump出來了,如下圖:
到此完整的DEX己經出來了,下面我們Dump出來,打包反編譯。
開始地址為0x5BC35000, 大小為0x005EDBA4, 結束地址為0x5C222BA4
4.將dump出來的dex重新打包並能成功反編,如下圖:
5.到此整個過程就完成了,下面該做些什么小伙伴們自己發輝吧,我就不知道了。(^_^)。(樣本就是上傳了,想玩玩的去XX加固保官網下載去吧)
資料下載
http://yunpan.cn/cAFzDYcB6weWY (提取碼:6e74)