Как преобразовать 32-битную встроенную сборку Linux в 64-битный код?

Я пытаюсь преобразовать RR0D Rasta Ring 0 Debugger из 32-битного режима в 64-битный режим (длинный режим) в Linux, используя gcc. Я знаком с 32-битной сборкой x86 (в среде MS-DOS), но я новичок в 64-битной сборке x86 и в программировании на ассемблере Linux в целом.

Этот проект предназначен для производственного использования (мне нужен работающий не исходный отладчик), но я также пытаюсь научиться выполнять преобразование 32-разрядных в 64-разрядные. Если возможно, я пытаюсь найти универсальный способ сделать 32-битное в 64-битное преобразование, которое можно было бы сделать в любой 32-битной программе с использованием регулярных выражений (чтобы его можно было автоматизировать). Я знаю, что не существует общего решения (64-битный код может занимать больше места, чем 32-битный код и т. Д. И потреблять больше стека и т. Д.), Но даже в этом случае автоматически преобразованный код будет служить отправной точкой.

Идея состоит в том, чтобы сохранить 8-битные и 16-битные операнды как есть, и заменить 32-битные операнды 64-битными операндами. Этот подход, естественно, потерпит неудачу, если pushw %ax; pushw %bx; popl %ecx заменяется на pushw %ax; pushw %bx; popq %rcx, но программы с хорошим поведением обычно не push два 16-битных операнда, а затем pop один 32-битный операнд, или они?

Это преобразования на данный момент:

Редактировать: Исправить: pusha / pushad можно заменить последовательным push потому что pusha / pushad Команды выдвигают значение sp / esp до фактического толчка sp, а также push sp работает аналогично в 286+, но по-разному в 8088/8086 базе данных языка ассемблера. Эта разница не проблема здесь (для кода 386+). pusha а также pushad Таким образом, может быть заменен последовательным push команды.

Альтернатива похожа на OpenSolaris privregs.h код

Редактировать: Исправить: использовать 64-битную адресацию памяти для всех команд.

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

    Редактировать: Исправить: допустимая альтернатива (используя lea Обратите внимание, что процессоры x86 имеют младший порядок: 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,

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

    Редактировать: Исправить: допустимая альтернатива (используя lea): 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,

    Редактировать: Исправить: popa а также popad поп значение sp / esp но откажитесь ( набор инструкций Intel - popa / popad). Давайте pop это в bx / rbx,

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

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

  5. pushfd -> pushfq,

  6. popfd -> popfq,

  7. Редактировать: push сегментных регистров, например. pushw %ds -> pushw %ax; pushw %ax; movw %ds, %ax; movw %ax, 2(%rsp); popw %ax,

  8. Редактировать: pop сегментных регистров, например. popw %ds -> pushw %ax; movw 2(%rsp), %ax; movw %ax, %ds; popw %ax,

  9. Редактировать: inc %reg16 -> add $1, %reg16 например inc %ax -> add $1, %ax,

  10. Редактировать: dec %reg16 -> sub $1, %reg16 например dec %ax -> sub $1, %ax,

  11. Редактировать: inc %reg32 -> add $1, %reg64 например inc %eax -> add $1, %rax,

  12. Редактировать: dec %reg32 -> sub $1, %reg64 например dec %eax -> sub $1, %rax,

  13. Редактировать: aaa ->?

  14. Редактировать: aad ->?

  15. Редактировать: aam ->?

  16. Редактировать: aas ->?

  17. Редактировать: arpl ->?

  18. Редактировать: bound ->?

  19. Редактировать: daa ->?

  20. Редактировать: das ->?

  21. Редактировать: lahf ->?

  22. Редактировать: sahf ->?

  23. Исправление редактирования: любая команда с прямым операндом, которая не соответствует размеру 32-битного операнда в 64-битном режиме, например. pushl $0xDEADBEEF -> pushq %rax; pushq %rax; movq $0xDEADBEEF, %rax; movq %rax, 8(%rsp); popq %rax,

  24. ret с непосредственным операндом: я думаю, что в этом случае исходный код должен быть возвращен, чтобы увидеть размеры последнего push операнды и действуют соответственно, например. pushl %eax; ret 4 -> pushq %rax; ret 8,

  25. Редактировать:: 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 (примечание: 32-разрядные системные вызовы могут иметь более 6 параметров, 6 в регистрах и остальные в стеке, 64-разрядные системные вызовы могут никогда не иметь более 6 параметров).

Редактировать: Что еще следует учитывать? Какие другие преобразования потребуются для преобразования 32-битного кода в 64-битный код (для запуска в длинном режиме)?

0 ответов

Другие вопросы по тегам