Wie Oli bereits in seiner Antwort betont hat, kann man nicht den ursprünglichen Quellcode einer ausführbaren Datei erhalten.
Während der Kompilierung eines Quellcodes (Kompilierung, die in ihrer typisch breiteren Akzeptanz beabsichtigt ist, daher als der gesamte Prozess, der einen Quellcode in eine ausführbare Datei "umwandelt"), gehen viele Informationen verloren.
Der C-Präprozessor führt unter anderem Folgendes aus:
- Präprozessor-Direktiven (
#
Anweisungen) interpretieren, ausführen und entfernen
- Kommentare entfernen
- Entfernen Sie unnötige Leerzeichen
Andererseits ist das, was bei der Kompilierung des Quellcodes nicht verloren geht, technisch auf einen funktional äquivalenten Quellcode zurücksetzbar.
Das ist weil:
- Binäre Anweisungen stimmen 1: 1 mit den Montageanweisungen überein. Das Zusammenstellen eines Assembly-Quellcodes ist lediglich eine Umwandlung der Assembly-Anweisungen in die binären Anweisungen auf der Grundlage einer Entsprechungstabelle. Eine einzelne Binäranweisung ist immer identifizierbar und kann auf eine einzelne Assembly-Anweisung zurückgesetzt werden .
- Montageanleitungen haben keine 1: 1 Übereinstimmung mit C-Anweisungen; Die Kompilierung eines C-Quellcodes ist in der Regel nicht nur eine bloße Umwandlung der C-Anweisungen in die Assembler-Anweisungen auf der Grundlage einer Entsprechungstabelle. Tatsächlich ist es oft das Gegenteil. In der Regel wird eine C-Anweisung in mehrere (je nach Compiler häufig unterschiedliche) Assembly-Anweisungen konvertiert. Jedoch sind Muster von mehreren Montageanleitung in der Regel erkennbar und umkehrbaren auf einen einzigen C - Befehl ;
Es gibt Tools, die als Decompiler bezeichnet werden und versuchen, eine ausführbare Datei auf einen funktional äquivalenten Quellcode zurückzusetzen. Das Ergebnis ist jedoch in der Regel etwas weit vom ursprünglichen Quellcode entfernt (und in der Regel auch nicht kompilierbar).
Betrachten Sie dieses Programm:
#include <stdio.h>
#define MESSAGE "Literal strings will be recovered" // This preprocessor directive won't be recovered
/*
This comment and the comment above won't be recovered
*/
int main(int argc, char* argv[]) {
printf(MESSAGE);
return 0;
}
Durch das Kompilieren in eine ausführbare Datei und das erneute Dekompilieren in einen Quellcode erhalten Sie mehr oder weniger das, was Sie normalerweise zurückbekommen (in diesem speziellen Fall habe ich gcc
/ Boomerang verwendet ):
// address: 0x80483fb
int main(int argc, char **argv, char **envp) {
printf("Literal strings will be recovered");
return 0;
}
Wie vorhergesagt:
- Präprozessor-Direktiven fehlen
- Kommentare fehlen (abgesehen von denen
// address: 0x80483fb
, die vom Dekompiler hinzugefügt wurden)
- Unnötiges Leerzeichen fehlt (abgesehen von Zeilenumbrüchen und Tabellierungen, die vom Dekompiler hinzugefügt wurden)
Dies ist auch ein ziemlich gutes Ergebnis; Es kommt nicht selten vor, dass Inline-Assembly-Anweisungen in den Code eingefügt werden:
asm("assembly_instruction");
__asm__("assembly_instruction");
Die Quintessenz ist (wie bereits in den anderen Antworten erwähnt): Sie können nicht die ursprüngliche Quelle einer ausführbaren Datei * erhalten.
* Jedoch auf die ausführbare Datei und auf Ihr Glück abhängig, Sie könnten der Lage sein , etwas mit einem Decompiler zu bekommen.
strings
Filterprogramm sehr nützlich sein kann, um zu identifizieren, was ein bestimmtes Binärprogramm ist oder tut, da es alle eingebetteten Textzeichenfolgen ausgibt, die länger als eine angegebene Länge in a sind Binärdatei und das Betrachten der Meldungen in einem Programm sagt manchmal viel darüber aus, was es ist und was es tut.