Во-первых, это вывод заголовка моей программы с использованием **readelf**: =
Код: Выделить всё
➜ ~ readelf -l /usr/bin/cat
Elf file type is DYN (Shared object file)
Entry point 0x31f0
There are 13 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000000318 0x0000000000000318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000000016e0 0x00000000000016e0 R 0x1000
LOAD 0x0000000000002000 0x0000000000002000 0x0000000000002000
0x0000000000004431 0x0000000000004431 R E 0x1000
LOAD 0x0000000000007000 0x0000000000007000 0x0000000000007000
0x00000000000021d0 0x00000000000021d0 R 0x1000
LOAD 0x0000000000009a90 0x000000000000aa90 0x000000000000aa90
0x0000000000000630 0x00000000000007c8 RW 0x1000
DYNAMIC 0x0000000000009c38 0x000000000000ac38 0x000000000000ac38
0x00000000000001f0 0x00000000000001f0 RW 0x8
NOTE 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
NOTE 0x0000000000000358 0x0000000000000358 0x0000000000000358
0x0000000000000044 0x0000000000000044 R 0x4
GNU_PROPERTY 0x0000000000000338 0x0000000000000338 0x0000000000000338
0x0000000000000020 0x0000000000000020 R 0x8
GNU_EH_FRAME 0x000000000000822c 0x000000000000822c 0x000000000000822c
0x00000000000002bc 0x00000000000002bc R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x0000000000009a90 0x000000000000aa90 0x000000000000aa90
0x0000000000000570 0x0000000000000570 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
03 .init .plt .plt.got .plt.sec .text .fini
04 .rodata .eh_frame_hdr .eh_frame
05 .init_array .fini_array .data.rel.ro .dynamic .got .data .bss
06 .dynamic
07 .note.gnu.property
08 .note.gnu.build-id .note.ABI-tag
09 .note.gnu.property
10 .eh_frame_hdr
11
12 .init_array .fini_array .data.rel.ro .dynamic .got
Код: Выделить всё
(gdb) shell cat /proc/18331/maps
555555554000-555555556000 r--p 00000000 103:03 3276961 /usr/bin/cat
555555556000-55555555b000 r-xp 00002000 103:03 3276961 /usr/bin/cat
55555555b000-55555555e000 r--p 00007000 103:03 3276961 /usr/bin/cat
55555555e000-555555560000 rw-p 00009000 103:03 3276961 /usr/bin/cat
7ffff7fc9000-7ffff7fcd000 r--p 00000000 00:00 0 [vvar]
7ffff7fcd000-7ffff7fcf000 r-xp 00000000 00:00 0 [vdso]
7ffff7fcf000-7ffff7fd0000 r--p 00000000 103:03 3325699 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7fd0000-7ffff7ff3000 r-xp 00001000 103:03 3325699 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7ff3000-7ffff7ffb000 r--p 00024000 103:03 3325699 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7ffc000-7ffff7ffe000 rw-p 0002c000 103:03 3325699 /usr/lib/x86_64-linux-gnu/ld-2.31.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall]
Прочитав много материалов, я думаю, что потому, что p_offset этого сегмента равен 0x9a90, что означает, что он будет находиться на той же странице, что и предыдущий сегмент. Таким образом, p_vaddr перемещается на 0x1000 байт вперед, чтобы его можно было поместить на другую страницу. Это означает, что фактический адрес, используемый для mmap, будет рассчитываться с помощью смещения плюс p_vaddr, округленного до ближайшего начального адреса страницы. Смещение рассчитывается по формуле p_offset минус p_offset mod p_align. При этом длина mmap будет вычисляться с помощью p_filesz плюс мод p_offset p_align:
Код: Выделить всё
mmap(PAGESTART(bias + p_vaddr), PAGE_ALIGN(p_filesz + p_offset mod p_align), FLAGS , p_offset - p_offset mod p_align)
Двигаясь дальше, в четвертом сегменте я вижу множество разделов:
Код: Выделить всё
.init_array .fini_array .data.rel.ro .dynamic .got .data .bss
Код: Выделить всё
➜ ~ objdump --disassemble-all /usr/bin/cat --start-address=0x9000 --stop-address=0xd000
/usr/bin/cat: file format elf64-x86-64
Disassembly of section .eh_frame:
0000000000009000 :
Disassembly of section .init_array:
000000000000aa90 :
...
Disassembly of section .fini_array:
000000000000aa98 :
...
Disassembly of section .data.rel.ro:
000000000000aaa0 :
...
Итак, если смещение 0x9000 и размер этого раздела 0x2000, не означает ли это, что Я полностью пропущу некоторые байты из этого сегмента (mmap отображает только адреса от 0x9000 до 0xB000, однако .init_array начинается с 0xaa90, что означает, что сегмент должен заканчиваться на 0xaa90 + p_filesz = 0xaa90 + 0x630 = 0xb0c0) ?
Подробнее здесь: https://stackoverflow.com/questions/784 ... -mechanism
Мобильная версия