Das Geheimnis der Binärdateien

Das Geheimnis der Binärdateien

Hier geht es um Dateien direkt aus dem Compiler, beispielsweise g++, und das -oFlag (outfile).

Wenn sie binär sind, sollten sie dann nicht einfach aus einer Reihe von Nullen und Einsen bestehen?

Beim Caten erhalten Sie eine unverständliche Ausgabe, aber auch vollständige Wörter.

Wenn Sie sie ablegen, erhalten Sie sofort die Antwort - es scheint keine Berechnung zu geben. Haben die Binärdateien tatsächlich Header mit solchen Informationen?

Ich dachte, eine binäre ausführbare Datei wäre einfach das gerade kompilierte Programm, nur in Form von Maschinenanweisungen, die Ihre CPU sofort und eindeutig verstehen kann. Wenn ja, ist dieser Befehlssatz dann nicht einfach nur Bitmuster? Aber was ist dann all das andere Zeug in den Binärdateien? Wie zeigen Sie die Bits an?

Und wenn Sie irgendwie an das Handbuch Ihres Prozessors kommen, könnten Sie dann eine Binärdatei manuell schreiben, einen Maschinenbefehl nach dem anderen? Das wäre schrecklich ineffektiv, abersehrfaszinierend, wenn Sie es sogar für eine „Hallo Welt!“-Demo zum Laufen gebracht haben.

Antwort1

Diese Super User-Frage:Warum wird kein Binärcode angezeigt, wenn Sie eine Binärdatei mit einem Texteditor öffnen?geht ganz gut auf Ihren ersten Punkt ein.

Binäre und Textdaten werden nicht getrennt: Es sind einfach Daten. Es hängt von der Interpretation ab, ob sie das eine oder das andere sind. Wenn Sie binäre Daten (z. B. eine Bilddatei) in einem Texteditor öffnen, ergeben viele davon keinen Sinn, weil sie nicht zu Ihrer gewählten Interpretation (als Text) passen.

Dateien werden als Nullen und Einsen gespeichert (z. B. Spannung/keine Spannung im Speicher, Magnetisierung/keine Magnetisierung auf der Festplatte). Sie sehen keine Nullen und Einsen, wenn Sie catdie Dateien durchsuchen, da die 0/1-Sequenzen für einen Menschen nicht viel nützen; Buchstaben sind sinnvoller und ein Hexdump ist für die meisten Zwecke besser (versuchen Sie es hexdumpmit einer Datei).

Ausführbare Dateienhabe einen Headerdas Parameter beschreibt, wie etwa die Architektur, für die das Programm erstellt wurde, und welche Abschnitte der Datei Code und Daten sind. Dies wird fileverwendet, um die Eigenschaften Ihrer Binärdatei zu identifizieren.

Und schließlich: Ja, Sie können Programme in Assemblersprache schreiben und dabei CPU-Opcodes direkt verwenden. Schauen Sie sich an:Einführung in die UNIX-Assemblerprogrammierungund dasIntel x86-Dokumentationfür einen Ausgangspunkt.

Antwort2

Alle Dateien werden als Einsen und Nullen gespeichert. Cat versucht, jedes BYTE (8 Bit) als Zeichen zu interpretieren. Deshalb werden Ihnen die unverständlichen Zeichen angezeigt.

Antwort3

Im Grunde sind alle Dateien binär: Sie werden als eine Folge vonGebisse.

Die einzelnen Dateien sind inBytes. Jede Datei besteht aus einer ganzen Zahl von Bytes. Alle Unix-Systeme und eigentlich fast alle Computer haben Bytes, die aus 8 Bits bestehen (bekannt alsOktettein der Netzwerkterminologie). Es gibt eine natürliche Möglichkeit, Bytes als 8-Bit-Zahlen zu interpretieren, also Zahlen zwischen 0 und 2 8 -1 = 255.

Um sie als Binärzahlen zu sehen, benötigen Sie ein Tool, das sie in Binärnotation ausgibt. Menschen sind für die Binärnotation nicht gut geeignet: Es dauert viel zu lange, etwas zu schreiben. Üblicher ist die Verwendung vonhexadezimalNotation mit 16 verschiedenen Ziffern. Beispielsweise 41ist (sechsundfünfzig in Hexadezimal) angenehmer zu lesen als 01000001(sechsundfünfzig in Binär). Sie können einen Befehl wieod(„Oktaldump“) oder hexdumpoder hdzum Auflisten einer Datei mit oktaler oder hexadezimaler Notation für jedes Byte ( od -t x1wechselt zu hexadezimal).

Bytes können Zeichen darstellen. Es gibt mehrereZeichenkodierungenin der Unix-Welt verwendet. Sie basieren alle aufASCII, das die Interpretation von Bytes zwischen 0 und 127 definiert. Beachten Sie, dass dies nur für die Hälfte der möglichen Bytewerte eine Bedeutung definiert. Beispielsweise steht 65 für den Großbuchstaben A, 97 für den Kleinbuchstaben a, 30 für die Ziffer 0usw. Einige Zeichenkodierungen stellen jedes Zeichen durch ein Byte dar; beispielsweise inLatein-1Kodierung, 163 steht für £, 241 steht für ñund so weiter. Die maximale Anzahl von Zeichen, die man auf diese Weise darstellen kann, ist 256, was nicht viel ist; daher gibt es andere Kodierungen, die mehr als ein Byte pro Zeichen verwenden. Die De-facto-Standardkodierung in der Unix-Welt ist heutzutageUTF-8, eine Kodierung mit variabler Länge (unterschiedliche Zeichen belegen unterschiedliche Byte-Anzahlen) für dieUnicode-Zeichensatz.

Eine Textdatei ist eine Binärdatei, die zufällig verständlichen Text enthält. Tatsächlich ist eine Datei für Unix-Programme eine Textdatei, solange sie zwei Bedingungen erfüllt:

  • Eine Textdatei darf kein Null-Byte (ein Byte mit dem numerischen Wert 0) enthalten. Dieses Byte stellt kein Zeichen dar und wird intern in vielen Textbearbeitungsprogrammen als spezielle Markierung verwendet.
  • Eine Textdatei besteht aus einer Folge von Zeilen und jede Zeile wird durch einNeue ZeileZeichen (das den numerischen Wert 10 hat).

Maschinen-Ausführbare Dateien sind eine besondere Art von Binärdateien. Wenn Sie den catBefehl auf ihnen ausführen, sehen Sie Müll mit gelegentlichen Textstücken. Diese Dateien können zufällig auch Befehle für Ihr Terminal enthalten. Sie können das Programm verwenden, stringsum alle Textfragmente in einer Binärdatei anzuzeigen und die nicht druckbaren Zeichen wegzulassen.

Maschinen-Ausführbare Dateien sind nicht genau genommen eine Folge von Maschinenanweisungen: Sie enthalten auch ein paar zusätzliche Informationen, die dem Betriebssystem sagen, wie die Datei in den Speicher geladen werden soll, normalerweise auch einige vom Programm verwendete Daten und optional Debuginformationen. Die meisten Unix-Systeme verwenden dieELFFormat für Maschinen-Ausführdateien. Dieses Format gibt an, wie eine Datei mit Maschinencode in Abschnitte unterteilt wird. Dieser Teil ist unabhängig von der Maschinenarchitektur. Einige Abschnitte enthalten Code, und die Bedeutung dieses Codes ist spezifisch für eine bestimmte Maschinenarchitektur.

Mit dem folgenden Befehl können Sie objdump -D /path/to/machine-executableeine Auflistung der ausführbaren Datei in einer für Menschen lesbaren Form anzeigen:Assemblersprache. Nun, für einen geschulten Menschen jedenfalls lesbar. Assemblersprache ist spezifisch für eine Prozessorarchitektur und wird direkt auf Maschinenanweisungen abgebildet.

Es ist möglich, ein komplettes Programm in Assemblersprache zu schreiben, aber das wird bei nicht-trivialen Programmen selten gemacht, weil es zu lange dauert. Wenn Sie wirklich verrückt sind, schreiben Sie Ihr Programm vielleicht direkt in Binärform. Einige Leute haben versucht, diekürzestmögliches Programm, das drucktHello world; Ryan Henszey erklärt, wie man einen142-Byte-ELF-ausführbare Datei für PC-Prozessoren; Brian Raiteranalysierte das ELF-Format und entwickelte ein 45-Byte-Programmdas Linux ausführen möchte (das Programm druckt nichts aus).

Es gibt auch ausführbare Dateien, die keine Binärdateien sind. Sie werden genanntSkripte. Und umgekehrt gibt es viele Binärdateien, die nicht ausführbar sind: Bilder, Videos, komprimierte Dateien, Textverarbeitungsdokumente, Codebibliotheken ohneEinstiegspunkt, ausführbare Dateien für andere Prozessorarchitekturen, …

verwandte Informationen