Linux内核---39.ELF 结构分析

来源:互联网 发布:系统优化软件排行榜 编辑:程序博客网 时间:2024/05/16 23:46
一. ELF 结构分析
1. ELF 头
在include/linux/elf.h中
  1. typedef struct
  2. {
  3.   unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
  4.   Elf32_Half e_type; /* Object file type */
  5.   Elf32_Half e_machine; /* Architecture */
  6.   Elf32_Word e_version; /* Object file version */
  7.   Elf32_Addr e_entry; /* Entry point virtual address */
  8.   Elf32_Off e_phoff; /* Program header table file offset */
  9.   Elf32_Off e_shoff; /* Section header table file offset */
  10.   Elf32_Word e_flags; /* Processor-specific flags */
  11.   Elf32_Half e_ehsize; /* ELF header size in bytes */
  12.   Elf32_Half e_phentsize; /* Program header table entry size */
  13.   Elf32_Half e_phnum; /* Program header table entry count */
  14.   Elf32_Half e_shentsize; /* Section header table entry size */
  15.   Elf32_Half e_shnum; /* Section header table entry count */
  16.   Elf32_Half e_shstrndx; /* Section header string table index */
  17. } Elf32_Ehdr;
下面以hello.ko为例分析一下:

  1. 0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000    //e_ident
  2. 0000010: 0100  2800   0100 0000   0000 0000   0000 0000 
  3.          type mach  version    entry      phoff
  4. 0000020: 2cb7 0000    0000 0005   3400    0000       0000    2800
  5.          shoff       flags     ehsize phentsize phnum  shensize
  6. 0000030: 2400     2100
  7.          shnum   shstrndx
e_shoff = 0xb72c  = 46892 --> section header table在文件中的偏移是46892
e_shentsize = 0x28 = 40  --> section header table 每个entry是40Byte
e_shnum = 0x24 =36 --> 有36个section header table
e_shstrndx = 0x21 = 33 --> shstrtab(节的名字符串)在section header table中的第33项,这是一个索引


2. Section header 
  1. typedef struct
  2. {
  3.   Elf32_Word sh_name; /* Section name (string tbl index) */
  4.   Elf32_Word sh_type; /* Section type */
  5.   Elf32_Word sh_flags; /* Section flags */
  6.   Elf32_Addr sh_addr; /* Section virtual addr at execution */
  7.   Elf32_Off sh_offset; /* Section file offset */
  8.   Elf32_Word sh_size; /* Section size in bytes */
  9.   Elf32_Word sh_link; /* Link to another section */
  10.   Elf32_Word sh_info; /* Additional section information */
  11.   Elf32_Word sh_addralign; /* Section alignment */
  12.   Elf32_Word sh_entsize; /* Entry size if section holds table */
  13. } Elf32_Shdr;

  1. sun@ubuntu:/work/6410/yaffs2/work/hello$ readelf -./hello.ko
  2. There are 36 section headers, starting at offset 0xb72c:       //0xb72c--> section_header_table首地址
  3. Section Headers:
  4.   [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
  5.   [ 0] NULL 00000000 000000 000000 00 0 0 0
  6.   [ 1] .note.gnu.build-i NOTE 00000000 000034 000024 00 A 0 0 4
  7.   [33] .shstrtab STRTAB 00000000 00b5cf 00015d 00 0 0 1        //第33个section是shstrtab,它的内容在文件的中的地址是0xb5cf
  8.   [34] .symtab SYMTAB 00000000 00ec34 0004a0 10 35 59 4
  9.   [35] .strtab STRTAB 00000000 00f0d4 000209 00 0 0 1          //一共有36个section

这很类似于按字母查<英汉字典>一样,先跳过前言 致谢等, 找到总的目录查找字母的索引在第几页,
在字母索引中找到 字母S在第几页,  在字母S中查找strtab在哪一页.
  1. info->sechdrs = (void *)info->hdr + info->hdr->e_shoff;   //section string table的地址,相当于跳过了前言找到总目录表
  2. info->secstrings = (void *)info->hdr + info->sechdrs[info->hdr->e_shstrndx].sh_offset;
其中 info->hdr 是hello.ko在内核空间的基地址
info->sechdrs[info->hdr->e_shstrndx] //shstrtab(节的名字符串)在数组section header table中的第33项,这就相当于从总目录表中找到了字母S在哪一页
info->sechdrs[info->hdr->e_shstrndx].sh_offset //相当于在字母S中找到了单词shstrtab在哪一页

shstrtab = b72c + 40*33  =  BC54
shstrtab.sh_offset =*(BC54) = 0000 b5cf
0 0