Geheimnis der Binärdateien

7

Hier geht es um Dateien direkt vom Compiler, z. B. g ++, und das -oFlag (outfile).

Wenn sie binär sind, sollten sie nicht einfach ein Bündel von Nullen und Einsen sein?

Wenn Sie sie katzen, erhalten Sie unverständliche Ausgaben, aber auch intakte Wörter.

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

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

Wenn Sie irgendwie auf das Handbuch Ihres Prozessors zugreifen, können Sie dann manuell eine Binärdatei schreiben, jeweils eine Maschinenanweisung? Das wäre furchtbar ineffektiv, aber sehr faszinierend, wenn Sie es auch für eine "Hallo Welt!" Demo.

Emanuel Berg
quelle
2
Der entscheidende Punkt ist, dass sich jede 1 und jede 0 in der Phrase "Es sind nur Einsen und Nullen" auf Bits bezieht , nicht auf Bytes . In der Regel präsentieren Programme Text / Daten byteweise. Sogar diese 1 und diese 0 sind eine Darstellung eines 8-Bit-Bytes, das die zugrunde liegenden wahren Einsen und Nullen enthält.
Peter.O
2
Sie können die Bits mit bekommen xxd -b file.
Emanuel Berg

Antworten:

16

Diese Super User-Frage: Warum wird beim Öffnen einer Binärdatei mit Texteditor kein Binärcode angezeigt? spricht Ihren ersten Punkt ganz gut an.

Binär- und Textdaten werden nicht getrennt: Es handelt sich lediglich um Daten. Es hängt von der Interpretation ab, die sie zum einen oder anderen macht. Wenn Sie Binärdaten (z. B. eine Bilddatei) in einem Texteditor öffnen, ist vieles davon nicht sinnvoll, da es nicht zu Ihrer gewählten Interpretation (als Text) passt.

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 catSie die Dateien bearbeiten, da die 0/1-Sequenzen für einen Menschen nicht von großem Nutzen sind. Zeichen sind sinnvoller und ein Hexdump ist für die meisten Zwecke besser (probieren Sie hexdumpeine Datei aus).

Ausführbare Dateien haben einen Header , der Parameter wie die Architektur beschreibt, 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.

Zum Schluss: Ja, Sie können Programme in Assemblersprache direkt mit CPU-Opcodes schreiben. Schauen Sie sich zunächst die Einführung in die UNIX-Assembly-Programmierung und die Intel x86-Dokumentation an.

Renan
quelle
9

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

mikhailvs
quelle
4

Alle Dateien sind unter der Haube binär: Sie werden als Folge von Bits gespeichert .

Die Bits von Dateien sind tatsächlich in Bytes gruppiert . Jede Datei besteht aus einer ganzzahligen Anzahl von Bytes. Alle Unix-Systeme und in der Tat fast alle Computer haben Bytes, die aus 8 Bits bestehen ( in der Netzwerkerminologie als Oktette bezeichnet ). Es gibt eine natürliche Möglichkeit, Bytes als 8-Bit-Zahlen zu interpretieren, dh Zahlen zwischen 0 und 2 8 -1 = 255.

Um sie als binär zu sehen, benötigen Sie ein Tool, das sie in binärer Notation schreibt. Menschen sind für die binäre Notation nicht gut geeignet: Es dauert viel zu lange, etwas zu schreiben. Es ist üblicher, die hexadezimale Notation mit 16 verschiedenen Ziffern zu verwenden. Zum Beispiel ist 41(fünfundsechzig hexadezimal) bequemer zu lesen als 01000001(fünfundsechzig binär). Sie können einen Befehl wie od("octal dump") oder hexdumpoder verwenden, hdum eine Datei mit oktaler oder hexadezimaler Notation für jedes Byte aufzulisten ( od -t x1wechselt zu hexadezimal).

Bytes können Zeichen darstellen. In der Unix-Welt werden verschiedene Zeichencodierungen verwendet. Sie basieren alle auf ASCII , das die Interpretation von Bytes zwischen 0 und 127 definiert. Beachten Sie, dass dies nur eine Bedeutung für die Hälfte der möglichen Bytewerte definiert. Zum Beispiel repräsentiert 65 den Großbuchstaben A, 97 den Kleinbuchstaben a, 30 die Ziffer 0und so weiter. Einige Zeichenkodierungen repräsentieren jedes Zeichen durch ein Byte; Beispielsweise repräsentiert in der Latin-1- Codierung 163 £, 241 repräsentiertñund so weiter. Die maximale Anzahl von Zeichen, die man auf diese Weise darstellen kann, beträgt 256, was nicht viel ist. Daher gibt es andere Codierungen, die mehr als ein Byte pro Zeichen verwenden. Die De-facto-Standardcodierung in der Unix-Welt ist heutzutage UTF-8 , eine Codierung variabler Länge (verschiedene Zeichen belegen unterschiedliche Anzahl von Bytes) für den Unicode-Zeichensatz .

Eine Textdatei ist eine Binärdatei, die verständlichen Text enthält. Tatsächlich ist eine Datei für Unix-Programme eine Textdatei, sofern zwei Bedingungen eingehalten werden:

  • Eine Textdatei darf kein Nullbyte enthalten (ein Byte mit dem numerischen Wert 0). 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 ein Zeilenumbruchzeichen (das den numerischen Wert 10 hat) abgeschlossen.

Maschinenausführbare Dateien sind eine bestimmte Art von Binärdatei. Wenn Sie den catBefehl auf ihnen ausführen , sehen Sie Müll mit gelegentlichem Text. Diese Dateien können zufällig auch Befehle für Ihr Terminal enthalten. Mit dem Programm können stringsSie alle Textfragmente in einer Binärdatei anzeigen, wobei die nicht druckbaren Zeichen weggelassen werden.

Die ausführbaren Dateien der Maschine sind nicht gerade eine Folge von Maschinenanweisungen: Sie enthalten auch einige zusätzliche Informationen, die dem Betriebssystem mitteilen, wie die Datei in den Speicher geladen werden soll, normalerweise auch einige vom Programm verwendete Daten, und optional Informationen debuggen. Die meisten Unix-Systeme verwenden das ELF- Format für ausführbare Maschinen. Dieses Format gibt an, wie eine Datei mit Maschinencode in Abschnitte unterteilt wird und dieser Teil unabhängig von der Maschinenarchitektur ist. Einige Abschnitte enthalten Code, und die Bedeutung dieses Codes ist spezifisch für eine bestimmte Maschinenarchitektur.

Mit dem Befehl können Sie objdump -D /path/to/machine-executableeine Liste der ausführbaren Datei in einer für Menschen lesbaren Form anzeigen: Assemblersprache . Na ja, für einen ausgebildeten Menschen sowieso lesbar. Die Assemblersprache ist spezifisch für eine Prozessorarchitektur und wird direkt den Maschinenanweisungen zugeordnet.

Es ist möglich, ein vollständiges Programm in Assemblersprache zu schreiben, dies wird jedoch bei nicht trivialen Programmen selten durchgeführt, da dies lange dauert. Wenn Sie wirklich verrückt sind, können Sie Ihr Programm direkt in Binärform schreiben. Einige Leute haben versucht, ein möglichst kurzes Programm zu entwickeln, das gedruckt wirdHello world . Ryan Henszey erklärt, wie eine 142-Byte-ELF-Datei geschrieben wird, die für PC-Prozessoren ausführbar ist . Brian Raiter analysierte das ELF-Format und entwickelte ein 45-Byte-Programm , das Linux ausführen möchte (dieses Programm gibt nichts aus).

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

Gilles 'SO - hör auf böse zu sein'
quelle