Forum: Mikrocontroller und Digitale Elektronik Verständnisproblem bei Disassemblierung


von Mike (Gast)


Lesenswert?

Hallo,

ich habe gerade ein kleines Disassemblierungsproblem. Vorweg, das Ganze 
ist vollkommen legal, es handelt sich um eine Aufgabe im Rahmen des 
Studiums.

Ich habe ein HEX-File, welches ich mit IDA disassembliert habe. Nun muss 
ich mich erstmal Stück für Stück dort durcharbeiten da an vielen Stellen 
nicht entschieden werden konnte, ob es sich um Daten oder um Code 
handelt.

Nun habe ich hier eine Funktion, in welcher Folgendes auftaucht:
1
ROM:00000E31    call    unk_41BD

Soweit ich das verstehe wird hier die Funktion unk_41BD aufgerufen, 
wobei der Bezeichner natürlich von IDA willkürlich gewählt wurde.

An der entsprechenden Adresse findet sich nun aber nur das:
1
ROM:000041BD    unk41_BD:    .byte 1

Davor und danach findet sich ebenfall über etliche Zeilen immer nur
1
ROM:0000vwxy    .byte 1

Für mich ergibt das ganze nun so überhaupt keinen Sinn da hier ja 
keinerlei ASM-Befehle zu finden sind. Kann mir da irgendjemand 
weiterhelfen, habe ich evt. etwas übersehen oder scheint das Programm 
hier tatsächlich (vom Programmierer beabsichtigt oder nicht) Murks zu 
machen?

von spess53 (Gast)


Lesenswert?

Hi

>Nun habe ich hier eine Funktion, in welcher Folgendes auftaucht:

>ROM:00000E31    call    unk_41BD

>Soweit ich das verstehe wird hier die Funktion unk_41BD aufgerufen,
>wobei der Bezeichner natürlich von IDA willkürlich gewählt wurde.

Ergibt denn die 'Umgebung' von 'ROM:00000E31    call    unk_41BD' 
sinnvollen Assemblercode? Wenn dort Daten stehen, dann ist natürlich die 
Übersetzung als 'call' schon falsch und an der Zieladresse muss kein 
Programmcode stehen.

Datenbereiche kann man eigentlich nur eindeutig als solche 
identifizieren, wenn illegale Op-Codes auftauchen.

MfG Spess

von Oliver (Gast)


Lesenswert?

Da wird der vermeintliche call auch schon in einem Datenblock gehören.

spess53 schrieb:
> Datenbereiche kann man eigentlich nur eindeutig als solche
> identifizieren, wenn illegale Op-Codes auftauchen.

oder wenn erkennbar da drüber ein ret o.ä. steht, und man erkennen kann, 
daß der Bereich danach nicht ausgeführt wird (fehlendes Label o.ä.).

oder wenn man im Code Bereiche hat, der Daten aus dem fraglichen Bereich 
lädt (ausser, es wäre selbstmodifizierender Code, aber der ist zum Glück 
selten geworden...)

Oliver

von spess53 (Gast)


Lesenswert?

Hi

>oder wenn erkennbar da drüber ein ret o.ä. steht, und man erkennen kann,
>daß der Bereich danach nicht ausgeführt wird (fehlendes Label o.ä.).

>oder wenn man im Code Bereiche hat, der Daten aus dem fraglichen Bereich
>lädt (ausser, es wäre selbstmodifizierender Code, aber der ist zum Glück
>selten geworden...)

Ich meinte eigentlich weniger ob 'man' das erkennt, sondern das es schon 
der Disassembler erkennt.

MfG

von Zorc (Gast)


Lesenswert?

Je nach Controller sind Befehle 2 byte lang und wenn der CodePointer um 
eins verschoben ist, kommt auch nur Mist raus.

von Karl H. (kbuchegg)


Lesenswert?

Du musst das so sehen.
Der Disassembler hat in erster Linie ein Assemblerlisting erzeugt, 
welches beim Assemblieren wieder dieses Hex-File generieren würde.
Ob er dabei alle Befehle auch tatsächlich richtig identifiziert hat, 
kannst du im Grunde nur endgültig dann sehen wenn du den Programmfluss 
verfolgst. Zum Beispiel, in dem du das mit einem Simulator in 
Einzelschritten durchsteppst. Erst da hast du dann die Gewissheit, dass 
jeder 'Befehl' den der Disassembler gebaut hat, auch tatsächlich einer 
ist.

Es gibt nämlich auch fiese Disassembler-Fallen, die bewusst eingebaut 
werden oder die sich aus der Funktionsweise von Subroutinen so ergeben, 
die vom Disassembler ohne aufwändige Logikanalysen nicht erkennbar sind, 
die ihn aber komplett aus dem Tritt bringen.
Ein einfacher Fall ist zb. das Einbetten eines einzelnen Bytes in den 
Code, über welches dann einfach drüber gesprungen wird. Dem Prozessor 
macht das nichts aus, aber der Disassembler wird dieses einzelne Byte 
als einen Befehl oder den Anfang eines Mehrbyte-Befehls ansehen und ab 
dort dann die Bytes völlig falsch interpretieren. Besonders fies ist es, 
wenn diese Befehlssequenz dann auch noch tatsächlich einen gültigen Code 
ergibt und vom Programm dann auch noch angesprungen wird. (Und in dem 
Fall zieh ich vor dem Programmierer meinen Hut, gleich nachdem ich ihn 
einen kranken Hund geschimpft habe. Angeblich gibt es in den 
Apollo-Programmen ein paar derartige Codestellen, die mit so einem 
Byteversatz arbeiten)

Das man ein Hex-File durch den Disassembler jagt und was Brauchbares 
rausbekommt, in dem man dann einfach nur noch ein paar Label-Namen 
anpasst, das ist leider eine Illusion.

von Heinz L. (ducttape)


Lesenswert?

Ich wußte ehrlich gesagt nicht dass IDA inzwischen AVR Hexfiles 
interpretieren kann.

Im Endeffekt ist der Call witzlos wenn Du nicht sicher weißt, dass das 
tatsächlich Code ist. Geh zum Programmstart und geh das Programm Schritt 
für Schritt durch. Check ob ein Bootloader installiert ist, geh zum 
dementsprechenden Programmstart und dann eben ab dafür.

von Jobst M. (jobstens-de)


Lesenswert?

Mike schrieb:
> ROM:0000vwxy    .byte 1

Sind das evtl. Adressen, die gar nicht im HEX-file auftauchen?
Dann ist der Zeiger darauf auch schon kein Code, sondern Daten. 
Eindeutig.


Gruß

Jobst

von Mike (Gast)


Lesenswert?

Hallo,

danke für eure Antworten. Mir ist klar, dass man sowas nicht einfach 
automatisiert irgendwo durchjagt und am Ende ein komplettes 
Programmlisting erhält.

Ich habe mich eigentlich manuell durch das Programm angefangen bei 
folgenden Zeilen:
1
ROM:00000000 .dw 0x940C
2
ROM:00000001 .dw  0xD0A

Das sieht für mich nach folgendem JMP-Befehl aus:
0x940C0D0A = 0b10010100000011000000110100001010

Würde ich jetzt manuell übersetzen als:
jmp 0xD0A

An der entsprechenden Position im ROM habe ich dann auch angefangen den 
von IDA ausgespuckten Code zu analysieren. Direkt vor dieser Adresse 
finden sich übrigens Klartext-String, so dass ich annehme, dass es sich 
dabei um Datenbereiche handelt. Allerdings kann es nun natürlich sein, 
dass dort irgendwelche Fallen versteckt sind, in die ich reingerannt 
bin. Ich denke, ich werde mich da nochmal byte für Byte durchhangeln :)

von Oliver (Gast)


Lesenswert?

Mike schrieb:
> Das sieht für mich nach folgendem JMP-Befehl aus:
>
> 0x940C0D0A = 0b10010100000011000000110100001010

Das sieht aus wie der Anfang der Vektortabelle, und der erste Vektor 
dort sollte der reset-Vektor sein.

Karl Heinz Buchegger schrieb:
> Angeblich gibt es in den
> Apollo-Programmen ein paar derartige Codestellen, die mit so einem
> Byteversatz arbeiten

Hatten die Angst, daß der Mann im Mond da unberechtigt die Fähre 
re-engineert?

Oliver

von Mike (Gast)


Lesenswert?

Oliver schrieb:
> Das sieht aus wie der Anfang der Vektortabelle, und der erste Vektor
> dort sollte der reset-Vektor sein.

Das sagt IDA auch, ich finde dort z.B. sämtliche Interrupvektoren z.B. 
für TIMER, USART, TWI usw.. Deswegen war ich auch verunsichert warum ich 
an einer Stelle plötzlich auf so einen "Mist" stoße. Ich hatte nicht 
damit gerechnet, dass man auch Fallen (neben sinnlosen/überflüssigen 
Funktionsblöcken) in ASM integrieren kann :D

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Mike schrieb:
> und am Ende ein komplettes Programmlisting erhält.


ach was, am Ende kommt ein in Prosa dokumentierter Programm-Ablaufplan 
und eine Powerpoint-Präsentation der Algorithmen raus (aber erst bei IDA 
Version 2060)

von Karl H. (kbuchegg)


Lesenswert?

Oliver schrieb:

> Karl Heinz Buchegger schrieb:
>> Angeblich gibt es in den
>> Apollo-Programmen ein paar derartige Codestellen, die mit so einem
>> Byteversatz arbeiten
>
> Hatten die Angst, daß der Mann im Mond da unberechtigt die Fähre
> re-engineert?

Die hat Speichernot Marke "Ende nie"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.