ELF Section Header的结构还是要从/usr/include/elf.h中看。
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;
同样,可以算出来Elf32_Shdr的大小是40B。其结构中的各个元素数据类型在elf.h中同样可以找到,含义见注释。整个section
header
table就是一个数组,数组的每一个元素就是Elf32_Shdr。Elf32_Shdr仅仅是section的一个索引,包括一些属性信息,并不是
section本省。简单的介绍一下各个元素的含义。
sh_name: section
name。不过其实sh_name中存放的是index,不是字符串,这一点从sh_name是定长应该能看出来,那么index又是什么意思
呢?index的含义是在string tabl总的第几个字节数。其实是这样的,所有的section name都存放在一个叫做string
table的表中,index就是该section名字的第一个字符在表中的位置,名字一直到遇到一个'\0'为止结束。至于string
table怎么找,还记得上一篇中提到的elf header中的e_shstrndx成员吗,它就指明了string table是在section
header table中的第几个入口。
sh_offset:这个元素就指明了这个Elf32_Shdr描述的section在文件中的偏移量。
其他各个变量可以查询《Executable and Linkable Format(ELF)》这个文档。
为了检验程序输出结果的对错,我们与readelf这个命令的输出结果作比较。
下面编程序来输出文件的section信息。首先要找到section header table在文件中的位置,回忆一下,section
header table的偏移量在elf header中的e_shoff中告诉了我们,所以,我们就知道了section header
table在文件中的位置了,同样,我们在elf header中可以找到section
header的大小及个数,这样我们用一个循环就可以输出出来每个section的信息了。
fseek(fp, elfheader.e_shoff, SEEK_SET);
shnum = elfheader.e_shnum;
printf("Number of Section headers: %d\n\n", shnum);
while(shnum != 0){
fread(&shdr, sizeof(char), sizeof(shdr), fp);
printf("sh_name : %d\n", shdr.sh_name);
printf("sh_type : %#x\n", shdr.sh_type);
printf("sh_flags : %d\n", shdr.sh_flags);
printf("sh_addr : %#x\n", shdr.sh_addr);
printf("sh_offset : %d\n", shdr.sh_offset);
printf("sh_size : %d\n", shdr.sh_size);
printf("sh_link : %d\n", shdr.sh_link);
printf("sh_info : %d\n", shdr.sh_info);
printf("sh_addralign : %d\n", shdr.sh_addralign);
printf("sh_entsize : %d\n\n", shdr.sh_entsize);
shnum--;
}
输出的结果如下:
Number of Section headers: 34
sh_name : 0
sh_type : 0
sh_flags : 0
sh_addr : 0
sh_offset : 0
sh_size : 0
sh_link : 0
sh_info : 0
sh_addralign : 0
sh_entsize : 0
sh_name : 27
sh_type : 0x1
sh_flags : 2
sh_addr : 0x80480f4
sh_offset : 244
sh_size : 19
sh_link : 0
sh_info : 0
sh_addralign : 1
sh_entsize : 0
sh_name : 35
sh_type : 0x7
sh_flags : 2
sh_addr : 0x8048108
sh_offset : 264
sh_size : 32
sh_link : 0
sh_info : 0
sh_addralign : 4
sh_entsize : 0
...
观察上面的结果可以看到,sh_name并不是section的名字,而是一个数字。回忆前面提到的,sh_name存放的只是section
name在string table的index。因此,为了输出section name我们必须先得到string table。string
table的信息也在section header table中存放,只要我们得到了string table
header的内容,就可以从里面的sh_offset知道string table的位置,从sh_size知道string
table的大小。此时问题就成为如何找到string talbe header在section header
table中的位置,即index.回忆前面讲到的,elf header中有一个变量e_shstrndx存放的就是string table
header在section header中的index。此时整个思路已经明白了,即elfheader.e_shstrndx -->
string table header --> string table。string
table里面到底是什么呢?其实就是一些带'\0'的字符串。比如\0.bss\0.text\0\0,那么如果sh_name是1,则该
sh_name代表的是从string table中零开始的直到遇到\0为止的字符串,即.bss。整个程序如下:
fseek(fp, elfheader.e_shoff + elfheader.e_shstrndx*elfheader.e_shentsize, SEEK_SET);
fread(&strhdr, sizeof(char), sizeof(strhdr), fp);//get the string table header
fseek(fp, strhdr.sh_offset, SEEK_SET);
strtable = (unsigned char *)malloc(sizeof(unsigned char)*strhdr.sh_size);
fread(strtable, sizeof(char), strhdr.sh_size, fp);
fseek(fp, elfheader.e_shoff, SEEK_SET);
shnum = elfheader.e_shnum;
printf("Number of Section headers: %d\n\n", shnum);
while(shnum != 0){
fread(&shdr, sizeof(char), sizeof(shdr), fp);
printf("sh_name : %s\n", strtable+shdr.sh_name);
printf("sh_type : %#x\n", shdr.sh_type);
printf("sh_flags : %d\n", shdr.sh_flags);
printf("sh_addr : %#x\n", shdr.sh_addr);
printf("sh_offset : %d\n", shdr.sh_offset);
printf("sh_size : %d\n", shdr.sh_size);
printf("sh_link : %d\n", shdr.sh_link);
printf("sh_info : %d\n", shdr.sh_info);
printf("sh_addralign : %d\n", shdr.sh_addralign);
printf("sh_entsize : %d\n\n", shdr.sh_entsize);
shnum--;
}
程序的输出结果为:
Number of Section headers: 34
sh_name :
sh_type : 0
sh_flags : 0
sh_addr : 0
sh_offset : 0
sh_size : 0
sh_link : 0
sh_info : 0
sh_addralign : 0
sh_entsize : 0
sh_name : .interp
sh_type : 0x1
sh_flags : 2
sh_addr : 0x80480f4
sh_offset : 244
sh_size : 19
sh_link : 0
sh_info : 0
sh_addralign : 1
sh_entsize : 0
sh_name : .note.ABI-tag
sh_type : 0x7
sh_flags : 2
sh_addr : 0x8048108
sh_offset : 264
sh_size : 32
sh_link : 0
sh_info : 0
sh_addralign : 4
sh_entsize : 0
sh_name : .hash
sh_type : 0x5
sh_flags : 2
sh_addr : 0x8048128
sh_offset : 296
sh_size : 64
sh_link : 4
sh_info : 0
sh_addralign : 4
sh_entsize : 4
阅读(2911) | 评论(0) | 转发(0) |