Kann jeder Code in kompilierter Sprache zeilenweise auf einzelne Bits jedes CPU-Befehls binär zurückverfolgt werden?

506
bertieb

Ich erkenne, dass wir äquivalente Assemblys aus C ++ - Code mit vielen Debugger und dergleichen ausgeben können.

Aber was ist mit Binärcode? Die Formatierung der Bits in jedem Byte bzw. den Bytes, aus denen sich die eigentlichen Maschinenbefehle zusammensetzen, aus denen (möglicherweise) die Mikroprogramme bestehen (falls die Mikroarchitektur eines hat).

Wenn jede Zeile des C ++ - Codes auf irgendeine Weise und irgendwann im Programm in Maschinencode konvertiert werden muss (z. B. kann ein Float in C ++ definiert werden, hat jedoch keine Verwendung, bis er auf den Stack verschoben wird. Daher kann 1 nicht konvertiert werden: 1 für den gesamten Maschinencode, Zeile für Zeile, wird jedoch unabhängig davon verwendet), jede Anweisung usw. kann verfolgt werden. Debugger geben jedoch nicht die Bildung von Bits aus, die die einzelnen Befehle besetzen.

Wenn für jedes Programm Byte- / Bitmusterbefehle für die CPU formatiert werden, muss es möglich sein (ich gehe davon aus), dass Sie den gesamten Code, den Sie schreiben, auf die eigentlichen Bits auf Schaltungsebene zurückverfolgen können.

Aber für die vollste Sicherheit möglich, ist es möglich, dies in dem Maße zu tun, ich bin hier zu beschreiben? Moderne Debugger / Software bieten diese Funktion nicht an, und selbst diejenigen, die scheinbar nicht die gesamte binäre Darstellung jedes Befehls für den Entwickler offenlegen.

PS: Dies setzt natürlich voraus, dass der kompilierte Code leicht mit Anweisungen für die beabsichtigte Architektur ausführbar ist (und nicht für eine interpretierte Sprache oder Bytecode, der ein anderes Programm benötigt, um ihn weiter zu übersetzen).

0

2 Antworten auf die Frage

1
luser droog

Sie können einen Disassembler verwenden, um den kompilierten Binärcode zurück in die Assembler-Sprache zu konvertieren. Das würde Ihnen erlauben, (nur mit Schwierigkeiten) Software zu lesen, die nur in Binärdateien verteilt ist.

Für den anderen Teil Ihrer Frage scheinen Sie eine Art Hardware-Dekompiler zu haben, der detailliertere Informationen darüber enthält, wie die CPU eine bestimmte binäre Anweisung ausführt. Ich kenne kein Werkzeug, um dies zu tun. Sie müssen wahrscheinlich die Hardware-Handbücher lesen und diese Art von Analyse in Ihrem Kopf durchführen.

1
Darth Android

Nein.

Nun, vielleicht, aber es gibt keine Garantie, da der Code, der in den Compiler eingegeben wird, aus zwei Gründen selten identisch ist mit dem Code, der ausgegeben wird: Menschen sind beim Schreiben von effizientem Code schrecklich, und Menschen denken nicht über Code auf dieselbe Weise nach dass eine CPU es verarbeiten muss. Aus diesem Grund optimieren Compiler den Quellcode, bevor sie ihn in Assembly / Binary konvertieren. Dies kann dazu führen, dass Anweisungen neu angeordnet werden, unbrauchbare Anweisungen entfernt und ganze Funktionen eingebettet werden .

Geben Sie beispielsweise den folgenden Pseudocode an:

int x = 3; x = 3*3; x = 4; function mult4(number) { return number * 4; } x = mult4(x); 

kann vollständig auf reduziert werden

int x = 16; 

durch einen guten Optimierungscompiler, der der Quelle überhaupt nicht entspricht. Aus diesem Grund müssen Sie beim Debuggen häufig Compiler-Optimierungen deaktivieren. Wenn alle Compiler-Optimierungen deaktiviert sind, versucht der Compiler, Assembly auszugeben, die dem Quellcode 1-für-1 entspricht.

Ich stimme nicht zu, dass es "der Quelle überhaupt nicht entspricht". In der Tat entspricht es * perfekt * der Quelle. David Schwartz vor 10 Jahren 0
Ich würde sagen, die semantische Bedeutung entspricht perfekt, aber nicht die wörtliche, genaue Bedeutung. Darth Android vor 10 Jahren 1