You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASLR与硬编码地址:链接时为何能确定符号值?

Linux x86-64汇编、重定位与ASLR的疑问

编写的汇编程序

.intel_syntax noprefix
.global _start

.section .text
_start:
    mov rax, offset _start
    ret

问题背景与疑问

  • 使用GNU as汇编后,目标文件中offset _start位置存在类型为R_X86_64_32S、加数为0的重定位条目,按文档应替换为32位值S + A(S为符号值,A为加数)。
  • 经GNU ld链接生成可执行文件后,重定位条目已被解析,且符号表中_start的符号值与程序头表中text段的vaddr一致。

疑问:在开启ASLR(地址空间布局随机化)的情况下,为何链接时就能确定任意符号的值?

解答

  • 链接器确定的是相对虚拟地址(RVA),而非进程运行时的实际虚拟地址。链接阶段会给每个段分配固定的相对虚拟地址(比如x86-64系统中text段通常默认从0x400000开始),符号的值就是它所在段的vaddr加上自身在段内的偏移,也就是该符号的RVA。
  • ASLR的作用是在进程加载时随机分配整个程序的加载基地址,运行时的实际虚拟地址 = 加载基地址 + RVA。链接器不需要关心加载基地址,因为这个值是内核在运行时决定的,链接阶段只需要确定符号相对于基地址的偏移即可。
  • 你使用的R_X86_64_32S重定位,存储的就是符号的RVA(因为S是链接时分配的虚拟地址,也就是RVA,A为0)。x86-64用户空间的地址仅低48位有效,而RVA的范围恰好能被32位有符号数覆盖,运行时加上随机的高16位基地址,就能得到合法的实际虚拟地址。
  • 链接后可执行文件无重定位条目,是因为这属于静态重定位:链接器已经把RVA直接写入指令中,运行时内核会自动处理基地址的偏移,不需要像共享库那样进行动态重定位。

内容的提问来源于stack exchange,提问作者mdjukan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:52:08