如何在 C 中编写与打印节标题的 readelf -S 相同的程序?
Posted
技术标签:
【中文标题】如何在 C 中编写与打印节标题的 readelf -S 相同的程序?【英文标题】:How to write a program in C donig the same thing as readelf -S that print the section header? 【发布时间】:2022-01-22 22:42:08 【问题描述】:我正在尝试用 c 编写一个字体,它采用一个 elf 文件并预测命令 readelf -S
$ readelf -S prog.o
There are 10 section headers, starting at offset 0x7d8:
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .strtab STRTAB 0000000000000000 00000730
00000000000000a6 0000000000000000 0 0 1
[ 2] .text PROGBITS 0000000000000000 00000040
000000000000022c 0000000000000000 AX 0 0 16
[ 3] .rela.text RELA 0000000000000000 00000520
00000000000001f8 0000000000000018 9 2 8
[ 4] .rodata.str1.1 PROGBITS 0000000000000000 0000026c
0000000000000128 0000000000000001 AMS 0 0 1
[ 5] .comment PROGBITS 0000000000000000 00000394
0000000000000031 0000000000000001 MS 0 0 1
[ 6] .note.GNU-stack PROGBITS 0000000000000000 000003c5
0000000000000000 0000000000000000 0 0 1
[ 7] .eh_frame X86_64_UNWIND 0000000000000000 000003c8
0000000000000038 0000000000000000 A 0 0 8
[ 8] .rela.eh_frame RELA 0000000000000000 00000718
0000000000000018 0000000000000018 9 7 8
[ 9] .symtab SYMTAB 0000000000000000 00000400
0000000000000120 0000000000000018 1 4 8
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
l (large), p (processor specific)````
我编写了这段代码,但我不知道如何继续,因为我无法提取所需的信息,因此我可以打印它们,例如 sh_name、sh_type、地址、标志等...
int main(int argc,char *argv[])
if(argc < 2)
printf("Error: no elf-file\n ");
exit(1);
FILE *elfFile=fopen(argv[1],"rb");
if(elfFile==NULL)
printf("File open error!\n");
exit(1);
Elf32_Ehdr elfHeader;
Elf32_Shdr elfShdr;
fread(&elfHeader,1,sizeof(elfHeader),elfFile);
printf("There are %d section headers, starting at offset
0x%lx:\n\n",elfHeader.e_shnum,elfHeader.e_shoff);
printf("Section Headers:\n [Nr] Name Type Address
Offset\n Size EntSize Flags Link Info Align\n");
for(int i=0;i<elfHeader.e_shnum;i++)
fread(&elfShdr,1,sizeof(header),elfFile);
printf("\t[%d] %s %s %016x %08x\n",elfShdr.sh_name,elfShdr.type);
printf("\t %016x %016x %s %d %d %d\n");
printf("Key to Flags:\n");
printf(" W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n");
printf(" L (link order), O (extra OS processing required), G (group), T (TLS),\n");
printf(" C (compressed), x (unknown), o (OS specific), E (exclude),\n");
printf(" l (large), p (processor specific)\n");
return 0;
【问题讨论】:
【参考方案1】:我不知道如何继续,因为我无法提取所需的信息,因此我可以打印它们,例如 sh_name、sh_type、地址、标志等...
This answer 显示如何打印.sh_name
。
对于sh_type
,您只需将各种SHT_...
值转换回它们的符号表示。这是实现这一目标的一种方法:
const char *sht_to_name(Elf32_Word sh_type)
const char *names[] =
"NULL",
"PROGBITS",
"SYMTAB",
"STRTAB",
"RELA",
.... etc.
;
if (sh_type < sizeof(names) / sizeof(names[0]))
return names[sh_type];
return "UNKNOWN";
标志的类似代码:
// Append decoded flags to the given buffer
void decode_flags(Elf32_Word flags, char buf[], size_t bufsz)
char *p = buf + strlen(buf);
char *end = buf + bufsz;
if (flags & SHF_WRITE)
// Append "WRITE" if there is space
if (flags & SHF_ALLOC)
// Append "ALLOC" if there is space
... etc.
【讨论】:
以上是关于如何在 C 中编写与打印节标题的 readelf -S 相同的程序?的主要内容,如果未能解决你的问题,请参考以下文章