我想在符号表中打印符号的名称。 我将elf映射到虚拟内存(使用mmap),我成功访问了符号表,但是在尝试打印符号名称时失败(显示了一个奇数字符串,将其与elf文件的结果进行比较)。
我的代码:
void printSymboles() {
Elf32_Sym* symtab;
Elf32_Shdr * sh_strtab_p ;
char *sh_strtab;
int symbol_num=-1;
if(currentFd==-1){
printf("not legal file set\n");
} else {
sectionHeader=(Elf32_Shdr*)(map_start+header->e_shoff);
int section_num=header->e_shnum;
int numSectionsFound=0;
for(int i=0;i<section_num &&numSectionsFound<2;i++){
if(sectionHeader[i].sh_type==SHT_SYMTAB) {
symtab=(Elf32_Sym *) (map_start+sectionHeader[i].sh_offset);
symbol_num= sectionHeader[i].sh_size/sectionHeader[i].sh_entsize; // symobl tbl size/ entrysize
numSectionsFound++;
}
if(sectionHeader[i].sh_type==SHT_STRTAB) {
sh_strtab_p=§ionHeader[i];
sh_strtab=(char*) map_start+sh_strtab_p->sh_offset;
numSectionsFound++;
}
}
if(symbol_num==-1) {
printf("symbol table doesn't exist");
} else {
printf("symbol table : \n");
for(int i=0;i<symbol_num;i++) {
printf("name : %s\n",sh_strtab+symtab[i].st_name);
}
}
答案 0 :(得分:1)
问题几乎可以肯定是,您在错误的SHT_STRTAB节中查找-扫描标题以查找SHT_STRTAB节,无论最后找到哪个,您都记得在sh_strtab_p中。如果您的ELF文件像大多数elf文件一样,则可能是节标题字符串表(包含节标题名称),而不是带有符号名称的字符串表。
要查找带有符号名称的字符串表,您需要查看符号表节标题的sh_link
字段-告诉您字符串表的节号(节标题中的索引)包含该符号部分中符号名称的部分。文件中可以有任意多个SYMTAB节,每个节都有自己的STRTAB节。
将所有内容放在一起,您想要更多类似的东西:
Elf32_Shdr *section = (Elf32_Shdr*)(map_start+header->e_shoff);
char *section_names = (char *)(map_start + section[header->e_shstrndx].sh_offset);
for(int i=0; i<header->e_shnum; i++) {
if(section[i].sh_type==SHT_SYMTAB) {
printf("Symobl table %s:\n", section_names + section[i].sh_name);
Elf32_Sym *symtab = (Elf32_Sym *)(map_start+section[i].sh_offset);
int symbol_num = section[i].sh_size/section[i].sh_entsize;
char *symbol_names = (char *)(map_start + section[section[i].sh_link].sh_offset);
for (int j=0; j<symbol_num; j++) {
printf("name : %s\n", symbol_names + symtab[j].st_name);
}
}
}
当然,最好进行完整性检查以确保没有索引超出它们所索引的部分的范围,并且sh_entsize和e_shentsize匹配所使用的结构的大小,以防万一ELF文件已损坏。
答案 1 :(得分:0)
就像@chris Dodd提到的那样,问题确实出在SHT_STRTAB上。 我已经更改了这段代码:
if(sectionHeader[i].sh_type==SHT_STRTAB) {
sh_strtab_p=§ionHeader[i];
sh_strtab=(char*) map_start+sh_strtab_p->sh_offset;
numSectionsFound++;
}
对此:
Elf32_Shde * sh_sectionStrTbl_p;
char * sh_sectionStrTbl;
sh_sectionStrTbl_p=§ionHeader[header->e_shoff);
sh_sectionStrTbl=map_start+sh_sectionStrTbl_p->sh_offset;
if(sectionHeader[i].sh_type==SHT_STRTAB) {
if(strcmp(sectionHeader[i].sh_name+sh_sectionStrTbl,".strtab")==0) {
sh_strtab_p=§ionHeader[i];
sh_strtab=(char*) map_start+sh_strtab_p->sh_offset;
numSectionsFound++;
}
}
,并且有效。