linux修改栈指针x86,为什么x86-64 Linux系统调用会修改RCX,这个值意味着什么?

本文详细解释了在Linux中使用sys_brk进行内存分配的过程,特别关注了系统调用后寄存器变化,着重解析了rcx寄存器在返回指针中的角色。文章还介绍了系统调用设计的细节,包括如何使用RCX/RIP和RFLAGS,以及与x86-64系统调用接口的关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我正在尝试使用sys_brk syscall在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 ;

rdx 0x0 0

rsi 0x0 0

rdi 0x8 8

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

解决方法:

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

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

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

您正在看到syscall/sysret指令如何设计为允许内核恢复用户空间执行但仍然很快的机制.

系统调用不执行任何加载或存储,它只修改寄存器.它不使用特殊寄存器来保存返回地址,而只使用常规整数寄存器.

在内核返回到用户空间代码之后,RCX = RIP和R11 = RFLAGS并不是巧合.这种情况的唯一方法是,如果ptrace系统调用在内核中修改了进程保存的rcx或r11值. (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位进程中的系统调用.)

而不是将返回地址推送到内核堆栈(如int 0x80),系统调用:

>设置RCX = RIP,R11 = RFLAGS(因此在执行系统调用之前,内核甚至无法查看这些寄存器的原始值).

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

有趣的事实:AMD首次提出的系统调用/交换设计并未掩盖RFLAGS,而是掩盖了they changed it after feedback from kernel developers on the amd64 mailing list(在〜2000年,比第一个芯片早几年).

>跳转到配置的系统调用入口点(设置CS:RIP = IA32_LSTAR).我想,旧的CS值不会保存在任何地方.

>它没有做任何其他事情,内核必须使用swapgs来访问保存内核堆栈指针的信息块,因为rsp仍然有来自用户空间的值.

因此,系统调用的设计需要一个系统调用ABI,其中注册符号,这就是为什么这些值是它们的原因.

标签:linux,assembly,x86-64,system-calls

来源: https://codeday.me/bug/20190828/1749140.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值