为什么我的数据段在已编译的二进制文件中出现两次? Ubuntu,x86,nasm,gdb,reaelf [英] Why does my data section appear twice in the compiled binary? Ubuntu, x86, nasm, gdb, reaelf
问题描述
先前的相关问题得到了回答.谢谢!但是,这给我提出了一个新问题. nasm为什么将数据字节放在两个不同的存储位置?我在下面包括程序信息和其他数据转储.
A prior related question was answered. Thank you! However this creates a new question for me. Why does nasm put data bytes at two different memory locations? I include program information and other data dump below.
---------- code snippet compiled with nasm, ld -----------------
section .text
...
zero: jmp short two
one: pop ebx
xor eax, eax
mov [ebx+12], eax
mov [ebx+8], ebx
mov [ebx+7], al
lea ecx, [ebx+8]
lea edx, [ebx+12]
mov al, 11
int 0x80
two: call one
section .data align=1
msg: db '/bin/sh0argvenvp'
-------- readelf output to show load locations --------
readelf -Wl myshdb
Elf file type is EXEC (Executable file)
Entry point 0x8048080
There are 2 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x0009d 0x0009d R E 0x1000
LOAD 0x00009d 0x0804909d 0x0804909d 0x00010 0x00010 RW 0x1000
Section to Segment mapping:
Segment Sections...
00 .text
01 .data
-------------- run with gdb and debug step to mov instructions ----------
---------------registers--------------
EAX: 0x0
EBX: 0x804809d ("/bin/sh0argvenvp")
----------- memory address checks ------------
gdb-peda$ p zero
$15 = {<text variable, no debug info>} 0x8048080 <zero>
gdb-peda$ p one
$16 = {<text variable, no debug info>} 0x8048082 <one>
gdb-peda$ p two
$17 = {<text variable, no debug info>} 0x8048098 <two>
gdb-peda$ p $ebx
$18 = 0x804809d
gdb-peda$ p msg
$19 = 0x6e69622f
gdb-peda$ x 0x804809d
0x804809d: "/bin/sh0argvenvp"
gdb-peda$ x msg
0x6e69622f: <error: Cannot access memory at address 0x6e69622f>
换句话说,在代码(0x804809d)之后,可直接从存储位置获得字符串消息.但是msg标签映射到0x6e69622f,这是我的数据标签.如何使用gdb在第二个地址查看数据? nasm是否将数据放在两个不同的位置?为什么?
In other words, the string message is available from a memory location directly after code (0x804809d). Yet msg label maps to 0x6e69622f, which is the label to my data. How can use gdb to see data at the second address? Is nasm putting the data at two different locations? Why?
推荐答案
让我们看一下LOAD
段:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x0009d 0x0009d R E 0x1000
LOAD 0x00009d 0x0804909d 0x0804909d 0x00010 0x00010 RW 0x1000
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x0009d 0x0009d R E 0x1000
LOAD 0x00009d 0x0804909d 0x0804909d 0x00010 0x00010 RW 0x1000
第一个指示加载程序从文件偏移量0
到地址0x08048000
的虚拟内存中mmap
0x9d
个字节.
The first one instructs the loader to mmap
0x9d
bytes from file offset 0
into virtual memory at address 0x08048000
.
加载器不能精确地做到 ,因为内存映射仅以一页(4096字节)的粒度起作用.因此,它mmap
是.text
以及文件中紧随其后的所有 ,最多一页,位于地址0x08048000
.
The loader can't do exactly that, because memory mapping only works at one page (4096 bytes) granularity. So it mmap
s the .text
, and everything that follows it in the file, up to one page, at address 0x08048000
.
这意味着偏移量0x9d
之后文件中.data
紧随.text
之后的任何内容将出现在地址0x0804809d
及更高版本中,但具有错误权限(R
ead和E
xecute).
This means that whatever .data
followed .text
in the file after offset 0x9d
will appear at address 0x0804809d
and later, but with wrong permissions (R
ead and E
xecute).
第二个LOAD
段指示加载程序从虚拟地址0x0804909d
的偏移量0x9d
开始mmap
文件内容.
The second LOAD
segment instructs the loader to mmap
file contents, starting at offset 0x9d
at virtual address 0x0804909d
.
对于相同的页面粒度",加载程序不能精确地做到 .原因.
The loader can't do exactly that either for the same "page granularity" reason.
相反,它将舍入偏移量和地址,以及从地址0x08049000
处的偏移量0
开始的mmap
文件内容.
Instead, it will round down the offset and the address, and mmap
file contents starting from offset 0
at address 0x08049000
.
这意味着文件中.data
之前的.text
都将出现在 0x0804909d
之前的地址上,并且权限错误(R
ead和W
时间).
That that means that whatever .text
preceded .data
in the file will appear at address before 0x0804909d
, again with the wrong permissions (R
ead and W
rite this time).
您可以通过使用GDB x/10i 0x8049080
确认正在发生这种情况-您将看到完全与x/10i 0x8048080
相同的说明.
You can confirm that that's what's happening by using GDB x/10i 0x8049080
-- you will see exactly the same instructions as with x/10i 0x8048080
.
您还可以观察到实际的mmap
系统调用由strace
执行的加载程序.
You can also observe the actual mmap
system calls the loader performed with strace
.
这篇关于为什么我的数据段在已编译的二进制文件中出现两次? Ubuntu,x86,nasm,gdb,reaelf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!