zoukankan      html  css  js  c++  java
  • 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字节,具体如下

    第一行:

    (对应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为段名串表的索引号。

    以上就是我们找到的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

    使用objdump -x hello.o检验

    4.readelf -h hello.o

    5.readelf -s hello.o

  • 相关阅读:
    8) linux安装samba服务器
    7) k8s获取apiversion下面的对应可用资源
    4) cobbler自动安装linux
    3) KVM命令--使用篇(1)
    2) 各种开源环境自动部署脚本
    1) nginx编译安装
    扁平式小清新导航
    互联网公司常用水平导航(二级导航)
    水平导航-三级导航-切换流畅
    简约蓝色系导航(三级导航)
  • 原文地址:https://www.cnblogs.com/whyfarrell/p/5544532.html
Copyright © 2011-2022 走看看