如何获取shstrtab的字符串?
How to get the strings of shstrtab?
我在写Linux'readelf的简化版。
我想打印栏目信息,所以我需要栏目名称。在 Elf64_Shdr 结构中,sh_name 变量仅将我指向 shstrtab 中的索引。但这似乎不是 shstrtab header 中的索引。它是其关联数据的索引。我想知道如何到达那里,因为 ELF header 只将我指向 shstrtab 部分 header,而不是它的相关数据。从文件的 hexdump 中可以看出,文件的结构如下:
ELF HEADER
phdr1
phdr2
segment1
segment2
shstrtab strings (i want this address, to make use of the sh_name indices)
shdr1
shdr2
shdr3 (this is the shstrtab section)
我是不是想错了?
任何人都可以指导我获取部分名称吗?
我刚刚自己找到了解决方案!
要获取某个部分的关联数据,只需在其 Elf64_Shdr 结构中使用 sh_offset。如果在文件的起始地址加上sh_offset,则直接得到段数据。
下面的代码可以列出 header 部分的名称。
int main()
{
const char *file_name;
char *strtable, *sh_name;
size_t file_size;
struct stat st;
void *data;
Elf64_Ehdr hdr;
Elf64_Shdr shdr;
int i, fd, idx, strndx, stroff, spot;
if ((fd = open(file_name, O_RDONLY)) < 0) {
printf("fail to open %s\n", file_name);
exit(EXIT_FAILURE);
}
data = MAP_FAILED;
if (!fstat(fd, &st)) {
file_size = st.st_size;
data = mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
}
close(fd);
if (data == MAP_FAILED) {
printf("Unable map\n");
exit(EXIT_FAILURE);
}
// read elf header
memcpy(&hdr, data, sizeof(hdr));
// read section header string table header
spot = hdr.e_shoff; // section header table file offset
strndx = hdr.e_shstrndx; // section header string table index
stroff = spot + strndx * hdr.e_shentsize;
memcpy(&shdr, (char *)data + stroff, hdr.e_shentsize);
// read section string table
strtable = (char *)malloc(shdr.sh_size);
memcpy(strtable, (char *)data + shdr.sh_offset, shdr.sh_size);
for (i = 0; i< hdr.e_shnum; ++i) {
memcpy(&shdr, (char *)data + spot, hdr.e_shentsize);
spot += hdr.e_shentsize;
sh_name = &(strtable[shdr.sh_name]);
printf("[%d] %s\n", i, sh_name);
}
}
结果如下:
[0]
[1] .interp
[2] .note.ABI-tag
[3] .gnu.hash
[4] .dynsym
[5] .dynstr
[6] .gnu.version
...
我在写Linux'readelf的简化版。
我想打印栏目信息,所以我需要栏目名称。在 Elf64_Shdr 结构中,sh_name 变量仅将我指向 shstrtab 中的索引。但这似乎不是 shstrtab header 中的索引。它是其关联数据的索引。我想知道如何到达那里,因为 ELF header 只将我指向 shstrtab 部分 header,而不是它的相关数据。从文件的 hexdump 中可以看出,文件的结构如下:
ELF HEADER
phdr1
phdr2
segment1
segment2
shstrtab strings (i want this address, to make use of the sh_name indices)
shdr1
shdr2
shdr3 (this is the shstrtab section)
我是不是想错了? 任何人都可以指导我获取部分名称吗?
我刚刚自己找到了解决方案!
要获取某个部分的关联数据,只需在其 Elf64_Shdr 结构中使用 sh_offset。如果在文件的起始地址加上sh_offset,则直接得到段数据。
下面的代码可以列出 header 部分的名称。
int main()
{
const char *file_name;
char *strtable, *sh_name;
size_t file_size;
struct stat st;
void *data;
Elf64_Ehdr hdr;
Elf64_Shdr shdr;
int i, fd, idx, strndx, stroff, spot;
if ((fd = open(file_name, O_RDONLY)) < 0) {
printf("fail to open %s\n", file_name);
exit(EXIT_FAILURE);
}
data = MAP_FAILED;
if (!fstat(fd, &st)) {
file_size = st.st_size;
data = mmap(0, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
}
close(fd);
if (data == MAP_FAILED) {
printf("Unable map\n");
exit(EXIT_FAILURE);
}
// read elf header
memcpy(&hdr, data, sizeof(hdr));
// read section header string table header
spot = hdr.e_shoff; // section header table file offset
strndx = hdr.e_shstrndx; // section header string table index
stroff = spot + strndx * hdr.e_shentsize;
memcpy(&shdr, (char *)data + stroff, hdr.e_shentsize);
// read section string table
strtable = (char *)malloc(shdr.sh_size);
memcpy(strtable, (char *)data + shdr.sh_offset, shdr.sh_size);
for (i = 0; i< hdr.e_shnum; ++i) {
memcpy(&shdr, (char *)data + spot, hdr.e_shentsize);
spot += hdr.e_shentsize;
sh_name = &(strtable[shdr.sh_name]);
printf("[%d] %s\n", i, sh_name);
}
}
结果如下:
[0]
[1] .interp
[2] .note.ABI-tag
[3] .gnu.hash
[4] .dynsym
[5] .dynstr
[6] .gnu.version
...