Hallo Besucher, der Thread wurde 11k mal aufgerufen und enthält 78 Antworten

letzter Beitrag von detlef am

Disassembler Logik

  • Ok, ein binäres TCP/IP-Protokoll. Das sieht gut aus. Das werde ich mir mal bei Gelegenheit näher anschauen.

    Viele Dank noch mal für die Hinweise! :thumbup:

  • Hat jemand ne Idee warum das hier : x64 -binarymonitor -binarymonitoraddress 127.0.0.1

    nicht Funktioniert in WinVice 3.2.


    Die Parameter sind unbekannt.

  • Hat jemand ne Idee warum das hier : x64 -binarymonitor -binarymonitoraddress 127.0.0.1

    nicht Funktioniert in Vice 3.2.

    Wurde hier kürzlich erwähnt :) - es geht erst seit Vice 3.3 oder 3.4:


    Die gibt es seit VICE 3.3 oder 3.4. Such mal -binarymonitor in diesem seltsamen .texi-File, da sind die Nachrichten beschrieben.

  • Erschreckenderweise sind ja sogar die ersten zaghaften Ansätze eines modernen Debuggers in WinVice in der GTK3-Version wieder ausgebaut und durch einen einfachen Monitor ersetzt worden.

    "C64 65XE NES Debugger" baut um Vice herum einen Debugger: https://sourceforge.net/projects/c64-debugger/

    Ist mir schon klar und das hat sicher seine Nutzer und Anwendungsfälle, ist aber halt so ziemlich genau das Gegenteil von einem modernen Debugger.

    Was könnte ein modernerer Debugger besser und was hält dich davon ab, so ein Projekt anzugehen?

  • Wurde hier kürzlich erwähnt :) - es geht erst seit Vice 3.3 oder 3.4

    Bin mal wieder etwas zu hektisch. Hatte Endurion mir ja auch schon geschrieben und ich habe es überlesen :-(

  • Was könnte ein modernerer Debugger besser und was hält dich davon ab, so ein Projekt anzugehen?

    Genauso gut könntest Du fragen und genauso schwierig und langatmig wäre es darauf zu antworten, was Windows 10 besser als DOS kann oder Solidworks besser als GIGA-CAD (usw.). Ich habe divers Sachen erwähnt und zwei moderne Debugger verlinkt - wer sich nicht die Mühe macht, sich das mal anzuschauen, wird sich auch nicht die Mühe machen, ausführlichere Antworten zu lesen.

    Und diese "wer fragt, muß liefern"-Attitüde ist etwas, was mich an der Menschheit im Allgemeinen und Foren im Speziellen verzweifeln läßt. Hätte ich Zeit, Lust und Laune, alle Sachen nach denen ich frage, oder deren Fehlen ich beklage, selber zu machen, wäre die Frage/Klage per se sinnlos. Aber wie die allermeisten Menschen kann ich meine knappe Freizeit und verbleibende Lebenszeit nicht darauf verwenden, mir für alles und jedes erst die Werkzeuge selber zu basteln. Habe ich auch schon gemacht, vermutlich öfter und länger als die meisten Menschen. Aber das geht halt nicht beliebig oft.

  • Wie Meister Groepaz mir freundlich zukommen liess, die Schnittstelle ist übrigens auch in dem vice.pdf beschrieben. Die Suchfunktion in meinem PDF-Viewer findet seltsamerweise die Struct-Namen (MON_CMD_...) nicht, daher hatte ich angenommen, dass die Beschreibung da nicht mit enthalten ist. Mea Culpa!

  • Danke auch von mir. Durch diesen Thread bin ich auf die Binary Monitor Schnittstelle im Vice aufmerksam geworden. :thumbup:

  • Nochmal ganz herzlichen Dank für Euren tollen Input zu dem Thema. Ich habe viel über das Thema gelernt und darüber einen kleinen Artikel geschrieben: https://www.awsm.de/blog/pydisass/

    Deutscher User mit deutscher Domain und dann alles in englisch. :(

  • Englisch hat mehr Reichweite. ;)

  • Nachdem ich den "Regenerator" ausprobiert und für ganz brauchbar befunden habe, ist mir bzgl. Disassembler-Logik eine weitere problematische Sache aufgefallen.

    Wenn in und von dem Assemblerprogramm mehrere Bereiche behandelt werden, indem Pointer gesetzt und benutzt wurden, wird die Pointer-Einrichtung zum Dilemma:


    Entweder 1.: Der Disassembler behandelt die Pointer-Einrichtung nicht mit Labels, sondern mit festen Werten.

    => Das Programm ist nicht relozierbar und kann somit auch nicht einfach weiterbearbeitet werden.


    Oder 2.: Er benutzt für die Pointer-Einrichtung Labels (à la LDA #<label:LDX #>label:STA pointer:STX pointer+1) =>


    2.1. ist das oftmals gar nicht so einfach bis sogar unmöglich, wenn der Code nicht so eindeutig ist wie im oberen Beispiel. Z.B., wenn was dazwischen steht oder das letzte Ergebnis für A oder X nur übernommen wird und vorher berechnet wurde, etc.


    2.2. kennt der Disassembler auch dabei mal wieder nicht die tatsächliche Intention. Wird ein Label benutzt, und das Label verschiebt sich durch Erweiterung/Kürzung des Codes, verändert sich dann natürlich auch die Belegung des Pointers. Aber es könnte sein, dass das gar nicht soll oder darf, z.B. weil etwas in dem ROM darüber gemeint ist, oder weil an die ursprüngliche Stelle im Laufe des Programms ein anderer Code geschoben oder dort generiert wird. Auch dann würde das Programm nicht mehr funktionieren.


    Man kommt dann also nicht drumherum, das disassemblierte Programm komplett zu analysieren, zu verstehen und selbst umzuschreiben, bevor man es richtig verändern kann.

    Schade ist beim Regenerator übrigens, dass er keinen Text im Screencode anzeigen kann.

  • Nachdem ich den "Regenerator" ausprobiert und für ganz brauchbar befunden habe, ist mir bzgl. Disassembler-Logik eine weitere problematische Sache aufgefallen.

    Ich kenne den Regenerator nicht, aber schafft der es denn, Code- und Datenbereiche einigermaßen sauber zu erkennen? Das ist eigentlich schon die erste Hürde für relozierbaren Code.

  • Wenn in und von dem Assemblerprogramm mehrere Bereiche behandelt werden, indem Pointer gesetzt und benutzt wurden, wird die Pointer-Einrichtung zum Dilemma: [...]

    Das ist tatsächlich ein ganz allgemeines Problem. Immediate-Konstanten sieht man nicht auf den ersten (und teilweise auch nicht auf den zweiten) Blick an, wo sie herkommen. Nicht nur Low- und High-Byte einer bestimmten Adresse kann dahinterstecken, es könnte sich auch um einen Offset handeln (der beim Verschieben dann wahrscheinlich nicht verändert werden muß) oder ein Adreßoffset ist bereits subsumiert.


    Hier mal ein Beispiel im Source, wo ich aus einem Bytewert im Bereich 32..127 einen Pointer in einen Charset berechne:

    Tja, und "TCharset-32*8" zeigt eben nicht direkt auf den Anfang des Datenbereichs, sondern 256 Byte davor. Den Regenerator möchte ich sehen, der das rauskriegt.

  • Ich beschäftige mich seit Anfang der 80er damit, Assemblerprogramme zu disassemblieren und relozierbaren Code daraus zu erzeugen.

    Habe damals zum Beispiel das Exbasic Level II für den CBM 3032 in einen relozierbarbaren Quellcode überführt. Und einen LISP-Interpreter.

    Und viele weitere Assemblerprogramme.

    Ich hatte mir damals auch schon einen "Regenerator" für den 65(C)02 und andere Prozessoren geschrieben. Bei mir hieß der "Unassembler". Zunächst in CBASIC unter CP/M. Dann umgeschrieben in Commodore Basic (lief durch einen Trick gar nicht so langsam). Inzwischen habe ich eine komfortable C# Version unter Windows.


    Das Disassmblieren ist nur ein erster Schritt beim Verstehen eines Assemblerprogramms. Meinen Unassembler kann ich genau parametrisieren wie er bestimmte Adressbereiche oder Adresse behandeln soll. Bis ich zu einem wirklich relozierbaren Code komme, braucht das in der Regel sehr viele manuelle Iterationsschritte wo immer mehr Vorgaben konfiguriere. Der Unassembler ist dabei nur ein Hilfsmittel.


    Und wie Mike schon geschrieben hat, die Bedeutung vieler Parameter (gerade bei Immediate) erschließen sich nur aus dem Zusammenhang.


    Wo ich sofort aufhöre, ist bei selbstmodifizierendem Code. Weil ich das ersten ablehne, mich mit sowas zu beschäftitgen und weil es zweitens auch unnötig aufwändig ist.

  • Wo ich sofort aufhöre, ist bei selbstmodifizierendem Code. Weil ich das ersten ablehne, mich mit sowas zu beschäftitgen und weil es zweitens auch unnötig aufwändig ist.

    Das erklärt natürlich, warum Du in manchen Threads dagegen wetterst ^^! Aus Sicht eines Dis/Un-Assemblers ist das natürlich in der Tat Teufelszeug, das sich jeder nicht-manuellen Analyse entzieht.

  • und "TCharset-32*8" zeigt eben nicht direkt auf den Anfang des Datenbereichs, sondern 256 Byte davor. Den Regenerator möchte ich sehen, der das rauskriegt.

    Vollautomatisch geht das natürlich nicht, aber deswegen sind die besseren Disassembler ja auch interaktiv. Z.B. SourceGen kann entsprechenden Source erzeugen: letztendlich sagt man einfach "bring den Operanden dieses Befehls irgendwie in Beziehung mit dem-und-dem Label", Offsets werden dann entsprechend vom Tool erzeugt.

  • Wo ich sofort aufhöre, ist bei selbstmodifizierendem Code. Weil ich das ersten ablehne, mich mit sowas zu beschäftitgen und weil es zweitens auch unnötig aufwändig ist.

    Das erklärt natürlich, warum Du in manchen Threads dagegen wetterst ^^! Aus Sicht eines Dis/Un-Assemblers ist das natürlich in der Tat Teufelszeug, das sich jeder nicht-manuellen Analyse entzieht.

    Nö, aus dem Grund plädiere ich für Open Source, damit ich gar nicht erst disassemblieren muss. :D

    Aber selbstmodifizierender Open Source Code interessiert mich eigentlich auch nicht.

  • [...] deswegen sind die besseren Disassembler ja auch interaktiv. [...]

    Alternativ bietet sich dann aber auch immer noch die Inspektion mit einem Monitor des eigenen Vertrauens an. Der ist auch interaktiv (zitiert aus einem anderen Thread mit demselben Thema):

    Von Hand kann man den Schritt bis hierhin mit einem beliebigen Monitor seines Vertrauens machen: nachdem man als erstes durch Angucken Code und Daten separiert hat, lenkt man die Ausgabe in eine Datei um, gibt eine Kalotte von "M xxxx xxxx"- und "D xxxx xxxx"-Befehlen ein und macht die Datei wieder zu.


    [...] [Ich plädiere] für Open Source [...]

    Das kannst Du ja gerne machen, aber außer in den wenigen Fällen wo durch Zufall noch Disketten und Papier von damals™ mit Quellcode und Notizen auftaucht, hast Du von den Programmen die Du vielleicht reversen möchtest eben nur den Objektcode.

    Wo ich sofort aufhöre, ist bei selbstmodifizierendem Code.

    Da ist doch dann ggfs. die Herausforderung da, den Code statisch zu machen! Aber o.k., wie die Vorgänger schon angemerkt haben, ist das Geschmackssache. Hatten wir auch schon zwischen. Das Beispiel mit der Linienzieh-Routine, wo Selbstmodifikation ungefähr den Faktor 6 an Code einspart, hatte ich dir ja auch schon woanders angediegen. :)


    Richtig übel wird der Versuch, ein Programm in Forth zu disassemblieren. Da sieht man nur den Interpreter mit NEXT und die nativen Worte als (65xx-)Maschinencode - der Rest sind Sprungadressen und Konstanten. 8|