binutils eine 1:1 reverse engineering Methode?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Joe58
Beiträge: 211
Registriert: 10.06.2014 17:14:29

binutils eine 1:1 reverse engineering Methode?

Beitrag von Joe58 » 23.09.2017 21:37:13

Hallo,

vorab: die Frage ist für mich sehr relevant.

Wenn ich beispielsweise aus einer EEPROM die Software also den Maschinencode auslese von meinem Computer's BIOS, den dann mit x86 in Assembler übersetze, erhalte ich dann funktionsfähigen Assembler Code??

Also eine 1:1 also Maschinencode zu Assembler Code?

Mir geht es nicht um den Quellcode von höheren Programmiersprachen, sondern mir geht es um den Assemblercode, ist dieser wieder verwendbar?

Was ist wenn ich den armv7 Maschinencode von meinem Tablet nehme, alles ohne Header und diesen an meinem Computer disassemble, also in Assembler Code übersetze.

Ist mein Computer in der Lage die Prozessor Befehle korrekt zu übersetzen also zu bestimmen, oder macht der da auch ab und zu Fehler?

Danke, denke auf der Frage müsste es eine Antwort geben.

MfG

Joe

cosmac
Beiträge: 4562
Registriert: 28.03.2005 22:24:30

Re: binutils eine 1:1 reverse engineering Methode?

Beitrag von cosmac » 24.09.2017 14:53:24

Joe58 hat geschrieben: ↑ zum Beitrag ↑
23.09.2017 21:37:13
Wenn ich beispielsweise aus einer EEPROM die Software also den Maschinencode auslese von meinem Computer's BIOS, den dann mit x86 in Assembler übersetze, erhalte ich dann funktionsfähigen Assembler Code??
Im Prinzip ja. Wahrscheinlich musst du die Formatierung von Hand anpassen, z.B. gibt objdump normalerweise eine Spalte mit den Adressen aus. Aber die eigentlichen Maschinenbefehle sind eindeutig -- wenn du das richtige objdump benutzt und das den genauen CPU-Typ kennt. Kann man den bei einem Tablett mit ARM rausfinden?

Dann musst du wissen, welches der erste Befehl ist. Maschinenbefehle sind ja unterschiedlich lang und objdump kann nicht erkennen, welches das erste Byte eines Befehls ist. Bei vollständigem Code aus einem ROM kennt man hoffentlich die erste Adresse nach einem Reset (muss ja nicht die physikalisch erste sein), dann ist es einfach.

ABER: Am Ende einer Funktion können Daten stehen. Deswegen kann objdump den Anfang der nächsten Funktion nicht ohne weiteres finden. Im schlimmsten Fall müsste man den Hexcode von Hand in einzelne Funktionen zerlegen -- keine Ahnung, wie das einfacher geht. In einer elf-Datei kann eine Symboltabelle mit diesen Adressen stehen, damit geht es gut. Aber im ROM wird es keine geben.
Ist mein Computer in der Lage die Prozessor Befehle korrekt zu übersetzen also zu bestimmen, oder macht der da auch ab und zu Fehler?
Bei den einzelnen Befehlen wird er keine Fehler machen, aber siehe oben... Probier's einfach, seit gestern gibt's ja wieder lange Winterabende ;)
Beware of programmers who carry screwdrivers.

Korodny
Beiträge: 306
Registriert: 09.09.2014 18:33:22
Lizenz eigener Beiträge: GNU Free Documentation License

Re: binutils eine 1:1 reverse engineering Methode?

Beitrag von Korodny » 24.09.2017 16:37:43

Joe58 hat geschrieben: ↑ zum Beitrag ↑
23.09.2017 21:37:13
Wenn ich beispielsweise aus einer EEPROM die Software also den Maschinencode auslese von meinem Computer's BIOS, den dann mit x86 in Assembler übersetze, erhalte ich dann funktionsfähigen Assembler Code??
Funktionsfähig schon - unter gewissen Voraussetzungen, das hat cosmac ja sehr anschaulich erklärt. Wie lesbar bzw. wartungsfreundlich dieser Code ist, ist aber eine andere Frage. Speziell wenn er ursprünglich in einer Hochsprache geschrieben wurde - Compiler generieren anderen Maschinencode als Menschen das tun würden.
Was ist wenn ich den armv7 Maschinencode von meinem Tablet nehme, alles ohne Header und diesen an meinem Computer disassemble, also in Assembler Code übersetze.
Wenn du mit "armv7 Maschinencode von meinem Tablet" das Betriebssystem meinst - vergiss es. Das mag theoretisch machbar sein, automatisisert kann das aber nicht funktionieren, da müsste ein erfahrener Assembler-Programmierer den automatisch generierten Output wochenlang überprüfen und korrigieren: Wo beginnt Code, wo liegen Datenstrukturen? Nachladen externer Bibliotheken? Komprimierte Datenstrukturen? usw.

cosmac
Beiträge: 4562
Registriert: 28.03.2005 22:24:30

Re: binutils eine 1:1 reverse engineering Methode?

Beitrag von cosmac » 24.09.2017 18:55:27

Hmm, Tablet mit Android? Dafür müsste man doch den Quelltext bekommen. Das würde die Sache ein wenig erleichtern ;) Die Linux-Quellen in C sind stellenweise recht gut verständlich.
Beware of programmers who carry screwdrivers.

Joe58
Beiträge: 211
Registriert: 10.06.2014 17:14:29

Re: binutils eine 1:1 reverse engineering Methode?

Beitrag von Joe58 » 24.09.2017 18:59:45

Danke für eure sehr hilfreichen Antworten.

@cosmac

Ja den Typ der CPU kann ich anhand des Bootloader Maschinencodes herausfinden. Denke mit objdump werde ich nicht weit kommen. Obj = Objektdateien? D.h. diese haben einen Header/Kopf mein Bare Metal Code hat ja keinen Kopf werde denke objdump nicht benutzen können, oder ist der Kopf irrelevant?

Ich kenne die Startadresse 0x0000 dort fängt mein Tablet an den Code zu benutzen. Ist Nand Chip oder die MicroSDKarte also Startpunkt ist 0x0 in den ersten 512 Bytes Sektor.

Mein Tablet hat einen 32-Bit Prozesor d.h. die Befehle sind normalerweise 32 Einheiten/Bits lang? Gibt es Ausnahmen? Ob der von links nach rechts oder andersherum liest ist auch noch fraglich.
Im schlimmsten Fall müsste man den Hexcode von Hand in einzelne Funktionen zerlegen -- keine Ahnung, wie das einfacher geht. In einer elf-Datei kann eine Symboltabelle mit diesen Adressen stehen, damit geht es gut. Aber im ROM wird es keine geben.
Okay manuell könnte man das wie machen? Armv7 müsste eine Art Tabelle haben, wo steht welche Nullen und Einsen welchen Befehl darstellen. Der ROM Code bzw. der Bootloader Code meines Tablets hat keinen ELF Kopf, Bare Metal, ja das stimmt. ;)

Ja Winter ist PC Zeit, da lohnt es wieder Projekte ans laufen zu bringen.

@Korodny

Wichtig ist das der Assembler Code funktioniert, wäre auch nicht schlimm wenn ich erst anhand der ersten 32 Bit des Codes herausfinde wierum die CPU liest und diesn dann wieder von Assembler durch den Compiler schicke und das Ergebnis ein 32 Bit Befehl ist was 1:1 wie die 1. 32 Bit meines Codes bei 0x0 ist.

Der eigentliche Code ist ein paar KB lang, der Rest was beides in Summe 14 KB ergibt, ist ein großer UCL Decompressor. Der Code des Decompressors wird nicht benötigt, außer funktionsfähig damit ich bei 0x8000 den eigentlichen 2. Bootloader entpacken kann. :) Das Entpackte werde ich dann entpackt wieder flashen ohne UCL damit ist U-Boot der 2. Bootloader überhaupt erst modifizierbar, weil bisher geht das null. U-Boot benutzt Umgebungsvariablen und damit kann ich dann etwas anfangen.

Das Betriebssystem zu disassembilieren, oha ja das wird Jahre dauern, ich habe wie bereits gesagt in diesem Beitrag nur vor den Bootloader zurück zu disassembilieren der mehr oder weniger groß als 14 KB ist, weil dort UCL Dekompressor drin ist. Dies alles wird gefolgt von einen 2. Bootloader U-Boot bei 0x8000 der komprimiert und nicht modifiziert werden kann, das wäre sehr toll wenn das ginge. ;)

Der Code ist hier: https://www.dropbox.com/s/rwfuw371iebv0 ... r.img?dl=0

Nur 269 KB des Codes sind Code der Rest sind nachfolgende Nullen und F's weil das ein Speicher dump oder wie das heißt ist. ;)

cosmac
Beiträge: 4562
Registriert: 28.03.2005 22:24:30

Re: binutils eine 1:1 reverse engineering Methode?

Beitrag von cosmac » 24.09.2017 22:50:54

Joe58 hat geschrieben: ↑ zum Beitrag ↑
24.09.2017 18:59:45
Denke mit objdump werde ich nicht weit kommen. Obj = Objektdateien? D.h. diese haben einen Header/Kopf mein Bare Metal Code hat ja keinen Kopf werde denke objdump nicht benutzen können, oder ist der Kopf irrelevant?
Obj=Objektdateien, das stimmt. Für reine binär-Daten kennt objdump die Option --target=binary. Na klar wäre es mit Header (und vor allem mit Symboltabelle) einfacher, aber Maschinen-Code bleibt Maschinen-Code, also grundsätzlich geht es trotzdem.
Mein Tablet hat einen 32-Bit Prozesor d.h. die Befehle sind normalerweise 32 Einheiten/Bits lang? Gibt es Ausnahmen?
ARM kennt auch 16-Bit-Befehle und Daten könnten beliebig lang sein. Aber selbst wenn alles exakt 32 Bit breit ist, kann ein Befehl mehr als ein 32-Bit Wort haben und am Ende einer Funktion können beliebig viele 32-Bit Datenworte stehen. Man muss sich also immer ab einer Startadresse an den Befehlen "entlang hangeln".
Ob der von links nach rechts oder andersherum liest ist auch noch fraglich.
Das weiß objdump wenn du ihm den richtigen CPU-Typ sagst. ARM kennt allerdings eine echte Gemeinheit: manche CPUs können die Richtung umschalten und wenn das dynamisch passiert... Ich hoffe, das betrifft "nur" Datenworte.
Im schlimmsten Fall müsste man den Hexcode von Hand in einzelne Funktionen zerlegen
Okay manuell könnte man das wie machen?
Im Prinzip ganz einfach. Zum Beispiel wird in den ersten zurück übersetzten Befehlen irgendein Unterprogramm an einer bestimmten Adresse aufgerufen. Dann weißt du, an dieser Adresse muss ein Befehl stehen und ab da kann man wieder Befehle dekodieren. Kleine Schikane: es muss nicht unbedingt der erste in dem Unterprogramm sein.
Armv7 müsste eine Art Tabelle haben, wo steht welche Nullen und Einsen welchen Befehl darstellen.
Natürlich, die muss in objdump eingebaut sein (bzw. in einer lib).
Der Code des Decompressors wird nicht benötigt, außer funktionsfähig damit ich bei 0x8000 den eigentlichen 2. Bootloader entpacken kann. :)
Kannst du den nicht auf dem PC mit einem PC-Programm entpacken?
Beware of programmers who carry screwdrivers.

Joe58
Beiträge: 211
Registriert: 10.06.2014 17:14:29

Re: binutils eine 1:1 reverse engineering Methode?

Beitrag von Joe58 » 25.09.2017 14:51:51

Hallo

@cosmac Danke für deine Antworten zunächst. Es sind nur ein paar Details die ich noch nicht kenne. Ich bin in dem Gebiet der IT noch neu. Prozessor Programmierung.
Für reine binär-Daten kennt objdump die Option --target=binary.
Dies kannte ich noch nicht. ;)

Das ist gut das man sich ab einer Startadresse dann vorwärts arbeiten kann, dachte mein 32-Bit Prozessor wäre wegen den armv7 Befehlssatz die nur 32 Bit lang sein können ein 32 Bit Prozessor. ;) (klar auch wegen den 4 GB RAM adressierbaren Limit)
manche CPUs können die Richtung umschalten und wenn das dynamisch passiert... Ich hoffe, das betrifft "nur" Datenworte.
Ich hoffe ebenfalls das dies nicht bei dem armv7 Befehlssatz der Fall ist.
Im Prinzip ganz einfach. Zum Beispiel wird in den ersten zurück übersetzten Befehlen irgendein Unterprogramm an einer bestimmten Adresse aufgerufen.
Aha, das heißt der Bootloader Code von mir in der Dropbox kann durchaus auch erst nach 0000x0000 ausgeführt werden, sprich es sind durchaus auch einfach nur Befehle vorgeschaltet oder eigentlich Nullen, die garnicht ausgeführt werden, sondern den Platz füllen? Fake-Code? Die MBR Signatur am ende des ersten 512 Byte Sektor ist auch mit 2 Nullen also 16 Bit trotzdem startet das Tablet. D.h. fake MBR, aber nicht umbedingt die ganzen 512 Bytes?
Natürlich, die muss in objdump eingebaut sein (bzw. in einer lib).
Ein Glück, dann hat man ja eine gewisse Quelloffenheit und könnte sehen wie das excakt funktioniert und manuell disassembilieren. Werde das aber jedenfalls mit binutils oder objdump machen.
Kannst du den nicht auf dem PC mit einem PC-Programm entpacken?
Ich denke das es sich bei 0x8000 um kein .zip oder ein anderes Archiv handelt, evtl handelt es sich um so ein Archiv aber ohne Kopf??

UCL soll oben im Bootloader bei 0x0000 und nachfolgend bis zu den cut von Nullen irgendwo sein. Ich habe in den 0x8000 Code Kabelsalat Code nachgeguckt und Strings in komischer Schreibweise gesehen. Ich frage mich, wo ist das richtige Entpackprogramm? Ist anscheinend nur in dem Bootloader vor dem 0x8000 Bootloader drin? Und der funktioniert nur über ARMv7.

Habe den Bootloader 1 und den Bootloader 2 in Aktion gesehen über serielle Konsole und die Ausgaben/Strings der Programme gesehen. Deswegen weiß ich was in 0x8000 für Strings vorkommen.

Antworten