gpt4 book ai didi

linux - 为什么x86-64 Linux系统调用会修改RCX,这个值是什么意思?

转载 作者:可可西里 更新时间:2023-11-01 11:45:11 27 4
gpt4 key购买 nike

我正在尝试使用 sys_brk 系统调用在 Linux 中分配一些内存。这是我尝试过的:

BYTES_TO_ALLOCATE equ 0x08

section .text
global _start

_start:
mov rax, 12
mov rdi, BYTES_TO_ALLOCATE
syscall

mov rax, 60
syscall

根据 linux 调用约定,我希望返回值位于 rax 寄存器(指向已分配内存的指针)中。我在 gdb 中运行它,在进行 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

在这种情况下,我不太理解 rcx 寄存器中的值。哪一个用作指向我用 sys_brk 分配的 8 个字节开头的指针?

最佳答案

系统调用返回值在rax中,一如既往。参见 What are the calling conventions for UNIX & Linux system calls on i386 and x86-64 .

请注意,sys_brkbrk/sbrk POSIX 函数的接口(interface)略有不同;查看C library/kernel differences section of the Linux brk(2) man page .具体来说,Linux sys_brk 设置程序中断; arg 和返回值都是指针。参见 Assembly x86 brk() call use .该答案需要投票,因为它是该问题上唯一好的答案。


您问题的另一个有趣部分是:

I do not quite understand the value in the rcx register in this case

您正在了解 syscall 的机制/sysret指令旨在允许内核恢复用户空间执行但仍然很快。

syscall 不做任何加载或存储,它只修改寄存器。它没有使用特殊寄存器来保存返回地址,而是简单地使用常规整数寄存器。

RCX=RIPR11=RFLAGS 在内核返回到您的用户空间代码之后并非巧合不是的唯一方法是,如果 ptrace 系统调用修改了进程保存的 rcxr11 在内核中时的值。 (ptrace 是 gdb 使用的系统调用)。在那种情况下,Linux 将使用 iret 而不是 sysret 返回用户空间,因为较慢的一般情况 iret 可以做到这一点。 (有关 Linux 系统调用入口点的一些演练,请参阅 What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?。大多数入口点来自 32 位进程,而不是来自 64 位进程中的 syscall。)


syscall 不是将返回地址压入内核堆栈(如 int 0x80 那样):

  • 设置 RCX=RIP,R11=RFLAGS(因此在您执行 syscall 之前内核甚至不可能看到这些 regs 的原始值)。

  • 使用来自配置寄存器(IA32_FMASK MSR)的预配置掩码来屏蔽 RFLAGS。这让内核禁用中断 (IF),直到完成 swapgs 并将 rsp 设置为指向内核堆栈。即使将 cli 作为入口点的第一条指令,也会存在一个漏洞窗口。您还可以通过屏蔽 DF 免费获得 cld 所以 rep movs/stos 即使用户空间向上曾使用过std

    有趣的事实:AMD 首次提出的 syscall/swapgs 设计并没有屏蔽 RFLAGS,而是 they changed it after feedback from kernel developers on the amd64 mailing list (大约在 2000 年,比第一 block 硅早几年)。

  • 跳转到配置的 syscall 入口点(设置 CS:RIP = IA32_LSTAR)。我认为旧的 CS 值没有保存在任何地方。

  • 它不做任何其他事情,内核必须使用 swapgs 来访问它保存内核堆栈指针的信息 block ,因为 rsp 仍然具有来自用户空间的值(value)。

因此 syscall 的设计需要一个破坏寄存器的系统调用 ABI,这就是为什么值是它们的原因。

关于linux - 为什么x86-64 Linux系统调用会修改RCX,这个值是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47983371/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com