最近、私はLinux上で少し疑わしいELFファイルを2つ見つけました。 "/bin/ls" ファイルを例にして readelf を実行すると、次のようになります。
オフセット0x213b8で始まる27個のセクションヘッダーがあります。
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al
[ 0] NULL 0000000000000000 000000 000000 00 0 0 0
[ 1] .interp PROGBITS 0000000000000318 000318 00001c 00 A 0 0 1
[ 2] .note.gnu.property NOTE 0000000000000338 000338 000050 00 A 0 0 8
[ 3] .note.gnu.build-id NOTE 0000000000000388 000388 000024 00 A 0 0 4
[ 4] .note.ABI-tag NOTE 00000000000003ac 0003ac 000020 00 A 0 0 4
[ 5] .gnu.hash GNU_HASH 00000000000003d0 0003d0 00005c 00 A 6 0 8
[ 6] .dynsym DYNSYM 0000000000000430 000430 000bb8 18 A 7 1 8
[ 7] .dynstr STRTAB 0000000000000fe8 000fe8 0005dd 00 A 0 0 1
[ 8] .gnu.version VERSYM 00000000000015c6 0015c6 0000fa 02 A 6 0 2
[ 9] .gnu.version_r VERNEED 00000000000016c0 0016c0 0000d0 00 A 7 1 8
[10] .rela.dyn RELA 0000000000001790 001790 001ea8 18 A 6 0 8
[11] .init PROGBITS 0000000000004000 004000 00001b 00 AX 0 0 4
[12] .text PROGBITS 0000000000004020 004020 0133d3 00 AX 0 0 16
[13] .fini PROGBITS 00000000000173f4 0173f4 00000d 00 AX 0 0 4
[14] .rodata PROGBITS 0000000000018000 018000 00514f 00 A 0 0 32
[15] .eh_frame_hdr PROGBITS 000000000001d150 01d150 0005bc 00 A 0 0 4
[16] .eh_frame PROGBITS 000000000001d710 01d710 0021a0 00 A 0 0 8
[17] .init_array INIT_ARRAY 0000000000020f70 01ff70 000008 08 WA 0 0 8
[18] .fini_array FINI_ARRAY 0000000000020f78 01ff78 000008 08 WA 0 0 8
[19] .data.rel.ro PROGBITS 0000000000020f80 01ff80 000af8 00 WA 0 0 32
[20] .dynamic DYNAMIC 0000000000021a78 020a78 0001c0 10 WA 7 0 8
[21] .got PROGBITS 0000000000021c38 020c38 0003b0 08 WA 0 0 8
[22] .data PROGBITS 0000000000022000 021000 000278 00 WA 0 0 32
[23] .bss NOBITS 0000000000022280 021278 001298 00 WA 0 0 32
[24] .comment PROGBITS 0000000000000000 021278 00001b 01 MS 0 0 1
[25] .gnu_debuglink PROGBITS 0000000000000000 021294 000010 00 0 0 4
[26] .shstrtab STRTAB 0000000000000000 0212a4 00010f 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
L (link order), O (extra OS processing required), G (group), T (TLS),
C (compressed), x (unknown), o (OS specific), E (exclude),
D (mbind), l (large), p (processor specific)
セクションヘッダー[23]と[24]のオフセットを見ると、これら2つのセクションのオフセット値が021278と等しいことがわかります。これらの2つのセクションでファイル内の同じオフセットを共有できますか?わかりません。ここに問題がありますか?
.bssセクションのように、異なるELFファイルに同じオフセットを共有する別のセクションがあることがわかりました。
オフセットが原因でこのような衝突が発生する理由を説明できる人はいますか?
答え1
ファイルの 2 つのセクションの最初のセクションが空であるため、同じオフセットを共有します。 BSSは実行時にスペースを予約するために使用されますが、スペースは既知のデフォルト値(すべて0)に初期化され、バイナリには保存されません。
セクションには、アドレス空間(「アドレス」列)とファイル(「オフセット」列)にオフセットがあります。 2つが一致する必要はありません。
示された例では、プログラムがロードされると、0x1298バイトがプログラムのアドレス空間に予約されます(これは「A」フラグの意味です)。