Post

Partie 18 - Le user land et kernel land

Le user land et kernel land

Vous vous ĂȘtes toujours demandĂ© la diffĂ©rence entre le noyau de votre OS, un programme lambda et un pilote ?

Ça tombe bien ! Nous allons tenter de comprendre comment interagissent ces diffĂ©rents composant d’un systĂšme d’exploitation. L’idĂ©e est que vous puissiez avoir une vision globale de l’interaction entre le user land et kernel land sans pour autant entrer dans les dĂ©tails du kernel land.

D’ailleurs, vous le saviez, vous, que le kernel Linux Ă©tait un fichier ELF et que le kernel Windows Ă©tait un fichier PE đŸ˜Č ?

Sous linux, le kernel se trouve ici : /boot/vmlinuz-$(uname -r). Vous pouvez suivre les Ă©tapes indiquĂ©es ici afin de constater par vous-mĂȘme que le kernel n’est finalement qu’un fichier ELF 🙃.

Sous Windows, le kernel est normalement présent ici : C:\Windows\System32\ntoskrnl.exe.

Les appels systĂšme (ou syscalls)

Nous n’allons pas nous attarder sur le kernel land en termes de reverse car il est nĂ©cessaire d’ĂȘtre trĂšs Ă  l’aise en rĂ©tro-ingĂ©nierie et d’avoir des connaissances avancĂ©es concernant le fonctionnement su kernel land et ce n’est pas forcĂ©ment un chapitre qu’il convient d’entamer dans un cours d’introduction au reverse.

Néanmoins, il y a une fonctionnalité que vous risquez de rencontrer et qui est à la limite du user land et du kernel land : les appels systÚme (ou syscalls).

DerriÚre ce nom alambiqué se cache une solution à une problématique relativement simple.

La problématique

Voici comment on pourrait reprĂ©senter la mĂ©moire du PC Ă  un instant T (sous Linux mais sous Windows le principe et plus ou moins le mĂȘme) :

Nous pouvons distinguer 3 parties :

  • Le user land : c’est la partie visible de l’iceberg, celle Ă  laquelle on est confrontĂ©s tous les jours : navigateur, terminal, programme compilĂ©, serveur web et j’en passe.
  • Le hardware : il s’agit du matĂ©riel et pĂ©riphĂ©rique que l’on branche Ă  un ordinateur, qui peuvent ĂȘtre essentiels (RAM, Disque dur / SSD 
) ou non (imprimante, carte graphique dĂ©diĂ©e, souris, clavier, ethernet 
).
  • Le kernel land : l’accĂšs au matĂ©riel et pĂ©riphĂ©riques Ă©tant beaucoup trop sensible ( exemple : risque de sabotage du Disque dur si mal utilisĂ©), il n’est pas possible de laisser n’importe quel programme en user land y accĂ©der. Il faut donc que des programmes bien spĂ©cifiques, appelĂ©s pilotes, modules ou drivers opĂšrent ce dĂ©licat travail . Le kernel land contient le kernel (noyau, merci Sherlock đŸ•”ïžâ€â™‚ïž) de l’OS. Le noyau est chargĂ© de faire un tas de choses dont : l’ordonnancement, la gestion de la mĂ©moire physique et virtuelle 


Ok je comprends bien, donc les pilotes gùrent les accùs au hardware afin que tout se passe bien, jusque-là, c’est ok.

Mais comment fait un programme en user land, par exemple mon navigateur, pour se connecter Ă  internet s’il n’a pas directement accĂšs Ă  la carte rĂ©seau WiFi / Ethernet đŸ€” ?

C’est justement LA problĂ©matique susmentionnĂ©e Ă  laquelle les appels systĂšme vont nous permettre de rĂ©pondre : comment interagir avec des composants ou fonctionnalitĂ© bas niveau Ă  partir du user land ?

Un appel systÚme, comment ça marche ?

PremiĂšrement voici une maniĂšre de reprĂ©senter l’utilitĂ© des appels systĂšme dans le prĂ©cĂ©dent schĂ©ma :

Les appels systùmes vont jouer le rîle d’interface entre le user land et le kernel land.

Les syscalls sont des fonctions prĂ©dĂ©finies prĂ©sentes dans le kernel lui mĂȘme. La liste des syscalls (sous Linux) est disponible dans le fichier include/linux/syscalls.h.

Si on y jette un Ɠil, au vu des noms de fonctions qui sont assez explicites, on constate qu’il y a des fonctions de gestion de fichiers (sys_read, sys_write, sys_open, sys_close 
 ) de gestion de mĂ©moire (sys_mmap, sys_mprotect, sys_munmap 
) et bien d’autres.

Par abus de langage, on parle souvent de syscall read pour parler de sys_read, write pour sys_write etc.

Vous remarquerez que beaucoup de ces noms de fonctions ressemblent tout simplement Ă  des fonctions de la libc (read, write, mmap 
). D’ailleurs, les fonctions associĂ©es dans la libc ne sont “que” des surcouches (wrappers) aux appels systĂšme idoines.

Quoi ? Vous ne me croyez pas 😞 ? Alors voici un exemple avec la fonction read :

1
2
3
4
5
6
7
8
9
10
#include <unistd.h>  
#include <stdio.h>  
  
int main()  
{  
 char buff[20];  
 read(0,buff,10);  
  
 return 1;  
}

Compilons-le en statique afin de pouvoir voir le contenu de read 
 en analyse statique : gcc -static main.c -o exe.

Si vous ouvrez le programme dans IDA et allez dans read, vous verrez cela :

En assembleur, le syscall est rĂ©alisĂ© avec l’instruction syscall (merci Sherlock đŸ•”ïžâ€â™‚ïž) :

En fait, l’instruction syscall n’est disponible qu’en x86_64. Ainsi, pour rĂ©aliser un appel systĂšme en x86, c’est plutĂŽt l’instruction (plus prĂ©cisĂ©ment, interruption) int 0x80 qui est utilisĂ©e.

Il y a une convention d’appel Ă  respecter lorsque l’on souhaite rĂ©aliser un appel systĂšme. Par exemple mettre le numĂ©ro du syscall dans eax/rax. NĂ©anmoins, comme nous n’allons pas nous attaquer au reverse kernel land, il n’est pas nĂ©cessaire de nous y attarder.

Convaincus maintenant 😏 ?

En somme, un appel systĂšme est une fonction prĂ©dĂ©finie du kernel que l’on peut appeler depuis le user land. Le kernel se dĂ©brouille ensuite pour utiliser les bons modules/pilotes afin de satisfaire la demande (lecture de l’entrĂ©e standard, allocation de mĂ©moire, Ă©criture dans un fichier 
).

Si vous souhaitez comprendre davantage le fonctionnement des appels systĂšme, cet article est fait pour vous. Il est rĂ©digĂ© en anglais mais permet de comprendre les aspects techniques sous-jacents lors d’un syscall.

Dans le prĂ©cĂ©dent schĂ©ma, tous les syscall finissent dans le kernel. N’est-il pas possible d’interagir aussi avec les diffĂ©rents pilotes en kernel land ?

Il est effectivement possible d’interagir avec des drivers avec un appel systĂšme bien prĂ©cis sous Linux : ioctl (et DeviceIoControl sous Windows).

L’explication et le fonctionnement de ce syscall sortent du cadre de ce cours et puis, de toute maniĂšre, on ne le voit pas trĂšs souvent quand on dĂ©bute en reverse, sauf Ă©ventuellement dans des programmes qui nĂ©cessitent d’échanger des donnĂ©es avec certains pilotes. Cela peut ĂȘtre le cas, par exemple, des programmes systĂšme.

Si vous ĂȘtes Ă©galement intĂ©ressĂ©s au sujet de la gestion des interruptions, voici un petit rĂ©sumĂ© qui en parle : les interruptions.

This post is licensed under CC BY-NC 4.0 by the author.