文章目录
- 写在前面
- 准备
- .text节
- .data节
- .strtab
- .symtab
- .shstrtab
- .shstrtab之后
写在前面
只看readelf这个工具说实话我感觉还是有点云里雾里,这里就逐字节分析一下ELF文件中text节(代码段)的内容
本文分析使用的汇编程序ELF文件内容详解这篇文章
准备
hexdump -Cv filename 以经典的格式打印出十六进制的文件内容,且不省略全零行
objdump -d filename 反汇编
.text节
在右图上我们可以看到:text段在此ELF文件中的起始地址是0xb0,长度是0x27,
在左边的十六进制内容中,我们圈出了0xb0 — 0xd6地址处的内容,是什么呢?
通过和反汇编的结果对比可以看出:
text段的内容就是十六进制格式的汇编指令
.data节
首先观察右上的readelf工具输出,可以看到data段从0xd7位置开始,长度是0xd个字节,那么data段的内容就是左边白色高亮的部分,
再看汇编代码与od工具的输出,可以看到是我们定义的hello world~这12个字符,再加上最后结尾的空字符\0
.strtab
先讲后面的strtab再讲前面的symtab,因为symtab的st_name属性依赖于strtab
观察hexdump右侧的打印,可以看到:
strtab这里存放的是程序中出现的字符串
.symtab
大名鼎鼎的 符号表
symtab的Aglin是8,它要按照8字节对齐
所以符号表并不是从data段的末尾0xe4处直接开始的,而是空了4个字节,从0xe8处开始
符号表分析比text段和data段要复杂一些,这是elf.h中对64位下符号表的定义:
可以看出符号表的格式:
st_name | st_info | st_other | st_shndx | st_value | st_size |
---|---|---|---|---|---|
4字节 | 1字节 | 1字节 | 2字节 | 8字节 | 8字节 |
一共24字节 |
我们看下_start这个符号:
它位于符号表的第8个,那么_start的起始地址就在0xe8+3*24=0x1a8的位置处
st_name:符号的名称;在strtab中保存,这里的值是在strtab中的偏移量
上述_start符号的st_name值是0x2d,那么_start符号的名称应该位于0x208+0x2d=0x235处
经对比可以看到,0x235至下一个\0字符处保存的确实是_start的ASCII码值
st_info:符号的类型和绑定属性,高4位表示notype、object、func等,低4位表示local、global、weak等
st_other:通常用于指定符号的其他属性,但在许多情况下它并未使用,并被设置为0(不懂)
st_shndx:这个字段指示了符号所在的段(或节)在节头表中的索引。段或节是目标文件中代码、数据等的逻辑分组。
作用:它提供了符号在内存中的位置信息,这对于链接器和加载器在加载和执行程序时定位符号非常重要。
st_value:表示符号的值。对于可重定位的目标文件,它通常是符号相对于其所在段起始位置的偏移量。对于可执行文件,它表示符号在虚拟地址空间中的地址。
上述_start符号的value是0x4000b0就意味着运行时它会被加载到虚拟地址的0x4000b0处
st_size:表示符号的大小,即符号所代表的值或数据的字节数。
.shstrtab
这里存放的是各节的名称
.shstrtab之后
上面的几个section都已经分析完了,但是后面明显还有一大段二进制内容,是什么呢?
谜底啊,就在谜面上
shstrtab里存放的是节头表的内容,就是上述的这些数据,有空的话我会写一下,现在先把节头表的定义放在这里,大家可以自己分析下