zoukankan      html  css  js  c++  java
  • 《Linux及安全》实践3.1

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

    一、基础操作

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

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

    2.编写hello.c文件

    3.查看文件类型、大小

    • 可以看到是可重定位文件,大小为1028比特

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

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

    • 可以看到,Size of this header(文件头部)52bytes

    二、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),可以由此找到各段的位置。

    4.分析各段

    1. .text段分析

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

    2. .strtab段分析

      • 该段的offset是0x3d8(正好在.symtab段之后),size是0x13,即到0x2ea为止。
        对应字符串为:“hello.cmainputs”

    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.补充

    • 从前面对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个段

  • 相关阅读:
    Git 进阶学习
    My SQL 学习打卡 60天搞定mysql
    设计模式 学习笔记
    docker 从入门到精通
    java 异步线程下的顺序控制
    Maven 工程 如何添加 oracle 驱动 问题
    Hive 2.1.1 学习笔记
    Linux 下 MySQL-5.6.16 安装
    hadoop2.x HDFS HA linux环境搭建
    [LC] 1146. Snapshot Array
  • 原文地址:https://www.cnblogs.com/lwr-/p/5545686.html
Copyright © 2011-2022 走看看