エルフヘッダー、プログラムヘッダー、セクション、セグメントなど、これらすべてを伝えるELF形式の仕様を読んでいます。これらのすべては、さまざまなフィールドと値を持つ構造として参照されます。
もしそうなら、問題はこれがどこに行くのかということです。私の言葉は、readelf
utilの出力の代わりに構造で処理できますか?
これらすべてを含む中間ファイルはありますか?エルフ魔法存在し、ソースコードにマージされましたか?それともコンパイラの内部構造であり、その構造は人間だけのための仕様書に言及されているのでしょうか? )
私にとって、これは「鶏と卵の問題」(コンパイルされたコードについて話すためにコードを使用する)のようです。
答え1
これらの構造はELFファイルに存在します。
ELFヘッダーを見てみましょう。
#define EI_NIDENT (16)
typedef struct
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
} Elf32_Ehdr;
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;
ELFヘッダーは次の場所にあります。すべてELFファイル。
これが実際に意味するのは、ELFファイルの最初の16バイトがe_ident
ELFヘッダーのフィールドであることです。
最初のバイトは0x7fです。
2番目は
'E'
;3番目は
'L'
;4番目
'F'
は5番目はクラスです。
6番目はデータエンコーディングです。
7番目はファイルバージョンです。
8番目はオペレーティングシステムABIです。
など。
このフィールドe_ident
の後の2バイトはですe_type
。
それがあなたなら、最初に近いものを見るhead /bin/bash
ことができます。ELF
これでELFファイルの先頭の16進ダンプが得られます。
$ xxd /bin/bash | xxdヘッダー| 00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF.............. 00000010: 0200 3e00 0100 0000 7005 4200 0000 0000 ..>.....pB.... 00000020: 4000 0000 0000 0000 c0cd 0f00 0000 0000 @........... 00000030:0000 0000 4000 3800 0900 4000 1d00 1c00 [Eメール保護]...@..... 00000040: 0600 0000 0500 0000 4000 0000 0000 0000 .......@....... 00000050: 4000 4000 0000 0000 4000 4000 0000 0000 @.@.....@.@..... 00000060: f801 0000 0000 0000 f801 0000 0000 0000 ........ 00000070: 0800 0000 0000 0000 0300 0000 0400 0000 ............ 00000080: 3802 0000 0000 0000 3802 4000 0000 0000 8.......8.@..... 00000090: 3802 4000 0000 0000 1c00 0000 0000 0000 8.@........................
この16進ダンプの最初の行は最初の16バイト(e_ident
)です。
最初のバイトは実際に
0x7f
;それから
"ELF"
;それには(ELF64)
0x02
クラスがあります。ELFCLASS64
0x01
その後、エンコードが続きますELFDATA2LSB
。など。
2行目の最初の2バイトはですe_type
。 LSBでエンコードされるので、ELFDATA2LSB
値は実際には実行可能ファイルであることを0x0002
意味します。ET_EXEC
次の2バイトはアーキテクチャ(e_machine
)です。これは実行可能ファイルだ0x003e
からです。EM_X86_64
x86_64
ELFヘッダー内のすべてのフィールドを手動でデコードできる必要があり、指定された値と同じ値を見つける必要がありますreadelf
。これにより、ファイル内ElfXX_Shdr
または他のELF構造を見つけ、その定義ElfXX_Phdr
に従ってデコードできます(与えられた情報と同じ情報を見つける必要がありますreadelf
)。
答え2
使用xxd
してawk
$ xxd hello_arm64 | awk '{for(i=2;i<NF;i++){a=a$i;c++;if(c>9){print a;exit;}}}'
7f454c460201010000000000000000000200b700
$ cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/bin/qemu-aarch64-static
flags: F
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff