【问题标题】:printing elf names of section headers打印节标题的精灵名称
【发布时间】:2021-03-13 12:06:03
【问题描述】:

我有一个 C 程序,我想在其中打印输入文件的节标题的名称。 我所做的一切都是基于研究 ELF 符号并帮助互联网上的现有程序,但它仍然无法正常工作。它只打印来自 for 循环的索引,其中也应该是部分名称。有人看到我错过的东西吗?

更新: 如果将来有人需要,我更新了代码并删除了导致 Stack Overflow 的错误。

代码:


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <elf.h>

int main(int argc, char *argv[]) {


    int fd;
    int val;

    Elf32_Ehdr elfHdr;
    Elf32_Shdr sectHdr;
    FILE* ElfFile = NULL;
    char* SectNames = NULL;

    if(argc != 2) {
        perror("Error while opening file");
        return 0;
    }   



    ElfFile = fopen(argv[1], "r");
    if(ElfFile == NULL) {
        printf("fopen");
        return -1;
    }

    //preberemo elf header
    fread(&elfHdr, 1, sizeof(Elf32_Ehdr), ElfFile);

    printf("\tVersion: 0x%.2X\n", elfHdr.e_version);

    printf("\tEntry point address: 0x%.8X\n", elfHdr.e_entry);

    printf("\tProgram header offset: 0x%.8X\n", elfHdr.e_phoff);

    printf("\tSection header offset: 0x%.8X\n", elfHdr.e_shoff);

    printf("\tFlags: 0x%.8X\n", elfHdr.e_flags);

    printf("\tSize of this header: 0x%X\n", elfHdr.e_ehsize);

    printf("\tSize of program headers: 0x%X\n", elfHdr.e_phentsize);

    printf("\tNumber of program headers: %d\n", elfHdr.e_phnum);

    printf("\tSize of section headers: 0x%X\n", elfHdr.e_shentsize);

    printf("\tNumber of section headers: %d\n", elfHdr.e_shnum);

    printf("\tSection header string table index: 0x%X\n", elfHdr.e_shstrndx);

    //premik do section tabele
    fseek(ElfFile, elfHdr.e_shoff + elfHdr.e_shstrndx * elfHdr.e_shentsize, SEEK_SET);
    fread(&sectHdr, 1, sizeof(sectHdr), ElfFile);
    SectNames = malloc(sectHdr.sh_size);
    fseek(ElfFile, sectHdr.sh_offset, SEEK_SET);
    fread(SectNames, 1, sectHdr.sh_size, ElfFile);

    for (int idx = 0; idx < elfHdr.e_shnum; idx++){
        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("%i %s\n", idx, name);
    }



    close(fd);

    return 0;
}

【问题讨论】:

    标签: c linux elf


    【解决方案1】:

    有人看到我错过的东西吗?

    您是否在 32 位模式下编译程序?

    更新:

    有一个“明显”的错误,我在第一次阅读时错过了,并且在使用-fsanitize=address 构建时暴露出来:

    Elf32_Ehdr elfHdr;
    ...
    fread(&elfHdr, 1, sizeof(Elf64_Ehdr), ElfFile);
    

    此错误会导致堆栈缓冲区溢出。为了防止此类错误,使用sizeof(variable) 而不是sizeof(Type) 总是更安全,例如

    fread(&elfHdr, 1, sizeof(elfHdr), ElfFile);
    

    它对我有用:

    gcc -w -m32 t.c && ./a.out ./a.out
        Version: 0x01
        Entry point address: 0x000010C0
        Program header offset: 0x00000034
        Section header offset: 0x000038B0
        Flags: 0x00000000
        Size of this header: 0x34
        Size of program headers: 0x20
        Number of program headers: 11
        Size of section headers: 0x28
        Number of section headers: 30
        Section header string table index: 0x1D
    0
    1 .interp
    2 .note.gnu.build-id
    3 .note.ABI-tag
    4 .gnu.hash
    5 .dynsym
    6 .dynstr
    7 .gnu.version
    8 .gnu.version_r
    9 .rel.dyn
    10 .rel.plt
    11 .init
    12 .plt
    13 .plt.got
    14 .text
    15 .fini
    16 .rodata
    17 .eh_frame_hdr
    18 .eh_frame
    19 .init_array
    20 .fini_array
    21 .dynamic
    22 .got
    23 .got.plt
    24 .data
    25 .bss
    26 .comment
    27 .symtab
    28 .strtab
    29 .shstrtab
    
    

    如果您尝试在 64 位 ELF 文件上运行它,则需要将 Elf32_EhdrElf32_Shdr 更改为它们的 Elf64_... 等效项。

    【讨论】:

    • 现在它会打印 28 个 .out 文件的名称。但是,如果我尝试打印 .o 文件的部分,例如,它不会显示任何内容。
    • @danilo 对我来说适用于 32 位 .o 文件。但答案已更新。
    • 天啊,问题当然出在 sizeof 上... 一行可以让人头疼。 :) 非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多