ELF-программы имеют заголовок программы, в котором перечислены PT_LOAD
сегменты (struct Elf32_Phdr
или struct Elf64_Phdr
).Они имеют смещение и длину файла (p_offset
и p_filesz
члены) и виртуальный адрес и длину (p_vaddr
и p_memsz
).Дело в том, что область, определяемая смещением и длиной файла, становится доступной во время выполнения по указанному виртуальному адресу.Виртуальный адрес относительно базового адреса объекта в памяти.
Вы можете просмотреть заголовки программы, используя readelf -l
:
Elf file type is DYN (Shared object file)
Entry point 0x1670
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000001f8 0x00000000000001f8 R E 0x8
INTERP 0x0000000000000238 0x0000000000000238 0x0000000000000238
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x000000000000627c 0x000000000000627c R E 0x200000
LOAD 0x0000000000006d68 0x0000000000206d68 0x0000000000206d68
0x00000000000004b8 0x0000000000000658 RW 0x200000
…
В этом случае есть два сегмента загрузкиодин читаемый и исполняемый (программный код), а другой читаемый и записываемый (данные и перемещения).
Не все части двоичного файла покрыты PT_LOAD
сегментами и, таким образом, отображаются загрузчиком во время выполнения,Если данные находятся в нераспределенном разделе, они просто не будут в памяти (если вы не прочитаете их с диска другими способами).
Но если данные распределены, то они попадут в одну из загрузоксегменты, и когда у вас есть базовый адрес, вы можете использовать информацию в сегменте загрузки для вычисления виртуального адреса из смещения файла.