Permalink
Browse files

French: corrections

  • Loading branch information...
mremy committed Oct 3, 2018
1 parent 4db3c14 commit 2343d872c0d6aec9b4a1b2c9d35f11a8583d133f
@@ -1,5 +1,5 @@
\part*{Epilogue}
\addcontentsline{toc}{part}{Epilogue}
\part*{Épilogue}
\addcontentsline{toc}{part}{Épilogue}

\mysection{Des questions ?}

@@ -20,7 +20,7 @@
\href{http://go.yurichev.com/17089}{GitHub}.

N'hésitez surtout pas à m'envoyer la moindre erreur que vous pourriez trouver, aussi
petite qu'elle soit, même si vous n'êtes pas certain que ce soit une erreur.
petite soit-elle, même si vous n'êtes pas certain que ce soit une erreur.
J'écris pour les débutants après tout, il est donc crucial pour mon travail d'avoir
les retours de débutants.

@@ -1,6 +1,6 @@
\chapter{Communautés}

Il existe deux excellents subreddits liés à la \ac{RE} (rétro-ingénierie) sur reddit.com :
Il existe deux excellents subreddits liés à la \ac{RE} (rétro-ingénierie) sur reddit.com :\\
\href{http://go.yurichev.com/17027}{reddit.com/r/ReverseEngineering/} et
\href{http://go.yurichev.com/17028}{reddit.com/r/remath}
(en lien avec la liaison de la \ac{RE} et des mathématiques).
@@ -9,6 +9,6 @@ \chapter{Communautés}

\par \href{http://go.yurichev.com/17029}{reverseengineering.stackexchange.com}.

Sur IRC, il y a un channel dédié au \#\#\'reverse\' sur
Sur IRC, il y a un channel \#\#re sur
FreeNode\footnote{\href{http://go.yurichev.com/17030}{freenode.net}}.

@@ -22,7 +22,7 @@
pas sûr à 100\% de ceci}, le 8086 peut supporter plusieurs fenêtres de 64KB simultanément,
situées dans l'espace d'adresse de 1MB.

C'est une sorte de virualisation de niveau jouet.
C'est une sorte de virtualisation de niveau jouet.
\myindex{x86!\Registers!CS}
\myindex{x86!\Registers!DS}
\myindex{x86!\Registers!ES}
@@ -53,7 +53,7 @@
Le programme peut contenir des adresses codées en dur comme 0x1234, mais l'\ac{OS}
peut avoir besoin de le charger à une adresse arbitraire, donc il recalcule les valeurs
du registre de segment de façon à ce que le programme n'ait pas à se soucier de
l'endroit il est placé dans la RAM.
l'endroit il est placé dans la RAM.

Donc, tout pointeur dans le vieil environnement MS-DOS consistait en fait en un segment
d'adresse et une adresse dans ce segment, i.e., deux valeurs 16-bit. 20-bit étaient
@@ -16,11 +16,11 @@
\end{lstlisting}

\myindex{x86!\Instructions!FXCH}
La première instruction \INS{FXCH} interverti les valeurs de \TT{ST(0)} et \TT{ST(1)}. La seconde
La première instruction \INS{FXCH} intervertit les valeurs de \TT{ST(0)} et \TT{ST(1)}. La seconde
effectue la même opération. Combinées, elles ne produisent donc aucun effet.
Cet extrait provient d'un programme qui utilise la librairie MFC42.dll, il a donc du être compilé
Cet extrait provient d'un programme qui utilise la bibliothèque MFC42.dll, il a donc être compilé
avec MSVC 6.0 ou 5.0 ou peut-être même MSVC 4.2 qui date des années 90.

Cette paire d'instruction ne produit aucun effet, ce qui expliquerait qu'elle n'ait pas été détectée
Cette paire d'instructions ne produit aucun effet, ce qui expliquerait qu'elle n'ait pas été détectée
lors des tests du compilateur MSVC. Ou bien j'ai loupé quelque chose ...

@@ -30,5 +30,5 @@
\end{figure}

Ces nombres dépendent beaucoup du style de programmation et peuvent s'avérer très différents pour
d'autres produits logiciels.
d'autres logiciels.

@@ -5,20 +5,20 @@
\myindex{x86!\Instructions!ROL}
\myindex{x86!\Instructions!ROR}

Les fonctions intrinsèques sont spécifiques à chaque compilateur. Ce ne sont pas des fonctions que
vous pouvez retrouver dans une librairie.
Le compilateur génère une séquence spécifique de code machine lorsqu'il rencontre la fonction
intrinsèque. Le plus souvent, il s'agit d'une pseudo fonction qui correspond à une instruction d'une
\ac{CPU} particulière. \\
Les fonctions intrinsèques sont spécifiques à chaque compilateur. Ce ne sont pas des fonctions que
vous pouvez retrouver dans une bibliothèque.
Le compilateur génère une séquence spécifique de code machine lorsqu'il rencontre la fonction
intrinsèque. Le plus souvent, il s'agit d'une pseudo fonction qui correspond à une instruction d'un
\ac{CPU} particulier.\\
\\
Par exemple, il n'existe pas d'opérateur de décalage cyclique dans les langages \CCpp. La plupart
Par exemple, il n'existe pas d'opérateur de décalage cyclique dans les langages \CCpp. La plupart
des \ac{CPU}s supportent cependant des instructions de ce type.
Pour faciliter la vie des programmeurs, le compilateur MSVC propose de telles pseudo fonctions
\IT{\_rotl()} and \IT{\_rotr()}\FNMSDNROTxURL{}
qui sont directement traduites par le compilateur vers les instructions x86 ROL/ROR. \\
\\
Les fonctions intrinsèques qui permettent de générer des instructions SSE sont un autre exemple.
Les fonctions intrinsèques qui permettent de générer des instructions SSE en sont un autre exemple.

La liste complète des fonctions intrinsèques exposées par le compilateur MSVC figurent dans le
La liste complète des fonctions intrinsèques proposées par le compilateur MSVC figurent dans le
\href{http://go.yurichev.com/17254}{MSDN}.

@@ -4,90 +4,90 @@

Bien qu'elle n'ai pas réussi à percer, l'architecture Intel Itanium (\ac{IA64}) est très intéressante.

ou les CPUs \ac{OOE} réarrangent les instructions afin de les exécuter en parallèle, l'architecture
les CPUs \ac{OOE} réarrangent les instructions afin de les exécuter en parallèle, l'architecture
\ac{EPIC} a constitué une tentative pour déléguer cette décision au compilateur.

Les compilateurs en question étaient évidemment particulièrement complexes.

Voici un exemple de code pour l'architecture \ac{IA64} qui implémente un algorithme de
Voici un exemple de code pour l'architecture \ac{IA64} qui implémente un algorithme de
chiffrage simple du noyau Linux:

\lstinputlisting[caption=Linux kernel 3.2.0.4,style=customc]{other/itanium/tea_from_linux.c}

Et voici maintenant le résultat de la compilation:

\lstinputlisting[caption=Linux Kernel 3.2.0.4 for Itanium 2 (McKinley)]{other/itanium/ia64_linux_3.2.0.4_mckinley.lst}
\lstinputlisting[caption=Linux Kernel 3.2.0.4 pour Itanium 2 (McKinley)]{other/itanium/ia64_linux_3.2.0.4_mckinley.lst}

Nous constatons tout d'abord que toutes les instructions \ac{IA64} sont regroupées par 3.

Chaque groupe représente 16 octets (128 bits) et se décompose en une catégorie de code sur 5 bits
Chaque groupe représente 16 octets (128 bits) et se décompose en une catégorie de code sur 5 bits
puis 3 instructions de 41 bits chacune.

Dans \IDA les groupes apparaissent sous la forme 6+6+4 octets~---le motif est facilement
Dans \IDA les groupes apparaissent sous la forme 6+6+4 octets~---le motif est facilement
reconnaissable.

En règle générale les trois instructions d'un groupe s'exécutent en parallèle, sauf si l'une d'elles
En règle générale les trois instructions d'un groupe s'exécutent en parallèle, sauf si l'une d'elles
est associée à un \q{stop bit}.

Il est probable que les ingénieurs d'Intel et de HP ont collecté des statistiques qui leur ont permis
d'identifier les motifs les plus fréquents. Ils auraient alors décidé d'introduire une notion de
type de groupe (\ac{AKA} \q{templates}). Le type du groupe définit la catégorie des instructions
Il est probable que les ingénieurs d'Intel et de HP ont collecté des statistiques qui leur ont permis
d'identifier les motifs les plus fréquents. Ils auraient alors décidé d'introduire une notion de
type de groupe (\ac{AKA} \q{templates}). Le type du groupe définit la catégorie des instructions
qu'il contient. Ces catégories sont au nombre de 12.

Par exemple, un groupe de type 0 représente \TT{MII}. Ceci signifie que la première instruction est
une lecture ou écriture en mémoire (M), la seconde et la troisième sont des manipulations d'entiers
Par exemple, un groupe de type 0 représente \TT{MII}. Ceci signifie que la première instruction est
une lecture ou écriture en mémoire (M), la seconde et la troisième sont des manipulations d'entiers
(I).

Un autre exemple est le groupe de type 0x1d: \TT{MFB}. La première instruction est la aussi de type
mémoire (M), la seconde manipule un nombre flottant (F instruction \ac{FPU}), et le dernier est un
Un autre exemple est le groupe de type 0x1d: \TT{MFB}. La première instruction est la aussi de type
mémoire (M), la seconde manipule un nombre flottant (F instruction \ac{FPU}), et la dernière est un
branchement (B).

Lorsque le compilateur ne parvient pas à sélectionner un instruction à inclure dans le groupe en
cours de construction, il utilise une instruction de type \ac{NOP}. Il existe donc des instructions
\TT{nop.i} pour remplacer ce qui devrait être une manipulation d'entier. De même un \TT{nop.m} est
Lorsque le compilateur ne parvient pas à sélectionner une instruction à inclure dans le groupe en
cours de construction, il utilise une instruction de type \ac{NOP}. Il existe donc des instructions
\TT{nop.i} pour remplacer ce qui devrait être une manipulation d'entier. De même un \TT{nop.m} est
utilisé pour combler un trou là où une instruction de type mémoire devrait se trouver.

Lorsque le programme est directement dédigé en assembleur, les instructions \ac{NOP}s sont ajoutées
Lorsque le programme est directement rédigé en assembleur, les instructions \ac{NOP}s sont ajoutées
de manière automatique.

Et ce n'est pas tout. Les groupes font eux-mêmes l'objet de regroupements.

Chaque instruction peut être marquée avec un \q{stop bit}. Le processeur exécute en parallèle, toutes
les instructions jusqu'à ce qu'il rencontre un \q{stop bit}.
Chaque instruction peut être marquée avec un \q{stop bit}. Le processeur exécute en parallèle toutes
les instructions, jusqu'à ce qu'il rencontre un \q{stop bit}.

En pratique, les processeurs Itanium 2 peuvent exécuter jusqu'à deux groupes simultanément, soit un
En pratique, les processeurs Itanium 2 peuvent exécuter jusqu'à deux groupes simultanément, soit un
total de 6 instructions en parallèle.

Il faut évidemment que les instructions exécutées en parallèle, n'aient pas d'effet de bord entre
elles. Dans le cas contraire, le résultat n'est pas défini.
Le compilateur doit respecter cette contrainte ainsi que le nombre maximum de groupes simultanés du
processeur cible en placant les \q{stop bit} au bon endroit.
Il faut évidemment que les instructions exécutées en parallèle, n'aient pas d'effet de bord entre
elles. Dans le cas contraire, le résultat n'est pas défini.
Le compilateur doit respecter cette contrainte ainsi que le nombre maximum de groupes simultanés du
processeur cible en plaçant les \q{stop bit} au bon endroit.

En langage assembleur, les bits d'arrêt sont identifiés par deux point-virgule situé après
En langage d'assemblage, les bits d'arrêt sont identifiés par deux point-virgule situés après
l'instruction.

Ainsi dans notre exemple les instructions [90-ac] peuvent être exécutées simultanément. Le prochain
Ainsi dans notre exemple les instructions [90-ac] peuvent être exécutées simultanément. Le prochain
groupe est [b0-cc].

Nous observons également un bit d'arrêt en 10c. L'instruction suivante comporte elle aussi un bit
Nous observons également un bit d'arrêt en 10c. L'instruction suivante comporte elle aussi un bit
d'arrêt.

Ces deux instructions doivent donc être exécutées isolément des autres, (comme dans une architecture
Ces deux instructions doivent donc être exécutées isolément des autres, (comme dans une architecture
\ac{CISC}).

En effet, l'instruction en 110 utilise le résultat produit par l'instruction précédente (valeur du
En effet, l'instruction en 110 utilise le résultat produit par l'instruction précédente (valeur du
registre r26). Les deux instructions ne peuvent s'exécuter simultanément.

Il semble que le compilateur n'ai pas trouvé de meilleure manière de paralléliser les instructions,
ou en d'autres termes de plus charger la \ac{CPU}. Les bits d'arrêt sont donc en trop grand nombre.
ou en d'autres termes, de plus charger la \ac{CPU}. Les bits d'arrêt sont donc en trop grand nombre.

La rédaction manuelle de code en assembleur est une tâche pénible. Le programmeur doit effectuer
La rédaction manuelle de code en assembleur est une tâche pénible. Le programmeur doit effectuer
lui-même les regroupements d'instructions.

Bien sûr, il peut ajouter un bit d'arrêt à chaque instruction mais cela dégrade les performances
Bien sûr, il peut ajouter un bit d'arrêt à chaque instruction mais cela dégrade les performances
telles qu'elles ont été pensée pour l'Itanium.

Les codes source du noyau Linux contiennent un exemple intéressant d'un code assembleur produit
Les codes source du noyau Linux contiennent un exemple intéressant d'un code assembleur produit
manuellement pour \ac{IA64}:

\url{http://go.yurichev.com/17322}.
@@ -96,7 +96,7 @@
[Mike Burrell, \IT{Writing Efficient Itanium 2 Assembly Code} (2010)]\footnote{\AlsoAvailableAs \url{http://yurichev.com/mirrors/RE/itanium.pdf}},
[papasutra of haquebright, \IT{WRITING SHELLCODE FOR IA-64} (2001)]\footnote{\AlsoAvailableAs \url{http://phrack.org/issues/57/5.html}}.

Deux autres caractéristiques très intéressantes d'Itanium feature sont la \IT{speculative execution}
Deux autres caractéristiques très intéressantes d'Itanium sont l'\IT{exécution spéculative}
et le bit NaT (\q{not a thing}) qui ressemble un peu aux nombres \gls{NaN} : \\
\href{http://go.yurichev.com/17323}{MSDN}.

@@ -75,7 +75,7 @@ \subsubsection{ARM: 3 arguments}

\myindex{ARM!\Registers!Link Register}
\myindex{ARM!\Instructions!B}
\myindex{Épilogue de la fonction}
\myindex{Epilogue de fonction}
C'est la version optimisée (\Othree) pour le mode ARM et cette fois nous voyons
\INS{B} comme dernière instruction au lieu du \INS{BL} habituel.
Une autre différence entre cette version optimisée et la précédente (compilée
@@ -34,7 +34,7 @@ \subsubsection{ARM: 8 arguments}

Ce code peut être divisé en plusieurs parties:

\myindex{Prologue de la fonction}
\myindex{Prologue de fonction}
\begin{itemize}
\item Prologue de la fonction:

@@ -84,7 +84,7 @@ \subsubsection{ARM: 8 arguments}

\item appel de \printf

\myindex{Épilogue de fonction}
\myindex{Epilogue de fonction}
\item Épilogue de fonction:

L'instruction \INS{ADD SP, SP, \#0x14} restaure le pointeur \ac{SP} à sa valeur

0 comments on commit 2343d87

Please sign in to comment.