Afficher une input

Auteur: Brouettelover 2024-01-03 14:18:29
Categories: > Tags:

Description

Dans cet article, je vais détaillé comment j’ai écris un code ASM x64 afin d’afficher une input d’un utilisateur précédé d’un texte.

Code source final

section .data
    text db 'texte :',0

section .bss
    buffer resb 10 ; Réserve un espace de 10 octets pour stocker l'entrée de l'utilisateur

section .text
    global _start

_start:
    ; Enregistrer dans une variable
    mov rax, 0          ; syscall pour lire l'entrée de la sortie standard
    mov rdi, 0          ; file descriptor 0 is stdin
    mov rdx, 10         ; défini la taille maximale de l'entrée
    mov rsi, buffer     ; pointeur vers la zone de mémoire tampon
    syscall

    ; Afficher "texte :"
    mov rax, 1          ; syscall number for sys_write
    mov rdi, 1          ; file descriptor 1 is stdout
    mov rsi, text       ; pointeur vers la chaîne de texte
    mov rdx, 7          ; longueur de la chaîne
    syscall

    ; Afficher la valeur saisie
    mov rax, 1          ; syscall number for sys_write
    mov rdi, 1          ; file descriptor 1 is stdout
    mov rsi, buffer     ; pointeur vers la zone de mémoire tampon
    mov rdx, 10         ; longueur de la chaîne
    syscall

    ; Sortir du programme
    mov rax, 60         ; syscall number for sys_exit
    xor rdi, rdi        ; code de sortie 0
    syscall

1 - Enregistrer l’input dans une variable

section .bss
    buffer resb 10 ; Réserve un espace de 10 octets pour stocker l'entrée de l'utilisateur

Pour pouvoir géré par la suite l’input, il faut allouer un espace mémoire. 10 octets non rempli sont donc réservé à la variable buffer.

; Enregistrer dans une variable
mov rax, 0          ; syscall pour sys_read
mov rdi, 0          ; file descriptor 0 is stdin
mov rdx, 10         ; défini la taille maximale de l'entrée
mov rsi, buffer     ; pointeur vers la zone de mémoire tampon
syscall

Le premier mov décrit comment le systême doit intéragir, dans ce cas ci sys_read.

Ce sys_read prend 3 paramètres au total.

Ce sys_read prend l’un de ses paramètres un “descripteur” stocké dans rdi qui correspond au descripteur stdin qui est l’équivalent de “lire l’entrée”.

Il prend aussi un pointeur vers la zone de mémoire où l’input doit être stocké dans notre cas l’instruction mov rsi,buffer spécifie l’adresse mémoire déjà définie où stocker l’input.

En dernier paramètre il prend aussi la taille maximal d’octets qu’il devra lire, ce qui se fait par l’opération mov rdx, 10 qui défini la taille maximal de l’entrée

2 - afficher le texte

Comme dans le hello world précédent.
## 3 - afficher ma variable avec l’input

; Afficher la valeur saisie
mov rax, 1          ; syscall number for sys_write
mov rdi, 1          ; file descriptor 1 is stdout
mov rsi, buffer     ; pointeur vers la zone de mémoire tampon
mov rdx, 10         ; longueur de la chaîne
syscall

Ma variable buffer possède a présent la valeur d’input qui a été placé via le 1 er point. Donc pour l’afficher il suffit d’effectuer les même opérations que pour afficher n’importe quelle texte.

4 - sortie du programme

remettre à 0 le code de sortie et mettre à jour rax pour le passer en mode sys_exit comme dans les programmes précédent.

Code source - broken

Afin d’arriver au code source fonctionnel du dessus, j’ai commencé à écrire ma version sans aide pour voir si j’avais bien compris les concepts.

Voici donc une version cassé :

section .data
    input db "", 0         ;
    texte db 'texte :',0     ;

section .text
    global _start

_start:
    ; enregistrer dans une variable
    mov rax, 0 ; syscall pour afficher l'entrée
    mov rdi, 0 ; syscall pour lire l'entrée de la sortie standar
    mov rdx, 10 ; défini la taille maximal de l'entrée
    mov rsi, input ; écrit dans ma variable input
    syscall

    ; afficher "texte :"
    mov rax, 1            ; syscall number for sys_write
    mov rdi, 1            ; file descriptor 1 is stdout
    mov rsi, texte        ; pointer to the string
    mov rdx, 7          ; length of the string
    syscall

    ; afficher la valeur 
    mov rax, 1            ; syscall number for sys_write
    mov rdi, 1            ; file descriptor 1 is stdout
    mov rsi, input        ; pointer to the string
    mov rdx, 10           ; length of the string
    syscall
    
    ; sortir du programme
    mov rax, 60           ; syscall number for sys_exit
    xor rdi, rdi          ; exit code 0
    syscall

J’ai mis pas mal de temps à comprendre ce qui n’allait pas puis j’ai réalisé que ma variable “input” qui remplace “buffer” du code précédent est définie comme ayant seulement un espace suivi d’un 0.

Ce qui lui donne une taille de deux, lorsque j’essaie d’exécuter ce code.

Le code va essayé d’écrire sur une adresse mémoire qui n’a pas l’espace suffisant il va donc overflow et écrire sur la variable définie après qui se trouve être mon texte.

Voici en image ce que cela donne :