Frage:
Wie funktioniert BinDiff?
perror
2013-04-02 14:35:57 UTC
view on stackexchange narkive permalink

Ich würde gerne wissen, was die Grundprinzipien (und vielleicht ein paar Dinge zu den Optimierungen und Heuristiken) der BinDiff-Software sind. Hat jemand eine nette und pädagogische Erklärung dafür?

@Nirlzr: Ich sehe nicht, wie es irgendetwas verbessert, die Tags 'bindiff' in 'tool-bindiff' zu ändern ... Aber ich habe vielleicht nur einen verdrehten Verstand, also erzähl mir mehr darüber ...
Vielleicht sollten Sie in http://meta.reverseengineering.stackexchange.com/questions/322/bindiff-verses-bin-diffing-tags sprechen
@kennytm: Ah, ich habe das verpasst ... Guter Fang, danke.
Zwei antworten:
#1
+16
newgre
2013-04-03 02:01:48 UTC
view on stackexchange narkive permalink

Im Allgemeinen funktioniert BinDiff in seiner aktuellen Version zum jetzigen Zeitpunkt (4.x), indem Attribute auf Funktionsebene abgeglichen werden. Grundsätzlich wird der Abgleich in zwei Phasen unterteilt: Es werden erste anfängliche Übereinstimmungen generiert, die dann in der Drilldown-Phase verfeinert werden.

Anfängliche Übereinstimmungen

Zunächst ordnet BinDiff eine Signatur zu, die auf der basiert Folgende Attribute für jede Funktion:

  • die Anzahl der Basisblöcke
  • die Anzahl der Kanten zwischen diesen Blöcken
  • die Anzahl der Aufrufe von Unterfunktionen

Dieser Schritt gibt uns eine Reihe von Signaturen für jede Binärdatei, die wiederum verwendet werden, um die Menge der anfänglichen Übereinstimmungen zu generieren. Nach einer Eins-zu-Eins-Beziehung wählt BinDiff diese anfänglichen Übereinstimmungen basierend auf den obigen Merkmalen aus.

Im nächsten Schritt wird versucht, Übereinstimmungen im Aufrufdiagramm jeder Binärdatei zu finden: für eine verifizierte Übereinstimmung die Menge von Aufgerufene Funktionen aus der übereinstimmenden Funktion werden untersucht, um weitere Übereinstimmungen zu finden. Dieser Vorgang wird wiederholt, solange neue Übereinstimmungen gefunden werden.

Drilldown

In der Praxis werden nicht alle Funktionen durch die durch die anfängliche Übereinstimmung induzierte Eins-zu-Eins-Beziehung abgeglichen Nachdem die anfänglichen Übereinstimmungen ermittelt wurden, haben wir immer noch eine Liste nicht übereinstimmender Funktionen. Die Idee der Drilldown-Phase besteht darin, mehrere verschiedene Strategien für Funktionsübereinstimmungen zu verwenden, die angewendet werden, bis eine Übereinstimmung gefunden wird. Die Reihenfolge der Anwendung dieser Strategien ist wichtig: BinDiff probiert zunächst die Strategien aus, für die es das höchste Vertrauen voraussetzt. Nur wenn keine Übereinstimmung gefunden werden konnte, wird mit der nächsten Strategie fortgefahren. Dies wird wiederholt, bis BinDiff keine Strategien mehr hat oder bis alle Funktionen übereinstimmen. Beispiele sind MD-Index, Übereinstimmung basierend auf Funktionsnamen (dh Importe), MD-Index für Callgraph-Kanten usw.

MD-Index-Papier

Diagrammbasierter Vergleich ausführbarer Objekte

Struktureller Vergleich ausführbarer Objekte

(Haftungsausschluss: working @ team zynamics / google, hoffentlich habe ich nichts durcheinander gebracht, sonst wird mich soeren grillen ;-))

Also arbeitest du noch daran? Oder ist das nur das Projekt jeden Freitag?
Ich arbeite nicht daran und habe es nie getan, aber BinDiff wurde nicht abgesagt, wenn Sie das gemeint haben!?
Zynamics, das Unternehmen hinter BinDiff, wurde von Google übernommen. Sie können einigen Mitarbeitern eine Nachricht senden, die auf dem Reddit für das Reverse Engineering sitzen.
#2
+7
fasmotol
2013-04-02 15:47:17 UTC
view on stackexchange narkive permalink

Ich kann nur ein paar Worte zum Erstellen von Kontrollflussgraphen sagen, obwohl meine Antwort definitiv nicht die vollständige ist.

BinDiff verwendet einen statischen Typ zum Erkennen von Ausführungsflüssen, vermutlich weil Code ausgeführt wird ist nicht immer möglich (zB für Ring 0-Treiber) oder vernünftig (Malware). Tatsächlich wird die angegebene Datei zerlegt, dann sollte sie in Basisblöcke aufgeteilt werden (dies sind Codeteile, die direkt ausgeführt werden können, obwohl diese Definition in diesem Fall richtig ist). Es ist klar (zum Beispiel unter Berücksichtigung der x86-Architektur), dass Anweisungen wie jxx den Kontrollfluss eines Programms ändern. Grundblöcke werden also normalerweise von ihnen beendet. Dieser Vorgang des Aufteilens von Code in Blöcke ist keine komplizierte Aufgabe. Der schwierigere Teil besteht darin, das Sprungziel zu bestimmen.

Zum Beispiel:

  ... jz eax  

Mit einer automatisierten statischen Analyse können wir also nicht (leicht) verstehen, auf was dieser Aufruf verweist. Trivialfälle können "emuliert" werden, aber im Allgemeinen ist diese Arbeit sehr hart und frustrierend. Die andere Möglichkeit besteht darin, das Programm zu verfolgen, um zu prüfen, welche Pfade der Code ausführt (dies kann manuell erfolgen). Wenn diese Blöcke gefunden werden, müssen nur noch lesbare Diagramme erstellt werden.

Wie auch immer Eine Reihe von Möglichkeiten, wie der Ausführungsfluss geändert werden kann (Ausnahmen, Hot-Patching durch einen anderen Thread, systemabhängige Ereignisse usw.).

Der [Originalartikel] (http://www.zynamics.com/downloads/bindiffsstic05-1.pdf) zum Algorithmus des Graphhomomorphismus ist ein guter Anfang. In jüngerer Zeit wurden einige [Tools] (https://github.com/MartialB/BinSlayer) vorgeschlagen (siehe dieses [Papier] (http://dl.acm.org/citation.cfm?id=2430557) und dies [Poster] (http://royalsociety.org/uploadedFiles/Royal_Society_Content/grants/labs-to-riches/2012/Andy%20king.pdf)). Dieser [Reddit-Thread] (http://www.reddit.com/r/ReverseEngineering/comments/16bc9t/binslayer_fast_comparison_of_binary_executables/) legt jedoch nahe, dass einige Verbesserungen an BinDiff vorgenommen wurden.


Diese Fragen und Antworten wurden automatisch aus der englischen Sprache übersetzt.Der ursprüngliche Inhalt ist auf stackexchange verfügbar. Wir danken ihm für die cc by-sa 3.0-Lizenz, unter der er vertrieben wird.
Loading...