提问人:St.Antario 提问时间:12/27/2017 最后编辑:Peter CordesSt.Antario 更新时间:12/28/2017 访问量:6919
为什么 x86-64 Linux 系统调用会修改 RCX,该值是什么意思?
Why do x86-64 Linux system calls modify RCX, and what does the value mean?
问:
我正在尝试使用 syscall 在 linux 中分配一些内存。这是我尝试过的:sys_brk
BYTES_TO_ALLOCATE equ 0x08
section .text
global _start
_start:
mov rax, 12
mov rdi, BYTES_TO_ALLOCATE
syscall
mov rax, 60
syscall
问题是按照 linux 调用约定,我希望返回值在寄存器中(指向分配的内存的指针)。我在 gdb 中运行了它,在进行系统调用后,我注意到以下寄存器内容rax
sys_brk
在系统调用之前
rax 0xc 12
rbx 0x0 0
rcx 0x0 0
rdx 0x0 0
rsi 0x0 0
rdi 0x8 8
系统调用后
rax 0x401000 4198400
rbx 0x0 0
rcx 0x40008c 4194444 ; <---- What does this value mean?
rdx 0x0 0
rsi 0x0 0
rdi 0x8 8
在这种情况下,我不太了解寄存器中的值。使用哪一个作为指向我分配的 8 个字节开头的指针?rcx
sys_brk
答:
系统调用返回值一如既往地位于 中。请参阅 i386 和 x86-64 上 UNIX 和 Linux 系统调用的调用约定是什么。rax
请注意,其接口与 / POSIX 函数略有不同;请参见 Linux brk(2)
手册页的 C 库/内核差异部分。具体来说,Linux sys_brk
设置程序中断;arg 和返回值都是指针。请参阅程序集 x86 brk() 调用使用。这个答案需要赞成,因为它是这个问题上唯一好的答案。sys_brk
brk
sbrk
您问题的另一个有趣部分是:
在这种情况下,我不太明白rcx寄存器中的值
你看到的是 syscall
/sysret
指令是如何被设计成允许内核恢复用户空间执行但仍然快速的机制。
syscall
不执行任何加载或存储,它只修改寄存器。它不是使用特殊的寄存器来保存返回地址,而是简单地使用常规整数寄存器。
内核返回到用户空间代码后的 RCX=RIP
和 R11=RFLAGS
并非巧合。避免这种情况的唯一方法是,如果系统调用修改了进程在内核内部的保存或值。(是 GDB 使用的系统调用)。在这种情况下,Linux 将使用 instead 而不是返回用户空间,因为较慢的一般情况可以做到这一点。(请参阅 What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?,了解 Linux 系统调用入口点的一些演练。不过,大多数是来自 32 位进程的入口点,而不是来自 64 位进程的入口点。ptrace
rcx
r11
ptrace
iret
sysret
iret
syscall
syscall
不是将返回地址推送到内核堆栈上(就像那样),而是:int 0x80
设置 RCX=RIP, R11=RFLAGS (因此内核甚至不可能在执行之前看到这些 regs 的原始值)。
syscall
使用配置寄存器 (MSR) 中的预配置掩码进行掩码。这允许内核禁用中断 (IF),直到它完成并设置为指向内核堆栈。即使作为入口点的第一条指令,也会有一个漏洞窗口。即使用户空间已经使用,您也可以通过屏蔽 so / 向上获取免费。
RFLAGS
IA32_FMASK
swapgs
rsp
cli
cld
DF
rep movs
stos
std
有趣的事实:AMD 的第一个提议/设计并没有掩盖 RFLAGS,但他们在 amd64 邮件列表上的内核开发人员的反馈后对其进行了更改(在 ~2000 年,比第一个芯片早了几年)。
syscall
swapgs
跳转到配置的入口点(设置 CS:RIP = )。我认为,旧值不会保存在任何地方。
syscall
IA32_LSTAR
CS
它不做任何其他事情,内核必须用来访问它保存内核堆栈指针的信息块,因为它仍然具有来自用户空间的值。
swapgs
rsp
因此,设计需要一个系统调用 ABI 来破坏寄存器,这就是值是什么的原因。syscall
评论
sysret
syscall
sysret
syscall
syscall
sysret
ret
call printf
RCX != RIP
R11 != RFLAGS
iret
sysret
%rcx/%r11
RIP/RFLAGS
sysret
ptrace
评论
cl
xor cl, cl
mov cl, 7