[英]How to overwrite operand value of x86 `movq` instruction via c pointer in linux kernel
[英]Why does this movq instruction work on linux and not osx?
运行时,下面的汇编代码提供了一个错误as
对OSX 10.9.4,但成功在Linux(Debian的7.6)。 特别是,movq指令似乎不喜欢label参数。
$ cat test.S
.globl _main
_main:
movq $_main, %rax
ret
这是错误:
$ as -o test.o test.S
test.S:3:32-bit absolute addressing is not supported for x86-64
test.S:3:cannot do signed 4 byte relocation
将第3行中的$_main
更改$_main
像$10
这样的文字可以正常工作。
代码必须以非常小的方式进行修改才能在Linux上运行 - 只需从标签中删除下划线即可。
$ cat test.S
.globl main
main:
movq $main, %rax
ret
很容易独立验证代码在Linux上是否可行:
$ as -o test.o test.S
$ gcc -o test.out test.o
$ ./test.out
请忽略代码并没有真正做很多事情,我故意尽可能地将其修剪下来以证明错误。
我已经看了很多使用LEA(加载有效地址),但在我做出改变之前,我想了解其中的区别 - 为什么它适用于Linux而不是OSX?
你对movq
指令无法引用绝对地址是正确的。 这部分是由于OS X ABI Mach-O格式,它使用符号的可重定位寻址。
编译为与位置无关的可执行文件( PIE
)的程序通常不能以与movq $_main, %rax
相同的方式引用绝对虚拟地址。 相反,调用全局偏移表 ,其允许位置相对代码( PC-rel
)和位置无关代码( PIC
)在其当前绝对地址位置处提取全局偏移代码。 如下所示, GOTPCREL(%rip)
创建了lea rdi, _msg
的解释:
PC-rel代码引用它的全局偏移表:
.globl _main
_main:
movq _main@GOTPCREL(%rip), %rax
sub $8, %rsp
mov $0, %rax
movq _msg@GOTPCREL(%rip), %rdi
call _printf
add $8, %rsp
ret
.cstring
_msg:
.ascii "Hello, world\n"
Mac OS X Mach-O汇编程序:
$ as -o test.o test.asm
Apple的GCC版本:
$ gcc -o test.out test.o
输出:
$ ./test.out
Hello, world
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.