【问题标题】:Force RIP-relative access to fixed offset in NASM强制 RIP 相对访问 NASM 中的固定偏移量
【发布时间】:2021-11-05 14:07:23
【问题描述】:

对于一个二进制检测项目,我在 NASM 中编写了一段汇编代码,在运行时将其映射到二进制的地址空间。

块被加载到地址instrument_addr,并且需要访问地址instrument_addr+data_offset的数据,其中data_offset是一个固定的31位数字。由于 ASLR,我在编译时不知道 instrument_addr 的值。

由于我不知道我的检测代码的绝对地址,但我的数据的相对偏移量,我想使用 RIP 相对寻址:

; Example for data_offset = 0x1000
0:  48 8b 05 f9 0f 00 00    mov    rax, QWORD PTR [rip+0xff9]    # 1000

然而,最直接的方法

; This is offset 0 of my assembly file
instrument:
    mov rax, qword [rel 0x1000]

只会导致:

$ nasm -f elf64 -o instrument.o instrument.asm
instrument.asm:3: warning: absolute address can not be RIP-relative [-w+other]

[absolute 0x1000] 与虚拟标签一起使用会产生相同的警告。

如何强制 NASM 生成对某个固定偏移量的 RIP 相关访问?

【问题讨论】:

    标签: assembly x86-64 nasm addressing-mode relative-addressing


    【解决方案1】:

    您要查找的语法是 [rel $+0x1000] 表示相对于当前位置的偏移量,或 [rel instrument+0x1000] 表示相对于标签的偏移量。在您问题的示例中,它们恰好是相同的,因为 mov 是标签之后的第一件事,但如果中间有任何东西,它们会有所不同。

    【讨论】:

      【解决方案2】:

      Nasm 将您的代码解释为“使用 rip-relative 寻址访问地址 0x1000”,因此它失败了。你可以做的是使用$符号指定一个相对地址,它代表当前指令的地址:

      mov rax, qword [rel $+0x1000]
      

      【讨论】:

      • 这仅在指令是文件中的第一个指令时才有效,因为$ 总是指向当前指令,正如您所说 - 对于其他指令,需要手动减去它们的偏移量,所以如另一个答案所示,使用第一个标签更优雅。从技术上讲,它仍然解决了问题中简化示例的问题:)
      • @janw:有趣的是,YASM 不会组装失败。它将mov eax, [rel 0x1000] 组装到mov eax,DWORD PTR [rip+0x0] # 0x6 2: R_X86_64_PC32 *ABS*+0xffcobjdump -drwC -Mintel 输出为.o),它使用重定位告诉链接器从该代码链接到的任何位置到达绝对地址0x1000。它只会成功链接到非 PIE 可执行文件,因此静态代码+数据进入低 2GiB 的地址空间,在0x1000 的范围内。
      猜你喜欢
      • 2021-09-29
      • 1970-01-01
      • 2015-09-22
      • 2017-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多