Disassembler programmieren

...komplette Frage anzeigen

5 Antworten

Wenn du kein Assembler kannst, dann wird das auch nix. Ansonsten läuft das darauf hinaus, dass du die Zieldatei binär öffnest, mit einer Schleife durchläufst und dann jeweils prüfst, welchem Mnemonic die momentanen 1 bis 3 Byte entsprechen (ich geh mal von 32bit-Programmen aus). Du findest also beispielsweise die Hexzahl "85 90 6E" und machst daraus "mov 6E,90" Diese Entsprechungen findest du in einer Referenz für dein Zielsystem.

Ich seh aber nicht so ganz den Sinn in deinem Vorhaben, ich würde eher einen fertigen Disassembler nehmen.

Ich seh aber nicht so ganz den Sinn in deinem Vorhaben

Ich habe so etwas schon selbst gemacht - für exotische Prozessoren, für die es keine fertigen Disassembler gab.

Für x86-, x64-, PowerPC, ARM usw. kann man aber tatsächlich einfach einen fertigen Disassembler nehmen.

1
@martin7812

Stimmt, das wäre ein Anwendungszweck... an solche speziellen Anwendungen denk ich bei GF-Fragen standardmäßig nicht. :)

0

Welche Sprache die beste dafür ist, hängt vom Zweck des Projekts ab. Ich würde es in Perl machen, schon aus Gewohnheit und wegen des Komforts, den Perl (im Unterschied zu C) gerade bei der Verarbeitung von Zeichenketten bietet. Solltest Du so große Mengen von Code disassemblieren wollen, daß Perl dafür zu langsam ist, nimm C oder Java. Vielleicht besser Java, u.a. weil man damit im Allgemeinen etwas rascher vorankommt als in C, und weil man im Bedarfsfall viel einfacher Visualisierungsfunktionen und/oder ein GUI dazubauen kann.

Hier gibt es ein paar Hinweise:

  • coding.derkeiler.com/Archive/Assembler/comp.lang.asm.x86/2004-10/0097.html
  • en.wikibooks.org/wiki/X86Disassembly/Disassemblersand_Decompilers
  • stackoverflow.com/questions/924303/how-to-write-a-disassembler

Das System hier hat leider, wie ich soeben erst sehe, die Wikibooks-Adresse kaputtgemacht, weil Unterstriche darin enthalten waren (die bei den Wiki-Medien als Ersatz für Leerzeichen in den Namen der Seiten dienen).

Hier hingehen: http://en.wikibooks.org/wiki/ und dort ins Suchfenster eingeben:

  • X86 Disassembly/Disassemblers and Decompilers
0

Das kannst du mit jeder Sprache machen. Es ist prinzipiell auch ganz einfach - du liest einen Befehl ein und suchst ihn, leicht vereinfacht gesagt, aus einer Tabelle heraus. Wenn du in der Tabelle den Zahlencode aus der EXE gefunden hast, nimmst du den entsprechenden ASM-Code und schreibst ihn in die Zieldatei.

Das ist auch praktisch nicht viel schwieriger als das. Es gibt nur ein (großes) Problem: Der Umfang des Befehlssatzes. Hier die Liste aller unterstützen Befehle des NASM-Assemblers (und damit auch des Disassemblers):

http://www.nasm.us/xdoc/2.10.09/html/nasmdocb.html

Der schiere Umfang sollte dir zeigen, weshalb viele Leute dein Vorhaben als nicht besonders gewinnbringend einstufen würden. Ich äußere mich dazu nicht, muss aber dazu sagen, dass es interessantere Projekte gibt, wie beispielsweise der Compilerbau. Der ist aber natürlich auch sehr viel komplizierter.

Aber wie komme ich denn an den Zahlencode?

0
@Trigamer

Der Netwide Assembler (NASM) (www.nasm.us) ist Open-Source, da kannst du dir also den Quellcode anschauen und die Befehle heraussuchen. Wenn es um einen anderen Prozessor als x86 geht, wird es etwas schwieriger: Für ARM findet man noch ein paar Assembler, ansonsten gibt es eigentlich nur noch den GNU Assembler. Der ist auch Open-Source, d.h. da kannst du auch mal nachschauen. Ansonsten gibt es noch die Prozessordokumentationen, die vom Hersteller veröffentlicht werden. Die letzte, ziemlich unkomfortable Möglichkeit ist die, dass du einen Disassembler auf ein bestehendes Programm anwendest. Hier beispielsweise ein Auszug aus einem Output des NDISASM:

...
00001345  75D9              jnz 0x1320
00001347  C6025C            mov byte [bp+si],0x5c
0000134A  83C301            add bx,byte +0x1
0000134D  83C201            add dx,byte +0x1
00001350  EBD5              jmp short 0x1327
00001352  C6025C            mov byte [bp+si],0x5c
00001355  0FB60F            movzx cx,[bx]
00001358  31DB              xor bx,bx
0000135A  884A01            mov [bp+si+0x1],cl
0000135D  83C202            add dx,byte +0x2
00001360  EBC5              jmp short 0x1327
00001362  C60224            mov byte [bp+si],0x24
00001365  0FB60F            movzx cx,[bx]
00001368  31DB              xor bx,bx
0000136A  884A01            mov [bp+si+0x1],cl
...

Links die Position im Programm, mittig der Zahlencode und rechts der Befel in Assembler. Diese Vorgehensweise ist aber höchstens dann geeignet, wenn du speziell nach einem Befehl suchst - dann schreibst du einfach schnell ein Programm, das diesen Befehl nutzt (es muss auch gar keinen Sinn ergeben), lässt es mal durch den Assembler und schaust dir dann an, was er so erzeugt hat. Unter Linux würde sich dafür natürlich objdump anbieten, was du aber unter Windows üblicherweise nicht zur Verfügung hast.

1
@Roadrunner2

Ich meinte eigentlich wie ich an das vom Prozessor verarbeitete rankomme.

LG Trigamer

0
@Trigamer

Die Mittelspalte vom obigen Auszug ist das, was vom Prozessor verarbeitet wird.

0

Jede Sprache, die Filestreams beherrscht, also C/C++ genauso gut wie Java...

Gibt es ein Buch zu dem Thema?

0

Wieviel Programmiererfahrung hast du denn?

Ein bisschen in C.

0

Was möchtest Du wissen?