Bei bytecode-basierten virtuellen Maschinensprachen wie Java, VB.NET, C #, ActionScript 3.0 usw. hört man manchmal, wie einfach es ist, einen Decompiler aus dem Internet herunterzuladen, den Bytecode einmal durchzuarbeiten und oftmals lassen Sie sich in Sekundenschnelle etwas einfallen, das nicht allzu weit vom ursprünglichen Quellcode entfernt ist. Angeblich ist diese Art von Sprache dafür besonders anfällig.
Ich habe mich kürzlich gefragt, warum Sie nicht mehr über nativen Binärcode erfahren, wenn Sie zumindest wissen, in welcher Sprache er ursprünglich geschrieben wurde (und somit in welche Sprache Sie zu dekompilieren versuchen). Lange Zeit dachte ich, es sei nur so, weil die Maschinensprache so viel verrückter und komplexer ist als der typische Bytecode.
Aber wie sieht Bytecode aus? Es sieht aus wie das:
1000: 2A 40 F0 14
1001: 2A 50 F1 27
1002: 4F 00 F0 F1
1003: C9 00 00 F2
Und wie sieht nativer Maschinencode aus (in hex)? Das sieht natürlich so aus:
1000: 2A 40 F0 14
1001: 2A 50 F1 27
1002: 4F 00 F0 F1
1003: C9 00 00 F2
Und die Anweisungen kommen aus einer ähnlichen Denkweise:
1000: mov EAX, 20
1001: mov EBX, loc1
1002: mul EAX, EBX
1003: push ECX
Angesichts der Sprache, in der versucht werden soll, native Binärdateien in C ++ zu dekompilieren, was ist daran so schwer? Die einzigen beiden Ideen, die sofort in den Sinn kommen, sind: 1) Es ist wirklich viel komplizierter als Bytecode, oder 2) Etwas an der Tatsache, dass Betriebssysteme dazu neigen, Programme zu paginieren und ihre Teile zu zerstreuen, verursacht zu viele Probleme. Wenn eine dieser Möglichkeiten richtig ist, erklären Sie bitte. Aber warum hörst du eigentlich nie davon?
HINWEIS
Ich bin dabei, eine der Antworten zu akzeptieren, aber ich möchte zuerst etwas erwähnen. Fast jeder bezieht sich auf die Tatsache, dass verschiedene Teile des ursprünglichen Quellcodes demselben Maschinencode zugeordnet werden könnten. lokale Variablennamen gehen verloren, Sie wissen nicht, welche Art von Schleife ursprünglich verwendet wurde usw.
Beispiele wie die beiden, die gerade erwähnt wurden, sind jedoch in meinen Augen trivial. Einige der Antworten geben jedoch an, dass der Unterschied zwischen Maschinencode und der ursprünglichen Quelle drastisch größer ist als etwas, das so trivial ist.
Wenn es zum Beispiel um lokale Variablennamen und Schleifentypen geht, verliert Bytecode diese Informationen ebenfalls (zumindest für ActionScript 3.0). Ich habe das Zeug vorher durch einen Decompiler zurückgespielt und es war mir egal, ob eine Variable aufgerufen wurde strMyLocalString:String
oder nicht loc1
. Ich konnte immer noch in diesem kleinen Bereich vor Ort nachsehen, wie es verwendet wird, ohne große Probleme. Und eine for
Schleife ist so ziemlich das Gleiche wie einewhile
Schleife, wenn Sie darüber nachdenken. Auch wenn ich den Quellcode mit irrFuscator ausführen würde (der im Gegensatz zu secureSWF nicht viel mehr als nur die Namen von Member-Variablen und -Funktionen zufällig auswählt), sah es so aus, als könnten Sie einfach damit beginnen, bestimmte Variablen und Funktionen in kleineren Klassen zu isolieren, Abbildung Finden Sie heraus, wie sie verwendet werden, weisen Sie ihnen Ihre eigenen Namen zu und arbeiten Sie von dort aus.
Damit dies eine große Sache wird, müsste der Maschinencode viel mehr Informationen verlieren, und einige der Antworten gehen darauf ein.