一. ELF 结构分析
1. ELF 头
在include/linux/elf.h中
下面以hello.ko为例分析一下:
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
这很类似于按字母查<英汉字典>一样,先跳过前言 致谢等, 找到总的目录查找字母的索引在第几页,
在字母索引中找到 字母S在第几页, 在字母S中查找strtab在哪一页.
其中 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
1. ELF 头
在include/linux/elf.h中
- 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;
- 0000000: 7f45 4c46 0101 0100 0000 0000 0000 0000 //e_ident
- 0000010: 0100 2800 0100 0000 0000 0000 0000 0000
- type mach version entry phoff
- 0000020: 2cb7 0000 0000 0005 3400 0000 0000 2800
- shoff flags ehsize phentsize phnum shensize
- 0000030: 2400 2100
- shnum shstrndx
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
- 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;
- sun@ubuntu:/work/6410/yaffs2/work/hello$ readelf -S ./hello.ko
- There are 36 section headers, starting at offset 0xb72c: //0xb72c--> section_header_table首地址
- Section Headers:
- [Nr] Name Type Addr Off Size ES Flg Lk Inf Al
- [ 0] NULL 00000000 000000 000000 00 0 0 0
- [ 1] .note.gnu.build-i NOTE 00000000 000034 000024 00 A 0 0 4
- [33] .shstrtab STRTAB 00000000 00b5cf 00015d 00 0 0 1 //第33个section是shstrtab,它的内容在文件的中的地址是0xb5cf
- [34] .symtab SYMTAB 00000000 00ec34 0004a0 10 35 59 4
- [35] .strtab STRTAB 00000000 00f0d4 000209 00 0 0 1 //一共有36个section
这很类似于按字母查<英汉字典>一样,先跳过前言 致谢等, 找到总的目录查找字母的索引在第几页,
在字母索引中找到 字母S在第几页, 在字母S中查找strtab在哪一页.
- info->sechdrs = (void *)info->hdr + info->hdr->e_shoff; //section string table的地址,相当于跳过了前言找到总目录表
- info->secstrings = (void *)info->hdr + info->sechdrs[info->hdr->e_shstrndx].sh_offset;
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