Linux system_call流程分析

system_call函数的汇编代码如下:

.text:FFFFFFFF8020AFC0                 public system_call
.text:FFFFFFFF8020AFC0                 swapgs					; 将gs切换至内核态
.text:FFFFFFFF8020AFC3                 db      66h, 66h, 66h, 66h, 2Eh
.text:FFFFFFFF8020AFC3                 nop     word ptr [rax+rax+00000000h] 
.text:FFFFFFFF8020AFD0                 mov     gs:pt_regs._r12, rsp ; old_rsp, 用户态栈指针
.text:FFFFFFFF8020AFD9                 mov     rsp, gs:pt_regs._r13 ; kernel_stack
.text:FFFFFFFF8020AFE2                 sti
.text:FFFFFFFF8020AFE3                 sub     rsp, 50h        ; rsp->pt_regs.rip
.text:FFFFFFFF8020AFE7                 mov     [rsp+40h], rdi  ; arg0
.text:FFFFFFFF8020AFEC                 mov     [rsp+38h], rsi  ; arg1
.text:FFFFFFFF8020AFF1                 mov     [rsp+30h], rdx  ; arg2
.text:FFFFFFFF8020AFF6                 mov     [rsp+20h], rax  ; 系统调用号
.text:FFFFFFFF8020AFFB                 mov     [rsp+18h], r8   ; arg4
.text:FFFFFFFF8020B000                 mov     [rsp+10h], r9   ; arg5
.text:FFFFFFFF8020B005                 mov     [rsp+8], r10    ; arg3
.text:FFFFFFFF8020B00A                 mov     [rsp+0], r11    ; eflags
.text:FFFFFFFF8020B00E                 mov     [rsp+48h], rax  ; 系统调用号
.text:FFFFFFFF8020B013                 mov     [rsp+50h], rcx  ; 返回地址rip
.text:FFFFFFFF8020B018                 mov     rcx, gs:pt_regs._r13
.text:FFFFFFFF8020B021                 sub     rcx, 1FD8h      ; thread_union大小为8KB
.text:FFFFFFFF8020B028                 test    [rcx+thread_union.thread_info.flags], 181h
.text:FFFFFFFF8020B02F                 jnz     tracesys
.text:FFFFFFFF8020B035                 cmp     rax, 11Fh       ; 检查系统调用号
.text:FFFFFFFF8020B03B                 ja      badsys
.text:FFFFFFFF8020B041                 mov     rcx, r10
.text:FFFFFFFF8020B044                 call    ds:sys_call_table[rax*8]
.text:FFFFFFFF8020B04B                 mov     [rsp+20h], rax  ; 返回值
.text:FFFFFFFF8020B04B system_call     endp
.text:FFFFFFFF8020B050 ret_from_sys_call:
.text:FFFFFFFF8020B050                 mov     edi, 0FEFFh     ; flag_mask

.text:FFFFFFFF8020B055 sysret_check    proc near   
.text:FFFFFFFF8020B055                 mov     rcx, gs:pt_regs._r13
.text:FFFFFFFF8020B05E                 sub     rcx, 1FD8h      ; kernel_stack
.text:FFFFFFFF8020B065                 cli
.text:FFFFFFFF8020B066                 mov     edx, [rcx+10h]
.text:FFFFFFFF8020B069                 and     edx, edi
.text:FFFFFFFF8020B06B                 jnz     short sysret_careful
.text:FFFFFFFF8020B06D                 mov     rcx, [rsp+50h]  ; 返回地址
.text:FFFFFFFF8020B072                 mov     r11, [rsp+0]    ; eflags
.text:FFFFFFFF8020B076                 mov     r10, [rsp+8]    ; arg3
.text:FFFFFFFF8020B07B                 mov     r9, [rsp+10h]   ; arg5
.text:FFFFFFFF8020B080                 mov     r8, [rsp+18h]   ; arg4
.text:FFFFFFFF8020B085                 mov     rax, [rsp+20h]  ; 返回值
.text:FFFFFFFF8020B08A                 mov     rdx, [rsp+30h]  ; 返回地址
.text:FFFFFFFF8020B08F                 mov     rsi, [rsp+38h]  ; arg2
.text:FFFFFFFF8020B094                 mov     rdi, [rsp+40h]  ; arg1
.text:FFFFFFFF8020B099                 mov     rsp, gs:pt_regs._r12 ; old_rsp
.text:FFFFFFFF8020B0A2                 swapgs                  ; 切换回用户态gs
.text:FFFFFFFF8020B0A5                 sysret                  ; 中断返回

进入system_call函数的寄存器初始状态:

在这里插入图片描述

// include/asm-x86/ptrace.h
struct pt_regs {
	unsigned long r15;
	unsigned long r14;
	unsigned long r13;			// kernel_stack
	unsigned long r12;			// old_rsp
	unsigned long rbp;
	unsigned long rbx;
/* arguments: non interrupts/non tracing syscalls only save upto here*/
	unsigned long r11;			// eflags
	unsigned long r10;			// arg3
	unsigned long r9;			// arg5
	unsigned long r8;			// arg4
	unsigned long rax;			// 系统调用号&系统调用返回值
	unsigned long rcx;			// 返回地址rip
	unsigned long rdx;			// arg2
	unsigned long rsi;			// arg1
	unsigned long rdi;			// arg0
	unsigned long orig_rax;		// 系统调用号(2)
/* end of arguments */
/* 内核态返回用户态需要恢复现场的数据 */
	unsigned long rip;			// 返回地址(2), 默认内核栈起始地址
	unsigned long cs;			// 用户态代码段
	unsigned long eflags;		// 用户态eflags
	unsigned long rsp;			// 用户栈顶
	unsigned long ss;			// 用户数据段
/* top of stack page */
};

  • rcx:返回地址
  • rax:系统调用号


0xffffffff8020afd0 <system_call+16>:	mov    %rsp,%gs:0x18	# 切换至内核栈

在这里插入图片描述
发起系统调用的用户态栈顶,其参数依次为:

  1. 返回地址
  2. 用户态代码段 cs
  3. 用户态 eflags
  4. 用户态栈顶 rsp
  5. 用户态栈段 ss

用户程序发起系统调用的汇编代码如下:
在这里插入图片描述

.text:FFFFFFFF8020B018                 mov     rcx, gs:pt_regs._r13
.text:FFFFFFFF8020B021                 sub     rcx, 1FD8h      ; thread_union大小为8KB

此时rsp指向thread_union结构体的首地址。


在这里插入图片描述




发起系统调用
在这里插入图片描述


返回值为pid=956
在这里插入图片描述


成功返回进程pid:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值