對脫殼腳本的一些改進--識別出目標DEX

一、前言

    通常對於加殼的程序,第一步的操作通常是脫殼,而現在脫殼一般都選擇利用frida來進行hook進行脫殼,不談其他脫殼方式,利用frida脫殼原理大致分爲兩種:

    1、找到DexFile對象(art虛擬機下是DexFile對象,dalvik虛擬機下是DexFile結構體),獲取到DEX文件的起始地址和大小,然後dump下來。常見能夠找到DexFile對象的函數有LoadMethodResolveMethod函數等,能直接獲取到DEX起始地址和大小的常見函數有openMemorydexparsedexFileParsedvmDexFileOpenPartial等函數。frida_unpack便是其中的代表作。

    2、利用frida的搜索內存,通過匹配DEX文件的特徵,例如DEX文件的文件頭中的magic---dex.035這個特徵。frida-Dexdump便是這種脫殼方法的代表作。

    然而不管是上述哪一種原理,在我這個有點強迫症的看來,都有一點小缺陷,這兩種方法從原理上決定了經過某個函數的DEX(或者存在於內存中的DEX)都會被dump下來,所以出現了dump下來很多個DEX文件,但是隻有其中一個或者幾個是我們的目標DEX,爲了尋找到目標DEX,只有全部反編譯出後來能知道,這就比較浪費時間和精力了,對此,本人對脫殼腳本做了一些改進,通過對dump下來的DEX進行解析,從而識別出那個是我們的目標DEX!!!


二、通過類名識別出DEX

    PS:通過類名識別是本人發現識別率最準確、實現代價最小的方法,所以本篇重點主要在這,後面的其他識別方法在某些特殊情況下更好用!!!

    DEX文件的格式可以大致分爲文件頭索引區數據區文件頭這個區域無法找到一個DEX文件的一個唯一特徵(ps:sha-1校驗碼這兩個能作爲一個DEX文件唯一特徵的前提是我們已經知道這個dex文件所有字節了,所以放在這裏並不成立),索引區包括了很多數據的索引,其中便包括字符串的索引,通過這我們可以解析出整個DEX文件使用到的字符串。而我們已知的DEX文件的一些信息便包括包名

    通過解析一個DEX文件,我們可以發現在DEX中一個類被表示出如下形式--L包名/類名;,例如Lcom/example/test/ManActivity;這種形式,例如下面爲使用腳本解析DEX的字符串,獲取到的類名的截圖:

1.png

    包名是唯一的,所以我們只需要構造/com/example/test這種形式的特徵,便可以很輕易的鎖定到目標DEX,但是,在殼程序中,也可能含有這種類型的字符串,我們的特徵便不再是唯一的,這個時候,我們便需要一個新的唯一特徵。

    在一個APP中,我們通常所寫的類不止一個,而是很多個,那麼便含有很多個上述所說的特徵;而寫過加殼程序都應該知道,我們在加殼程序中,最多也就拉起那麼一個或幾個類。那麼,通過這種數量上的差異同樣也可以作爲唯一特徵,以下是脫殼改進腳本腳本運行截圖:

2.png


三、其他識別方法

    1、其他字符串,通過將app安裝運行手動觀察到的,但是這種方式有點碰運氣,只有直接寫入到java源碼中的才能作爲特徵,寫入到strings.xml便不得行。如下截圖(ps:爲直接寫入到java中的,可以在字符串池中解析出來的),解析字符串池:

3.png

    2、佈局xml文件名、控件名(ps:這種可行性太低,在這裏籌字數的,基本不能作爲特徵)

    3、佈局、控件資源ID,這些16進制搜索整個DEX文件也可以作爲特徵,但是有很其他DEX文件裝車的可能。

    4、方法原型,例如一個方法返回值是Double,參數也是Double,那個這個方法原型便是FF,而這個方法原型一定存在於字符串池中,但是也不是很靠譜這個特徵,原因如下截圖所示(而且還需要知道一個方法纔行):

4.png

    5、對DEX做更深入解析,解析出更多特徵,而不僅僅止於解析出字符串池,感興趣的研究一下,但第一個依靠類名便夠用了。


五、其他

    github地址:https://github.com/windy-purple/dumpshell

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