LINUX系统调用

系统调用是用户程序和linux内核交互的接口,linux的系统调用有下面三种方式:

int 80

在x86与x86_64的系统中,都可以使用int $0x80指令来执行系统调用,参数使用如下:

调用号 参数1 参数2 参数3 参数4 参数5 参数6 返回值
eax ebx ecx edx esi edi ebp eax

syscall

x86_64引入了一个新指令syscall来执行系统调用,参数使用如下:

调用号 参数1 参数2 参数3 参数4 参数5 参数6 返回值
rax rdi rsi rdx r10 r8 r9 rax

库函数

正常调用库函数(man 3 execve),传参方式见x86 调用约定

查看调用号与参数

查看调用号:头文件/usr/include/asm/unistd.h内容如下,所以32位和64位的调用号可以分别在unistd_32.h和unistd_64.h中找到

/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _ASM_X86_UNISTD_H
#define _ASM_X86_UNISTD_H

/* x32 syscall flag bit */
#define __X32_SYSCALL_BIT   0x40000000UL

# ifdef __i386__
#  include 
# elif defined(__ILP32__)
#  include 
# else
#  include 
# endif

#endif /* _ASM_X86_UNISTD_H */

查看参数:man 2 execve

示例

execve为例,man 2 execve查看其接口如下:int execve(const char *pathname, char *const argv[], char *const envp[]);

下面汇编实现了execve("/bin/sh", 0, 0)

32位:

xor ecx, ecx
push 0x0b
pop eax
cdq
push 0x68732f
push 0x6e69622f
mov ebx, esp
int 0x80

64位:

mov rdx, 0x68732f6e69622f
push rdx
push rsp
pop rdi
xor rsi, rsi
xor rdx, rdx
push 59
pop rax
syscall

参考

  • X86 Assembly/Interfacing with Linux
  • AT&T汇编之32位与64位系统调用
  • Linux/x64 - execve(/bin/sh) Via Push Shellcode (23 bytes)
  • Linux/x86 - execve(/bin/sh) Shellcode (21 bytes) (4)
  • Linux x64下编写shellcode - execve(/bin/sh)

你可能感兴趣的:(LINUX系统调用)