我正在运行一些 C 代码,在 Linux 上编译为 32 位 x86。我正在尝试访问一些内存。显然我可以写入.bss
和写入.data
堆栈。前段时间,.ctors 和 .dtors 段曾经是可写的,但似乎它们已经消失了。
如果没有反复试验,我如何找出这些段映射到内存中的哪些部分?如何找出哪些地址映射到可写内存,哪些是可执行的?
我正在运行一些 C 代码,在 Linux 上编译为 32 位 x86。我正在尝试访问一些内存。显然我可以写入.bss
和写入.data
堆栈。前段时间,.ctors 和 .dtors 段曾经是可写的,但似乎它们已经消失了。
如果没有反复试验,我如何找出这些段映射到内存中的哪些部分?如何找出哪些地址映射到可写内存,哪些是可执行的?
如果没有反复试验,我如何找出这些段映射到内存中的哪些部分?
当您谈论ELF
可执行文件时,节和段具有特定的含义,并且您上面的用法与该含义不一致。
ELF 部分在加载时无关紧要,只有(可加载)段才重要。
该readelf -l a.out
命令准确地提供了从 ELF 部分到段的映射。例如
readelf -l /bin/date
Elf file type is EXEC (Executable file)
Entry point 0x8048c60
There are 6 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
INTERP 0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x05fe0 0x05fe0 R E 0x1000
LOAD 0x006000 0x0804e000 0x0804e000 0x00208 0x00334 RW 0x1000
DYNAMIC 0x006078 0x0804e078 0x0804e078 0x000c8 0x000c8 RW 0x4
NOTE 0x000108 0x08048108 0x08048108 0x00020 0x00020 R 0x4
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata
03 .data .eh_frame .dynamic .ctors .dtors .jcr .got .bss
04 .dynamic
05 .note.ABI-tag
这告诉您.ctors
映射到可写的段 3(此输出来自古代UnitedLinux 1.0
分布)。
现在,.ctors
被放入一个不同于 的段中.data
,并在重定位后通过特殊GNU_RELRO
段保护不写。
查看/proc/$pid/maps
(或使用该pmap
实用程序)。它会告诉你比你想知道的更多关于内存区域的信息。