Como converter o assembly in-line gcc de 32 bits do Linux para um código de 64 bits? [fechadas]

Estou tentando converterRR0D Rasta Ring 0 Depurador do modo de 32 bits para o modo de 64 bits (modo longo) no Linux, usando o gcc. Estou familiarizado com o assembly x86 de 32 bits (no ambiente MS-DOS), mas sou iniciante em montagem de 64 bits x86 e em programação de montagem Linux em geral.

Este projeto é para uso em produção (eu preciso de um depurador que não seja de trabalho), mas também tento aprender como fazer a conversão de 32 bits para 64 bits. Se possível, tento encontrar uma maneira universal de fazer conversão de 32 bits para 64 bits que possa ser feita em qualquer programa de 32 bits usando expressões regulares (para que possa ser automatizada). Estou ciente de que não existe uma solução geral (o código de 64 bits pode ocupar mais espaço do que o código de 32 bits etc. e consumir mais pilha etc.), mas mesmo nesse caso o código convertido automaticamente serviria como ponto de partida.

A idéia seria manter os operandos de 8 e 16 bits como estão e substituir operandos de 32 bits por operandos de 64 bits. Esta abordagem irá naturalmente falhar sepushw %ax; pushw %bx; popl %ecx é substituído porpushw %ax; pushw %bx; popq %rcx, mas programas bem comportados geralmente nãopush dois operandos de 16 bits e, em seguida,pop um operando de 32 bits, ou eles?

Estas são as conversões até agora:

Editar: Consertar:pusha / pushad posso ser substituído por consecutivospushporquepusha / pushad comandos empurrar o valor desp / esp antes o impulso real despepush sp funciona da mesma maneira em 286+, mas diferente em 8088/8086O banco de dados Assembly Language. Essa diferença não é um problema aqui (para código 386+).pusha epushad pode assim ser substituído porpush comandos.

Uma alternativa é semelhante à deOpenSolaris 'privregs.h código.

Editar: Correção: use o endereçamento de memória de 64 bits para todos os comandos.

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

Editar: Correção: uma alternativa válida (usandolea), note que os processadores x86 são little-endian: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.

Editar: Fix: Uma alternativa válida (usandolea):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.

Editar: Consertar:popa epopad estourar o valor desp / esp mas descartá-lo (Conjunto de instruções Intel - popa / popad). Vamospop embx / 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.

Editar: push de registradores de segmento, por exemplo.pushw %ds ->pushw %ax; pushw %ax; movw %ds, %ax; movw %ax, 2(%rsp); popw %ax.

Editar: pop de registradores de segmento, por exemplo.popw %ds ->pushw %ax; movw 2(%rsp), %ax; movw %ax, %ds; popw %ax.

Editar: inc %reg16 ->add $1, %reg16, por exemplo.inc %ax ->add $1, %ax.

Editar: dec %reg16 ->sub $1, %reg16, por exemplo.dec %ax ->sub $1, %ax.

Editar: inc %reg32 ->add $1, %reg64, por exemplo.inc %eax ->add $1, %rax.

Editar: dec %reg32 ->sub $1, %reg64, por exemplo.dec %eax ->sub $1, %rax.

Editar: aaa ->

Editar: aad ->

Editar: aam ->

Editar: aas ->

Editar: arpl ->

Editar: bound ->

Editar: daa ->

Editar: das ->

Editar: lahf ->

Editar: sahf ->

Editar Correção: qualquer comando com operando direto que não se encaixa no tamanho do operando de 32 bits no modo de 64 bits, por exemplo.pushl $0xDEADBEEF ->pushq %rax; pushq %rax; movq $0xDEADBEEF, %rax; movq %rax, 8(%rsp); popq %rax.

ret com operando imediato: Eu acho que, neste caso, o código-fonte deve ser backtraced para ver os tamanhos do últimopushoperandos ed, e agir de acordo, por exemplo.pushl %eax; ret 4 ->pushq %rax; ret 8.

Editar:: 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 (nota: o syscalls de 32 bits pode ter mais de 6 parâmetros, 6 em registradores e o restante na pilha; o syscalls de 64 bits pode nunca ter mais de 6 parâmetros).

Editar: O que mais deve ser levado em conta? Quais outras conversões seriam necessárias para converter o código de 32 bits em código de 64 bits (para ser executado no modo longo)?

questionAnswers(0)

yourAnswerToTheQuestion