Wie konvertiere ich Linux 32-Bit-GCC-Inline-Assembly in 64-Bit-Code? [geschlossen]

Ich versuche zu konvertierenRR0D Rasta Ring 0 Debugger vom 32-Bit-Modus in den 64-Bit-Modus (Long-Modus) unter Linux mit gcc. Ich bin mit x86-32-Bit-Assemblys (in MS-DOS-Umgebungen) vertraut, bin jedoch Anfänger in x86-64-Bit-Assemblys und in der Linux-Assemblyprogrammierung im Allgemeinen.

Dieses Projekt ist für die Produktion gedacht (ich benötige einen funktionierenden Nicht-Source-Debugger), aber ich versuche auch zu lernen, wie die 32-Bit-in-64-Bit-Konvertierung durchgeführt wird. Wenn möglich, versuche ich, eine universelle Methode zur Konvertierung von 32-Bit in 64-Bit zu finden, die mit regulären Ausdrücken in jedem 32-Bit-Programm durchgeführt werden kann (damit sie automatisiert werden kann). Mir ist bewusst, dass es keine allgemeine Lösung gibt (64-Bit-Code benötigt möglicherweise mehr Platz als 32-Bit-Code usw. und verbraucht mehr Stapel usw.), aber selbst in diesem Fall würde automatisch konvertierter Code als Ausgangspunkt dienen.

Die Idee wäre, 8-Bit- und 16-Bit-Operanden unverändert zu lassen und 32-Bit-Operanden durch 64-Bit-Operanden zu ersetzen. Dieser Ansatz wird natürlich scheitern, wennpushw %ax; pushw %bx; popl %ecx wird ersetzt durchpushw %ax; pushw %bx; popq %rcx, aber wohlerzogene Programme normalerweise nichtpush zwei 16-Bit-Operanden und dannpop ein 32-Bit-Operand, oder?

Dies sind die bisherigen Umrechnungen:

Bearbeiten: Fix:pusha / pushad können durch aufeinanderfolgende ersetzt werdenpushweilpusha / pushad Befehle drücken den Wert vonsp / esp Vor der eigentliche schub vonsp, undpush sp Funktioniert genauso in 286+, aber anders in 8088/8086Die Assembler-Datenbank. Dieser Unterschied ist hier kein Problem (für 386+ Code).pusha undpushad kann somit durch aufeinanderfolgende ersetzt werdenpush befehle.

Eine Alternative ist ähnlich wie inOpenSolaris 'privregs.h Code.

Bearbeiten: Korrektur: Verwenden Sie für alle Befehle die 64-Bit-Speicheradressierung.

pusha ->push %ax; push %cx; push %dx; push %bx; push %sp; push %bp; push %si; push %di.

Bearbeiten: Fix: Eine gültige Alternative (mitlea), beachten Sie, dass x86-Prozessoren Little-Endian sind:pusha ->movq %rax, -8(%rsp); lea -8(%rsp), %rax; mov %ax, -10(%rsp); movq -8(%rsp), %rax; movw %cx, -4(%rsp); movw %dx, -6(%rsp); movw %bx, -8(%rsp); movw %bp, -12(%rsp); movw %si, -14(%rsp); movw %di, -16(%rsp); lea -16(%rsp), %rsp.

pushad ->push %rax; push %rcx; push %rdx; push %rbx; push %rsp; push %rbp; push %rsi; push %rdi.

Bearbeiten: Fix: Eine gültige Alternative (mitlea):pushad ->movq %rax, -8(%rsp); movq %rcx, -16(%rsp); movq %rdx, -24(%rsp); movq %rbx, -32(%rsp); lea -32(%rsp), %rax; movq %rax, -40(%rsp); movq -8(%rsp), %rax; movq %rbp, -48(%rsp); movq %rsi, -56(%rsp); movq %rdi, -64(%rsp); lea -64(%rsp), %rsp.

Bearbeiten: Fix:popa undpopad Pop den Wert vonsp / esp aber wirf es weg (Intel Befehlssatz - Popa / Popad). Lasst unspop es inbx / rbx.

popa ->popw %di; popw %si; popw %bp; popw %bx; popw %bx; popw %dx; popw %cx; popw %ax.

popad ->popq %rdi; popq %rsi; popq %rbp; popq %rbx; popq %rbx; popq %rdx; popq %rcx; popq %rax.

pushfd ->pushfq.

popfd ->popfq.

Bearbeiten: push von Segmentregistern, z.pushw %ds ->pushw %ax; pushw %ax; movw %ds, %ax; movw %ax, 2(%rsp); popw %ax.

Bearbeiten: pop von Segmentregistern, z.popw %ds ->pushw %ax; movw 2(%rsp), %ax; movw %ax, %ds; popw %ax.

Bearbeiten: inc %reg16 ->add $1, %reg16, z.B.inc %ax ->add $1, %ax.

Bearbeiten: dec %reg16 ->sub $1, %reg16, z.B.dec %ax ->sub $1, %ax.

Bearbeiten: inc %reg32 ->add $1, %reg64, z.B.inc %eax ->add $1, %rax.

Bearbeiten: dec %reg32 ->sub $1, %reg64, z.B.dec %eax ->sub $1, %rax.

Bearbeiten: aaa ->?

Bearbeiten: aad ->?

Bearbeiten: aam ->?

Bearbeiten: aas ->?

Bearbeiten: arpl ->?

Bearbeiten: bound ->?

Bearbeiten: daa ->?

Bearbeiten: das ->?

Bearbeiten: lahf ->?

Bearbeiten: sahf ->?

Bearbeiten Behebung: Jeder Befehl mit Direktoperanden, der nicht in die 32-Bit-Operandengröße im 64-Bit-Modus passt, z.pushl $0xDEADBEEF ->pushq %rax; pushq %rax; movq $0xDEADBEEF, %rax; movq %rax, 8(%rsp); popq %rax.

ret mit sofortigem Operanden: Ich denke in diesem Fall muss der Quellcode zurückverfolgt werden, um die Größen des letzten zu sehenpushOperanden und handeln dementsprechend, z.pushl %eax; ret 4 ->pushq %rax; ret 8.

Bearbeiten:: syscalls:int $0x80 ->pushq %rdi; movq %rbp, %r9; movq %rdi, %r8; movq %rbx, %rdi; xchgq %rcx, %rsi; -- replace %rax value using a substitution list --; syscall; popq %rdi; xchgq %rcx, %rsi (Hinweis: 32-Bit-Systemaufrufe können mehr als 6 Parameter haben, 6 in Registern und der Rest im Stapel, 64-Bit-Systemaufrufe dürfen nie mehr als 6 Parameter haben.)

Bearbeiten: Was ist sonst noch zu beachten? Welche anderen Konvertierungen wären erforderlich, um 32-Bit-Code in 64-Bit-Code zu konvertieren (um im Langzeitmodus ausgeführt zu werden)?

Antworten auf die Frage(0)

Ihre Antwort auf die Frage