zoukankan      html  css  js  c++  java
  • LINUX实践--ELF分析

    一、ELF文件头(定义在/usr/include/elf.h)中

    二、实践部分

    第一行

    对应e_ident[EI_NIDENT]:实际表示内容为7f45 4c46 0101 0100 0000 0000 0000 0000。
    前4字节,是一个魔数,表示这是一个ELF对象

    下一个字节01说明是个32位对象(64位的是02);

    再下一个字节是01,说明使用的是小端方式

    再下来一个字节01表示文件头版本,剩下默认设置为0

    第二行:

    • e_type(占2字节)0x0002,表示是可执行文件

    • e_machine(2字节)0003,说明是intel 80386

    • e_version(4字节)0x00000001,说明是当前版本

    • e_entry(4字节)0x8048310,表面入口点为8048310

    • e_phoff(4字节)值为0x00000034 ,表示程序头表

    • e_shoff(4字节)值为0x000017d4,表示段表的偏移地址

    • e_flags(4字节)0x00000000,表示未知处理器特点标志(#define EF_SH_UNKNOWN 0x0)

    • e_ehsize(2字节)0x0034,表示ELF文件头大小为0x34H,(64位的是0x40H)

    • e_phentsize(2字节)0x0020,program header的大小是32比特。

    • e_phnum(2字节) 0x0009,program headers的数量是9个

    • e_ ehentsize(2字节) 0x0028,表示段头大小为40字节(由此可知section header table 里面表格header的大小)

    • e_ shnum(2字节) 0x001f,表示段表入口地址有31个(由此知道段表有31个段)

    • e_shstrndx (2字节) 0x001c,表示段名串表的在段表中的索引号(由此知.shstrtab段(符号表)的信息在段表的索引号是28)

    使用readelf -h hello查看ELF文件头。

    e_type表示文件类型,2表示可执行文件。

    e_machine:指明可以在哪种机器结构中运行。

    e_version:指明版本信息

    e_entry:指明系统运行该程序时将控制权转交到的虚拟地址的值,如果没有则为零。

    e_phoff: program header table在文件中的字节(Byte)偏移offset,如果没有program header table, 则该值为零。

    e_shoff: section header table在文件中的字节偏移,如果没有section header table, 则该值为零

    e_flags: 有关处理器的信息

    e_ehsize: elf header的大小,单位:字节

    e_phentsize: 在program header table中一个entry的大小,前面提到过,program header table & section header table都是数组,所以它们的每一个元素,即每一个entry的大小,都是一样的。

    e_phnum: program header table中元素的个数,即entry的个数。

    e_shentsize: section header table每一个entry的大小,与e_phentsize类似。

    e_shnum: section header table中元素的个数,即entry的个数。可以看出来,这个program header table或者section header table的大小可以用entry的个数乘以每一个entry的大小得到。

    e_shstrndx: 指明string name table在section header table中的index。

    通过readelf -a hello时查看段表头的情况,找到section headers

    然后分析其中各项的含义

    sh_name指出section的名字,它的值是后面将会讲到的section header string table中的索引,指出一个以null结尾的字符串。
    sh_type是类别
    sh_flags指示该section在进程执行时的特性。
    sh_addr指出若此section在进程的内存映像中出现,则给出开始的虚地址。
    sh_offset给出此section在文件中的偏移。

    找到段表

    由第三行的elf头可知,e_shoff值为0x000017d4,表示段表的偏移地址
    从这里开始找
    同理,e_ ehentsize(2字节) 0x0028,表示段表长度为40字节(由此可知section header table 里面表个header的大小)
    e_ shnum(2字节) 0x001f,表示段表入口地址有31个(由此知道段表有31个段)

    第一个段

    第二个段

    下面是一个段表结构
    typedef struct
    {
    Elf32_Word sh_name; /* Section name (string tbl index) /
    Elf32_Word sh_type; /
    Section type /
    Elf32_Word sh_flags; /
    Section flags /
    Elf32_Addr sh_addr; /
    Section virtual addr at execution /
    Elf32_Off sh_offset; /
    Section file offset /
    Elf32_Word sh_size; /
    Section size in bytes /
    Elf32_Word sh_link; /
    Link to another section /
    Elf32_Word sh_info; /
    Additional section information /
    Elf32_Word sh_addralign; /
    Section alignment /
    Elf32_Word sh_entsize; /
    Entry size if section holds table */
    } Elf32_Shdr;

    第三个段表

    第四个段表

    总共有31个段表

    理解常见的。text .strtab .symtabl .rodata等section

    文件的section含有程序和控制信息,系统使用一些特定的section,并有其固定的类型和属性(由sh_type和sh_info指出)。
    下面介绍几个常用到的section:“.bss”段含有占据程序内存映像的未初始化数据,当程序开始运行时系统对这段数据初始为零,但这个section并不占文件空间。
    “.data.”和“.data1”段包含占据内存映像的初始化数据。
    “.rodata”和“.rodata1”段含程序映像中的只读数据。
    “.shstrtab”段含有每个section的名字,由section入口结构中的sh_name索引。
    “.strtab”段含有表示符号表(symbol table)名字的字符串。
    “.symtab”段含有文件的符号表,在后文专门介绍。
    “.text”段包含程序的可执行指令。

  • 相关阅读:
    java.lang.OutOfMemoryError:GC overhead limit exceeded填坑心得
    linux修改系统时间和linux查看时区、修改时区的方法
    关于elasticsearch和kibana的时区和日期问题
    Jmeter中的几个重要测试指标释义
    jmeter之json数据参数化 断言等
    daemon
    linux之cp/scp命令+scp命令详解
    C语言中文件的读取和写入
    koa 项目实战(四)注册接口和调试工具(postman)
    koa 项目实战(三)创建测试接口和用户模型
  • 原文地址:https://www.cnblogs.com/5320zhq/p/5547510.html
Copyright © 2011-2022 走看看