天天看點

ELF分析(1)

ELF Header:

首先利用ndk系統裡面的readelf指令,檢視so檔案的elf 頭資訊:

ELF分析(1)

自己解析的話:

ELF分析(1)

ELF Header資料結構

ELF分析(1)

由上面兩張表推導出,elf 頭檔案各個結構的位置:

ELF分析(1)

例如一個elf檔案頭資訊():

ELF分析(1)

将這些字段,按照規定解析之後:

ELF分析(1)

e_ident[]數組:

(也叫魔數Magic Number)給出了ELF的一些辨別資訊:

ELF分析(1)

e_ident[]數組的下表以及取值:

ELF分析(1)

e_ident[]是unsigned char,根據上面資料格式表,e_ident[]每一個位占一個byte大小。

ELF分析(1)
ELF分析(1)

 e_ident[EL_MAG0]=e_ident[0]=”7f”;-----------7f 45 4c 46 固定格式,elf檔案标志

e_ident[EL_MAG1]=e_ident[1]=”45”;------------由16進制轉成ASCII碼為E

e_ident[EL_MAG2]=e_ident[2]=”4c”; ------------由16進制轉成ASCII碼為L

e_ident[EL_MAG3]=e_ident[3]=”46”; ------------由16進制轉成ASCII碼為F

e_ident[EL_CLASS]=e_ident[4]=”01” -------------32位目标

e_ident[EL_DATA]=e_ident[5]=”01”; -------------之後資料的排序都是高位在前,就是在這邊确定的。

e_ident[EL_VERSION]=e_ident[6]=”01”; --------沒啥用

e_ident[PAD]=e_ident[7]=”00”; --------------------補0

e_ident[NIDENT]=e_ident[16]=””;-----------------這一位貌似沒看到

e_type:

ELF分析(1)

檢視字段,可知03為DYN:

ELF分析(1)

Readelf中也可看出來是DYN:

ELF分析(1)

e_machine:

ELF分析(1)

字段中沒有,不過可通過readelf檔案中推斷,0x28即40為ARM

ELF分析(1)
ELF分析(1)
ELF分析(1)

e_version:

ELF分析(1)

表示目前版本:

ELF分析(1)
ELF分析(1)

e_entry:

ELF分析(1)
ELF分析(1)

e_phoff:

ELF分析(1)

phoff---推斷全稱為program head off,即程式表頭的偏移,可以查出程式表頭的開始位置:

ELF分析(1)

這個比較重要,這裡面0x34即52=16*3+4,可以查出程式表頭的開始位置如下圖:

ELF分析(1)

e_shoff:

ELF分析(1)

為segment head off,即節區頭部表格偏移,可以查出節區表頭的開始位址:

ELF分析(1)

也重要,0x3130,可以查出節區表頭的開始位址如下圖:

ELF分析(1)

e_flags:

ELF分析(1)
ELF分析(1)

e_ehsize:

ELF分析(1)

Elf head size,這個頭檔案的大小

ELF分析(1)

可以看出這個頭的大小為0x34即52位元組

ELF分析(1)

e_phentsize:

ELF分析(1)

這個表示之後每一個處程式頭的大小0x20即32位元組

ELF分析(1)
ELF分析(1)

e_phnum:

ELF分析(1)

表示程式頭的個數,至此,根據程式頭的偏移e_phoff=0x34(即52),程式頭的大小e_phentsize=0x20(即32),以及這裡的程式頭的個數e_phnum=0x07(即7),就可以完全解析出每個程式頭的精确位置。

ELF分析(1)

e_shentsize:

ELF分析(1)

表示節區頭部表格的大小0x28=40,根據之前的e_shoff=0x3130可以精确定位第一個節區表頭的位置

ELF分析(1)
ELF分析(1)

e_shnum:

ELF分析(1)

表示節區頭部表格,個數為0x15(即21)個。

ELF分析(1)

至此,根據e_shoff 0x3130, e_shentsize 0x28以及這個e_shnum 0x15可以完全确定所有節區頭部表格的精确位置。下圖位置畫錯了。

ELF分析(1)

e_shstrndx:

ELF分析(1)
ELF分析(1)

标記節區頭部表格中,字元串節區頭部表格的索引,即第幾個節區是字元串節區頭部表格。這個索引是從0開始。是以這邊0x14即20就是第21個節區頭部表格表示的是字元串的節區頭部表格。如下圖:

ELF分析(1)

Program Headers:

使用NDK中的readelf –l xx.so檢視program headers資訊

ELF分析(1)

Segment Headers:

使用NDK中的readelf –S xx.so檢視segment headers資訊

ELF分析(1)
ELF分析(1)

首先根據elf header中最後一個e_shstrndx=0x14确定節區頭部中字元串節區頭部的位置是第20個(索引位置,0開始),然後根據字元串節區頭部位置中的sh_offset和sh_size确定字元串節區的位置。

字元串節區頭部位置:

ELF分析(1)

得出的字元串節區的位置

ELF分析(1)

sh_name:

ELF分析(1)

這個名稱,根據上面查到的字元串節區來比對名稱:

ELF分析(1)
ELF分析(1)

根據字元串節區,得到0x01的名稱為.shstrtab

檢視readelf –S的到的結果相同

ELF分析(1)

sh_type:

ELF分析(1)

對比下面表格取值

ELF分析(1)
ELF分析(1)
ELF分析(1)

sh_flags:

ELF分析(1)

根據下面表格取值,可能不全。可以取多種值,相加即可

ELF分析(1)
ELF分析(1)

sh_add:

ELF分析(1)

不知道有什麼用,可能在實際運作的時候才有用

sh_offset:

靜态偏移位址,根據這個可以檢視到相對應節區的開始位置

sh_size:

相對應節區的大小,和sh_offset相結合,可以檢視處對應節區的具體位址

sh_link:

ELF分析(1)

sh_info:

ELF分析(1)

sh_addralign:

ELF分析(1)

sh_entsize

ELF分析(1)
elf