作者:
zyq8709
·
2015/10/03 10:03
0x00 前言
之前對Android的兩個執行時的原始碼做了一些研究,又加上如火如荼的Android加固服務的興起,便產生了打造一個用於脫殼的執行時,於是便有了DexHunter的誕生(原始碼:https://github.com/zyq8709/DexHunter/)。今天,我就透過這篇小文聊聊我的一些簡單的思路,供大家參考和討論。
0x02 相關機制
首先,先來看一看Android執行時的一些相關機制,看看我們來怎麼搞。
首當其衝,要脫殼少不了研究一下Dex檔案的格式,這一點Android的官方文件寫的已經很清晰了,我這裡就簡單再提一下。整個結構便如圖1所示:
圖1 Dex檔案結構
其實就是分割槽段儲存不同的內容,在頭部裡有指向各個區段起始的偏移值。當然我們最關心的就是class_defs和data這兩個段了。
class_defs包含了所有的類,用class_def_item來描述。圖2是對class_def_item展開的一個示意圖:
圖2 class_def_item結構
每個class_def_item指向一個class_data_item,每個class_data_item 包含了一個class的資料,每個方法用encoded_method結構來描述,它又指向了一個code_item,這個裡面就儲存著一個方法的所有指令。
對於ART下,安裝後的dex檔案會被編譯為oat檔案,這個oat檔案其實是一個ELF檔案,圖3是它的一個結構:
圖3 OAT檔案結構
其中可以看到oatdata指向的部分包含了原有的Dex檔案,這個是我們的目標。當然oatexec指向了編譯後的ARM指令,但是對於我們暫時來說沒有什麼卵用。
0x03 四個時機
為了脫殼,我們要建立一個概念,就是“時機”。對於非虛擬機器殼,從記憶體中轉儲是一個最為有效和統用的技巧,那麼就必須要找到一個時機,保證記憶體中的資料是完全正確的。
在Android中呢,便有這麼四個時機:
開啟Dex檔案
就是把APK中的dex檔案提取並做cache,那麼最終開啟的其實是odex或oat檔案;
載入Class
執行時讀取儲存在Dex中的每個class,並用來填充一個生成的Class物件,其中包含了class的所有成員,這樣一個class才能被使用;圖4表示了ART和DVM下的Class物件的結構
圖4 Class的結構
初始化Class
如果一個class有static塊,那麼這個部分就會編譯為類的初始化器,具體看說就是