linux实践——ELF分析

一、ELF的部分结构定义

  1. elf header(定义在/usr/include/elf.h)//64位的系统ELF文件头包括以下两个部分

    #define EI_NIDENT (16)
    typedef struct
    {
        unsigned char   e_ident[EI_NIDENT];/* Magic number  and other info */
    Elf32_Half  e_type;         /* Object file type */
    Elf32_Half  e_machine;      /* Architecture */
    Elf32_Word  e_version;      /* Object file version */
    Elf32_Addr  e_entry;        /* Entry point virtual address */
    Elf32_Off   e_phoff;        /* Program header table file offset */
    Elf32_Off   e_shoff;        /* Section header table file offset */
    Elf32_Word  e_flags;        /* Processor-specific flags */
    Elf32_Half  e_ehsize;       /* ELF header size in bytes */
    Elf32_Half  e_phentsize;        /* Program header table entry size */
    Elf32_Half  e_phnum;        /* Program header table entry count */
    Elf32_Half  e_shentsize;        /* Section header table entry size */
    Elf32_Half  e_shnum;        /* Section header table entry count */
    Elf32_Half  e_shstrndx;     /* Section header string table index */
    }   Elf32_Ehdr;  //32位
    
    typedef struct
    {
    unsigned char   e_ident[EI_NIDENT]; /* Magic number     and other info */
    Elf64_Half  e_type;         /* Object file type */
    Elf64_Half  e_machine;      /* Architecture */
    Elf64_Word  e_version;      /* Object file version */
    Elf64_Addr  e_entry;        /* Entry point virtual address */
    Elf64_Off   e_phoff;        /* Program header table file offset */
    Elf64_Off   e_shoff;        /* Section header table file offset */
    Elf64_Word  e_flags;        /* Processor-specific flags */
    Elf64_Half  e_ehsize;       /* ELF header size in bytes */
    Elf64_Half  e_phentsize;        /* Program header   table entry size */
    Elf64_Half  e_phnum;        /* Program header   table entry count */
    Elf64_Half  e_shentsize;        /* Section header   table entry size */
    Elf64_Half  e_shnum;        /* Section header   table entry count */
    Elf64_Half  e_shstrndx;     /* Section header   string table index */
    } Elf64_Ehdr;//64位
  2. section header

    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;
    
    typedef struct
    {
    Elf64_Word  sh_name;        /* Section name (string tbl index) */
    Elf64_Word  sh_type;        /* Section type */
    Elf64_Xword sh_flags;       /* Section flags */
    Elf64_Addr  sh_addr;        /* Section virtual addr at execution */
    Elf64_Off   sh_offset;      /* Section file offset */
    Elf64_Xword sh_size;        /* Section size in bytes */
    Elf64_Word  sh_link;        /* Link to another section */
    Elf64_Word  sh_info;        /* Additional section information */
    Elf64_Xword sh_addralign;       /* Section alignment */
    Elf64_Xword sh_entsize;     /* Entry size if section holds table */
    } Elf64_Shdr;

二、实践部分

hexdump hello.o

1.64位的文件头是64字节,具体如下

810675-20160531011832711-1326638000.png

第一行:

(对应e_ident[EI_NIDENT]):实际表示内容为7f45 4c46 0201 0100 0000 0000 0000 0000。

前四个字节7f45 4c46(0x45,0x4c,0x46是’e','l','f'对应的ASCⅡ)是一个魔数(magic number),表示这是一个ELF对象,接下来的一个字节02表示是一个64位对象(32位的对象是01),再接下来的一个字节01表示采用小端法表示,再接下来的一个字节01表示文件头版本,剩下的默认都设置为0。

第二行:

e_type(两个字节)值为0x0001,表示是一个重定位文件。
e_machine(两个字节)值为0x003e,表示是X86-64的处理器体系结构。
e_version(四个字节)值为0x00000001,表示是当前版本。
e_entry(八个字节)值为0x0000000000000000,表示没有入口点。

第三行:

e_phoff(八个字节)值为0x0000000000000000,表示没有程序头表。
e_shoff(八个字节)值为0x00000000000002b0,表示段表的偏移地址。

第四行:

e_flags(四个字节)值为0x00000000,表示未知处理器特定标志(#define EF_SH_UNKNOWN 0x0);
e_ehsize(两个字节)值为0x0040,表示elf文件头大小;
e_phentsize(两个字节)值均为0x0000,因为重定位文件没有程序头表。
e_phnum(两个字节)的值为0x0000,因为重定位文件没有程序头表。
e_ehentsize(两个字节)值为0x0040表示段头大小为64个字节(由这里知道section header table里面每个header的大小)。
e_shnum(两个字节)值为0x000d,表示段表入口有13个(由这里知道段表有13个段)。
e_shstrndx(两个字节)值为0x000a,表示段名串表的在段表中的索引号(由这里知道.shstrtab段(符号表)的信息在段表的索引号是10)。

2.由ELF头可知段表从000002b0开始,每个节区大小为0040,共有000d个节区,第000a为段名串表的索引号。

810675-20160531011931117-1536739244.png

810675-20160531012408633-423432204.png

810675-20160531012425289-1424739352.png

以上就是我们找到的section header table,然后我们再通过其找到各个section。

3.找具体section,如节区(2f0-320)

typedef struct
{
  Elf64_Word    sh_name;        /* Section name (string tbl index) */
  Elf64_Word    sh_type;        /* Section type */
  Elf64_Xword   sh_flags;       /* Section flags */
  Elf64_Addr    sh_addr;        /* Section virtual addr at execution */
  Elf64_Off sh_offset;      /* Section file offset */
  Elf64_Xword   sh_size;        /* Section size in bytes */
  Elf64_Word    sh_link;        /* Link to another section */
  Elf64_Word    sh_info;        /* Additional section information */
  Elf64_Xword   sh_addralign;       /* Section alignment */
  Elf64_Xword   sh_entsize;     /* Entry size if section holds table */
} Elf64_Shdr;

由Elf64_Word sh_name;得知此节区段名在段命串表中的偏移00000020
Elf64_Off sh_offset;段的起始位置00000040
Elf64_Xword sh_size段的大小00000031

810675-20160531012506383-454541738.png

使用objdump -x hello.o检验

810675-20160531012535696-2015096099.png

4.readelf -h hello.o

810675-20160531012601274-1149564453.png

5.readelf -s hello.o

810675-20160531012615602-2004572892.png

转载于:https://www.cnblogs.com/whyfarrell/p/5544532.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值