Android逆向(6)——脫殼前奏,激動人心的so原始碼分析
0x00 前言
之前看來dex載入的過程是不是特別開心。現在我們就更接近脫殼了。so的動態載入,連結,等等,你都會在這篇文章裡看到。當然還是要自己進行一個研究才可以。
0x01 so的載入初步分析
so的載入分析。
我們還是從原始碼入手。
主要函式 dlopen
這裡dlopen的函式有一個重點就是do_dlopen。
我們追蹤到do_dlopen.
這裡看到的兩個函式就是我們的重點部分。
首先來看CallConstructors
來看看這兩個欄位。
CallFunction("DT_INIT", init_func);
CallArray("DT_INIT_ARRAY" , init_array, init_array_count, false);
這裡就是.init和.initarray的執行部分。
我們知道在.init部分最先執行的地方。
然後我們再來看看另外一個函式,說到這個函式那我們就要進行另一個部分分析了。
0x02 so載入的步驟
1.find_library部分分析
首先,我們來開啟find_library的原始碼,find_library是整個so載入的開始流程。也是我們要研究的主控部分。
這裡呼叫了find_library_internal函式,跟蹤,進入原始碼檢視
這裡我們看到一個load_library函式,這個就是開始載入的部分,簡單的說就是現find然後再load。
現在來看load_library
然後看到了這個elf_reader。我們先來看看名字,elf reader,是不是就是讀取elf,elf就是我們的so檔案。
我們進入.load欄位檢視。
ReadElfHeader() &&
VerifyElfHeader() &&
ReadProgramHeader() &&
ReserveAddressSpace() &&
LoadSegments() &&
FindPhdr();
我們來一個一個看,ReadElfHeader()讀取elf頭部資訊
VerifyElfHeader(),校驗elf頭部資訊
ReadProgramHeader(),讀取程式頭
ReserveAddressSpace() 預留地址空間
LoadSegments() 載入segments
FindPhdr(); 我們來看下解釋,Returns the address of the program header table as it appears in the loaded segments in memory. This is in contrast with ‘phdr_table_’ which is temporary and will be released before the library is relocated.
也就是說這裡裝載對比phdr_table_ 這個欄位
之前看過一些文章,說可以進行segments加密。利用只加載segments的原理實現的。看到了系統原始碼之後就會有了很深的理解了。
我們接著回頭去看load_library。
soinfo_alloc函式,返回一個結構體。
結束之後就到了連線部分。
回到find_library_internal部分。
跟蹤到soinfo_link_image函式
這裡可以詳細看到連結的過程。
首先是Extract dynamic section。提取動態部分,也就是找到動態節區。
接下來就是Extract useful information from dynamic section,從動態部分提取有用的資訊。也就是說這裡在解析動態節區。
下一步,Sanity checks.檢查
接下來進行判斷If this is the main executable, then load all of the libraries from LD_PRELOAD now.如果這是主要的可執行檔案,然後載入所有的Library的ld_preload。
在這裡呼叫了soinfo_relocate,我們跟蹤進行檢視。
這裡是做了一個.dynsym的符號資訊匯入,這裡參考大神的一張圖。
有了這個圖就應該好理解多了。
至此,link就分析到這裡。