我需要将有关 ELF 的信息放入标题结构中,其中结构的字段是 64 位值。当我尝试以通常的方式阅读它们时,我在所有领域都得到 0。您能告诉我如何使下面的代码正常工作吗?
用于读取 ELF 字节的 hexdump 文件
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 01 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>.............| 00000020 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......| 00000030 00 00 00 00 40 00 00 00 00 00 40 00 05 00 02 00 |....@.....@.....| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000080 01 00 00 00 01 00 00 00 06 00 00 00 00 00 00 00 |................| 00000090 00 00 00 00 00 00 00 00 80 01 00 00 00 00 00 00 |................| 000000a0 0c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000b0 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000000c0 07 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 |................| 000000d0 00 00 00 00 00 00 00 00 90 01 00 00 00 00 00 00 |................| 000000e0 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |!...............| 000000f0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000100 11 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 |................| 00000110 00 00 00 00 00 00 00 00 c0 01 00 00 00 00 00 00 |................| 00000120 60 00 00 00 00 00 00 00 04 00 00 00 03 00 00 00 |`...............| 00000130 04 00 00 00 00 00 00 00 18 00 00 00 00 00 00 00 |................| 00000140 19 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 |................| 00000150 00 00 00 00 00 00 00 00 20 02 00 00 00 00 00 00 |........ .......| 00000160 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000170 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000180 b8 3c 00 00 00 bf 00 00 00 00 0f 05 00 00 00 00 |.<..............| 00000190 00 2e 74 65 78 74 00 2e 73 68 73 74 72 74 61 62 |..text..shstrtab| 000001a0 00 2e 73 79 6d 74 61 62 00 2e 73 74 72 74 61 62 |..symtab..strtab| 000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001d0 00 00 00 00 00 00 00 00 01 00 00 00 04 00 f1 ff |................| 000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 000001f0 00 00 00 00 03 00 01 00 00 00 00 00 00 00 00 00 |................| 00000200 00 00 00 00 00 00 00 00 07 00 00 00 10 00 01 00 |................| 00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000220 00 65 78 31 2e 73 00 5f 73 74 61 72 74 00 00 00 |.ex1.s._start...|
将ELF读入结构的源代码
#include <iostream> #include <fstream> #include <stdint.h> /* Type for a 16-bit quantity. */ typedef uint16_t Elf64_Half; /* Types for signed and unsigned 32-bit quantities. */ typedef uint32_t Elf64_Word; /* Type of addresses. */ typedef uint64_t Elf64_Addr; /* Type of file offsets. */ typedef uint64_t Elf64_Off; /* The ELF file header. This appears at the start of every ELF file. */ #define EI_NIDENT (16) typedef struct { unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ Elf64_Half e_type; /* Object file type */ Elf64_Half e_machine; /* Architecture */ Elf64_Word e_version; /* Object file version */ Elf64_Addr e_entry; /* Entry point virtual address */ Elf64_Off e_phoff; /* Program header table file offset */ Elf64_Off e_shoff; /* Section header table file offset */ Elf64_Word e_flags; /* Processor-specific flags */ Elf64_Half e_ehsize; /* ELF header size in bytes */ Elf64_Half e_phentsize; /* Program header table entry size */ Elf64_Half e_phnum; /* Program header table entry count */ Elf64_Half e_shentsize; /* Section header table entry size */ Elf64_Half e_shnum; /* Section header table entry count */ Elf64_Half e_shstrndx; /* Section header string table index */ } Elf64_Ehdr; int main(int argc, char const *argv[]) { Elf64_Ehdr ehdr = {}; std::ifstream ifs; ifs.open("ex1.o", std::ios::binary|std::ios::in); for (int i = 0; i < EI_NIDENT; i++) { ifs >> ehdr.e_ident[i]; } ifs >> ehdr.e_type; ifs >> ehdr.e_machine; ifs >> ehdr.e_version; ifs >> ehdr.e_entry; ifs >> ehdr.e_phoff; ifs >> ehdr.e_shoff; ifs >> ehdr.e_flags; ifs >> ehdr.e_ehsize; ifs >> ehdr.e_phentsize; ifs >> ehdr.e_phnum; ifs >> ehdr.e_shentsize; ifs >> ehdr.e_shnum; ifs >> ehdr.e_shstrndx; return 0; }
结果:除 e_ident 之外的所有字段都包含 0
尝试而不是所有这些阅读每个字段依次阅读
幸运的是,你有一个显式的 POD(plain old data,C 风格的plain old data)。
这很有趣 - 那些具有非 POD 结构的人 - 尝试将一块写入内存,而那些拥有纯 POD 的人 - 相反,开始不必要(而且不正确)按字段读取......