百度脫殼的一點嘗試--人肉修復

前言

最近把研究dex的脫殼,順便又是再次熟悉了一下dex的標準格式以及dex被解析後在內存中所存在的格式。自己上官網加了一個殼子,發現跑不起來。於是求助幾個基友,最後樣本是海總給的apk,很全面,帶有Activity、Application、BroadcastReceiver、ContentProvider、以及Service。

0x1 加殼前後對比

這裏寫圖片描述

加固後的文件列表變化:
新增一個so文件以及一個jar包:
libbaiduprotect.so
baiduprotect.jar
修改:
META-INF文件夾
AndroidManifest.xml
Classes.dex

0x2 IDA嘗試

用IDA來遠程調試,直接跑掛了。看來有反調試。
從殼入口Java層找到如下語句:

 static {
        if(!Debug.isDebuggerConnected()) {
            String v0 = Build.CPU_ABI;
            if(v0 != null && (v0.startsWith("x86"))) {
                StubApplication.loadX86Library();
                return;
            }

            System.loadLibrary("baiduprotect");
        }
}

把第一個if刪掉之後,程序順利的加載了baiduprotect.so,順利的進入了殼的領空,不過不知道是程序在so裏面做了完整性校驗還是再次檢測了debuggerconnected,每次跑都是進入了一個死循環後,然後程序就跑掛了,跑了很多次都是難以逃出那個trap。這個時候就比較糾結了。既然反調試過不去,想起360的殼子用DD也可以脫的很完美,那就換個方式試試。

0x3 DD大法

dd if=/proc/PID/mem of=XX skip=0 ibs=1 count=LENGTH 
skip改成偏移地址
偏移地址 
cat /proc/pid/maps

1.這裏首先要感謝下wbyang博士猛男,這個DD大法也是上次挑戰賽之後向他學來的。程序跑起來,把內存都dump出來,大概是100多mb的東西。找幾個字符串,然後向上翻,找到dex文件的頭,發現是被抹掉的。如圖:
這裏寫圖片描述
前面紅色框的8字節是odex的magic頭。後面的0x70字節是dex的頭。除了一些size和編碼標誌沒有被抹掉,其他的已經是面目全非,修復後如下:
這裏寫圖片描述
這下把dex文件摳出來了。
2.把dex反編譯成smali文件
出現如下錯誤:

這裏寫圖片描述

反覆檢查後發現瞭如下是CodeItems下面的offset錯誤:
這裏寫圖片描述
Dex的文件大小才0xA30DC,而offset指向了外面的東西。當然是無法解析的,這裏我是有一個問題的,第三個偏移,這個0x0220E8E8,指向的是前面的內存,這是如何做到的?我個人認爲是百度是在加載完成之後故意改成這個數字的。若有錯誤,還望前輩不吝指正。
把這三個offset 都改成0就可以達到反編譯成功,當然是在缺三個DataItem的前提下編譯成功的。找到被抹掉的DataItem地址:
這裏寫圖片描述

以上三處爲0的區域就是加固前的dex代碼所存放的位置。
因此,假設我們能從dex的結構逆推出該三處的數據並且用應該的數據填充這塊,靜態就能把這個殼子搞定了。
3.如何修復

360殼子要修復的數據爲DataclassDef中的offset即可。而百度的更爲麻煩一些,不僅它的偏移需要修復一下,更爲麻煩的是DataItem的數據也要修復。這個難度就更大了。
總的修復原則是導出函數表,然後按順序來修復dex中被抹掉的數據,如下:
這裏寫圖片描述

逆計算出函數的uleb128的索引值、常見函數的一些accessflags、以及指向函數內容的offset。
修復後如下:
這裏寫圖片描述

修復的過程比較繁瑣,有時候還需要自己嘗試幾次才知道size是多少。所以叫它人肉修復好了。
修復好了反編譯如圖
這裏寫圖片描述

發現onCreate函數沒有代碼,檢查了一下,又有新發現!
這裏寫圖片描述

原來是oncreate中的insns[]也被抹掉了。這個算是最基本的單位了,功力太弱,無法逆推。

最後總結下,百度的殼子需要修復dex頭中的magic、簽名值、校驗值以及各個offset。還需要修復Dataclassoffset,以及Dataclass和opcodes。前兩者是可以靜態修復的,最後的只能動態調試尋找了。百度殼子新增了一個oncreate001的函數,調用的殼中的d方法以及e方法,猜測是d方法填充了insns[]解密數據,然後e方法爲清潔工,抹去正確的數據或者是改成一些非法數據。此時就淚奔了。。(心裏暗想:百度好猥瑣啊。。。)

由於過去幾天了,再次寫文章又重新做了一遍,把各種東西找好,寫完花了將近三個小時,累覺不愛了。。。T T

由於水平有限,難免有錯誤,還望各位看官不吝指正。
2015.3.24 By Ericky

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章