ELF分析(1)

时间:2024-03-19 12:38:37

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)