Access a system call directly from a user program

Ubuntu kernel 2.6.32.2

How to call an existing system call from user code directly without using any library? I read in books and on the Internet to solve this, and then wrote the following code, but still got the error. Please, help

Want to know the process ID of the current process

#include <stdio.h> #include<linux/unistd.h> // for __NR_getpid _syscall0(int, getpid) int main() { printf("Current Process ID : %d\n",getpid()); return 0; } 

Error during compilation:

 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' 

What is the problem in the code? please, help...

+7
source share
2 answers

The manpage for _syscall(2) states:

Starting with kernel 2.6.18, the _syscall macros have been removed from the header files provided in user space. Use syscall (2) instead. (Some architectures, in particular ia64, never provided _syscall macros; syscall (2) was always required on these architectures.)

Thus, your desired approach may not work on more modern kernels. (You can clearly see that if you run the preprocessor in your code, it will not solve the _syscall0 macro) Use syscall :

Here is a usage example given in 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); } 

Since you asked for a direct way to invoke the Linux kernel without any shells for user space, I will show you examples for the 80386 and amd64 architectures.

First, you need to get the system call number from the table, for example this one . In the case of getpid the system call number is 39 for amd64 and 20 for 80386. Then we create a function that calls the system for us. On the 80386 processor, you use interrupt 128 to call the system, on amd64 we use the special syscall instruction. The system call number goes into the eax register, the output is also written to this register. To make the program easier, we write it in the assembly. Subsequently, you can use strace to verify proper operation.

This is the code for 80386. It should return the low byte of its pid as the exit status.

  .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 

Build with:

 as -m32 -o 80386.o 80386.s ld -m elf_i386 -o 80386 80386.o 

This is the same code for 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 

Build with:

 as -o amd64.o amd64.s ld -o amd64 amd64.o 
+11
source

"How to call an existing system call from user code directly without the help of any library? I read in books and on the Internet to solve this, and then wrote the following code, but still get the error"

your question, like the question of how to use printf without using glibc / libc, I assume that only one solution gets printf source code, inserts it into your code and uses it

Want to know the process ID of the current process

process id can be found using getpid function from libc, which takes care of ur system call.

system calls are not defined in libraries; these are functions written to access kernel data.

Regards, Bison

-3
source

All Articles