我正在修补(静态链接)ELF可执行文件。我想从二进制文件的多个不同部分在虚拟地址空间中创建页面。
下面是一个简单的可视化案例,说明我正在努力实现的目标。
(|
标记内存页边界):
file: |aabb|ccdd|
mem: |aadd|
页面的前半部分来自文件的第一页面大小范围的前半部分,并且后半部分来自第二页面大小范围的后半部分,因此每个片段的对齐在其范围内是正确的。
有可能以任何方式实现这一点吗?
我修改了一个二进制文件,使其具有以下程序头表(打印为readelf -l
)
Elf file type is EXEC (Executable file)
Entry point 0x401520
There are 12 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000560000 0x0000000000400000 0x0000000000400000
0x0000000000000040 0x0000000000000040 R 0x1000
LOAD 0x0000000000001270 0x0000000000400270 0x0000000000400270
0x00000000000002c8 0x00000000000002c8 R 0x1000
LOAD 0x0000000000002000 0x0000000000401000 0x0000000000401000
0x0000000000075ac1 0x0000000000075ac1 R E 0x1000
LOAD 0x0000000000078000 0x0000000000477000 0x0000000000477000
0x0000000000027053 0x0000000000027053 R 0x1000
LOAD 0x000000000009f7d8 0x000000000049f7d8 0x000000000049f7d8
0x0000000000005ab8 0x000000000000b288 RW 0x1000
LOAD 0x0000000000000000 0x00000000004ab000 0x00000000004ab000
0x00000000000002e0 0x00000000000002e0 R 0x1000
NOTE 0x0000000000001270 0x0000000000400270 0x0000000000400270
0x0000000000000040 0x0000000000000040 R 0x8
NOTE 0x00000000000012b0 0x00000000004002b0 0x00000000004002b0
0x0000000000000044 0x0000000000000044 R 0x4
TLS 0x000000000009f7d8 0x000000000049f7d8 0x000000000049f7d8
0x0000000000000018 0x0000000000000060 R 0x8
GNU_PROPERTY 0x0000000000001270 0x0000000000400270 0x0000000000400270
0x0000000000000040 0x0000000000000040 R 0x8
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 0x10
GNU_RELRO 0x000000000009f7d8 0x000000000049f7d8 0x000000000049f7d8
0x0000000000003828 0x0000000000003828 R 0x1
正如你所看到的,我正在尝试从文件的两个单独的“页面”中拼凑出0x400000
处的内存页面:第一个0x40
字节来自偏移量为0x560000
的“页”,其余的来自偏移量为0x1000
的“页”。
当我在GDB中运行可执行文件时,info proc mappings
有以下输出:
Start Addr End Addr Size Offset Perms objfile
0x400000 0x401000 0x1000 0x1000 r--p <the executable>
0x401000 0x477000 0x76000 0x2000 r-xp <the executable>
0x477000 0x49f000 0x28000 0x78000 r--p <the executable>
0x49f000 0x4a6000 0x7000 0x9f000 rw-p <the executable>
0x4a6000 0x4ab000 0x5000 0x0 rw-p
0x4ab000 0x4ac000 0x1000 0x0 r--p <the executable>
0x7ffff7ff9000 0x7ffff7ffd000 0x4000 0x0 r--p [vvar]
0x7ffff7ffd000 0x7ffff7fff000 0x2000 0x0 r-xp [vdso]
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 --xp [vsyscall]
好像我的第一个phdr条目没有效果。
1条答案
按热度按时间jhkqcmku1#
我正试图从文件的两个单独的“页”中拼凑出位于0x400000的内存页
这是行不通的:内核将一次一个地“解释”和执行
LOAD
“指令”。给出:内核将做(等效于)
然后第二个
mmap
将替换第一个,这正是您在GDB中观察到的。