ELF分析(1)

本文详细介绍了如何解析SO文件中的ELF格式,包括ELFHeader的各项字段含义及其作用,如魔数、类型、机器类型等,并展示了如何通过e_phoff、e_shoff等字段定位Program Headers和Section Headers。
摘要由CSDN通过智能技术生成

ELF Header:

首先利用ndk系统里面的readelf命令,查看so文件的elf 头信息:

 

自己解析的话:

 

ELF Header数据结构

 

由上面两张表推导出,elf 头文件各个结构的位置:

 

例如一个elf文件头信息():

将这些字段,按照规定解析之后:

e_ident[]数组:

(也叫魔数Magic Number)给出了ELF的一些标识信息

e_ident[]数组的下表以及取值:

e_ident[]是unsigned char,根据上面数据格式表,e_ident[]每一个位占一个byte大小。

 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:

查看字段,可知03为DYN:

Readelf中也可看出来是DYN:

 

e_machine:

字段中没有,不过可通过readelf文件中推断,0x28即40为ARM

 

 

e_version:

表示当前版本:

 

e_entry:

 

e_phoff:

phoff---推断全称为program head off,即程序表头的偏移,可以查出程序表头的开始位置:

这个比较重要,这里面0x34即52=16*3+4,可以查出程序表头的开始位置如下图:

 

e_shoff:

为segment head off,即节区头部表格偏移,可以查出节区表头的开始地址:

也重要,0x3130,可以查出节区表头的开始地址如下图:

 

 

e_flags:

 

e_ehsize:

Elf head size,这个头文件的大小

可以看出这个头的大小为0x34即52字节

 

e_phentsize:

这个表示之后每一个处程序头的大小0x20即32字节

 

e_phnum:

表示程序头的个数,至此,根据程序头的偏移e_phoff=0x34(即52),程序头的大小e_phentsize=0x20(即32),以及这里的程序头的个数e_phnum=0x07(即7),就可以完全解析出每个程序头的精确位置。

 

 

e_shentsize:

表示节区头部表格的大小0x28=40,根据之前的e_shoff=0x3130可以精确定位第一个节区表头的位置

 

e_shnum:

表示节区头部表格,个数为0x15(即21)个。

至此,根据e_shoff 0x3130, e_shentsize 0x28以及这个e_shnum 0x15可以完全确定所有节区头部表格的精确位置。下图位置画错了。

 

 

e_shstrndx:

标记节区头部表格中,字符串节区头部表格的索引,即第几个节区是字符串节区头部表格。这个索引是从0开始。所以这边0x14即20就是第21个节区头部表格表示的是字符串的节区头部表格。如下图:

 

 

Program Headers:

使用NDK中的readelf –l xx.so查看program headers信息

 

 

 

Segment Headers:

使用NDK中的readelf –S xx.so查看segment headers信息

首先根据elf header中最后一个e_shstrndx=0x14确定节区头部中字符串节区头部的位置是第20个(索引位置,0开始),然后根据字符串节区头部位置中的sh_offset和sh_size确定字符串节区的位置。

 

 

字符串节区头部位置:

得出的字符串节区的位置

 

sh_name

这个名称,根据上面查到的字符串节区来匹配名称:

根据字符串节区,得到0x01的名称为.shstrtab

查看readelf –S的到的结果相同

 

 

sh_type:

对比下面表格取值

 

sh_flags:

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

 

sh_add:

不知道有什么用,可能在实际运行的时候才有用

 

sh_offset:

静态偏移地址,根据这个可以查看到相对应节区的开始位置

 

sh_size:

相对应节区的大小,和sh_offset相结合,可以查看处对应节区的具体地址

 

sh_link

 

sh_info:

 

sh_addralign:

 

sh_entsize

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值