Add ASM course

This commit is contained in:
Yorick Barbanneau 2023-01-23 01:43:10 +01:00
parent 89c4a93002
commit f82330af00

View file

@ -0,0 +1,90 @@
---
title: "Sécurité logicielle : L'assembleur"
date: 2023-01-20
tags: ["programmation", "intel", "processeur"]
categories: ["Sécurité logicielle", "Cours"]
---
Il existe plusieurs niveau de langages:
* langage de **haut niveau** : no-code, python, Java, ce sont des langages
souvent interprété ou le développeur ne gère pas le matériel (typiquement la
mémoire et contenant des objets abstrais ( lambda, liste, objet).
* langages de **bas niveau** : comme le C, le développeur manipule la mémoire
(pointeurs, allocation et libération de la mémoire)
* **assembleur** : on se rapproche un peu plus du matériel, notamment du
processeur en manipulant instruction et registres, mais le tout reste lisible
par un humain
* **code machine** : ici nous avons que du binaire, *"à même le proce'"*
L'*assembleur* et le *langage machine* sont deux manières différentes de
**représenter la même chose**.
## La compilation
Que se passe-t-il lors du passage d'un programme en C en code machine?
1. **le pré-processing** : les fichiers inclus via les `#include` sont insérés
dans le code source.
2. **compilation en assembleur** : les fichiers C obtenus précédemment sont
traduits en *assembleur*
3. **compilation en langage machine** : les fichiers obtenus précédemment sont
traduits en langage machine
4. *édition des liens* : le code obtenu est alors lié avec les bibliothèques
externes, il deviens **un vrai programme**.
Sous Linux, un programme est chargé automatiquement avec `ld-linux`. Lors du
chargement d'un programme **setuid** (qui peut obtenir les droits root),
`ld-linux` ne prend pas en compte les variable d'environnement `LD_LIBRARY_PATH`
et `LD_PRELOAD` afin d'éviter tout risque pour la sécurité.
### Problèmes potentiels sur ces étapes
Pour l'étape 1, il n'y a en général pas de problèmes, cependant **certaines
macros** peuvent poser problèmes.
Pour l'étape 2, le problème pourrait venir du *"mensonge"* fait par le
compilateur lors de la traduction du C vers l'assembleur, ou encore l'interface
chaise clavier lors de l'écriture du programme.
Pour l'étape 3, pas de problème, c'est ici une simple traduction littérale
Pour l'étape 4, il peut arriver quelques trucs horrible, typiquement des
**conflits de symboles** lorsque le programme et une librairie ont un nom de
variable (globale) en commun.
Lors de l'exécution, il est possible d'utiliser `LD_LIBRARY_PATH` et
`LD_PRELOAD` pour détourner des bibliothèques utilisées.
## L'assembleur
C'est un langage élémentaire, très verbeux et fastidieux. Mais parfois c'est le
seul moyen de voir **ce qui se passe réellement**. Prenons cet exemple en C :
```c
unsigned x = 0;
while (x < -1) {
printf("ok\n");
}
```
Ici nous allons entrer dans une boucle infinie, la faute au *cast* de `x`
(`unsigned int` vers `int`).
### Qu'est-ce que l'assembleur?
C'est le cœur du calcul, entre la machine de Turing (mais en moins complexée) et
l'architecture de [Von Neumann][l_vonneumann].
C'est un langage non structuré avec des **instructions arithmétiques simples** :
* lecture / écritures dans la mémoire
* opération de saut
* test (if)
* pas d'appel de fonctions
* pas de scope
Les commentaires sont essentiels afin de marquer les points essentiels du code
(début de test, branchement) et le rendre pus intelligible.
[l_vonneumann]:https://fr.wikipedia.org/wiki/Architecture_de_von_Neumann