Introduction à l'ASM X86

De UnixWiki
Aller à : navigation, rechercher

Exécuter un appel système en assembleur

Appel Système

Ce qu'on appelle un appel système c'est par exemple open(..), write(..), exit() en C

L'intégralité des appels systèmes disponibles et leurs numéros associés sont disponibles dans le fichier :

/usr/include/asm/unistd_32.h 
/usr/include/asm/unistd_64.h

Les appels systèmes sont appelés en ASM par l'interruption int 0x80

Passer des arguments à un appel système

  • EAX : Contient le numéro de l'appel système
  • EBX : Première Argument
  • ECX : Deuxième Argument
  • EDX : Troisième Argument
  • ESI : Quatrième Argument
  • EDI : Cinquième Argument

Exemple

Ici nous allons appeler la fonction exit(0)

Le prototype C de la fonction exit est :

void _exit(int status);

Tout d'abord on donne le code n°1 (exit) au registre EAX :

movl $1,%eax // movl : permet de déplacer 32 bits (valeur d'un registre) et $1 permet d'affecter la valeur plutôt que l'adresse mémoire  

Puis on remplis le statut de la fonction argument n°1 au registre EBX

movl $0,%ebx

Enfin l'interruption système

int $0x80

Programme final

.text

.globl _start

_start:

 movl $1,%eax
 movl $0,%ebx
 int $0x80


Pour compiler le fichier et le linker

as -o Exittest.o Exittest.s // puis
ld -o Exittest Exittest.o

On peut observer les appels systèmes via la commandes strace :

strace ./Exittest
execve("./justExit", ["./justExit"], [/* 36 vars */]) = 0
write(0, NULL, 0 <unfinished ... exit status 0>

Exemple

Afficher un shell

 ;affichage-shell.asm
segment .data  ;déclaration du segment des variables initialisées et globales
cheminshell db "/bin/sh0aaaabbbbb"  ;db déclare une chaine de caractères
segment .text  ;declaration du segment de code
global _start  ;point d'entrée pour le format ELF
_start:  ;here we go

mov eax,70  ;on met eax à 70 pour préparer l'appel à setreuid mov ebx,0  ;real uid 0 => root mov ecx,0  ;effective uid 0 => root int 0x80  ;Syscall 70
mov eax,0  ;on met 0 dans eax mov ebx,cheminshell  ;on met l'adresse de cheminshell dans ebx mov [ebx+7],al  ;on met le 0 (de eax) 7 caractères après le début de la chaîne  ;en fait, on réécrit le 0 de la chaine avec un nul byte  ;al occupe 1 byte mov [ebx+8],ebx  ;on met l'addresse de la chaine 8 caractères après son début  ;En fait, on réécrit aaaa par l'adresse de cheminshell mov [ebx+12],eax  ;12 caractères après le début, on met les 4 bytes de eax  ;en fait, on réécrit bbbb par 0x00000000 mov eax,11  ;on met eax à 11 pour préparer l'appel à execve lea ecx,[ebx+8]  ;on charge l'adresse de (anciennement) aaaa dans ecx lea edx,[ebx+12]  ;on charge l'adresse de (anciennement) bbbb dans edx int 0x80  ;Syscall 11

Pour compiler:

  nasm affichage-shell.asm -o affichage-shell.o -f elf && ld -s affichage-shell.o -o affichage-shell && ./affichage-shell

sh-3.1$