Kurs:Wie funktioniert eigentlich ein Computer/Tage/Tag1
Zurück zur Übersicht
Tag 1 - Freitag, 28.06.2013
BearbeitenAufgabe 1 - Thema : Unterschiedliche Ausgabe bei gleicher Dateigröße
BearbeitenAufgabenstellung
BearbeitenErstellen von zwei Programmen, die identisch sind bis auf die Ausgabe. Bei einem Programm wird noch ein Ausrufezeichen zusätzlich ausgegeben:
hello.c
#include<stdio.h>
int main()
{
printf("Hallo Welt");
}
hello2.c
#include<stdio.h>
int main()
{
printf("Hallo Welt!");
}
Wenn man die Größe der kompilierten Dateien vergleicht, sieht man dass sie beide 5137 Bytes groß sind, obwohl sie eine andere Ausgabe haben:
Dies liegt daran, dass der Befehl
printf()
beim Aufruf einen bestimmten Speicherbereich reserviert. Fügen wir nun das Ausrufezeichen zum auszugebenden Text hinzu, wird dieser in den zuvor leeren, aber reservierten Bereich geschrieben.
Ist es dann möglich die Ausgabe des Programm zu verändern nachdem es kompiliert wurde?
Lösung
BearbeitenZuerst öffnen wir die beiden kompilierten Dateien mit Emacs im Hexl-Mode.
Hinweis: Um in Emacs in die Hexadezimal-Anzeige zu kommen, muss man M-X drücken und dann "hexl-mode" eingeben. Im Hexl-Mode wird in der ersten Spalte die Zeilennummerierung in Hexadezimal-Schreibweise angezeigt. In den mittleren 8 Spalten sind ist Inhalt des Programms in Hexadezimal-Schreibweise und in der rechten Spalte als ASCII-Code interpretiert.
In dem Programm, das das Ausrufezeichen ausgibt suchen wir nach einer 2116. In der ASCII-Tabelle entspricht das einem Ausrufezeichen. Es gibt nur wenige Ergebnisse und wir nehmen die Stelle wo in der rechten Spalte "Hallo Welt!" steht. Parallel (im der anderen Datei) wird die selbe Stelle anhand der Zeilennummer gesucht.
Man kann erkennen, dass anstelle der 2116 hier eine 0016 steht. Diese Stelle ist also der Grund für die unterschiedliche Ausgabe. Wir können also an diese Stelle ein beliebiges Zeichen der ASCII-Tabelle in hexadezimaler Schreibweise setzen, wodurch sich die Ausgabe dementsprechend verändert.
Aufgabe 2 - Thema : Finden eines Additionsbefehls im kompilierten Programm
BearbeitenAufgabenstellung
BearbeitenWir haben ein Programm, welches zwei Zahlen miteinander addiert. Nun wollen wir herausfinden, an welcher Stelle der Befehl für die Addition im kompilierten Programm steht.
Lösungsansätze
BearbeitenUnsere Idee war es, zwei möglichst einfache Programme zu schreiben. Der einzige Unterschied sollte sein, dass das eine Programm 2 Zahlen addiert und das andere die gleichen Zahlen subtrahiert. Im Quellcode können wir den Unterschied sehen, nun wollen wir wissen, wo in der "Maschienensprache" der Unterschied liegt. Da es uns nicht möglich war, den binären Code zu verändern und dieses auch zu unübersichtlich gewesen wäre fiel diese Option weg. Dann wollten wir uns die Hexadezimalcodes der beiden Programme 'anschauen', vergleichen und so den Unterschied -also die Stelle, an der die beiden Zahlen verrechnet werden- finden.
Beispiellösung
BearbeitenZu den Beispiellösungen:
- Alle Befehle für Ubuntu bzw. Emacs werden mit'-->' gekennzeichnet.
1. Schreibe zwei Programme , 'plus.c' [1] und 'minus.c' . 2. Beide Programme kompilieren.
- --> gcc 'plus.c' -o 'plus'
- --> gcc 'minus.c' -o 'minus'
3. --> Objdump -d 'plus' > 'plusausgabe' [2]
- --> Objdump -d 'minus' > 'minusausgabe'
4. --> diff 'plusausgabe' 'minusausgabe' [3]
- Alternative: --> diff -y 'plusausgabe' 'minusaugabe' > 'vergleich' [4]
Fußnoten:
- ↑ Alle Namen die in einfachen Anführungsstrichen stehen sind beliebig wählbar
- ↑ Dieser Befehl zeigt das Programm in den einelnen Hexadezimalcodes und die jeweiligen Opcodes an.
- ↑ Dieser Befehl gibt einem den genauen Unterschied mit Zeilen angabe aus.
- ↑ Dieser Befehl erzeugt eine neue Datei ( in diesem Fall namens 'vergleich') in der die beiden Programme 'plusausgabe' und 'minusausgabe' nebeneinander gestellt werden und verglichen werden können. Die Datei kann einfach mit emacs geöffnet werden