为啥我的可执行文件中的入口点地址是 0x8048330? (0x330 是 .text 部分的偏移量)
Posted
技术标签:
【中文标题】为啥我的可执行文件中的入口点地址是 0x8048330? (0x330 是 .text 部分的偏移量)【英文标题】:Why is the entry point address in my executable 0x8048330? (0x330 being the offset of .text section)为什么我的可执行文件中的入口点地址是 0x8048330? (0x330 是 .text 部分的偏移量) 【发布时间】:2012-09-11 08:47:39 【问题描述】:我编写了一个小程序来添加两个整数,并在使用readelf -a executable_name
时将 elf 标头中的入口点地址显示为:
Entry point address: 0x8048330
我的可执行文件如何在加载程序将其加载到内存之前预先知道该地址?
elf_format.pdf
表示该成员给出系统首先将控制权转移到的虚拟地址,从而启动进程。谁能解释一下这个语句是什么意思,这里的虚拟地址是什么意思?
另外让我知道,可执行文件从哪里获取0x8048330
的值作为入口点地址。只是为了交叉检查,我编译了另一个程序,为此,入口点地址保持相同的值0x8048330
(.text
部分的偏移量在两种情况下都是0x330
)。
【问题讨论】:
如果您有兴趣,请在 Wikipedia 上查找虚拟地址或虚拟地址转换或虚拟内存等。除非您使用其中任何一个来制作自己的操作系统,否则出于您的目的,不需要知道它们是什么,只需删除虚拟这个词。还有一些工具,它们应该能够告诉你很多关于可执行文件的信息。试试 objdump。 【参考方案1】:第一个问题:
您看到的入口点0x8048330
是一个虚拟内存地址(相反,是物理内存)。
这意味着您的主管不必知道要映射的物理地址。 (用装载机装载后)
它甚至无法访问物理内存。
对于您的程序进程,您的 .text 部分始终从 0x8048330
开始,然后您的系统(操作系统和硬件)将在运行时将其(虚拟地址)映射到物理内存。
映射和管理物理内存涉及很多方面,您可以在 Google 上查看更多信息。
第二个问题
我不确定哪个部分让您感到困惑,所以我会尝试将它们全部覆盖:
可以有多个程序具有相同的入口点吗?是的,可能有另一个程序具有相同的入口点0x8048330
。因为这个地址是虚拟的,当你尝试同时运行它们时,程序会在运行时映射到不同的物理内存。
0x8048330
?
嗯,Linux 执行者是从0x8048000
开始的,但是.text 节的偏移量与其他节的长度有关。所以不,它可能是0x8048034
或其他任何东西。
0x8048000
开始?
我认为这是一种历史,Linux 的设计者出于某种未知甚至随机的原因选择了这个。您可以参考this thread 以查看该区域下的内容。
【讨论】:
【参考方案2】:入口地址由链接编辑器在创建时设置 可执行。加载程序将程序文件映射到指定的地址 在将控制权转移到入口地址之前通过 ELF 标头。
要使用具体示例,请考虑以下内容:
% file a.out
a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, \
for GNU/Linux 2.6.15, not stripped
% readelf -e a.out
... snip ...
Elf file type is EXEC (Executable file)
Entry point 0x8048170
There are 6 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x7cca6 0x7cca6 R E 0x1000
LOAD 0x07cf98 0x080c5f98 0x080c5f98 0x00788 0x022fc RW 0x1000
... snip ...
第一个程序头指定文件的内容在 文件偏移量 0 应映射到虚拟地址 0x08048000。这 该段的文件和内存大小为 0x7cca6 字节。这 段将被映射为可读可执行但不可写 (它包含程序的代码)。
ELF头中指定的入口点地址为0x8048170,即 位于包含程序代码的区域内。
John Levine 所著的《Linkers and Loaders》一书是一个很好的资源,可用于咨询与链接编辑器和加载器相关的问题。
【讨论】:
【参考方案3】:关于虚拟地址问题:
普通用户态应用程序使用虚拟地址,这意味着它们不直接访问内存空间。操作系统(借助一些微处理器的特殊功能)将此虚拟地址映射到物理地址。
这样,操作系统可以防止应用程序读取/写入其他应用程序内存或操作系统保留内存。此外,这允许应用程序以透明的方式内存分页(使用硬盘作为内存)。
【讨论】:
以上是关于为啥我的可执行文件中的入口点地址是 0x8048330? (0x330 是 .text 部分的偏移量)的主要内容,如果未能解决你的问题,请参考以下文章
如何从visual c ++中的exe文件中获取“入口点的地址”?
为啥我的链接器脚本中的 ENTRY() 没有设置为 . = <地址> 部分?