x86_64中运行时代码替换的绝对寻址

nux*_*nux 9 64-bit assembly gcc x86-64 addressing

我目前正在使用32位代码替换方案,其中代码移动到另一个位置,读取变量和类指针.由于x86_64不支持绝对寻址,因此无法在代码的新位置获取变量的正确地址.问题在于,由于rip相对寻址,指令指针地址与编译时不同.

那么有没有办法在x86_64中使用绝对寻址或以其他方式获取变量的地址而非指令指针相对?

类似的东西:leaq variable(%%rax), %%rbx也会有所帮助.我只想依赖指令指针.

Gun*_*iez 7

尝试使用x86_64 的代码模型.在gcc中,可以使用-mcmodel = large选择.编译器将对代码和数据使用64位绝对寻址.

您还可以添加-fno-pic以禁止生成与位置无关的代码.

编辑:我用-mcmodel = large构建了一个小测试应用程序,结果二进制文件包含类似的序列

400b81:       48 b9 f0 30 60 00 00    movabs $0x6030f0,%rcx
400b88:       00 00 00 
400b8b:       49 b9 d0 09 40 00 00    movabs $0x4009d0,%r9
400b92:       00 00 00 
400b95:       48 8b 39                mov    (%rcx),%rdi
400b98:       41 ff d1                callq  *%r9
Run Code Online (Sandbox Code Playgroud)

这是一个绝对64位立即(在这种情况下是地址)的加载,后跟间接调用或间接加载.指令序列

moveabs $variable, %rbx
addq %rax, %rbx
Run Code Online (Sandbox Code Playgroud)

相当于"leaq offset64bit(%rax),%rbx"(不存在),有一些副作用,如标志更改等.