ファイルへのアドレスオフセット


0

私はELFシンボルテーブルから値4195622を読みました。16進数に変換すると、値は400580です。ファイルオフセットは580バイトです。

私の質問は具体的にアドレスをファイルオフセットに具体的に変換する方法です。

おかげ

0

st_valueから減算0x400000アドレスがバイナリの第LOADセグメントに位置しているからです。別のオブジェクトファイルの種類の

シンボルテーブルエントリは少しあります


システムV ABI(ジェネリック)によると、st_value記号の意味は、バイナリがあるオブジェクトファイルの種類によって異なりst_valueメンバーの異なる解釈

  • 再配置可能ファイルでは、st_valueは、セクションインデックスがSHN_COMMONのシンボルの配置制約を保持します。
  • リロケータブルファイルでは、st_valueは定義済みのシンボルのセクションオフセットを保持します。つまり、st_valueは、st_shndxが識別するセクションの先頭からのオフセットです。
  • 実行可能ファイルおよび共有オブジェクトファイルでは、st_valueは仮想アドレスを保持します。これらのファイルのシンボルをダイナミックリンカーにとってより便利にするために、セクションオフセット(ファイルの解釈)は、セクション番号が無関係な仮想アドレス(メモリの解釈)に影響します。

ldによって連結された実行可能なELF64オブジェクトファイルは、リンカスクリプト変数__executable_startによって与え0x0000000000400000の標準ベース・アドレスを有します。つまり、st_valueからベースアドレスの値を減算してファイルオフセットを見つけることができます。

これは、ELF64バイナリのリンクマップを調べることで確認できます。ここでld -M /bin/lsの出力の抜粋:これはさらにreadelf -l /bin/ls介して同じバイナリのセクションにセグメントのマッピングを調べることによって確認することができる

Memory Configuration 

Name  Origin  Length  Attributes 
*default* 0x0000000000000000 0xffffffffffffffff 

Linker script and memory map 

LOAD /bin/ls 
    0x0000000000400000  PROVIDE (__executable_start, 0x400000) <-------------- 
    0x0000000000400190  . = (0x400000 + SIZEOF_HEADERS) 

.interp  0x0000000000400190 0x1c 
*(.interp) 
.interp 0x0000000000400190 0x1c /bin/ls 

.note.ABI-tag 0x00000000004001ac 0x20 
.note.ABI-tag 0x00000000004001ac 0x20 /bin/ls 

.note.gnu.build-id 
    0x00000000004001cc 0x24 
*(.note.gnu.build-id) 
.note.gnu.build-id 
    0x00000000004001cc 0x24 /bin/ls 

は:

Elf file type is EXEC (Executable file) 
Entry point 0x404890 
There are 9 program headers, starting at offset 64 

Program Headers: 
  Type  Offset  VirtAddr  PhysAddr 
    FileSiz  MemSiz  Flags Align 
  PHDR  0x0000000000000040 0x0000000000400040 0x0000000000400040 
    0x00000000000001f8 0x00000000000001f8 R E 8 
  INTERP  0x0000000000000238 0x0000000000400238 0x0000000000400238 
    0x000000000000001c 0x000000000000001c R 1 
   [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] 
  LOAD  0x0000000000000000 0x0000000000400000 0x0000000000400000 <------------- 
    0x0000000000019d44 0x0000000000019d44 R E 200000 
  LOAD  0x0000000000019df0 0x0000000000619df0 0x0000000000619df0 
    0x0000000000000804 0x0000000000001570 RW 200000 
  DYNAMIC 0x0000000000019e08 0x0000000000619e08 0x0000000000619e08 
    0x00000000000001f0 0x00000000000001f0 RW 8 
  NOTE  0x0000000000000254 0x0000000000400254 0x0000000000400254 
    0x0000000000000044 0x0000000000000044 R 4 
  GNU_EH_FRAME 0x000000000001701c 0x000000000041701c 0x000000000041701c 
    0x000000000000072c 0x000000000000072c R 4 
  GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 
    0x0000000000000000 0x0000000000000000 RW 10 
  GNU_RELRO 0x0000000000019df0 0x0000000000619df0 0x0000000000619df0 
    0x0000000000000210 0x0000000000000210 R 1 

Section to Segment mapping: 
  Segment Sections... 
  00 
  01 .interp 
  02 .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
  03 .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss 
  04 .dynamic 
  05 .note.ABI-tag .note.gnu.build-id 
  06 .eh_frame_hdr 
  07 
  08 .init_array .fini_array .jcr .dynamic .got 

最初LOADセグメントを有していますベースアドレスは0x0000000000400000です。

Address列のものとOff列の値を比較します。遅れて申し訳ありません。このため

$ readelf -SW /bin/ls 
There are 28 section headers, starting at offset 0x1a700: 

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 0000000000400238 000238 00001c 00 A 0 0 1 
  [ 2] .note.ABI-tag NOTE  0000000000400254 000254 000020 00 A 0 0 4 
  [ 3] .note.gnu.build-id NOTE  0000000000400274 000274 000024 00 A 0 0 4 
  [ 4] .gnu.hash  GNU_HASH 0000000000400298 000298 000068 00 A 5 0 8 
  [ 5] .dynsym  DYNSYM  0000000000400300 000300 000c18 18 A 6 1 8 
  [ 6] .dynstr  STRTAB  0000000000400f18 000f18 000593 00 A 0 0 1 
  [ 7] .gnu.version VERSYM  00000000004014ac 0014ac 000102 02 A 5 0 2 
  [ 8] .gnu.version_r VERNEED  00000000004015b0 0015b0 000090 00 A 6 2 8 
  [ 9] .rela.dyn  RELA  0000000000401640 001640 0000a8 18 A 5 0 8 
  [10] .rela.plt  RELA  00000000004016e8 0016e8 000a80 18 A 5 12 8 
  [11] .init  PROGBITS 0000000000402168 002168 00001a 00 AX 0 0 4 
  [12] .plt  PROGBITS 0000000000402190 002190 000710 10 AX 0 0 16 
  [13] .text  PROGBITS 00000000004028a0 0028a0 00f65a 00 AX 0 0 16 
  [14] .fini  PROGBITS 0000000000411efc 011efc 000009 00 AX 0 0 4 
  [15] .rodata  PROGBITS 0000000000411f20 011f20 0050fc 00 A 0 0 32 
  [16] .eh_frame_hdr PROGBITS 000000000041701c 01701c 00072c 00 A 0 0 4 
  [17] .eh_frame  PROGBITS 0000000000417748 017748 0025fc 00 A 0 0 8 
  [18] .init_array INIT_ARRAY 0000000000619df0 019df0 000008 00 WA 0 0 8 
  [19] .fini_array FINI_ARRAY 0000000000619df8 019df8 000008 00 WA 0 0 8 
  [20] .jcr  PROGBITS 0000000000619e00 019e00 000008 00 WA 0 0 8 
  [21] .dynamic  DYNAMIC  0000000000619e08 019e08 0001f0 10 WA 6 0 8 
  [22] .got  PROGBITS 0000000000619ff8 019ff8 000008 08 WA 0 0 8 
  [23] .got.plt  PROGBITS 000000000061a000 01a000 000398 08 WA 0 0 8 
  [24] .data  PROGBITS 000000000061a3a0 01a3a0 000254 00 WA 0 0 32 
  [25] .bss  NOBITS  000000000061a600 01a5f4 000d60 00 WA 0 0 32 
  [26] .gnu_debuglink PROGBITS 0000000000000000 01a5f4 000008 00 0 0 1 
  [27] .shstrtab  STRTAB  0000000000000000 01a5fc 0000fe 00 0 0 1 
Key to Flags: 
  W (write), A (alloc), X (execute), M (merge), S (strings), l (large) 
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) 
  O (extra OS processing required) o (OS specific), p (processor specific) 
+1

おかげで、! 28 11月. 172017-11-28 11:20:55

  0

@ Marius.pharoe問題ありません - あなたは歓迎です 28 11月. 172017-11-28 22:22:13