c-打印elf文件的节头的名称

  • 本文关键字:elf 文件 打印 c elf
  • 更新时间 :
  • 英文 :


typedef struct
{
uint8  e_ident[16];
uint16 e_type;
uint16 e_machine;
uint32 e_version;
uint32 e_entry;
uint32 e_phoff;
uint32 e_shoff;
uint32 e_flags;
uint16 e_ehsize;
uint16 e_phentsize;
uint16 e_phnum;
uint16 e_shentsize;
uint16 e_shnum;
uint16 e_shstrndx;
} Elf32Hdr;
typedef struct
{
uint32 sh_name;
uint32 sh_type;
uint32 sh_flags;
uint32 sh_addr;
uint32 sh_offset;
uint32 sh_size;
uint32 sh_link;
uint32 sh_info;
uint32 sh_addralign;
uint32 sh_entsize;
} Elf32SectHdr;
#pragma pack(pop)
{
FILE* ElfFile = NULL;
char* SectNames = NULL;
Elf32Hdr elfHdr;
Elf32SectHdr sectHdr;
uint idx;
// ...
// read ELF header
fread(&elfHdr, 1, sizeof elfHdr, ElfFile);
// read section name string table
// first, read its header
fseek(ElfFile, elfHdr.e_shoff + elfHdr.e_shstrndx * sizeof (sectHdr), SEEK_SET);
fread(&sectHdr, 1, sizeof sectHdr, ElfFile);
// next, read the section, string data
SectNames = malloc(sectHdr.sh_size);
fseek(ElfFile, sectHdr.sh_offset, SEEK_SET);
fread(SectNames, 1, sectHdr.sh_size, ElfFile);
// read all section headers
for (idx = 0; idx < elfHdr.e_shnum; idx++)
{
const char* name = "";
fseek(ElfFile, elfHdr.e_shoff + idx * sizeof sectHdr, SEEK_SET);
fread(&sectHdr, 1, sizeof sectHdr, ElfFile);
// print section name
if (sectHdr.sh_name);
name = SectNames + sectHdr.sh_name;
printf("%2u %sn", idx, name);
}
// ...
}

我正试图打印所有章节标题的名称,但有一点我不明白。为什么我们需要使用:fseek(ElfFile,elfHdr.e_shoff+elfHdr.e_shstrndx*sizeof(sectHdr(,SEEK_SET(;而不仅仅是
fseek(ElfFile、elfHdr.e_shoff、SEEK_SET(;我只是有点困惑,因为我不知道为什么它必须是elfHdr.e_shoff+elfHdr.e_shstrndx*sizeof(sectHdr(,而elfHdr.e_shoff表示节头的开始

为什么我们需要使用

要读取节头(它们是固定长度的记录(,您需要fseek(..., elfHdr.e_shoff, SEEK_SET)

但这不是名称(可变长度字符串(所在的位置。

要读取字符串,您需要读取特定(shstrndx(节的标头(这样您就知道在哪里可以找到其内容(,然后读取该节的内容。这正是这个代码所做的:

// first, read its header
fseek(ElfFile, elfHdr.e_shoff + elfHdr.e_shstrndx * sizeof (sectHdr), SEEK_SET);
fread(&sectHdr, 1, sizeof sectHdr, ElfFile);
// next, read the section, string data
SectNames = malloc(sectHdr.sh_size);
fseek(ElfFile, sectHdr.sh_offset, SEEK_SET);
fread(SectNames, 1, sectHdr.sh_size, ElfFile);

更新:

那么为什么我们需要相乘呢?

shstrndx中,您有字符串所在部分的索引。假设这个指数是17。所以你想阅读第17节的内容。

要获取第0节的标题,您需要查找
elfHdr.sh_offset + 0*elfHdr.e_shentsize

要获得2第2节的标题,您需要查找
elfHdr.sh_offset + 2*elfHdr.e_shentsize

要获得17第8节的标题,您需要查找
elfHdr.sh_offset + 17*elfHdr.e_shentsize

要获取shstrndx第10节的标题,您需要查找
elfHdr.sh_offset + elfHdr.e_shstrndx*elfHdr.e_shentsize

p.S.

从技术上讲,乘以sizeof(sectHdr)是不正确的——应该乘以elfHdr.e_shentsize

这在实践中并不重要——我从未见过e_shentsize != sizeof(sectHdr)的机器,但这样的机器可能存在

最新更新