《Linux及安全》实践3.1

《Linux及安全》实践三 ELF格式文件分析

1、基础操做

1.查看大小端、32仍是64

  • 由此能够看出,本人实践所用到的是32位Ubuntu,数据存储采用小端法。linux

2.编写hello.c文件

3.查看文件类型、大小

  • 能够看到是可重定位文件,大小为1028比特安全

4.以16进制形式输出hello.o文件

5.经过ELF headers table阅读文件各个段的信息

  • 能够看到,Size of this header(文件头部)52byteside

2、ELF文件格式分析

1.查看ELF头部定义

  • ELF头部的定义在/usr/include/elf.h中:
    • - (为不一样位数设置)
    • - (ELF头结构体定义)

2.分析hello 的ELF头部

  • 已知头部大小52字节
    • 0000000 457f 464c 0101 0001 0000 0000 0000 0000
        0000010 0002 0003 0001 0000 8320 0804 0034 0000
        0000020 1174 0000 0000 0000 0034 0020 0009 0028
        0000030 001e 001b
    • 第一行分析:
      • 其前16个字节(第一行,对应e_ident[EI_NIDENT])实际表示内容为7f45 4c46 0101 0100 0000 0000 0000 0000,前四个字节7f454c46(0x45,0x4c,0x46是'e','l','f'对应的ascii编码)是一个魔数(magic number),表示这是一个ELF对象。接下来的一个字节01表示是一个32位对象,接下来的一个字节01表示是小端法表示,再接下来的一个字节01表示文件头版本。剩下的默认都设置为0。
    • 第二行分析:
      • e_type(两个字节)值为0x0002,表示可执行文件。
      • e_machine(两个字节)值为0x0003,表示是intel80386处理器体系结构。
      • e_version(四个字节)值为0x00000001,表示是当前版本。
      • e_entry(四个字节)值为0x83200804,表示程序进入点。
      • e_phoff(四个字节)值为0x00340000,表示结头表偏移量。
    • 第三行分析:
      • e_shoff(四个字节)值为0x1174,表示段表的偏移地址。
      • e_flags(四个字节)值为0x00000000,表示未知处理器特定标志(#define EF_SH_UNKNOWN 0x0)。
      • e_ehsize(两个字节)值为0034,表示elf文件头大小(正好是52个字节)。
      • e_phentsize(两个字节)为0x0020,表示程序头表中每一个条目的大小为32.
      • e_ehentsize(两个字节)值为0x0028表示段头大小为40个字节。
      • e_shnum(两个字节)值为0x001e,表示段表入口有28个。e_shstrndx(两个字节)值为0x001b,表示段名串表的在段表中的索引号为27。

3.分析hello.o的section header table

  • 由上图可见,section header table中包括了各段的偏移地址(off)和大小(size),能够由此找到各段的位置。this

4.分析各段

  1. .text段分析编码

    • Hello.o中.text大小为0X1c,即十进制的28。
    • 对hello.o进行反汇编
      • 能够看到.text段跨越0x0到0x1b,刚好共0x1c(即28)个字节3d

  2. .strtab段分析
    • 该段的offset是0x3d8(正好在.symtab段以后),size是0x13,即到0x2ea为止。
      对应字符串为:“\0hello.c\0main\0puts\0”code

  3. .symtab段分析
      • 上图是.symtab所拥有的入口数量
    • 从上面的分析已经知道,.symtab的偏移量为0x328(即808),大小为0xb0(即十进制176)。于是数据即上图中标为黄色的部分
    • 该结构大小为16个字节,而整个符号表段大小为176个字节,因此总共能够分红11个符号。
    • 这11个符号恰好和前面objdump输出的符号表(10个符号,第一个符号为空,因此被忽略)结果相对应;也和使用readelf中符号表相关内容对应(readelf命令输出结果比objdump输出结果看起来更易懂一些):对象

  4. rodata段分析
    • 由于位于.rodata段上面的.bss段size为0x00,因此.bss和.rodata偏移量同样(都是0x50),.rodata段大小为0xd,也就是13个字节。即:
      68 65 6c 6c 6f 20 2c 20 35 32 31 36 00。
      • 对照ACII码表 ,能够拼出其正好对应HELLO,5216

5.补充blog

  • 从前面对ELF头的解析能够知道段表的地址是从0x1174(e_shoff项)开始,而上面的.shstrtab的开始地址为0xc0,大小为0x5f,因此此处段表应该是从0x11f开始(0xc0+0x5f)。再根据e_shnum=23和ehentsize=28可知,有23个段,每一个段占28个字节大小,总共占据644个字节(16进制为0x284)。段入口的类型定义以下(/usr/include/elf.h):
    • 从0x1174开始有13个段,每一个段占28个字节大小。
  • 第一个段,其中内容所有为0,因此不表示任何段。内容以下:
  • 第二个段对应内容为:
    • 段中每一个成员均为4个字节,因此分析起来相对简单一些。
    • sh_name值为0x0000001f,它表示该段名称在.shstrtab中偏移量,经过计算可知该名称为.text。
    • sh_type值为0x00000001(对应SHT_PROGBITS),表示这个段拥有程序所定义的信息,其格式和含义彻底有该程序肯定。
    • sh_flags值为0x00000006(对应于SHF_ALLOC和SHF_EXECINSTR)。
    • sh_addr值为0x00000000,表示这个段不会出如今进程的地址镜像中。
    • sh_offset值为0x00000034(偏移地址),
    • sh_size值为0x00000017,表示代码段大小为23(0x17)个字节。
    • sh_link值为0x00000000,表示没有连接信息。
    • sh_info值为0x00000000,表示没有辅助信息。
    • sh_addalign值为0x00000004,表示4个字节对齐
    • sh_entsize值为0x00000000,表示没有入口。
  • 第三个段为:
    • 该段为.rel.text段(偏移量为0x0000001b),sh_type为0x00000009(对应SHT_REL),sh_offset为0x000003ec,sh_size为0x00000010(16个字节)。sh_link和sh_info分别为b和1,分别表示相关符号表索引和重定位应用段的段头索引。其他段的内容再也不详细分析,能够本身分析并于前面readelf输出结果相对照。
      ……索引

  • 第23个段
相关文章
相关标签/搜索