Linux下可执行文件虚拟内存地址分配及相关技术疑问
Linux下可执行文件的虚拟内存分配与地址映射问题
我执行
objdump -d bin后得到如下输出:11b0 48 83 c4 08 add $0x8,%rsp 11b4 c3 ret
针对你提出的几个问题,逐一解答:
1. 每个字节都会被分配虚拟内存地址吗?
没错,可执行文件加载到内存后,所有被实际加载的字节都会映射到唯一的虚拟内存地址。就像你看到的objdump输出,0x11b0对应指令的第一个字节48,0x11b1对应第二个字节83,以此类推——CPU就是通过这些逐个对应的虚拟地址来读取、执行指令的。
不过要注意:文件里的内容不是全部都会加载到物理内存,比如未初始化的.bss段,内核只会给它分配虚拟地址空间,不会立即占用物理内存,只有当程序第一次往这个段写入数据时,才会分配对应的物理页。
2. 这些地址是否基于文件加载时的基地址?
是的。Linux下的可执行文件基本都是ELF格式,编译链接时,链接器会给它指定一个默认基地址(比如x86_64系统下默认是0x400000)。objdump里显示的0x11b0是相对于这个默认基地址的偏移量,程序实际运行时的虚拟地址是加载基地址 + 偏移量。
举个例子,如果加载基地址是0x400000,那你看到的0x11b0对应的实际运行地址就是0x4011b0。
3. 基地址对每个程序是否相同?是否受ASLR影响?
- 如果关闭ASLR,同一个可执行文件每次启动的基地址都是固定的,就是链接器指定的默认值,不同程序的默认基地址也可能相同(比如大部分x86_64程序默认都是
0x400000)。 - Linux默认开启ASLR(地址空间布局随机化),开启后:
- 每个程序启动时,内核会随机分配一个不同的加载基地址,同一个可执行文件每次启动的实际基地址都不一样。
- 除了可执行文件的基地址,动态链接库的加载地址、栈、堆的起始地址也都会被随机化,以此提升系统安全性,防止攻击者利用固定地址做漏洞攻击。
内容的提问来源于stack exchange,提问作者evstack
相关产品推荐
相关产品推荐

