系统调用的demo程序分析

我的理解是为了保护系统的整体稳定性,把程序划分为3环和0环,用户所编写的程序运行在3环内,各自拥有独立的堆栈。用户在编写代码的时候需要使用一些硬件资源,这个时候需要访问内核的接口,cpu有保护模式,所以只能通过系统调用来完成我们想执行的功能。我们大部分时候会访问glibc库中帮我们封装好的接口,在glibc封装的函数里,在需要调用真正的内核函数之前,glibc的函数会int 0x80(中断号)进行软中断,使用eax传入的系统调用号,在调用表sys_call_table上通过偏移,找到对应的函数的入口,保存3环的寄存器环境,切换到内核态,然后执行内核代码。执行结束后,把返回值保存在eax里面,然后跳到ret_from_sys_call(),完成系统调用

gdb-peda$ disassemble main
Dump of assembler code for function main:
   0x000000000040114a <+0>: 	push   rbp
   0x000000000040114b <+1>: 	mov    rbp,rsp
   0x000000000040114e <+4>: 	sub    rsp,0x10
   #X64的程序,传参第一个寄存器是rdi,这里使用的是rdi的低四位(3环内)
   0x0000000000401152 <+8>:  	mov    edi,0x224 
   0x0000000000401157 <+13>:	mov    eax,0x0
   0x000000000040115c <+18>:	call   0x401040 <syscall@plt>
   #此时rax里面是返回值,传递给了栈里面的变量
   0x0000000000401161 <+23>:	mov    QWORD PTR [rbp-0x8],rax
   0x0000000000401165 <+27>:	mov    rax,QWORD PTR [rbp-0x8]
   #X64的程序,传参顺序%rdi, %rsi, %rdx, %rcx, %r8, %r9
   #这里的rsi被赋值为系统调用的返回值
   0x0000000000401169 <+31>:	mov    rsi,rax
   #这里的0x402004指向一个地址
   #arg[0]: 0x402004 --> 0x3b031b0100006425 --->后面的6425 就是%d
   0x000000000040116c <+34>:	mov    edi,0x402004
   0x0000000000401171 <+39>:	mov    eax,0x0
   0x0000000000401176 <+44>:	call   0x401030 <printf@plt>
   0x000000000040117b <+49>:	mov    eax,0x0
   0x0000000000401180 <+54>:	leave  
   0x0000000000401181 <+55>:	ret    
End of assembler dump.
gdb-peda$ disassemble 
Dump of assembler code for function syscall:
   #这里发现内存地址跨度变换了,进入到了0环,这个把 rdi传给了rax,符合系统调用的条件
   0x00007ffff7efdca0 <+0>: 	mov    rax,rdi
   0x00007ffff7efdca3 <+3>: 	mov    rdi,rsi
   0x00007ffff7efdca6 <+6>: 	mov    rsi,rdx
   0x00007ffff7efdca9 <+9>: 	mov    rdx,rcx
   0x00007ffff7efdcac <+12>:	mov    r10,r8
   0x00007ffff7efdcaf <+15>:	mov    r8,r9
   0x00007ffff7efdcb2 <+18>:	mov    r9,QWORD PTR [rsp+0x8]
   0x00007ffff7efdcb7 <+23>:	syscall #怀疑这里是执行系统调用的函数,但是跟不进去,不知道为什么
=> 0x00007ffff7efdcb9 <+25>:	cmp    rax,0xfffffffffffff001
   0x00007ffff7efdcbf <+31>:	jae    0x7ffff7efdcc2 <syscall+34>
   0x00007ffff7efdcc1 <+33>:	ret    
   0x00007ffff7efdcc2 <+34>:	mov    rcx,QWORD PTR [rip+0xbe19f]        # 0x7ffff7fbbe68
   0x00007ffff7efdcc9 <+41>:	neg    eax
   0x00007ffff7efdccb <+43>:	mov    DWORD PTR fs:[rcx],eax
   #这里应该是系统调用失败,返回一个负数
   0x00007ffff7efdcce <+46>:	or     rax,0xffffffffffffffff
   0x00007ffff7efdcd2 <+50>:	ret    
End of assembler dump.

猜你喜欢

转载自blog.csdn.net/qq_43553690/article/details/120987945