---
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.

### Un peu d'histoire

 * 1971: *Intel* commercialise le 4004 cadencé à 740 Khz et avec 640 bits de
   mémoire
 * 1972: *Intel* commercialise le 8008, registres de 8bits et 800Khz de
   fréquence
 * 1978: *Intel* commercialise le 8086 avec des registres de 16 bits et cadancé
   jusqu'à 10 Mhz.
 * 1985: *Intel* commercialise le 386 aved des registres de 32 bits et 4Go de
   mémoire adressable. Ce processeur introduit la mémoire virtuelle.
 * 1997: *Intel* commercialise le Pentium

### Un peu de vocabulaire

Voici un code en C :

```c
t[i]++
```

Et son équivalent en assembleur :

```asm
addl1 $1, t(%eax,4)
```

 * `addl` : mnémonique, ici *add long*
 * `$1` est `t(%eax,4)` sont des opérandes
 * `$1` est une immédiat
 * `%eax` est un resgistre
 * `t` est une référence, il pointe vers un endroit de la mémoire
 * `4` est un multiplicateur

On peu en déduire que `t(%eax,4)` est une **adresse mémoire**.

[l_vonneumann]:https://fr.wikipedia.org/wiki/Architecture_de_von_Neumann
