從Android執行時出發,打造我們的脫殼神器

wyzsk發表於2020-08-19
作者: 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中呢,便有這麼四個時機:

  1. 開啟Dex檔案

    就是把APK中的dex檔案提取並做cache,那麼最終開啟的其實是odex或oat檔案;

  2. 載入Class

    執行時讀取儲存在Dex中的每個class,並用來填充一個生成的Class物件,其中包含了class的所有成員,這樣一個class才能被使用;圖4表示了ART和DVM下的Class物件的結構

    圖4 Class的結構

  3. 初始化Class

    如果一個class有static塊,那麼這個部分就會編譯為類的初始化器,具體看說就是

相關文章