GNU/Linux >> Tutoriels Linux >  >> Linux

Explorez les fichiers binaires à l'aide de cet outil Linux complet

Dans 10 façons d'analyser des fichiers binaires sous Linux , j'ai expliqué comment utiliser le riche ensemble d'outils natifs de Linux pour analyser les binaires. Mais si vous souhaitez explorer davantage votre binaire, vous avez besoin d'un outil conçu sur mesure pour l'analyse binaire. Si vous débutez dans l'analyse binaire et que vous avez principalement travaillé avec des langages de script, 9 outils binutils GNU essentiels vous aidera à commencer à apprendre le processus de compilation et ce qui constitue un binaire.

Pourquoi ai-je besoin d'un autre outil ?

Plus de ressources Linux

  • Aide-mémoire des commandes Linux
  • Aide-mémoire des commandes Linux avancées
  • Cours en ligne gratuit :Présentation technique de RHEL
  • Aide-mémoire sur le réseau Linux
  • Aide-mémoire SELinux
  • Aide-mémoire sur les commandes courantes de Linux
  • Que sont les conteneurs Linux ?
  • Nos derniers articles Linux

Il est naturel de se demander pourquoi vous avez encore besoin d'un autre outil si les outils Linux natifs existants font des choses similaires. Eh bien, c'est pour les mêmes raisons que vous utilisez votre téléphone portable comme réveil, pour prendre des notes, comme appareil photo, pour écouter de la musique, pour surfer sur Internet et occasionnellement pour passer et recevoir des appels. Auparavant, des appareils et des outils distincts géraient ces fonctions, comme un appareil photo physique pour prendre des photos, un petit bloc-notes pour prendre des notes, un réveil de chevet pour se réveiller, etc. Avoir un appareil pour faire plusieurs choses (mais liées) est pratique pour l'utilisateur. De plus, la fonctionnalité qui tue est l'interopérabilité entre les fonctions séparées.

De même, même si de nombreux outils Linux ont un objectif spécifique, il est très utile d'avoir des fonctionnalités similaires (et meilleures) regroupées dans un seul outil. C'est pourquoi je pense que Radare2 devrait être votre outil de choix chaque fois que vous avez besoin de travailler avec des binaires.

Radare2 (également connu sous le nom de r2) est un "framework d'ingénierie inverse de type Unix et un ensemble d'outils de ligne de commande", selon son profil GitHub. Le "2" dans son nom est dû au fait que cette version a été entièrement réécrite pour la rendre plus modulaire.

Pourquoi Radare2 ?

Il existe des tonnes d'outils Linux (non natifs) qui sont utilisés pour l'analyse binaire, alors pourquoi devriez-vous choisir Radare2 ? Mes raisons sont simples.

Premièrement, c'est un projet open source avec une communauté active et saine. Si vous recherchez de nouvelles fonctionnalités astucieuses ou la disponibilité de correctifs de bogues, cela compte beaucoup.

Deuxièmement, Radare2 peut être utilisé sur la ligne de commande et dispose d'un environnement d'interface utilisateur graphique (GUI) riche appelé Cutter pour ceux qui sont plus à l'aise avec les interfaces graphiques. Étant un utilisateur Linux de longue date, je me nourris plus à l'aise sur le shell. Bien qu'il y ait une légère courbe d'apprentissage pour se familiariser avec les commandes de Radare2, je le comparerais à l'apprentissage de Vim. Vous apprenez d'abord les choses de base, et une fois que vous les maîtrisez, vous passez à des choses plus avancées. En un rien de temps, cela devient une seconde nature.

Troisièmement, Radare2 prend bien en charge les outils externes via des plugins. Par exemple, l'outil d'analyse binaire et d'inversion Ghidra récemment open source est populaire pour sa fonction de décompilation, qui est un élément essentiel du logiciel d'inversion. Vous pouvez installer et utiliser le décompilateur Ghidra directement depuis la console Radare2, ce qui est incroyable et vous offre le meilleur des deux mondes.

Commencer avec Radare2

Pour installer Radare2, clonez simplement le référentiel et exécutez le user.sh scénario. Vous devrez peut-être installer certains packages prérequis s'ils ne se trouvent pas déjà sur votre système. Une fois l'installation terminée, exécutez le r2 -v commande pour voir si Radare2 a été installé correctement :

$ git clone https://github.com/radareorg/radare2.git
$ cd radare2
$ sys/user.sh

# version

$ r2 -v
radare2 4.6.0-git 25266 @ linux-x86-64 git.4.4.0-930-g48047b317
commit :48047b3171e6ed0480a71a04c3693a0650d03543 build :2020-11-317__09 :03
$

Obtenir un exemple de test binaire

Maintenant que r2 est installé, vous avez besoin d'un exemple de fichier binaire pour l'essayer. Vous pouvez utiliser n'importe quel binaire système (ls , bash , etc.), mais pour garder les choses simples pour ce tutoriel, compilez le programme C suivant :

$ cat adder.c 
#include

int adder(int num) {
        return num + 1;
}

int main() {
        int res, num1 =100 ;
        res =adder(num1);
        printf("Le numéro est maintenant :%d\n", res);
        return 0;
}
$
$
$ gcc adder.c -o adder
$
$ file adder
Adder :ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamiquement lié, interpréteur /lib64/ld-linux-x86-64.so.2, pour GNU/Linux 3.2.0, BuildID [sha1]=9d4366f7160e1ffb46b14466e8e0d70f10de2240, non dépouillé
$
$ ./adder
Le nombre est maintenant :101
$

Charger le binaire

Pour analyser le binaire, vous devez le charger dans Radare2. Chargez-le en fournissant le fichier comme argument de ligne de commande au r2 commande. Vous êtes déposé dans une console Radare2 distincte de votre shell. Pour quitter la console, vous pouvez taper Quitter ou Quitter ou appuyez sur Ctrl +D :

$ r2 ./adder
 -- Apprenez le pancake comme si vous étiez un radar !
[0x004004b0]> quittez
$

Analyser le binaire

Avant de pouvoir explorer le binaire, vous devez demander à r2 de l'analyser pour vous. Vous pouvez le faire en exécutant le aaa commande dans la console r2 ;

$ r2 ./adder
 -- Désolé, radare2 a rencontré une erreur interne.
[0x004004b0]>
[0x004004b0]>
[0x004004b0]> aaa
[x] Analyse tous les drapeaux commençant par sym. et entrée0 (aa)
[x] Analyser les appels de fonction (aac)
[x] Analyser len octets d'instructions pour les références (aar)
[x] Vérifier les vtables
[ x] Analyse de correspondance de type pour toutes les fonctions (aaft)
[x] Propager les informations sans retour
[x] Utilisez -AA ou aaaa pour effectuer une analyse expérimentale supplémentaire.
[0x004004b0]>

Cela signifie que chaque fois que vous choisissez un binaire pour l'analyse, vous devez taper une commande supplémentaire pour aaa après avoir chargé le binaire. Vous pouvez contourner cela en appelant r2 avec -A suivi du nom binaire ; cela indique à r2 d'analyser automatiquement le binaire pour vous :

$ r2 -A ./adder
[x] Analyse tous les drapeaux commençant par sym. et entrée0 (aa)
[x] Analyser les appels de fonction (aac)
[x] Analyser len octets d'instructions pour les références (aar)
[x] Vérifier les vtables
[ x] Analyse de correspondance de type pour toutes les fonctions (aaft)
[x] Propager les informations sans retour
[x] Utilisez -AA ou aaaa pour effectuer une analyse expérimentale supplémentaire.
 -- Déjà à jour- date.
[0x004004b0]>

Obtenir des informations de base sur le binaire

Avant de commencer à analyser un binaire, vous avez besoin d'un point de départ. Dans de nombreux cas, cela peut être le format de fichier du binaire (ELF, PE, etc.), l'architecture pour laquelle le binaire a été construit (x86, AMD, ARM, etc.), et si le binaire est 32 bits ou 64 bits. . Le iI pratique de R2 commande peut fournir les informations requises :

[0x004004b0]> iI
arch     x86
baddr    0x400000
binsz    14724
bintype  elf
bits     64
canary   false
class    ELF64
compilateur GCC :(GNU) 8.3.1 20190507 (Red Hat 8.3.1-4)
crypto   false
endian   little
havecode true
intrp    /lib64/ld -linux-x86-64.so.2
laddr    0x0
lang     c
linenum  true
lsyms    true
architecture machine AMD x86-64
maxopsz  16
minopsz  1
nx       true
os       linux
pcalign  0
pic      false
relocs   true
relro    partial
rpath    NONE
sanitiz  false
static   false
stripped false
subsys   linux
va       true

[0x004004b0]>
[0x004004b0]>

Importations et exportations

Souvent, une fois que vous savez à quel type de fichier vous avez affaire, vous voulez savoir quel type de fonctions de bibliothèque standard le binaire utilise ou apprendre les fonctionnalités potentielles du programme. Dans l'exemple de programme C de ce tutoriel, la seule fonction de bibliothèque est printf pour imprimer un message. Vous pouvez le voir en exécutant le ii commande, qui affiche toutes les importations du binaire :

[0x004004b0]> ii
[Importations]
nth vaddr      bind   type     lib name
――――――――――――――――――――― ------------------
1 0x00000000 Notype faible _itm_deregistertmclonetable
2 0x004004A0 Global Func Printf
3 0x00000000 Global Func __libc_Start_main
4 0x00000000 Faible NOTYPE     __gmon_start__
5   0x00000000 FAIBLE   NOTYPE     _ITM_registerTMCloneTable

Le binaire peut également avoir ses propres symboles, fonctions ou données. Ces fonctions sont généralement affichées sous Exports . Le binaire de test a deux fonctions — main et adder — qui sont exportées. Le reste des fonctions est ajouté lors de la phase de compilation lors de la construction du binaire. Le chargeur en a besoin pour charger le binaire (ne vous en souciez pas trop pour l'instant) :

[0x004004b0]> 
[0x004004b0]> iE
[Exportations]

nième paddr       vaddr      lier   type   taille nom de bibliothèque
――――――― ―――――――――――――――――――――――――――――――――――――――――╀> 82 0x00000650 0x00400650 0x00400650 Global Func 5 __libc_csu_fini
85 ---------------------------------------------------------------------------------> 86 0x00000658 0x00400658 Global Func 0 _fini
89 0x00001020 0x0060101020 Global Nothype 0 __Data_Start
90 0x00000596 0x00400596 0x00400596 Global Func 15 ADDER
92 0x00000670 0x00400670 0x00400670 Global Obj 0 __dso_handle
93 0x00000668 0x00400668 0x00400668 Global Obj 4 _IO_STDIN_Utilisé
94 0x000005E0 0x004005E0 Global Func 101 __libc_csu_init
95 - ---------- 0x00601028 Global Nothype 0 _end
96 0x000004e0 0x004004E0 Global Func 5 _DL_Relocate_static_Pie
0x004004B0 Global Func 47 _start
98 ---------- - 0x00601024 GLOBAL NOTTYPE 0        __bss_start
99   0x00000 5A5 0x004005A5 Global Func 55 Princip
100 ------------------------ 0x00601028 Global Obj 0 __TMC_end__
102 0x00000468 0x00400468 Func global 0 _Init

[0x004004B0]>

Informations de hachage

Comment savoir si deux binaires sont similaires ? Vous ne pouvez pas exactement ouvrir un binaire et afficher le code source qu'il contient. Dans la plupart des cas, le hachage d'un binaire (md5sum, sha1, sha256) est utilisé pour l'identifier de manière unique. Vous pouvez trouver le hachage binaire en utilisant le it commande :

 [0x004004b0]> il 

md5 7e6732f2b11dec4a0c7612852cede670 SHA1 d5fa848c4b53021f6570dd9b18d115595a2290ae

SHA256 13dd5a492219dac1443a816ef5f91db8d149e8edbf26f24539c220861769e1c2 [0x004004b0]>

Fonctions

Le code est regroupé en fonctions ; pour lister les fonctions présentes dans un binaire, exécutez le afl commande. La liste suivante montre les fonctions principales et additionnelles. Généralement, les fonctions qui commencent par sym.imp sont importés de la bibliothèque standard (glibc dans ce cas) :

 [0x004004b0]> AFL 
0x004004B0 1 46 Entry0
0x004004F0 4 41 -> 34 SYM.DEREGISTER_TM_CLONES
0x00400520 4 57 -> 51 SYM.REGISTER_TM_CLONES
0x00400560 3 33 -> 32 SYM .__ DO_GLOBAL_DTORS_AUX
0x00400590 1 6 Entrée.Init0
0x00400650 1 5 SYM .__ libc_csu_fini
0x00400658 1 13 SYM._FINI
0x00400596 1 15 SYM.Ajouder
0x004005E0 4 101 LOC..Annobin_fl_Init.c
0x004004E0 1 5 LOC..Annobin_static_Reloc.c
0x004005A5 1 55 Main
0x004004A0 1 6 SYM.IMP.PRINTF
0x00400468 3 27 SYM. _init
[0x004004b0]>

Références croisées

En C, la fonction principale est l'endroit où un programme commence son exécution. Idéalement, d'autres fonctions sont appelées depuis main et, à la sortie d'un programme, la fonction main renvoie un état de sortie au système d'exploitation. Cela est évident dans le code source; cependant, qu'en est-il d'un binaire? Comment pouvez-vous savoir où la fonction d'addition est appelée ?

Vous pouvez utiliser le axt commande suivie du nom de la fonction pour voir où la fonction d'addition est appelée ; comme vous pouvez le voir ci-dessous, il est appelé depuis la fonction principale. C'est ce qu'on appelle les références croisées. Mais qu'appelle la fonction principale elle-même ? Le axt main la fonction ci-dessous indique qu'elle est appelée par entry0 (Je vais partir apprendre sur entry0 comme exercice pour le lecteur):

[0x004004b0]> axt sym.adder
main 0x4005b9 [CALL] call sym.adder
[0x004004b0]>
[0x004004b0]> axt main
entry0 0x4004d1 [DATA ] mov rdi, main
[0x004004b0]>

Rechercher des emplacements

Lorsque vous travaillez avec des fichiers texte, vous vous déplacez souvent dans un fichier en faisant référence à un numéro de ligne suivi d'un numéro de ligne ou de colonne; dans un binaire, vous utilisez des adresses. Ce sont des nombres hexadécimaux commençant par 0x suivi d'une adresse. Pour trouver où vous en êtes dans un binaire, exécutez les s commande. Pour vous déplacer vers un autre emplacement, utilisez les s commande suivie de l'adresse.

Les noms de fonction sont comme des étiquettes, qui sont représentées par des adresses en interne. Si le nom de la fonction est au format binaire (non dépouillé), vous pouvez utiliser les s commande suivie du nom de la fonction pour accéder à une adresse de fonction spécifique. De même, si vous voulez sauter au début du binaire, tapez s 0 :

[0x004004b0]> s
0x4004b0
[0x004004b0]>
[0x004004b0]> s principal
[0x004005a5]>
[0x004005a5]> s
0x4005a5
[0x004005a5]>
[0x004005a5]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[ 0x00400596]>
[0x00400596]> s 0
[0x00000000]>
[0x00000000]> s
0x0
[0x00000000]>

Vue hexadécimale

Souvent, le binaire brut n'a pas de sens. Il peut être utile de visualiser le binaire en mode hexadécimal avec sa représentation ASCII équivalente :

[0x004004b0]> s main
[0x004005a5]>
[0x004005a5]> px
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x004005a5  5548 89e5 4883 ec10 c745 fc64 0000 008b  UH..H....E.d....
0x004005b5  45fc 89c7 e8d8 ffff ff89 45f8 8b45 f889  E.........E..E. .
0x004005c5  c6bf 7806 4000 b800 0000 00e8 cbfe ffff  ..x.@...........
0x004005d5  b800 0000 00c9 c30f 1f40 00f3 0f1e fa41  ....... [email protected]
0x004005e5  5749 89d7 4156 4989 f641 5541 89fd 4154  WI..AVI..AUA..AT
0x004005f5  4c8d 2504 0820 0055 488d 2d04 5830 0%. .UH.-.. .S
0x00400605  4c29 e548 83ec 08e8 57fe ffff 48c1 fd03  L).H....W...H...
0x00400615  741f 31db 0f1f 8000 0000 004c 89fa 4c89 t.1........L..L.
0x00400625  f644 89ef 41ff 14dc 4883 c301 4839 dd75  .D..A...H...H9.u
0x00400635  ea48 83c4 085b 5d41 5c41 5d41 5e41 5fc3  .H...[]A\A]A^A_.
0x00400645  9066 2e0f 1f84 0000 0000 00f3 0f1e fac3  .f............. .
0x00400655  0000 00f3 0f1e fa48 83ec 0848 83c4 08c3  .......H...H....
0x00400665  0000 0001 0002 0000 0000 0000 0000 0000  ................
0x00400675  0000 004e 756d 6265 7220 6e6f 7720 6973  ...Le numéro est désormais
0x00400685  2020 3a20 2564 0a00 0000 0001 1b03 3b44   9 %d........0;D 0000 0007 0000 0000 feff ff88 0000 0020  ...............
[0x004005a5]>

Démontage

Si vous travaillez avec des binaires compilés, il n'y a pas de code source que vous pouvez afficher. Le compilateur traduit le code source en instructions en langage machine que le CPU peut comprendre et exécuter; le résultat est le binaire ou l'exécutable. Cependant, vous pouvez afficher les instructions d'assemblage (mnémoniques) pour donner un sens à ce que fait le programme. Par exemple, si vous voulez voir ce que fait la fonction main, vous pouvez rechercher l'adresse de la fonction main en utilisant s main puis exécutez le pdf commande pour afficher les instructions de démontage.

Pour comprendre les instructions d'assemblage, vous devez vous référer au manuel d'architecture (x86 dans ce cas), à son interface binaire d'application (son ABI ou ses conventions d'appel) et avoir une compréhension de base du fonctionnement de la pile :

[0x004004b0]> s principal
[0x004005a5]>
[0x004005a5]> s
0x4005a5
[0x004005a5]>
[0x004005a5]> pdf
           ; DATA XREF from entry0 @ 0x4004d1
┌ 55 :int main (int argc, char **argv, char **envp);
│          ; var int64_t var_8h @ rbp-0x8
│          ; VAR INT64_T VAR_4H @ RBP-0X4
│ 0x004005A5 55 Push RBP
0x004005A6 4889E5 MOV RBP, RSP <4883EC10 SUB RSP, 0x10
│ 0x004005AD C745FC640000. mov dword [var_4h], 0x64    ; 'ré'; 100
│ 0x004005B4 8B45FC MOV EAX, DWORD [VAR_4H]
0x004005B7 89C7 MOV EDI, EAX
│ 0x004005B9 E8D8FFFFFFFFFP Appelez-vous
│ 0x004005BE 8945F8 MOV DWORD [VAR_8H], EAX
│ 0x004005C1 8B45F8 MOV EAX, DWORD [VAR_8H]
│ 0x004005C4 89C6 MOV ESI, EAX
│ 0x004005C6 BF78064000 MOV EDI, str.number_now_is __:__ d; 0x400678 ; "Le numéro est maintenant :%d\n" ; const char *format
│           0x004005cb      b800000000     mov eax, 0
│           0x004005d0      e8cbfeffff     call sym.imp.printf           ; int Printf (Const Char * Format)
│ 0x004005D5 B800000000 MOV EAX, 0
│ 0x004005DA C9 Longez
└ 0x004005DB C3 RET
[0x004005A5]>

Voici le démontage pour la fonction additionneur :

[0x004005a5]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[0x00400596]>
[0x00400596]> pdf
           ; CALL XREF from main @ 0x4005b9
┌ 15 :sym.adder (int64_t arg1);
│          ; var int64_t var_4h @ rbp-0x4
│          ; ARG INT64_T arg1 @ rdi
0x00400596 55 Push RBP
0x00400597 4889E5 MOV RBP, RSP
│ 0x0040059A 897DFC MOV DWORD [var_4h], EDI; Arg1
│ 0x0040059D 8B45FC MOV EAX, DWORD [VAR_4H]
│ 0x004005A0 83C001 Ajouter EAX, 1
│ 0x004005A3 5D POP RBP
└ 0x004005A4 C3 RET
[0x00400596]>

Chaînes

Voir quelles chaînes sont présentes dans le binaire peut être un point de départ pour l'analyse binaire. Les chaînes sont codées en dur dans un binaire et fournissent souvent des conseils importants pour vous concentrer sur l'analyse de certains domaines. Exécutez le iz commande dans le binaire pour lister toutes les chaînes. Le binaire de test n'a qu'une seule chaîne codée en dur dans le binaire :

[0x004004b0]> iz
[Chaînes]
nth paddr      vaddr      len size section type  string
――――――――――――――――――― ------------------------------------------------------> 0 0x00000678 0x00400678 20 21 .RODAta ASCII Numéro maintenant est :%d\n

[0x004004b0]>

Chaînes de références croisées

Comme pour les fonctions, vous pouvez croiser les chaînes pour voir d'où elles sont imprimées et comprendre le code qui les entoure :

[0x004004b0]> ps @ 0x400678
Le numéro est maintenant : %d

[0x004004b0]>
[0x004004b0]> axt 0x400678
main 0x4005c6 [DATA ] mov edi, str.Number_now_is__:__d
[0x004004b0]>

Mode visuel

Lorsque votre code est compliqué avec plusieurs fonctions appelées, il est facile de se perdre. Il peut être utile d'avoir une vue graphique ou visuelle des fonctions appelées, des chemins empruntés en fonction de certaines conditions, etc. Vous pouvez explorer le mode visuel de r2 en utilisant le VV commande après être passé à une fonction qui vous intéresse. Par exemple, pour la fonction d'addition :

[0x004004b0]> s sym.adder
[0x00400596]>
[0x00400596]> VV

Débogueur

Jusqu'à présent, vous avez fait de l'analyse statique - vous regardez simplement les choses dans le binaire sans l'exécuter. Parfois, vous devez exécuter le binaire et analyser diverses informations en mémoire au moment de l'exécution. Le débogueur interne de r2 vous permet d'exécuter un binaire, de mettre des points d'arrêt, d'analyser les valeurs des variables ou de vider le contenu des registres.

Démarrez le débogueur avec le -d flag, et ajoutez le -A flag pour effectuer une analyse au fur et à mesure que les chargements binaires. Vous pouvez définir des points d'arrêt à divers endroits, comme des fonctions ou des adresses mémoire, en utilisant le db <function-name> commande. Pour afficher les points d'arrêt existants, utilisez le dbi commande. Une fois que vous avez placé vos points d'arrêt, lancez l'exécution du binaire en utilisant le dc commande. Vous pouvez afficher la pile en utilisant le dbt commande, qui affiche les appels de fonction. Enfin, vous pouvez vider le contenu des registres en utilisant le drr commande :

$ r2 -d -A ./adder
Le processus avec le PID 17453 a démarré...
=attach 17453 17453
bin.baddr 0x00400000
Utilisation de 0x400000
asm.bits 64
[x] Analyse tous les drapeaux commençant par sym. et entrée0 (aa)
[x] Analyser les appels de fonction (aac)
[x] Analyser len octets d'instructions pour les références (aar)
[x] Vérifier les vtables
[ x] Analyse de correspondance de type pour toutes les fonctions (aaft)
[x] Propager les informations de non-retour
[x] Utilisez -AA ou aaaa pour effectuer une analyse expérimentale supplémentaire.
 --git checkout hamster
[0x7f77b0a28030]>
[0x7f77b0a28030]> db main
[0x7f77b0a28030]>
[0x7f77b0a28030]> db sym.adder
[0x7f77b0a28030]>
[0x7f77b0a280 ]> dbi
0 0x004005a5 E:1 T:0
1 0x00400596 E:1 T:0
[0x7f77b0a28030]>
[0x7f77b0a28030]> afl | grep principal
0x004005a5    1 55           principal
[0x7f77b0a28030]>
[0x7f77b0a28030]> afl | grep sym.adder
0x00400596    1 15           sym.adder
[0x7f77b0a28030]>
[0x7f77b0a28030]> dc
point d'arrêt atteint :0x4005a5
[0x004005a5]>
[0x004005A5]> DBT
0 0x4005A5 SP:0x0 0 [Main] Main Sym.adder + 15
1 0x7f77B0687873 SP:0x7FFE35FF6858 0 [??] Section..gnu.build.Attributes-1345820597
2  0x7f77b0a36e0a     sp :0x7ffe35ff68e8      144  [??]  map.usr_lib64_ld_2.28.so.r_x+65034
[0x004005a5]> dc
point d'arrêt atteint :0x400596
> DBT
0 0x400596 SP:0x0 0 [SYM.ADER] Entrée RIP.Init0 + 6
1 0x4005be SP:0x7FFE35FF6838 0 [Main] Main + 25
2 0x7F77B0687873 SP:0x7FFE35FF6858 32 [ ??]  section..gnu.build.attributes-1345820597
3  0x7f77b0a36e0a     sp :0x7ffe35ff68e8      144  [??]  map.usr_lib64_ld_2.28.so.r_x+65034
[0x00400596]> [0x00400596]>
[0x00400596]> dr
rax =0x00000064
rb x =0x00000000
rcx =0x7f77b0a21738
rdx =0x7ffe35ff6948
r8 =0x7f77b0a22da0
r9 =0x7f77b0a22da0
r10 =0x0000000f
r10 =0020 r12/> =0x004004b0
r13 =0x7ffe35ff6930
r14 =0x00000000
r15 =0x00000000
rsi =0x7ffe35ff6938
rdi =0x00000064
rsp =0x7ffe35ff />838 =
rsp =0x7ffe35ff />838 0x7ffe35ff6850
rip =0x00400596
rflags =0x00000202
orax =0xffffffffffffffff
[0x00400596]>

Décompilateur

Être capable de comprendre l'assemblage est une condition préalable à l'analyse binaire. Le langage d'assemblage est toujours lié à l'architecture sur laquelle le binaire est construit et est censé fonctionner. Il n'y a jamais de correspondance 1:1 entre une ligne de code source et un code assembleur. Souvent, une seule ligne de code source C produit plusieurs lignes d'assemblage. Ainsi, lire le code assembleur ligne par ligne n'est pas optimal.

C'est là qu'interviennent les décompilateurs. Ils essaient de reconstruire le code source possible en se basant sur les instructions d'assemblage. Ce n'est JAMAIS exactement le même que le code source utilisé pour créer le binaire; c'est une représentation proche de la source basée sur l'assemblage. De plus, tenez compte du fait que les optimisations du compilateur qui génèrent un code assembleur différent pour accélérer les choses, réduire la taille d'un binaire, etc., rendront le travail du décompilateur plus difficile. De plus, les auteurs de logiciels malveillants obscurcissent souvent délibérément le code pour dissuader un analyste de logiciels malveillants.

Radare2 fournit des décompilateurs via des plugins. Vous pouvez installer n'importe quel décompilateur pris en charge par Radare2. Voir les plugins actuels avec le r2pm -l commande. Installez un exemple r2dec décompilateur avec l'r2pm install commande :

$ r2pm  -l
$
$ r2pm install r2dec
Clonage dans 'r2dec'...
distant :énumération d'objets :100, terminé.
distant :Comptage d'objets :100 % (100/100), terminé.
distant :Compression d'objets :100 % (97/97), terminé.
distant :Total 100 (delta 18), réutilisé 27 (delta 1), pack-reused 0
Objets reçus :100 % (100/100), 1,01 Mio | 1,31 Mio/s, terminé.
Résolution des deltas :100 % (18/18), terminé.
Installation terminée pour r2dec
gmake :entrée du répertoire '/root/.local/share/radare2 /r2pm/git/r2dec/p'
[CC] duktape/duktape.o
[CC] duktape/duk_console.o
[CC] core_pdd.o
[CC] core_pdd.so
gmake :quitter le répertoire '/root/.local/share/radare2/r2pm/git/r2dec/p'
$
$ r2pm  -l
r2dec
$

Vue du décompilateur

Pour décompiler un binaire, chargez le binaire dans r2 et analysez-le automatiquement. Déplacez-vous vers la fonction qui vous intéresse—l'additionneur dans cet exemple—en utilisant le s sym.adder commande, puis utilisez la commande pdda commande pour afficher l'assemblage et le code source décompilé côte à côte. Lire ce code source décompilé est souvent plus facile que de lire l'assemblage ligne par ligne :

$ r2 -A ./adder
[x] Analyse tous les drapeaux commençant par sym. et entrée0 (aa)
[x] Analyser les appels de fonction (aac)
[x] Analyser len octets d'instructions pour les références (aar)
[x] Vérifier les vtables
[ x] Analyse de correspondance de type pour toutes les fonctions (aaft)
[x] Propager les informations sans retour
[x] Utilisez -AA ou aaaa pour effectuer une analyse expérimentale supplémentaire.
 -- Que voulez-vous déboguer aujourd'hui ?
[0x004004b0]>
[0x004004b0]> s sym.adder
[0x00400596]>
[0x00400596]> s
0x400596
[ 0x00400596]>
[0x00400596]> pdda
   ; assemblage                               | /* Sortie de pseudo-code r2dec */
                                             | /* ./adder @ 0x400596 */
                                             | #include
                                             |
   ; (fcn) sym.adder ()                     | additionneur int32_t (int64_t arg1) {
                                             | int64_t var_4h;
                                             | rdi =arg1 ;
    0x00400596 push rbp                      |
    0x00400597 mov rbp, rsp                  |
    0x0040059a mov dword [rbp - 4], edi      | *((rbp - 4)) =edi;
    0x0040059d mov eax, dword [rbp - 4]      | eax =*((rbp - 4));
    0x004005a0 ajouter eax, 1                    | eax++;
    0x004005a3 pop rbp                       |
    0x004005a4 ret                           | retourner eax ;
                                             | }
[0x00400596]>

Configurer les paramètres

Au fur et à mesure que vous vous familiariserez avec Radare2, vous voudrez modifier sa configuration pour l'adapter à votre façon de travailler. Vous pouvez afficher les configurations par défaut de r2 en utilisant le e commande. Pour définir une configuration spécifique, ajoutez config = value après le e commande :

[0x004005a5]> e | wc -l
593
[0x004005a5]> e | syntaxe grep
asm.syntax =intel
[0x004005a5]>
[0x004005a5]> e asm.syntax =att
[0x004005a5]>
[0x004005a5]> e | syntaxe grep
asm.syntax =att
[0x004005a5]>

Pour rendre les modifications de configuration permanentes, placez-les dans un fichier de démarrage nommé .radare2rc que r2 lit au démarrage. Ce fichier se trouve généralement dans votre répertoire personnel; sinon, vous pouvez en créer un. Voici quelques exemples d'options de configuration :

$ cat ~/.radare2rc 
e asm.syntax =att
e scr.utf8 =true
eco solarisé
e cmd.stack =true
e pile.taille =256

Explore plus

Vous avez vu suffisamment de fonctionnalités Radare2 pour vous repérer dans l'outil. Étant donné que Radare2 suit la philosophie Unix, même si vous pouvez faire diverses choses à partir de sa console, il utilise un ensemble distinct de fichiers binaires en dessous pour effectuer ses tâches.

Explorez les binaires autonomes répertoriés ci-dessous pour voir comment ils fonctionnent. Par exemple, les informations binaires vues dans la console avec le iI La commande peut également être trouvée en utilisant le rabin2 <binary> commande :

$ cd bin/
$
$ ls
prefix  r2agent    r2pm  rabin2   radiff2  ragg2    rarun2   rasm2
r2      r2-indent  r2r   radare2  rafind2  rahash2  rasign2  rax2
$

Que pensez-vous de Radare2 ? Partagez vos commentaires dans les commentaires.


Linux
  1. Partage de fichiers open source avec cet outil Linux

  2. Inspectez les capacités des binaires ELF avec cet outil open source

  3. Effectuez des analyses de mémoire Linux avec cet outil open source

  4. Comment comparer trois fichiers sous Linux à l'aide de l'outil diff3

  5. Utiliser l'outil de capture d'écran GNOME sous Linux comme un pro

Afficher les informations réseau sous Linux à l'aide de What IP Tool

Comment comparer des fichiers sous Linux à l'aide de l'outil Meld (Diff/Merge)

Utilisation du transfert de port SSH comme outil de sécurité sous Linux

Utilisation de la commande Watch sous Linux

Comment cloner ou sauvegarder un disque Linux à l'aide de Clonezilla Imaging Tool

Comment synchroniser l'heure avec NTP sous Linux à l'aide de l'outil Chrony