Rumah Operasi dan penyelenggaraan operasi dan penyelenggaraan linux Bagaimana untuk melaksanakan panggilan sistem Linux

Bagaimana untuk melaksanakan panggilan sistem Linux

May 18, 2023 am 09:07 AM
linux

一、通过 glibc 提供的库函数
glibc 是 linux 下使用的开源的标准 c 库,它是 gnu 发布的 libc 库,即运行时库。glibc 为程序员提供丰富的 api(application programming interface),除了例如字符串处理、数学运算等用户态服务之外,最重要的是封装了操作系统提供的系统服务,即系统调用的封装。那么glibc提供的系统调用api与内核特定的系统调用之间的关系是什么呢?

  • 通常情况,每个特定的系统调用对应了至少一个 glibc 封装的库函数,如系统提供的打开文件系统调用 sys_open 对应的是 glibc 中的 open 函数;

  • 其次,glibc 一个单独的 api 可能调用多个系统调用,如 glibc 提供的 printf 函数就会调用如 sys_open、sys_mmap、sys_write、sys_close 等等系统调用;

  • 另外,多个 api 也可能只对应同一个系统调用,如glibc 下实现的 malloc、calloc、free 等函数用来分配和释放内存,都利用了内核的 sys_brk 的系统调用。

举例来说,我们通过 glibc 提供的chmod 函数来改变文件 etc/passwd 的属性为 444:

#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>

int main()
{
  int rc;

  rc = chmod("/etc/passwd", 0444);
  if (rc == -1)
    fprintf(stderr, "chmod failed, errno = %d\n", errno);
  else
    printf("chmod success!\n");
  return 0;
}
Salin selepas log masuk

在普通用户下编译运用,输出结果为:

chmod failed, errno = 1
上面系统调用返回的值为-1,说明系统调用失败,错误码为1,在 /usr/include/asm-generic/errno-base.h 文件中有如下错误代码说明:

#define eperm 1 /* operation not permitted */
即无权限进行该操作,我们以普通用户权限是无法修改 /etc/passwd 文件的属性的,结果正确。

二、使用 syscall 直接调用
使用上面的方法有很多好处,首先你无须知道更多的细节,如 chmod 系统调用号,你只需了解 glibc 提供的 api 的原型;其次,该方法具有更好的移植性,你可以很轻松将该程序移植到其他平台,或者将 glibc 库换成其它库,程序只需做少量改动。
但有点不足是,如果 glibc 没有封装某个内核提供的系统调用时,我就没办法通过上面的方法来调用该系统调用。如我自己通过编译内核增加了一个系统调用,这时 glibc 不可能有你新增系统调用的封装 api,此时我们可以利用 glibc 提供的syscall 函数直接调用。该函数定义在 unistd.h 头文件中,函数原型如下:

long int syscall (long int sysno, ...)

  • 每个系统调用都有一个独特的sysno系统调用号来进行标识。在sys/syscall.h中,所有可能使用的系统调用号都被定义为宏。

  • ... 为剩余可变长的参数,为系统调用所带的参数,根据系统调用的不同,可带0~5个不等的参数,如果超过特定系统调用能带的参数,多余的参数被忽略。

  • 返回值 该函数返回值为特定系统调用的返回值,在系统调用成功之后你可以将该返回值转化为特定的类型,如果系统调用失败则返回 -1,错误代码存放在 errno 中。

还以上面修改 /etc/passwd 文件的属性为例,这次使用 syscall 直接调用:

#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <errno.h>

int main()
{
  int rc;
  rc = syscall(sys_chmod, "/etc/passwd", 0444);

  if (rc == -1)
    fprintf(stderr, "chmod failed, errno = %d\n", errno);
  else
    printf("chmod succeess!\n");
  return 0;
}
Salin selepas log masuk

在普通用户下编译执行,输出的结果与上例相同。

三、通过 int 指令陷入
如果我们知道系统调用的整个过程的话,应该就能知道用户态程序通过软中断指令int 0x80 来陷入内核态(在intel pentium ii 又引入了sysenter指令),参数的传递是通过寄存器,eax 传递的是系统调用号,ebx、ecx、edx、esi和edi 来依次传递最多五个参数,当系统调用返回时,返回值存放在 eax 中。

仍然以上面的修改文件属性为例,将调用系统调用那段写成内联汇编代码:

#include <stdio.h>
#include <sys/types.h>
#include <sys/syscall.h>
#include <errno.h>

int main()
{
  long rc;
  char *file_name = "/etc/passwd";
  unsigned short mode = 0444;

  asm(
    "int $0x80"
    : "=a" (rc)
    : "0" (sys_chmod), "b" ((long)file_name), "c" ((long)mode)
  );

  if ((unsigned long)rc >= (unsigned long)-132) {
    errno = -rc;
    rc = -1;
  }

  if (rc == -1)
    fprintf(stderr, "chmode failed, errno = %d\n", errno);
  else
    printf("success!\n");

  return 0;
}
Salin selepas log masuk

如果 eax 寄存器存放的返回值(存放在变量 rc 中)在 -1~-132 之间,就必须要解释为出错码(在/usr/include/asm-generic/errno.h 文件中定义的最大出错码为 132),这时,将错误码写入 errno 中,置系统调用返回值为 -1;否则返回的是 eax 中的值。上面程序在 32位linux下以普通用户权限编译运行结果与前面两个相同!

Atas ialah kandungan terperinci Bagaimana untuk melaksanakan panggilan sistem Linux. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Tag artikel panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

DeepSeek Web Versi Pintu Masuk Laman Web Rasmi DeepSeek DeepSeek Web Versi Pintu Masuk Laman Web Rasmi DeepSeek Feb 19, 2025 pm 04:54 PM

DeepSeek Web Versi Pintu Masuk Laman Web Rasmi DeepSeek

Android TV Box mendapat peningkatan Ubuntu 24.04 tidak rasmi Android TV Box mendapat peningkatan Ubuntu 24.04 tidak rasmi Sep 05, 2024 am 06:33 AM

Android TV Box mendapat peningkatan Ubuntu 24.04 tidak rasmi

Cara Memasang DeepSeek Cara Memasang DeepSeek Feb 19, 2025 pm 05:48 PM

Cara Memasang DeepSeek

Alamat muat turun aplikasi dompet BitPie Bitpie Alamat muat turun aplikasi dompet BitPie Bitpie Sep 10, 2024 pm 12:10 PM

Alamat muat turun aplikasi dompet BitPie Bitpie

Pemasangan Laman Web Rasmi Bitget (Panduan Pemula 2025) Pemasangan Laman Web Rasmi Bitget (Panduan Pemula 2025) Feb 21, 2025 pm 08:42 PM

Pemasangan Laman Web Rasmi Bitget (Panduan Pemula 2025)

Pemasangan penyusunan kod sumber Zabbix 3.4 Pemasangan penyusunan kod sumber Zabbix 3.4 Sep 04, 2024 am 07:32 AM

Pemasangan penyusunan kod sumber Zabbix 3.4

Penjelasan terperinci: Perintah parameter pertimbangan pembolehubah skrip Shell Penjelasan terperinci: Perintah parameter pertimbangan pembolehubah skrip Shell Sep 02, 2024 pm 03:25 PM

Penjelasan terperinci: Perintah parameter pertimbangan pembolehubah skrip Shell

Pakej pemasangan OUYI OKX disertakan secara langsung Pakej pemasangan OUYI OKX disertakan secara langsung Feb 21, 2025 pm 08:00 PM

Pakej pemasangan OUYI OKX disertakan secara langsung

See all articles