Android ELF檔案根據函式名查詢函式位置

2021-09-11 05:11:37 字數 2323 閱讀 1547

最近一段時間,工作比較空閒,準備研究下so檔案上的函式加密和函式名混淆,首先從根據函式名找到對應**開始。記得很早之前,自己寫過乙個elf解析工具,到現在都忘得差不多了,趁現在這個機會,順便複習下。本文給出兩種方法來查詢函式**位置,第一種是直接遍歷動態符號表,取出字串與目標函式名比較,找到之後,根據裡面的字段來得到函式**位置。第二種是根據elf檔案中的hash節來遍歷動態符號表,android原始碼中用的是第二種方法。我們先講第一種方法。

首先找到elf頭,elf頭里包含兩我們所需的字段,節區頭陣列的起始偏移和該陣列的大小,e_shoff表示節區頭陣列的偏移 e_shnum表示陣列的大小

接著根據節區頭陣列的起始偏移和該陣列的大小遍歷節區頭,在這裡我們找到節區頭的sh_type欄位為dynsym的節頭,找到對應節頭之後,在節頭中找到節的偏移(sh_offset),和節的大小(sh_size)。

找到dynsym的節後,裡面是乙個結構體陣列,可以看到這個結構體中有個st_name欄位,它就是我們要找的函式名,但它的資料型別卻是乙個elf_32_word(其實就是乙個unsigned int),並不是乙個字串,其實它是乙個字串的偏移,這個字串也儲存在乙個節中,要找到這個節,當然也要遍歷節頭陣列,跟找型別為dynsym的節頭的方法是一樣的,只是這裡的型別為dynstr。找打節頭後,找到對應節的偏移再加上面提到的st_name,就找到了對應的字串,接著根據這個方法遍歷結構體陣列中的所有字串跟我們自己的目標函式字串做比較,找打所需的結構體,根據裡面的結構體裡的字段st_value和st_size,分別找到對應**的首位址和**的大小。最後,我們還需要做**修正,因為目標函式是arm指令,還是thumb指令,對其所做的操作是不一樣的。下面的第四部分會介紹**的修正,這裡先不介紹。

首先遍歷節區頭,找到type欄位為.hash的節區頭,根據節區頭找到對應的節區,這個節區是乙個無符號整數陣列,首先該陣列的第乙個數(索引為0)是nbucket,代表bucket陣列的大小,第二個數(索引為1)是nchain,代表chain陣列的大小。chain陣列緊跟bucket陣列。如下圖所示。

知道了資料結構,接下來就要看怎麼使用了,首先將我們要查詢的函式名用hash演算法進行計算,hash演算法在android4.4原始碼中的linker.cpp中有給出,它的引數是我們給的函式名,返回乙個無符號整數。

得到elfhash函式的返回值後,用這個返回值對nbucket取餘,得到值mod,接著得到y = bucket[mod],比較y是否為0,不為0的話,將y做為索引去動態符號表上查詢資料,找到符號表的結構後,取出函式名進行比較,假如不是的話,將y值做為索引在chain陣列上查詢下乙個數。**如下。

本來**的編寫就到此為止了,但本人將同樣的elf檔案拖入到ida pro中(一款反編譯工具)和自己所編寫的解析工具中,發現ida  pro中顯示的函式起始位址比自己解析出來的少1個位元組的偏移。

我的:ida的:

這是因為在arm體系架構中,通常arm指令的位元組數都是4位元組的,還有一種叫做thumb的指令集通常為兩位元組的。後來又出了一種叫thumb-2的,兩位元組和四位元組混搭的,但是不管幾位元組,從arm模式轉換到thumb模式時,會執行一條跳轉指令(blx或者bx),處理器會檢查目標位址的最後一位是否為1,為1的話說明需要切換到thumb模式。同理thumb模式切換到arm模式,會檢查最後一位是否為0,為0就切換到arm模式。這時候就明白了,自己解析出來的函式位址,需要減一才是函式執行的起始位址,多出來的1是為了程式在執行的時候能區分出arm模式切換到thumb模式。這也解決了以前看ida pro中的thumb**總感覺不對,因為ida pro顯示的是真實跳轉位址。

做為乙個從事android逆向人員,對elf檔案都應該了解,更需要編寫**來實踐。本文是對以前elf檔案的複習和擴充套件,也為以後編寫so檔案加密打下乙個基礎。

linux根據條件查詢檔案 根據檔案內容查詢檔案

find 命令選項 路徑 表示式選項 選項 empty 查詢空白檔案或目錄。group 按組查詢。name 按文件名稱查詢。iname 按文件名稱查詢,且不區分大小寫。mtime 按修改時間查詢。size 按容量大小查詢。user 按使用者查詢。exec 對找到的檔案執行特定的命令。a 並且。o 或...

mysql讀寫檔案函式 讀寫檔案 檔案方法 函式

讀寫檔案 全域性申明 import codecs encodeing utf 8 開啟檔案的模式有 r,唯讀模式 預設 w,只寫模式。不可讀 不存在則建立 存在則刪除內容 a,追加模式。可讀 不存在則建立 存在則只追加內容 表示可以同時讀寫某個檔案 r 可讀寫檔案。可讀 可寫 可追加 w 寫讀 a ...

webstorm根據 eslintrc檔案自動修復

自 開啟webstorm file settings eslint 選項解讀 按我選的就好 這樣的話,右鍵點選fix eslint problems,webstorm就可以根據.eslintrc檔案的規則來自動恢復.但是有快捷鍵的話,就更加方便了,那我們就給他乙個快捷鍵.同樣在settings裡搜尋...