Rizin : un framework de rétro-ingénierie qui va bien ? Et un peu de Cutter (GUI)

Rizin : un framework de rétro-ingénierie qui va bien ? Et un peu de Cutter (GUI)

- 15 mins

Fin 2020, préparant un atelier de découverte de la rétro-ingénierie informatique1, je voyais passer un début de fork de Radare2. Pour préparer cet atelier au j’avais écrit à julien Voisin, après sa conférence de 2015 au MiNET « Rétro-ingénierie pour tous ! Le pouvoir ne se donne pas, il se prend. ».

J'ai commencé mes notes en octobre 2022, ce billet pour son brouillon en novembre 2022. Je pensais le publier en décembre 2022. Les choses de la vie m'ont emmenées ailleurs et autrement. Nous somme en vail 2023


En 2021, à la suite de ma participation axée sur la rétro-ingénierie comme technique d’investigation2 au sein des groupes de travail avec Exposing The Invisible, ma collègue Clio Flego3 réalise un podcast intitulé “Reverse-engineering: aesthetic and speculative representation” (Primé au Pixelache !), avec Oliver KELLER (Applied Physics & Engineering at CERN) et David BENQUÉ (Designer/Researcher, Institute of the diagram studies, Cryptpad). Clio et moi avions très succinctement essayé de mettre cela en discussion lors du FOSDEM 2021, sans grande réussite. J’étais toujours les mains dans Radare2 (et un peu dans gdb + peda, une autre histoire ça). Je ne portai un œil que lointain sur son fork.

Cette semaine j’ai de nouveau échangé avec julien Voisin. Il me pointe vers Rizin “Free and Open Source Reverse Engineering Framework. Rizin takes a unique, Unix-friendly approach on reverse engineering”.

WoW Je suis un peu hypé dès la page d’accueil et je me dis que 2 ans ça passe trop rapidement et que c’est déjà un temps conséquent dans le développement informatique et les évolutions associées. Alors, j’y plonge !

Rizin

Il y a un compte dans Mastodon pour Rizin

Les dépots des sources est dans github, avec des licences LGPL-3.0 et GPL-3.0, et quelques autres (voir […]/rizin/tree/dev/LICENSES). Rizin a participé au Google Summer of Code (2021 et 2022). Dans le commit 9023f8b997db210cef3b9a25cf1748fbc94942ed, de passage en v0.4.1, la licence de Rizin est LGPL3.

Rizin est un fork de Radare2 par des personnes qui étaient profondément impliquées dans Cutter et r2, avec une volonté affichée d’utilisabilité, de stabilité et « d’environnement accuillant ».

“Rizin is a fork of radare2 with a focus on usability, stability, and working features, which strives to provide a welcoming environment for developers and users alike. Rizin was founded by a group of the core developers of radare2 and Cutter who contributed to the project in one way or the other in the past years and together constructed the Core group of radare2. With the establishment of Rizin, we are committed to creating an environment and a project which will be aligned with our values and vision.” RizinAnnouncing Rizin!”, 8 décembre 2020.

Quelques « explications », très polies, au sujet du départ du projet Radare2 et du fork sur disponible dans la faq.

La contribution dans Rizin semble bien active : un millier de profils dans le github à cette date, 282 issues ouvertes et 28 Pull Request. Leur page web “organization” offre en regard plus serré sur qui s’y implique et coordonne.

Il y a un code de « sociabilité », “Contributor Covenant Code of Conduct” :

“We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community” Rizin 2020 - 2022

C’est toujours plaisant de voir une telle démarche et cohérent avec ce qui fut annoncé en décembre 2020. Reste à s’attacher à une mise en œuvre associée et des efforts de facilitation et de maintien des discussions, et de leurs conditions d’accessibilité et d’ouverture, qui permettent cette conduite. Il y a aussi une lourde de question d’un code conçu et déployé dans un régime particulier duquel découlent des hiérarchisations (épistémologie) et des violences.

C’est une intégration du “Contributor Covenant” de Coraline Ada Ehmke (2014), une forme de proposition de « civilité » qui est aussi adoptée par des entreprises comme Google, Apple, Microsoft. Un CoC qui est donc soluble dans le capitalisme et adopté par des entreprises qui ont fait preuves des persécutions sur des personnes et des communautés LBGTQIA+ ; des racisées ; et bien d’autres.

Pour l’évolution de rizin :

Rizin est annoncé avec paquets binaires disponibles pour la plupart des OS, « Windows, MacOS, Linux », et l’on peut compiler rizin soi-même pour de nombreuses autres architectures/systèmes d’exploitation (Android par exemple). Bon, il y a du dispo au moins pour :

Pour Ubuntu, CentOS, Debian, OpenSuse, Fedora, vous serez invité⋅e⋅s à utiliser le Build serviced d’openSuse.

Pour mon Archlinux j’ai :

Dépôt                    : community
Nom                      : rizin
Version                  : 0.4.1-1
Description              : Open-source tools to disasm, debug, analyze and manipulate binary files
Architecture             : x86_64
URL                      : https://rizin.re
Licences                 : GPL3  LGPL3
Groupes                  : --
Fournit                  : --
Dépend de                : sh  capstone  libcapstone.so=4-64  openssl  libzip  zlib  lz4  xxhash
                           libxxhash.so=0-64  file  libuv  tree-sitter  libtree-sitter.so=0-64
                           libzip.so=5-64  libmagic.so=1-64
Dépendances opt.         : rz-ghidra: ghidra decompiler plugin
Est en conflit avec      : --
Remplace                 : --
Taille du téléchargement : 5,04 MiB
Taille installée         : 20,94 MiB
Paqueteur                : Antonio Rojas <arojas@archlinux.org>
Compilé le               : lun. 05 déc. 2022 22:42:59
Validé par               : Somme MD5  Somme SHA-256  Signature

Pour Radare2 c’est actuellement 6,40 MiB au télachargement et 28,34 MiB installé.

Il y a aussi disponible un très intéressant python-rzpipe 0.4.0-1 : Access rizin via pipe from any programming language.

Testons très succinctement

Capture d'écran du rendu d'information pour la commande rizin -h


Pour faire vite et simple ici je repars sur le même morceau pris dans l’exercice de 2020 et 2021, à savoir :

Il ne s’agit pas ici d’aller dans une optique d’exploit sur un exécutable, après l’avoir décortiqué et avoir résolu le problème posé, pour cela ici xxd ou strings suffisent largement. Je vais manipuler Rizin pour voir si cela me convient dans son installation minimaliste.

Il y a 2 ans, j’avais mis en place un ~/.config/radare2/radare2rc en fonction de mes besoins. Ici, je vais prendre Rizin comme il m’est donnée, autrement sans créer de spécifique configuration ~/.rizinrc (voir documentation)

Avant de commencer, un petit bout d’info utile : comment sortir de rizin

Usage: q[!?]   # Quit rizin
| q         # Quit rizin
| q!        # Force quit rizin
| q!!       # Force quit rizin without saving history
| q<yn><yn> # Quit rizin and choose to kill the process and save projects

La commande exit fonctionne aussi. Et si on fait une faute à la frappe du clavier :

[0x0000000]> exite
Command 'exite' does not exist.
Displaying the help of command 'exit'.

Usage: exit   # Exit Rizin

Lançons-nous dans rizin…

$ rizin 1st_reverse
 -- Toggle between disasm and graph with the space key
[0x00001060]> 

Nous avons encore et toujours une petite phrase d’accueil, pseudo-aléatoire.

Comme nous l’avions fait avec Radare2, je demande une analyse de notre exécutable.

[0x00001060]> aaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls
[x] Analyze len bytes of instructions for references
[x] Check for classes
[x] Analyze local variables and arguments
[x] Type matching analysis for all functions
[x] Applied 0 FLIRT signatures via sigdb
[x] Propagate noreturn information
[x] Finding function preludes
[x] Enable constraint types analysis for variables

C’était annoncé sur la page d’accueil du site web de rizin, il y a fourni par défaut Fast Library Identification and Recognition Technology (FLIRT, voir IDA F.L.I.R.T. Technology: In-Depth. Ceci étant à visée de nous éviter une fastidieuse marche de désassemblage sur des fonctions déjà connues piochées dans une base de données, ici via rizinorg/sigdb.

Passons maintenant à l’étape suivante d’analyse de fonction avec la commande afl

[0x00001060]> afl
0x00001060    1 46           entry0
0x00001090    4 41   -> 34   sym.deregister_tm_clones
0x000010c0    4 57   -> 51   sym.register_tm_clones
0x00001100    5 65   -> 55   sym.__do_global_dtors_aux
0x00001150    1 9            entry.init0
0x00001000    3 27           sym._init
0x00001280    1 5            sym.__libc_csu_fini
0x00001288    1 13           sym._fini
0x00001210    4 101          sym.__libc_csu_init
0x00001159    7 168          main
0x00001030    1 6            sym.imp.printf
0x00001040    1 6            sym.imp.strcmp
0x00001050    1 6            sym.imp.fprintf

Capture d'écran d'un terminal avec les commandes rizin ci-dessus écrites


Sans avoir ajouté un once de configuration supplémentaire, rizin m’offre ici déjà un minimum esthétique satisfaisant, alors qu’avec radare2 il m’avait fallu ajouté mes réglages dans fichier de configuration pour commencer à explorer.

Lançons une visualisation de l’exécutable

Pour ne pas se tromper :

Usage: v[*i]  
| v        open visual panels
| v test   load saved layout with name test
| v= test  save current layout with name test
| vi test  open the file test in 'cfg.editor'

avec un | ag[?] [options] draw graphs in various formats et

Et surtout ciblons la partie qui nous intéresse ici avec la commande $ v @ main(sans aucun ajout de réglage d’affichage toujours ici)

Pour indication comparative, avec Radare2 5.7.8 0 (au 29 décembre 2022, build 2022-12-03 + ma config évoquée ci-avant), j’ai en sortie graphique dans mon terminal ceci :

Un coup de clic de souris sur une des fenêtres, celle en haut à gauche qui m’affiche par défaut la sortie d’analyse fonctions afl, et je lui fait afficher l’entropie.

Radare2 est très verbeux, affichant une grande quantité d’informations (moves data from src to dst ou encore compare two operands pour exemple) avec une arborescence du fonctionnement de l’exécutable représentée graphiquement plus dense et détaillée que rizin (qui semble se concentrer sur le rendu des infos de base pour l’ingénierie inverse et le désassemblage). Ici, je ne déploie radare2 ou rizin sur un très simpliste fichier exécutable avec très peu d’opérations, pesant seulement 16,3 Kio.

Point de facilitation ou de friction à l’usage en mode visualisation du panel : avec rizin, Graph (agf) , je peux réduire ou agrandir les fenêtres avec la souris (en plus des commandes clavier Ctrl + et Ctrl −) et cela ne se fait pas avec radare2, Graph (uniquement les commandes clavier Ctrl + et Ctrl −) dans la documentation …book.rada.re/visual_mode/visual_panels.html.

Le déplacement dans cette arborescence ce faisant avec les touches h, j, k, l.

Avec Rizin $ v @ main

Si je passe comme commande n’importe quoi à radare2 v*igjfnzjfnz il me sort un graphique de l’exécutable, si je passe la même à rizin il me renvoie :

Usage: v[*i]  
| v        open visual panels
| v test   load saved layout with name test
| v= test  save current layout with name test
| vi test  open the file test in 'cfg.editor'

Une interface graphique plus finement conçue et aidant au travail de désassemblage sera utile. Avant de passer rizin avec cutter, vérifions un truc ou deu : est-ce que rizin envoie des informations à des tiers lorsque je l’utilise ?

$ strace -f -e trace=network -s 10000 -p <PID rizin>
strace: Process <PID rizin> attached
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---

et ensuite

$ strace -f -e trace=send,recv,read -s 10000 -p <PID rizin>
strace: Process <PID rizin> attached
read(0, "\33", 1)                       = 1
read(0, "[", 1)                         = 1
read(0, "A", 1)                         = 1
read(0, "\r", 1)                        = 1
read(0, "v", 1)                         = 1
read(0, " ", 1)                         = 1
read(0, "@", 1)                         = 1
read(0, " ", 1)                         = 1
read(0, "m", 1)                         = 1
read(0, "a", 1)                         = 1
read(0, "i", 1)                         = 1
read(0, "n", 1)                         = 1
read(0, "\r", 1)                        = 1

Et $ netstat -anop | grep <PID rizin>, ou alternativement $ netstat -anop | grep -E rizin, ne rend rien de son côté.

Au 7 mars 2023, rizin-0.5.1-1 est sur ma machine de travail.

Avec un nethogs en mode -v 2 (merci Da Scritch via Mastodon) ; J’apprends et peu d’infos parlantes, voir pas du tout, sortent.

En tout cas déjà connu :

$ strace -e trace=[ce que tu veux tracer] -s 10000 rizin 
# plutôt que de d'y attacher strace une fois lancé : 
# tu peux manquer les premières tentatives (éventuellement les seules).

« Pour le coup, tu peux ajouter le suivi des appels à connect() dans ton strace, ça te dira à quoi le programme se connecte et comment. Je pense que c’est l’information la plus lisible que tu puisse avoir.

Aussi, je lancerai le programme avec strace (strace -e trace=[ce que tu veux tracer] -s 10000 rizin) plutôt que de d’y attacher strace une fois lancé : tu peux manquer les premières tentatives (éventuellement les seules).

Et sinon, pour ce qui est des outils, strace/tcpdump/wireshark sont les outils les plus accessibles pour ce que tu veux faire. strace a l’avantage de pouvoir plus facilement cibler le processus (là où tcpdump va monitorer tout ce qui passe sur ta carte et va capturer trop d’infos). Quand à lsof et netstat, iels font des instantanés de l’état de tes connexion, il est improbable qu’un programme laisse une connexion inutilisée ouverte, donc tu as de grandes chances de ne jamais voir quoi que ce soit. » par Enerhpozyks

En bref, après tout cela, depuis mars 2022 à aujourd’hui − avril 2023 −, je ne détecte pas de sortie d’information.

Avec cutter

Ici exemple d’usage de cutter sur une exécutable censé controller les LEDs (RGB) d’un AceMagician AMR5

Le dashboard

Ici le travail depuis hexdump dans le sub.WINSPOOL.DRV_DocumentPropertiesA :

Avec un petit zoom sur la section (à droite de l’interface graphique) d’aide au travail de reconnaissance et d’évaluation de partie de code :

Rizin est en Release v0.5.2 au 27 mars 2023. Time flies, time goes on…

Autres ressources bibliographiques sur la rétro-ingénierie

  1. « Exercice de découverte de désassemblage avec radare2 » https://notecc.kaouenn-noz.fr/doku.php?id=pages:norae:si:exercice_de_decouverte_de_desassemblage_avec_radare2 

  2. « Défaire ? (V0.3 version française) », octobre 2020, https://xavcc.frama.io/defaire/ 

  3. Clio Flego is an italian researcher and cultural project manager passionate about bio and sound arts. She has cooperated as a creative and critical thinker with Universities and cultural institutions all around the world, collaborating in many international festivals and events based across Europe. For this podcast ‘Reverse-engineering: aesthetic and speculative representation’, she collaborated with the International NGO Tactical Tech in the IQEA group. 

  4. voir les notes d’atelier ici https://notecc.kaouenn-noz.fr/doku.php?id=pages:norae:si:exercice_de_decouverte_de_desassemblage_avec_radare2#gcc 

Merci à toutes les personnes qui soutiennent les efforts par leurs dons


Xavier Coadic

Xavier Coadic

Human Collider

rss framagit github mail linkedin stackoverflow