直接从用户程序访问系统调用

Omk*_*ant 9 c posix system-calls

在Ubuntu上 - 内核2.6.32.2

如何在没有任何库帮助的情况下直接从用户代码调用已有的系统调用?我读书和在互联网上解决这个问题,然后写下面的代码但仍然出错.请帮忙

想要找出当前进程的进程ID

#include <stdio.h>
#include<linux/unistd.h> // for __NR_getpid
_syscall0(int, getpid)

int main() {
 printf("Current Process ID : %d\n",getpid());
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译时出错:

root@Omkant:~/os# gcc -Wall getpid.c -o getpid
getpid.c:5:16: error: expected declaration specifiers or ‘...’ before ‘getpid’
getpid.c:5:1: warning: data definition has no type or storage class
getpid.c:5:1: warning: type defaults to ‘int’ in declaration of ‘_syscall0’
getpid.c: In function ‘main’:
getpid.c:8:2: warning: implicit declaration of function ‘getpid’
Run Code Online (Sandbox Code Playgroud)

代码中的问题是什么?请帮忙...

fuz*_*fuz 13

对于手册页_syscall(2)指出:

从内核2.6.18开始,从提供给用户空间的头文件中删除了_syscall宏.请改用syscall(2).(有些架构,尤其是ia64,从未提供_syscall宏;在这些架构上,始终需要syscall(2).)

因此,您所需的方法无法在更现代的内核上运行.(您可以清楚地看到,如果您在代码上运行预处理器.它将无法解析_syscall0宏)尝试使用该syscall函数:

以下是一个使用示例,引自syscall(2):

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>

int
main(int argc, char *argv[])
{
    pid_t tid;
    tid = syscall(SYS_gettid);
}
Run Code Online (Sandbox Code Playgroud)

当您要求直接调用Linux内核而没有任何用户空间包装器时,我将向您展示80386和amd64架构的示例.

首先,您必须从表中获取系统调用号,例如表.在这种情况下getpid,amd64的系统调用号为39,80386的系统调用号为20.接下来,我们创建一个为我们调用系统的函数.在80386处理器上使用中断128来调用系统,在amd64上我们使用特殊syscall指令.系统调用号进入寄存器eax,输出也写入该寄存器.为了使程序更容易,我们在汇编中编写它.您可以稍后使用strace验证它是否正常工作.

这是80386的代码.它应该返回其pid的最低字节作为退出状态.

        .global _start
_start: mov $20,%eax       #system call number 20:
        int $128           #call the system
        mov %eax,%ebx      #move pid into register ebx
        mov $1,%eax        #system call number 1: exit, argument in ebx
        int $128           #exit
Run Code Online (Sandbox Code Playgroud)

组装:

as -m32 -o 80386.o 80386.s
ld -m elf_i386 -o 80386 80386.o
Run Code Online (Sandbox Code Playgroud)

这是amd64的相同代码:

        .global _start
_start: mov $39,%eax    #system call 39: getpid
        syscall         #call the system
        mov %eax,%edi   #move pid into register edi
        mov $60,%eax    #system call 60: exit
        syscall         #call the system
Run Code Online (Sandbox Code Playgroud)

组装:

as -o amd64.o amd64.s
ld -o amd64 amd64.o
Run Code Online (Sandbox Code Playgroud)