Wie schwer ist es (wirklich) zu dekompilieren Assembler-code?
Ich versuche zu finden, die harten Fakten, die helfen, meine management-verstehen, wie schwer/einfach es ist das reverse-Engineering kompilierte C-code.
Ähnliche Frage gestellt, bevor auf dieser Website (siehe z.B. Ist es möglich, zu "dekompilieren" ein Windows .exe-Datei? Oder zumindest die Ansicht der Versammlung? oder Möglich, zu dekompilieren DLL in C geschrieben?), aber das wesentliche in diesen Fragen ist, dass der Dekompilierung der kompilierte C-code ist "hart, aber nicht völlig unmöglich".
Zur Erleichterung der Antworten basieren, in der Tat, ich bin auch von kompiliertem code für ein Rätsel Funktion, und ich schlage vor, dass Antworten auf diese Frage ermitteln Sie den Erfolg oder Misserfolg der vorgeschlagenen Techniken durch, ob Sie bestimmen können, was diese Funktion tut. Dies mag ungewöhnlich sein, für SO aber ich denke, es ist der beste Weg, um "gute subjektive" oder sachliche Antworten zu dieser technischen Frage. Daher Was ist Ihre beste Vermutung an, was diese Funktion tut, und wie?
Dies ist der kompilierte code, kompiliert auf Mac OS x mit gcc:
_mystery:
Leh_func_begin1:
pushq %rbp
Ltmp0:
movq %rsp, %rbp
Ltmp1:
movsd LCPI1_0(%rip), %xmm1
subsd %xmm0, %xmm1
pxor %xmm2, %xmm2
ucomisd %xmm1, %xmm2
jbe LBB1_2
xorpd LCPI1_1(%rip), %xmm1
LBB1_2:
ucomisd LCPI1_2(%rip), %xmm1
jb LBB1_8
movsd LCPI1_0(%rip), %xmm1
movsd LCPI1_3(%rip), %xmm2
pxor %xmm3, %xmm3
movsd LCPI1_1(%rip), %xmm4
jmp LBB1_4
.align 4, 0x90
LBB1_5:
ucomisd LCPI1_2(%rip), %xmm1
jb LBB1_9
movapd %xmm5, %xmm1
LBB1_4:
movapd %xmm0, %xmm5
divsd %xmm1, %xmm5
addsd %xmm1, %xmm5
mulsd %xmm2, %xmm5
movapd %xmm5, %xmm1
mulsd %xmm1, %xmm1
subsd %xmm0, %xmm1
ucomisd %xmm1, %xmm3
jbe LBB1_5
xorpd %xmm4, %xmm1
jmp LBB1_5
LBB1_8:
movsd LCPI1_0(%rip), %xmm5
LBB1_9:
movapd %xmm5, %xmm0
popq %rbp
ret
Leh_func_end1:
UPDATE
@Igor Skochinsky ist der erste, der die richtige Antwort: es ist in der Tat eine naive Implementierung des Heron-Algorithmus zur Berechnung von Quadratwurzeln. Der original source code ist hier:
#include <stdio.h>
#define EPS 1e-7
double mystery(double x){
double y=1.;
double diff;
diff=y*y-x;
diff=diff<0?-diff:diff;
while(diff>=EPS){
y=(y+x/y)/2.;
diff=y*y-x;
diff=diff<0?-diff:diff;
}
return y;
}
int main() {
printf("The square root of 2 is %g\n", mystery(2.));
}
Wie ist "ratet mal, was mein assembler nicht?" überhaupt eine zulässige Frage? (oder war das Sarkasmus?)
Ich gebe Ihnen ein anderes Beispiel hier, wo 10 Zeilen inline-Funktionen und C++ - templates werden kompiliert in 4-5 Maschine Anweisungen. Was sind die Chancen, dass jemand reproduzieren können, die original-source-code?
Im Allgemeinen ist es unmöglich, die ursprüngliche Quelle ist absolut unmöglich, in den seltenen Fällen, in denen keine Optimierer verwendet wurde und der code war so trivial, dass Sie nicht brauchen, um die Mühe gehen wieder zurück zu C, dann könnten Sie rekonstruieren etwas, das ist funktional das gleiche.
Stellen Sie sich dies als Umwandlung einer wav-Datei in eine mp3-Datei (ein Bild, um jpg -, einen Film zu mpeg, etc) eine verlustbehaftete Komprimierung. Sie nicht mehr das ursprüngliche signal. Das gleiche passiert in den compiler an, Informationen aus dem source code kompilieren verloren ist, ist nicht sichtbar in der Ausgabe, können Sie nicht zurück zum original. Funktional ähnlich wie C-code, wo möglich, nicht mehr lesbar oder wartbar ist als die Assembler-Sprache, Sie sind besser dran, wenn Sie änderungen, um es in asm oder schreiben Sie C-code von hand aus einer Analyse der asm.
InformationsquelleAutor lindelof | 2013-01-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier die Ergebnisse der Dekompilierung mit dem Hex-Rays Decompiler nachdem ich konvertierte code zu x86 (es unterstützt keine x64 im moment), Hinzugefügt einige Daten Definitionen fehlen in der original-Beitrag, und montiert es:
Klar, es könnte einige Verbesserungen verwenden (XMM-Unterstützung ist etwas basic jetzt), aber ich denke, der grundlegende Algorithmus ist schon verständlich.
Bearbeiten: denn es ist offensichtlich, dass nur die niedrigen zweistelligen aller XMM-Register verwendet wird, scheint die Funktion tatsächlich funktioniert mit skalaren verdoppelt-und nicht Vektoren. Für die _mm_xor_pd (xorpd) intrinsische, ich denke, es ist nur die Art, wie der compiler implementiert sign inversion durch xoring mit eine vordefinierte Konstante, die 1s in Vorzeichen-bit-Positionen und 0 überall sonst. Mit dem oben im Kopf, und nach etwas Aufräumen, bekomme ich den folgenden code:
Produziert assembly ziemlich ähnlich zu dem original-Beitrag.
Sieht aus wie die Babylonische Methode der Quadrat-Wurzel Berechnung. LCPI1_0 ist die erste Näherung, LCPI1_2 ist epsilon, und LCPI1_3 ist konstant 0.5.
herzlichen Glückwunsch, Sie dit it!
InformationsquelleAutor Igor Skochinsky
Reverse engineering /dekompilieren jeder code ist eine Frage der Zeit es braucht, vs der Vorteil dabei; nicht, wie schwer es ist, das zu tun.
Wenn Sie einige geheime Zutat, die Sie absolut nicht erlauben, Sie zu bekommen, dann ist die einzige Sache, die Sie tun können, ist das Geheimrezept, wie ein web-Dienst, der aufgerufen wird, auf als notwendig. Auf diese Weise werden die binaries verlassen nie Ihr corporate Wände.
Sogar Verschleierung nur so weit geht alles zurückverfolgt werden kann, wenn ein hacker hat die kompilierten Binärdateien auf einem system, das Sie kontrollieren. Was solls, die original-PC-Klone wurden durch reverse engineering erstellt die IBM-BIOS.
So, zurück zu dem Punkt: Nochmals, es geht nicht darum wie schwer etwas ist, es ist mehr eine Frage, ob jemand möchte, um zu versuchen... und das basiert auf das, was wahrgenommen Wert, würden Sie bekommen aus ihm heraus. Ob direkt-Dollar (empfangen oder speichern), Wettbewerbsvorteil oder einfach prahlen. Compoundierung dies ist die Verfügbarkeit der Anwendung: größere Verbreitung bedeutet eine höhere Potenzial für die Suche nach dem Weg in eine Hacker-Eimer von Dingen zu arbeiten.
Wenn diese Werte vorhanden sind, dann können Sie sicher sein, dass jemand versuchen wird, und Sie werden Erfolg haben. Was dazu führen sollte, Sie zu der nächsten Frage: Was ist, wenn Sie es tun? Was ist das Schlimmste Ergebnis?
In einigen Fällen es ist einfach ein verlorener Kauf ist, dass Sie möglicherweise nicht bekommen haben, sowieso. In anderen könnte es sein, den Verlust des Geschäfts.
InformationsquelleAutor NotMe
Grundlegend, tun einzelnen Maschinen-Befehl "reverse engineering" ist ziemlich einfach, da die Maschine Anweisungen haben sehr gut definierte Semantik. Dies wird Ihnen einen schlechten C-code, aber das ist wohl nicht das Ziel. (Zu wissen, dass das binäre Muster in einer Datei ist ein Maschinenbefehl ist technisch Turing-hart, - e.g, unmöglich in einigen Fällen, weniger wahrscheinlich zu sein, so im Falle der vom compiler generierte code).
Darüber hinaus, dass Sie versuchen ableiten, algorithmen und Vorsatz. Das ist extrem schwer; wo kommt das wissen halt alle das her?
Finden Sie vielleicht meine Papier auf reverse engineering interessant. Es deutet auf eine Weise zu codieren, die notwendigen Kenntnisse.
Gibt es auch kommerzielle tools, um dies zu tun zu einem gewissen Grad. Dies muss nicht so weit gehen, wie das Schema mein Papier skizziert, aber produziert immer noch ziemlich vernünftigen C-code, wie ich es verstehe. (Ich habe keine Besondere Erfahrung mit diesem tool, aber habe großen Respekt für den Autor und seine Werkzeuge).
InformationsquelleAutor Ira Baxter