Art der Codekonvertierung, die in ausführbaren Linux-Dateien verwendet wird

13

Ich möchte fragen, welche Art von Codierung verwendet wird, um ausführbare Linux-Dateien, z. B. hexadezimal, binär oder irgendetwas anderes, zu erstellen. Wie wird es konvertiert? Gibt es eine Möglichkeit, den ursprünglichen Code aus dieser ausführbaren Datei wiederherzustellen?

Hier ist ein bisschen Code, den ich habe:

ELF���������>�����%|�����@�������������������@�8��@���������������������@�������@�����7<�����7<������� ������������������f�����f���������������������� ������[�UPX!L
h�h�8����������?�E�h=��ڊ̓�N�    4���9ISloB�q�w�]ȉ.��,ς��Q䝦����#e��-�N����/�b,���d<��'��-E��6E�s�/�U���ly�V�Y2]"a��S�.�hU�|�S�J�I�2���X}
�G0�;���5d�$���.)

Was soll das heißen?

Redchief
quelle
Obwohl es Ihnen nicht hilft, viel von etwas zurückzubekommen, ist es erwähnenswert, dass das stringsFilterprogramm 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.
Joe
Möglich / teilweise duplizieren? stackoverflow.com/questions/193896/whats-a-good-c-decompiler
Arielf

Antworten:

29

Es ist binär. Der Quellcode wurde kompiliert. Sie können es in einem Editor anzeigen (ein Hex-Editor wie blesskönnte genauere Änderungen bewirken), aber Sie müssen wirklich wissen, was Sie tun. Es ist wahrscheinlich nur zum Ändern von Zeichenfolgen geeignet.

Für etwas Hardcore können Sie beginnen, die Binärdatei in Assembler- Code umzuwandeln. Dies wird oft als die vom Menschen analysierbare Computersprache der untersten Ebene angesehen.

objdump -d helloworld | less

Aber es wird auch eine Menge Compiler-Quatsch enthalten. Wenn Sie beispielsweise das Einfachstehelloworld.cpp mit G ++ kompilieren und es dann objdumpausführen, erhalten Sie 226 Zeilen (208 Zeilen) Yuck. Sie könnten eine "Hallo Welt" in nur 15 Zeilen Assembler schreiben , kompilieren und objdumpes, aber das blüht noch in 166 Zeilen (gestrippt).

Wenn Sie mit Baugruppen gut genug umgehen können, erhalten Sie möglicherweise genügend Zugriff, um zu verstehen, was gerade passiert, und können sogar Änderungen vornehmen ... Um jedoch Ihre ursprüngliche Frage zu beantworten:

Sie können kompilierten Code nicht in den ursprünglichen Quellcode zurückverwandeln .

Es tut uns leid. Es handelt sich um eine Einwegtransformation, die Informationen (Kommentare, Formatierungen, lesbare Algorithmuskonzepte usw.) verliert, statisch mit anderen Dingen verknüpft und im Allgemeinen so optimiert ist, dass sie nur für die besten und erfahrensten Programmierer verständlich ist.

Um Ihnen einen Überblick über das Ausmaß des Problems zu geben, verfügt die gesamte Idee der Reverse Engineering-Software über eine eigene Stack Exchange-Site .

Oli
quelle
Können Sie mir sagen, wie ich es zurückentwickle und die maximale Menge an Code zurückerhalte, da ich die Quelle verloren habe
Redchief
7
Siehe meine letzte Bearbeitung. Es gibt kein Zurück zur ursprünglichen Quelle. Mit viel Lernaufwand und viel Zeit können Sie möglicherweise den Quellcode basierend auf dem disassemblierten Assemblycode neu schreiben. In den meisten Fällen ist dies jedoch billiger (es sei denn, Ihre Zeit ist wertlos) und einfacher, ihn von Grund auf neu zu schreiben.
Oli
1
Um die maximale Codemenge zurückzugewinnen, müssen Sie die letzte Sicherung wiederherstellen. Dies ist im Übrigen auch die einzige Möglichkeit, etwas, das dem ursprünglichen Quellcode ähnelt, zuverlässig wiederherzustellen.
ein Lebenslauf vom
1
Ich bin mit dem letzten Absatz überhaupt nicht einverstanden, nur eine Randnotiz: Einige Dekompilierer von IME leisten hervorragende Arbeit bei der Wiederherstellung der genauen Codestruktur (abgesehen von den Kommentaren, der Formatierung, den Namen der Symbole ...). Wenn Sie das Programm nicht an erster Stelle geschrieben haben, ist der wiederhergestellte Quellcode möglicherweise immer noch unverständlich. Ich denke jedoch, dass dies eine großartige Option ist, um (zumindest teilweise) einen verlorenen Quellcode / einen unbekannten Quellcode (mit zumindest Teilen davon) wiederherzustellen tatsächlich verständlich, abhängig vom spezifischen Code und davon, ob Sie auch Glück haben)
kos
1
All diese EULAs in der proprietären Software-Welt sagen, dass Sie dies nicht tun dürfen - Reverse Engineering / Disassemblierung. Sie enthalten Klauseln wie diese, weil es möglich ist - aber sicherlich nicht einfach! Aber wie @ MichaelKjörling sagt, ist die einzige gute Möglichkeit, Dinge zurückzubekommen, die auf mehreren Sicherungsebenen für alles liegen, was Ihnen wichtig ist.
Joe
7

Ich habe nicht genug Rufpunkte für einen Kommentar, daher ist dies eine Antwort:

Nein, es ist nicht möglich, es "zurück" zu konvertieren. Sie erwähnen upx packer, haben Sie jemals das Handbuch von upx gelesen?

Wenn Sie die Quelle verloren haben oder keinen Zugriff auf den Code einer anderen Person haben, ist dies einfach nicht möglich.

Die ausführbare Binärdatei wurde mit einem Compiler erstellt. Glauben Sie nichts, was auf dieser Site angegeben ist. Lesen Sie einfach das Handbuch dieses Compilers. Dann können Sie hier hinzufügen, in welcher Sprache der Originalcode geschrieben wurde, welcher Compiler verwendet wurde, und sich dann selbst merken, dass diese Schritte (Vorverarbeitung, Kompilieren, Verknüpfen, möglicherweise Packen) nicht als Ganzes umgekehrt sind, sondern nur analysiert werden, was der ursprüngliche Autor beabsichtigt haben könnte, und geschrieben.

justabot
quelle
3

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.

kos
quelle
2

Ausführbare Dateien sind normalerweise binär, wenn es sich um kompilierte Programme handelt. Weitere Informationen finden Sie unter file path/to/executable. Sie können ausführbare Binärdateien hexadezimal anzeigen, indem Sie z. B. verwenden hexdump -C path/to/executable | less(was auch immer Sie tun würden). Wenn Sie es "wieder in seine ursprüngliche Form konvertieren" möchten, müssen Sie einen entsprechenden Dekompiler verwenden, siehe diesen Beitrag. Dies würde jedoch zu einem unlesbaren Code führen, der nicht dem Original entspricht, aus dem es kompiliert wurde. Wenn es sich nicht um eine kompilierte Binärdatei handelt, handelt es sich um eine Art ausführbares Skript, das in jedem Texteditor leicht lesbar sein sollte. Was Sie uns hier gezeigt haben, ist wahrscheinlich eine kompilierte ausführbare Datei. ELF bedeutet "Ausführbares und Verknüpfendes Format", ein auf Linux / Unix-Systemen gebräuchliches Binärformat. Dort'strings path/to/executable, wenn du das brauchst.

Hinz
quelle
Ich habe versucht, es mit upx packer zurückzuentwickeln, aber es hat nicht funktioniert und auch nicht mit dem Post, den Sie vorgeschlagen haben. Also sag mir bitte, ob es einen anderen Weg gibt.
Redchief
Es tut mir sehr leid, aber ich kann Ihnen nichts weiter sagen als das, was in @ Olis ausgezeichnetem Beitrag geschrieben steht.
Hinz