Forum: Mikrocontroller und Digitale Elektronik AVR einlesen und in C Code umwandeln


von The E. (the_engineer)


Lesenswert?

Hallo,

habe das Problem, das ich einen Festplattenabsturz hatte und die 3
letzten Tage in meinem Mikrokontroller drinstecken.Ein Restore meines
Quellcodes Backups war erfolgreich, aber die letzten 3 Tage sind in
meinem AVR Mega 8 und Mega 162 versteckt*g

Gibt es eine Möglichkeit das mit Ponyprog ausgelesene Programm wieder
zu recompilieren und in C Code für WinAVR umzuwandeln ?

Danke im vorraus !
Thorsten

von Gernot F. (gernotfrisch)


Lesenswert?

Das ist wie Kuh aus einem Hamburger machen... Sorry.

von akw (Gast)


Lesenswert?

Schwätz net raus! Das geht schon, der Code sieht dannach glaub nemme so
gut aus, aber soweit ich weiß geht das!! Such doch mal, das gabs
schonmal!

gruß

von Dirk D. (dirkd)


Lesenswert?

> Schwätz net raus!
Nett

> Das geht schon, der Code sieht dannach glaub nemme so
> gut aus, aber soweit ich weiß geht das!!

Beispiel?

Was natürlich geht ist Assembler-Code daraus zu gewinnen. Wenn man dann
noch Adressen durch Labels ersetzt kann es wieder einigermaßen lesbar
werden, aber das ist auch viel Arbeit.

Für das was der OP will, brauchst Du ein Tool das in der Lage wäre aus
Assembler wieder C-Code zu erzeugen. Da ist mir nichts bekannt.

von The E. (the_engineer)


Lesenswert?

Jo danke ! Also der Zeitaufwand aus Assembler das wieder lesbar zu
machen ist glaube ich länger als die ca 15h wieder neu zuprogrggen.

Trotzdem Danke !
Thorsten

von The E. (the_engineer)


Lesenswert?

Sorry für die Rechtschreibfehler !*g Ist wohl der Kaffe zitter

von AndreasB (Gast)


Lesenswert?

@Gernot

Akw hatte schon recht. Der Kuh-Hamburger Vergleich passt hier nicht
(auch wenn er noch so toll ist). Es ist schon möglich den Code wieder
zurück zu übersetzen. Aber es ist eben theoretisch nich möglich, jeden
bekannten Code vollautomatisch in endlicher Zeit zurückzuübersetzen.

Warum das doch geht, und warum Handlungsreisende doch zum Ziel kommen,
obwohl das Problem des Handlungsreisenden gelöst ist lässt sich
nachlesen unter:

http://www.program-transformation.org/Transform/DecompilationPossible

@Dirk

Es gibt Decompiler auch wenn dir das nicht bekannt ist:
http://de.wikipedia.org/wiki/Decompiler

Gruß Andreas

von Thomas K. (thkais)


Lesenswert?

AndreasB:
Mag ja sein, dass es Decompiler gibt - nicht jedoch für den AVR-GCC.
Aber der Code, der heraus kommt, dürfte dem originalen Code bestenfalls
ähnlich sein. Sämtliche Variablennamen, Strukturen, Funktionsnamen
(Kommentare sowieso) sind verloren. Außerdem kann es durch die
Optimierung des Compilers zu Rückübersetzungen kommen, die dem
originalen Code nicht mal ähnlich sind. Zum Beispiel inline-Funktionen
dürften nur schwer zu erkennen sein, da sie sich nicht durch einen
Subroutine-Aufruf verraten.

In Maschinensprache/Assembler mag das noch ansatzweise gehen, aber für
C ein sinnloses Unterfangen.

Das ist bestenfalls Stoff für einen Informatiker, der kein besseres
Thema für seine Diplomarbeit findet. Das ist meine Meinung.

von Peter D. (peda)


Lesenswert?

Der Kuh-Hamburger Vergleich paßt hier wirklich sehr gut.

Du kannst Die Hamburger zu was zusammenpappen, das wie ne Kuh aussieht,
aber sie lebt nicht mehr.

Du kannst Assembler in irgenwas C-Syntax zusammenpappen, aber alle
Variablennamen, Funktionsnamen und Kommentare, die die Seele des
Programms sind, sind für immer wech.


Wenn man 3 Tage wirklich selber am Programm gearbeitet hat, dann kann
man das auch in 1-2 Stunden wieder hinschreiben.


Peter

von Dirk D. (dirkd)


Lesenswert?

> Es gibt Decompiler auch wenn dir das nicht bekannt ist:

Ok, ich befasse mich nicht so oft mit theoretischer Informatik ;-)

Aber Spaß beiseite. Der Hinweise auf die Decompiler ist ganz
interessant.

Aber wenn man sich dann mal die Beispiele ansieht, wird auch klar wie
sinnlos das ganze ist. Selbst einfache Sache wie eine
Fibonnaci-Berechnung werden (zumindest durch die freien Programme) nur
mühsam wieder hergestellt.

Und das ganze noch auf normalen Workstations/PCs. Dort sind dann aber
oft noch die  Symbol/Debug-Informationen enthalten. Das erleichert das
ganze natürlich sehr.

Alles in allem kann man die Frage des OP mit gutem Gewissen mit einem
klaren

"Nein, es geht nicht!"

beantworten.

von Michael B. (one)


Lesenswert?

Ich kann da Dirk nur zustimmen... Theoretisch ginge es aber...
Belassen wirs bei nem einfachen

"Nein, es geht nicht!"

3 Tage ist ja nicht so schlimm, hab auch schonmal Code von einer Woche
verloren da ich rsync verwendete für Backups (nun Subversion).

Grüße

von Dirk D. (dirkd)


Lesenswert?

Wobei ich sogar noch zugeben würde, daß es in diesem Beispiel vielleicht
noch relativ gut gehen könnte.

Man kennt den Compiler, man kennt die Optimierungen, man hat noch einen
Teil des Codes (es sei denn es wurde sehr viel geändert).

Jemand der sich gut mit dem Code-Generierungteils des AVR-GCC auskennt
wäre wohl in der Lage ein Tool zu schreiben, daß bei einer manuellen
Rückübersetzung assistieren könnte.

von Wegstabenverbuchsler (Gast)


Lesenswert?

schick mir mal den code, ich pump den durch ida pro durch, mal schaun
was rumkommt

http://www.datarescue.com/idabase/idaavr.htm



wegs tab en verb uch   sler (ättt]  cts [minus} con sult  (PunKt)   de

von Sebastian (Gast)


Lesenswert?

Mal ganz ehrlich:

Ich glaube, es ist auf jeden Fall einfacher, den Code komplett neu zu
schreiben (ja, komplett, nicht nur die letzten drei Tage) als zu
decompilieren. Damit wirst Du deutlich länger beschäftigt sein. Die
Gründe wurden alle schon hier genannt.

Auch in Dekompilierer muss man sich reinfuchsen. Gerade die Probleme:

-Kommentare sind weg
-logische Variablennamen sind weg (nur noch Adressen, die einem erstmal
nix sagen, da muss man basteln, welche Adresse welche Bedeutung hat.
-Optimierungen lassen sich nicht komplett rückgängig machen. Ein
Vergleich der vielleicht besser passt als der mit der Kuh: versuch mal
aus einer mp3-Datei wieder die originale wav zu machen. Geht nicht,
weil mp3 ein verlustbehaftetes Verfahren ist. Die mp3 hört sich
vielleicht genau so an, wie die wav (=der Code tut das selbe), ist es
aber nicht. Nur wenn Du alle Optimierungen beim kompilieren
ausgeschaltet hattest, hast Du eine Chance, das mit recht geringem
Zeitaufwand wiederherzustellen.

Also: Nachdenken, was Du alles geändert hast und neu auf das Backup
aufbauen. Du wirst feststellen, dass das deutlich weniger Zeit braucht
als drei Tage, weil Du die Denkprozesse jetzt schneller machst. Ich
schätze, in weniger als einem Tag hast Du das wieder so, wie es vor dem
Datenverlust war.

Viel Erfolg,
Sebastian

von ??? (Gast)


Lesenswert?

...jaja, Decompiler sind etwas feines wenn es Bebug-Informationen im
binary gibt... oder der compiler etwas blöd war und nix optimiert hat.
Das ist etwa so:
Jemand erzählt eine schöne Geschichte (den Quelltext) mit vielen
bekannten Namen und Orten. Also etwa Politiker und Berliner Adressen.
Ein Mann von einem bekannten Dienst schreibt alles was er braucht mit.

seine Kollegen nehmen die entstandene Wegbeschreibung und fahren die
Adressen ab...
ein Journalist bekommt die wegbeschreibung zu fassen und liesst:
"Start at home, 200m nördlich, 3.Etage links, 20 Minuten, Weiter 4.
Kreuzung rechts..."
Daraus lässt sich nie die Geschichte rekonstruieren. Das geht nur wenn
irgendwo die Klarnamen stehen.
Aber: wenn man sich mit Assambler beschäftigt und die Compiler-Ausgabe
als ASM betrachtet kann man sicher was lernen.

von Unbekannter (Gast)


Lesenswert?

Decompilieren ist in der Praxis nutzlos.

Sobald Du -Os oder -O2 verwendet hast, hat das Decompilat absolut
nichts mehr mit dem ursprünglichen Source zu tun.

von AndreasB (Gast)


Lesenswert?

Hi,

Mir ging es eher drum richtigzustellen dass es eben prinzipiell möglich
ist - ich geb zu nicht grade ein praktischer Ansatz :-)

Es stimmt, der Code der wieder rauskommt so nicht so aus wie der
ursprüngliche. Aber nochmal zum Hamburgervergleich: Ich man kann aus
dem Hamburger wieder etwas zusammensetzen, das (wenn man's nochmal
durch den Wolf dreht) wieder zu einem Hamburger wird.

Aus praktischer Sicht geb ich euch natürlich recht: Nicht praktikabel.


Gruß Andreas

...Irgenwie bekomm ich bei dem Thema Bock auf Grillen...

von Hagen R. (hagen)


Lesenswert?

>>Sobald Du -Os oder -O2 verwendet hast, hat das Decompilat absolut
>>nichts mehr mit dem ursprünglichen Source zu tun.

Sorry aber solche Aussagen halte ich für dumm.
Denn wenn das Compilat nichts mehr mit dem Source gemein hätte dann
würde das Compilat nicht das machen was man ihm als Source befohlen
hat.

Das Compilat ist also funktional gesehen eine 1 zu 1 Kopie des Sources,
allerdings in eine Sprache transformiert/übersetzt die eben auf Grund
fehlender/entfernter Informationen nicht mehr 1 zu 1 zurückübersetzt
werden kann.

Der Vergleich mit der Kuh und Hambuger hinkt also ein bischen, denn der
Hambuger macht nicht mehr Muh und gibt keine Milch ab. Aber genetisch
betrachtet enthält er alle Informationen um wiederum eine Kuh zu
reproduzieren nur können wir das heutzutage nicht mehr
"rückübersetzen" so das eine Kuh daraus entstünde.

Gruß Hagen

von Peter D. (peda)


Lesenswert?

Besonders lustig ist es, wenn ein Disassembler versucht, konstante Daten
in Code zu übersetzen. Woher soll er auch wissen, daß es Daten sind.

Und bei Architekturen mit variabler Befehlslänge sind dann auch noch
die nächsten echten Instruktionen total verwurstet, ehe der
Dissassembler sich wieder fängt.


Nur ein Mensch kann erkennen, daß total sinnloser Code warscheinlich
Daten sind und versucht bis zu dem letzten sinnvollen Sprungbefehl
zurückzugehen. Vor einem Datenfeld muß ja der Code irgendwo anders
weiter machen (mit Jump, Call, Ret).


Der Keil C51 setzt z.B. konstante Daten hinter einen Call. Der
Aufgerufene weiß, daß das Daten sind, holt sich die Returnadresse vom
Stack und nimmt sie als Datenpointer, zählt hübsch alle Daten hoch, um
dann hinter die Daten zurückzukehren.

Sowas nach C zurück zu übersetzen, dürfte nur mit KI auf nem
Teraflops-Rechner machbar sein.

Oder man läßt den Code komplett ausführen, um zu sehen, wo Daten- und
wo Codezugriffe erfolgen.
Um nun alle möglichen Varianten an bedingten Sprüngen,
Funktionspointer, Dateninhalte usw. zu durchlaufen, dürften auch
mehrere Teraflops nötig sein.


Beschäftige Dich daher lieber mit der Quadratur des Kreises, das ist
auch nicht weniger Erfolg versprechender.


Peter

von Rolf Magnus (Gast)


Lesenswert?

> ...Irgenwie bekomm ich bei dem Thema Bock auf Grillen...

Was findest du an einer Grille denn so sexy? ;-)

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Die Unterscheidung zwischen Code und Daten ist noch das kleinste
Problem, gängige Disassembler bekommen das gut hin. Wenn nicht gerade
völlig chaotisch mit indirekten Sprüngen herumgesaut wird lässt sich
relativ einfach feststellen welche Adressen angesprungen werden können
und wo "toter Code" bzw. Daten sind. Dazu braucht man keine TeraFLOPS
(man braucht überhaupt keine FLOPs).

von Unbekannter (Gast)


Lesenswert?

> >>Sobald Du -Os oder -O2 verwendet hast, hat das Decompilat absolut
> >>nichts mehr mit dem ursprünglichen Source zu tun.

> Sorry aber solche Aussagen halte ich für dumm.

Nun, was soll das lange raten, hier einfach mal ein Beispiel.
Source-Code:


  static int func1(int a, int b)
  {
    int c = 0;
    c += a + b;
    c += a * b;
    return c;
  }
  int func2(int x, int y)
  {
    int p = func1(x, 1);
    int q = func1(y, 2);
    return func1(p, q);
  }


Habe gerade keinen AVR-Compiler hier, deshalb mal mit x86. Das macht
der gcc ohne Optimierung aus dem Source:


        .file   "test1.c"
        .text
        .type   func1, @function
 func1:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $4, %esp
        movl    $0, -4(%ebp)
        movl    12(%ebp), %eax
        movl    8(%ebp), %edx
        addl    %eax, %edx
        leal    -4(%ebp), %eax
        addl    %edx, (%eax)
        movl    8(%ebp), %eax
        movl    %eax, %edx
        imull   12(%ebp), %edx
        leal    -4(%ebp), %eax
        addl    %edx, (%eax)
        movl    -4(%ebp), %eax
        leave
        ret
        .size   func1, .-func1
 .globl func2
        .type   func2, @function
 func2:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        pushl   $1
        pushl   8(%ebp)
        call    func1
        addl    $8, %esp
        movl    %eax, -4(%ebp)
        pushl   $2
        pushl   12(%ebp)
        call    func1
        addl    $8, %esp
        movl    %eax, -8(%ebp)
        pushl   -8(%ebp)
        pushl   -4(%ebp)
        call    func1
        addl    $8, %esp
        leave
        ret
        .size   func2, .-func2
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.4.6 (Gentoo 3.4.6-r1, ssp-3.4.5-1.0,
pie-8.7.9)"


So weit, so gut. Obiges Assembler-Listing in C-Code zu decompilieren
ist schlichtweg trivial. Es sind noch fast alle Informationen
enthalten.

Aber was macht der Compiler, wenn er voll wüten darf? Hier der gleiche
C-Source mit "-O3 -fomit-frame-pointer" compiliert:


        .file   "test1.c"
        .text
        .p2align 2,,3
 .globl func2
        .type   func2, @function
 func2:
        movl    8(%esp), %eax
        movl    4(%esp), %ecx
        leal    2(%eax,%eax,2), %edx
        leal    1(%ecx,%ecx), %ecx
        leal    (%ecx,%edx), %eax
        imull   %edx, %ecx
        addl    %ecx, %eax
        ret
        .size   func2, .-func2
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.4.6 (Gentoo 3.4.6-r1, ssp-3.4.5-1.0,
pie-8.7.9)"


Ja, das ist noch alles!

Dieses Listing hat praktisch gar nichts mehr mit dem Original-Source zu
tun.


> Das Compilat ist also funktional gesehen eine 1 zu 1 Kopie
> des Sources,

Klar, das ist ja logisch, über diese Frage müssen wir nicht wirklich
diskutieren, oder?

Dennoch ist Decompilieren nur akademischer Natur mit kaum praktischem
Nutzen, wenn der Compiler wüten durfte.

Der Sinn vom Decompilieren ist der, aus dem niedrigen Objekt-Code bzw.
Assenbler-Listing wieder ein Programm in Hochsprache zu erzeugen, das
auch dem Namen Hochsprache gerecht wird.

von The E. (the_engineer)


Lesenswert?

Upala Soviel Feedback *g

Also Code ist jetzt eh weg, da ich Controller schon überschrieben habe
und Code ist fast wieder auf alten Stand.Ging also vermutlich doch
schneller *g

Trotzdem Danke

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.