android 脫殼 之 dvmDexFileOpenPartial斷點脫殼原理分析
導語:
筆者主要研究方向是網絡通信協議的加密解密, 對應用程序加固脫殼技術很少研究, 脫殼殼經歷更是經歷少之甚少。但是脫殼作為一個逆向工程師必備技能,怎能不會,於是找了幾個脫殼的帖子,看別人是怎么剖殼,筆者看過阿里加固殼,360加固的殼,愛加密的殼都被脫殼,無一幸免。加固/剖殼技術其實與筆者研究通信協議加密解密時一樣一樣的。 我看到幾個這些帖子, 給出自己的一下總結。
1.大部分殼都會反調試結合使用, 因為脫殼必然需要動態調試,然后dump dex 文件。為了防止動態調試,不部分的殼保護程序都會使用的反調試。 關於反調試筆者已經談過,在這個就不談了。
2. 大部分殼我們可以對int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)函數下斷點。然后dump 地址:addr, 長度:len 到文件中。然后就算脫殼成功能, 有的殼,會對dvmDexFileOpenPartial 進行重寫, 筆者分析的360的殼機重寫啦。所以了解為什么脫殼需要對dvmDexFileOpenPartial 下斷點,以及這個函數都干了些啥。
分析結論:
Android系統啟動時會先啟動init進程,init進程會啟動zygote進程,該進程會為每個要啟動的App進程孵化出一個Davlik虛擬機實例.Zygote 進程還會啟動optdex進程,這個進程將要運行App的DEX文件映射到內存中,然后校驗,優化,轉成虛擬機能夠操作的Dex對象DvmDex.
dvmDexFileOpenPartial的函數原型如下:int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)
參數1:加載的DEX文件在內存中的基址.(也就是DEX.035)
參數2:加載的DEX文件的文件長度,
參數3:出參, DEX 文件轉成DvmDex結構,里面包含Dex文件的類,字段,方法,字符串信息。Dalivk操作Dex文件的對象這是結構結構體
分析過程:
就提分析如下:dexopt對應源碼在: /dalvik/dexopt/OptMain.cpp, 查看main函數
這里根據解析文件方式不同,選擇不同方案進行選擇方法,我們這里研究是dex文件,所以跟進函數fromDex函數。截取fromDex 函數的片段:
dvmPreForDexOpt函數的作用在對函數進行優化前,檢測Dalivk虛擬機是否進入工作狀態, 如果進入工作狀態就會調用dvmContinueOptimization對Dex文件進行優化。 我們 進入dvmContinueOptimization跟進函數看看他是如何進行優化的。 截取代碼片段分析
通過共享內存映射,將Dex文件映射到內存中。
發現這里會調用我們主角 dvmDexFileOpenPartial , 這個函數主要功能就是完成將內存中DexDile 轉化成DilivikVM的Dex文件DvmDex。我們查看一下DvmDex文件的結構:
這里我們看到我們熟知的字符串對象,內對象,方法, 字符等等信息,根據這些信息,我們就可以運行我們的DexFile文件了。