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