Question:
Comment fonctionne BinDiff?
perror
2013-04-02 14:35:57 UTC
view on stackexchange narkive permalink

Je voudrais savoir quels sont les principes de base (et peut-être quelques informations sur les optimisations et l'heuristique) du logiciel BinDiff. Quelqu'un a-t-il une explication intéressante et pédagogique?

@Nirlzr: Je ne vois pas en quoi cela améliore quoi que ce soit de changer les balises 'bindiff' en 'tool-bindiff' ... Mais, j'ai peut-être juste un esprit tordu, alors dites-moi plus à ce sujet ...
Peut-être devriez-vous exprimer votre voix dans http://meta.reverseengineering.stackexchange.com/questions/322/bindiff-verses-bin-diffing-tags
@kennytm: Ah, j'ai raté ça ... Bonne prise, merci.
Deux réponses:
#1
+16
newgre
2013-04-03 02:01:48 UTC
view on stackexchange narkive permalink

En général, BinDiff dans sa version actuelle au moment de l'écriture (4.x) fonctionne en faisant correspondre les attributs au niveau de la fonction. Fondamentalement, la correspondance est divisée en deux phases: les premières correspondances initiales sont générées qui sont ensuite affinées dans la phase d'exploration.

Correspondances initiales

Tout d'abord, BinDiff associe une signature basée sur le attributs suivants pour chaque fonction:

  • le nombre de blocs de base
  • le nombre d'arêtes entre ces blocs
  • le nombre d'appels aux sous-fonctions

Cette étape nous donne un ensemble de signatures pour chaque binaire qui à son tour sont utilisées pour générer l'ensemble des correspondances initiales. Suite à une relation biunivoque, BinDiff sélectionne ces correspondances initiales en fonction des caractéristiques ci-dessus.

L'étape suivante essaie de trouver des correspondances sur le graphe d'appel de chaque binaire: pour une correspondance vérifiée, l'ensemble des les fonctions appelées à partir de la fonction correspondante sont examinées afin de trouver plus de correspondances d'événements. Ce processus est répété tant que de nouvelles correspondances sont trouvées.

Exploration vers le bas

En pratique, toutes les fonctions ne seront pas mises en correspondance par la relation un-à-un induite par la correspondance initiale Une fois que les correspondances initiales ont été déterminées, nous avons toujours une liste de fonctions sans correspondance.L'idée de la phase d'exploration est d'avoir plusieurs stratégies de correspondance de fonctions différentes qui sont appliquées jusqu'à ce qu'une correspondance soit trouvée. L'ordre d'application de ces stratégies est important: BinDiff essaie d'abord les stratégies pour lesquelles il suppose la plus grande confiance. Seulement si aucune correspondance n'a pu être trouvée, il continue avec la stratégie suivante. Ceci est répété jusqu'à ce que BinDiff soit à court de stratégies, ou jusqu'à ce que toutes les fonctions correspondent. Les exemples incluent l'index MD, la correspondance basée sur les noms de fonction (c'est-à-dire les importations), l'index MD des arêtes du graphe d'appel, etc.

Document d'index MD

Comparaison graphique des objets exécutables

Comparaison structurelle des objets exécutables

(Disclaimer: working @ team zynamics / google, j'espère que je n'ai rien gâché, sinon soeren va me griller ;-))

Alors vous travaillez toujours dessus? Ou est-ce juste le projet tous les vendredis?
Je ne travaille pas dessus et je ne l'ai jamais fait, mais BinDiff n'a pas été annulé si c'est ce que vous vouliez dire !?
Zynamics, la société derrière BinDiff, a été rachetée par Google. Vous pouvez envoyer un message à certains employés qui participent au reddit de rétro-ingénierie.
#2
+7
fasmotol
2013-04-02 15:47:17 UTC
view on stackexchange narkive permalink

Je peux dire juste quelques mots sur la création de graphes de flux de contrôle, bien que ma réponse ne soit certainement pas la complète.

BinDiff utilise un type statique de détection des flux d'exécution, je suppose parce que l'exécution de code n'est pas toujours possible (par exemple pour les pilotes Ring 0) ou raisonnable (malware). En fait, le fichier donné est désassemblé, puis il doit être divisé en blocs de base (ce sont des morceaux de code qui ont un mode d'exécution simple, bien que cette définition soit correcte dans ce cas précis). Il est clair (compte tenu de l'architecture x86, par exemple) que des instructions comme jxx modifient le flux de contrôle d'un programme. Les blocs de base sont donc généralement terminés par eux. Ce processus même de division du code en blocs n'est pas une tâche compliquée, la partie la plus difficile est de déterminer la destination du saut.

Par exemple, quelque chose comme ça:

  ... jz eax  

Nous ne pouvons donc pas (facilement) comprendre avec une analyse statique automatisée où cet appel est pointé. Les cas triviaux peuvent être «imités», mais en général, ce travail est très difficile et frustrant. L'autre option est de tracer le programme pour voir quels chemins le code exécute (cela peut être fait manuellement) .Lorsque ces blocs sont trouvés, la seule chose qui reste est de construire un graphique lisible par l'homme.

Quoi qu'il en soit, il y a un tas de façons dont le flux d'exécution peut être modifié (exceptions, correctifs à chaud par un autre thread, événements dépendants du système, etc.).

L '[article original] (http://www.zynamics.com/downloads/bindiffsstic05-1.pdf) sur l'algorithme d'homomorphisme des graphes est un bon début. Plus récemment, des [outils] (https://github.com/MartialB/BinSlayer) ont été proposés (voir cet [article] (http://dl.acm.org/citation.cfm?id=2430557) et ce [affiche] (http://royalsociety.org/uploadedFiles/Royal_Society_Content/grants/labs-to-riches/2012/Andy%20king.pdf)). Mais, ce [fil Reddit] (http://www.reddit.com/r/ReverseEngineering/comments/16bc9t/binslayer_fast_comparison_of_binary_executables/) suggère que certaines améliorations ont été apportées sur BinDiff.


Ce Q&R a été automatiquement traduit de la langue anglaise.Le contenu original est disponible sur stackexchange, que nous remercions pour la licence cc by-sa 3.0 sous laquelle il est distribué.
Loading...