如何在 ELF 文件中查找 .strtab?
How to find `.strtab` in an ELF file?
当 运行 readelf -S
我得到:
[27] .strtab STRTAB 0000000000000000 00001630
00000000000001d7 0000000000000000 0 0 1
[28] .shstrtab STRTAB 0000000000000000 00001807
0000000000000103 0000000000000000 0 0 1
如何获取.strtab
的索引?
起初我尝试使用 Type
字段来检测它,但是如您所见(27 和 28 具有相同的类型),这不起作用。另外我不能确定它会是第一个出现的 STRTAB 类型。
我的结构和一些解释:
/*
* Section header.
*/
typedef struct {
Elf64_Word sh_name; /* Section name (index into the
section header string table). */
Elf64_Word sh_type; /* Section type. */
Elf64_Xword sh_flags; /* Section flags. */
Elf64_Addr sh_addr; /* Address in memory image. */
Elf64_Off sh_offset; /* Offset in file. */
Elf64_Xword sh_size; /* Size in bytes. */
Elf64_Word sh_link; /* Index of a related section. */
Elf64_Word sh_info; /* Depends on section type. */
Elf64_Xword sh_addralign; /* Alignment in bytes. */
Elf64_Xword sh_entsize; /* Size of each entry in section. */
} Elf64_Shdr;
How can I get the index of .strtab
?
您一一阅读 Elf64_Shdr
。当你读完第28条,你就会读到.strtab
,你就会知道它的索引。
通过将其名称与 ".strtab"
字符串文字进行比较,您将知道它是 .strtab
部分。
(你可能是想问一个不同的问题,但如果是这样,那是你没有表达好。)
更新:
Can't I do anything else rather than comparing strings
也许吧。如果您真正的问题是找到 .strtab
部分,那不是真的。
(which is somehow hard) can I assume it will be the first STRTAB in the file for example?
不能保证会是这种情况。
注意:如果你担心strcmp()
的速度,请注意你只能在.sh_type == SHT_STRTAB
时strcmp()
,因为通常最多有两个这样的部分在任何给定的文件中,对 strcmp()
速度的担忧很可能是错误的。您的代码类似于:
if (shdr.sh_type == SHT_STRTAB) {
const char *sh_name = contents_of_shstrab + shdr.sh_name;
if (strcmp(sh_name, ".strtab") == 0) {
/* found .strtab; do whatever you need with it */
}
}
更新 2:
your solution is wrong, please see:
你不能说我的解决方案是错误的,因为我没有提供完整的解决方案。也是不错的。
这是完整的代码(省略了大部分错误检查):
#include <elf.h>
#include <fcntl.h>
#include <link.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
if (argc < 1) return 1;
int fd = open(argv[1], O_RDONLY);
if (fd == -1) return 2;
struct stat st_buf;
if (fstat(fd, &st_buf) != 0) return 3;
char *data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data == MAP_FAILED) return 4;
const ElfW(Ehdr) *ehdr = (const ElfW(Ehdr) *)data;
const ElfW(Shdr) *shdr = (const ElfW(Shdr) *)(data + ehdr->e_shoff);
const char *shstrtab = data + shdr[ehdr->e_shstrndx].sh_offset;
for (int j = 0; j < ehdr->e_shnum; j++) {
printf("[%2d] %s\n", j, shstrtab + shdr[j].sh_name);
}
return 0;
}
$ gcc -g t.c -Wall
$ ./a.out ./a.out
[ 0]
[ 1] .interp
[ 2] .note.gnu.build-id
[ 3] .note.ABI-tag
[ 4] .gnu.hash
[ 5] .dynsym
[ 6] .dynstr
...
[32] .symtab
[33] .strtab
[34] .shstrtab
当 运行 readelf -S
我得到:
[27] .strtab STRTAB 0000000000000000 00001630
00000000000001d7 0000000000000000 0 0 1
[28] .shstrtab STRTAB 0000000000000000 00001807
0000000000000103 0000000000000000 0 0 1
如何获取.strtab
的索引?
起初我尝试使用 Type
字段来检测它,但是如您所见(27 和 28 具有相同的类型),这不起作用。另外我不能确定它会是第一个出现的 STRTAB 类型。
我的结构和一些解释:
/*
* Section header.
*/
typedef struct {
Elf64_Word sh_name; /* Section name (index into the
section header string table). */
Elf64_Word sh_type; /* Section type. */
Elf64_Xword sh_flags; /* Section flags. */
Elf64_Addr sh_addr; /* Address in memory image. */
Elf64_Off sh_offset; /* Offset in file. */
Elf64_Xword sh_size; /* Size in bytes. */
Elf64_Word sh_link; /* Index of a related section. */
Elf64_Word sh_info; /* Depends on section type. */
Elf64_Xword sh_addralign; /* Alignment in bytes. */
Elf64_Xword sh_entsize; /* Size of each entry in section. */
} Elf64_Shdr;
How can I get the index of
.strtab
?
您一一阅读 Elf64_Shdr
。当你读完第28条,你就会读到.strtab
,你就会知道它的索引。
通过将其名称与 ".strtab"
字符串文字进行比较,您将知道它是 .strtab
部分。
(你可能是想问一个不同的问题,但如果是这样,那是你没有表达好。)
更新:
Can't I do anything else rather than comparing strings
也许吧。如果您真正的问题是找到 .strtab
部分,那不是真的。
(which is somehow hard) can I assume it will be the first STRTAB in the file for example?
不能保证会是这种情况。
注意:如果你担心strcmp()
的速度,请注意你只能在.sh_type == SHT_STRTAB
时strcmp()
,因为通常最多有两个这样的部分在任何给定的文件中,对 strcmp()
速度的担忧很可能是错误的。您的代码类似于:
if (shdr.sh_type == SHT_STRTAB) {
const char *sh_name = contents_of_shstrab + shdr.sh_name;
if (strcmp(sh_name, ".strtab") == 0) {
/* found .strtab; do whatever you need with it */
}
}
更新 2:
your solution is wrong, please see:
你不能说我的解决方案是错误的,因为我没有提供完整的解决方案。也是不错的。
这是完整的代码(省略了大部分错误检查):
#include <elf.h>
#include <fcntl.h>
#include <link.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
if (argc < 1) return 1;
int fd = open(argv[1], O_RDONLY);
if (fd == -1) return 2;
struct stat st_buf;
if (fstat(fd, &st_buf) != 0) return 3;
char *data = mmap(NULL, st_buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if (data == MAP_FAILED) return 4;
const ElfW(Ehdr) *ehdr = (const ElfW(Ehdr) *)data;
const ElfW(Shdr) *shdr = (const ElfW(Shdr) *)(data + ehdr->e_shoff);
const char *shstrtab = data + shdr[ehdr->e_shstrndx].sh_offset;
for (int j = 0; j < ehdr->e_shnum; j++) {
printf("[%2d] %s\n", j, shstrtab + shdr[j].sh_name);
}
return 0;
}
$ gcc -g t.c -Wall
$ ./a.out ./a.out
[ 0]
[ 1] .interp
[ 2] .note.gnu.build-id
[ 3] .note.ABI-tag
[ 4] .gnu.hash
[ 5] .dynsym
[ 6] .dynstr
...
[32] .symtab
[33] .strtab
[34] .shstrtab