Accéder à un appel système directement depuis le programme utilisateur

Sur Ubuntu – kernel 2.6.32.2

Comment appeler directement un appel système existant depuis le code utilisateur sans l’aide d’une bibliothèque? J’ai lu dans des livres et sur Internet pour résoudre ce problème, puis j’ai écrit le code suivant, mais j’ai toujours des erreurs. S’il vous plaît aider

Vous voulez connaître l’identifiant du processus en cours

#include  #include // for __NR_getpid _syscall0(int, getpid) int main() { printf("Current Process ID : %d\n",getpid()); return 0; } 

Erreur lors de la 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' 

Quel est le problème dans le code? aidez s’il vous plaît …

La page de _syscall(2) de _syscall(2) indique:

À partir du kernel 2.6.18, les macros _syscall ont été supprimées des fichiers d’en-tête fournis à l’espace utilisateur. Utilisez syscall (2) à la place. (Certaines architectures, notamment ia64, n’ont jamais fourni les macros _syscall; sur ces architectures, syscall (2) était toujours requirejs.)

Ainsi, votre approche souhaitée ne peut pas fonctionner sur des kernelx plus modernes. (Vous pouvez clairement voir que si vous exécutez le préprocesseur sur votre code. Cela ne résoudra pas la macro _syscall0 ) Essayez d’utiliser la fonction syscall place:

Voici un exemple d’utilisation cité de syscall(2) :

 #define _GNU_SOURCE #include  #include  #include  int main(int argc, char *argv[]) { pid_t tid; tid = syscall(SYS_gettid); } 

Comme vous avez demandé un moyen direct d’appeler le kernel Linux sans aucun encapsuleur d’espace utilisateur, je vais vous montrer des exemples pour l’architecture 80386 et l’architecture amd64.

Premièrement, vous devez obtenir le numéro d’appel système d’une table, telle que celle-ci . Dans le cas de getpid , le numéro d’appel système est 39 pour amd64 et 20 pour 80386. Ensuite, nous créons une fonction qui appelle le système pour nous. Sur le processeur 80386, vous utilisez l’interruption 128 pour appeler le système, sur amd64, nous utilisons l’instruction spéciale syscall . Le numéro d’appel système entre dans le registre eax, la sortie est également écrite dans ce registre. Afin de faciliter le programme, nous l’écrivons en assembly. Vous pouvez utiliser ultérieurement strace pour vérifier qu’il fonctionne correctement.

C’est le code pour 80386. Il devrait renvoyer l’octet le plus bas de son pid comme état de sortie.

  .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 

Assembler avec:

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

C’est le même code pour 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 

Assembler avec:

 as -o amd64.o amd64.s ld -o amd64 amd64.o 

“Comment appeler directement un appel système existant depuis un code utilisateur sans l’aide d’aucune bibliothèque? J’ai lu dans des livres et sur Internet pour résoudre ce problème, puis écrit le code suivant, mais j’obtiens toujours une erreur”

votre question c’est comme demander comment utiliser printf sans utiliser glibc / libc, je suppose qu’il n’y a qu’une seule solution: obtenir le code source de printf, collez-le dans votre code et utilisez-le.

Vous voulez connaître l’identifiant du processus en cours

l’identifiant du processus peut être trouvé en utilisant la fonction getpid de libc qui s’occupe de votre appel système.

Les appels système ne sont pas définis dans les bibliothèques. Ce sont des fonctions écrites pour accéder aux données du kernel.

Cordialement, Zubraj