考虑以下汇编程序:
bits 64
global _start
_start:
mov rax, 0x0000111111111111
add byte [rax*1+0x0], al
jmp _start
当您使用nasm
and ld
(在 Ubuntu,内核 5.4.0-48-generic,Ryzen 3900X 上)编译它时,您会得到一个段错误:
$ ./segfault-addr
[1] 107116 segmentation fault (core dumped) ./segfault-addr
(gdb) p $_siginfo._sifields._sigfault.si_addr
$1 = (void *) 0x111111111111
但是,如果您将 16 个最高有效位中的任何一个设置为 1,如下所示:
bits 64
global _start
_start:
mov rax, 0x0001111111111111
add byte [rax*1+0x0], al
jmp _start
您显然仍然会遇到段错误,但现在地址为 NULL:
(gdb) p $_siginfo._sifields._sigfault.si_addr
$1 = (void *) 0x0
为什么会这样?是gdb
Linux,还是CPU本身造成的?
我能做些什么来防止这种行为吗?