nrz*_*nrz 11 linux assembly gcc x86-64 inline-assembly
我正在尝试使用gcc在Linux 中将RR0D Rasta Ring 0调试器从32位模式转换为64位模式(长模式).我熟悉x86 32位程序集(在MS-DOS环境中),但我是x86 64位程序集和Linux程序集编程的初学者.
这个项目是供生产使用的(我需要一个可用的非源调试器),但我也尝试学习如何进行32位到64位的转换.如果可能的话,我试图找到一种通用的方法来进行32位到64位的转换,可以使用正则表达式在任何32位程序上完成(这样它就可以自动化).我知道没有通用的解决方案(64位代码可能占用比32位代码更多的空间等,并且消耗更多的堆栈等),但即使在这种情况下,自动转换的代码也可以作为起点.
我们的想法是保持8位和16位操作数不变,并用64位操作数替换32位操作数.如果pushw %ax; pushw %bx; popl %ecx替换为这种方法自然会失败pushw %ax; pushw %bx; popq %rcx,但是性能良好的程序通常不会有push两个16位操作数,而是pop一个32位操作数,或者它们呢?
这些是到目前为止的转换:
编辑:修复:pusha/ pushad 可以用连续的push'es 替换,因为pusha/ pushad命令在实际推送之前推送sp/ 的值,并且在286+中以相同的方式工作,但在8088/8086 汇编语言数据库中有所不同.这种差异不是问题(对于386+代码).并且因此可以与连续的替换命令.esp sppush sppushapushadpush
替代方法与OpenSolaris的privregs.h代码类似.
编辑:修复:对所有命令使用64位内存寻址.
pusha- > push %ax; push %cx; push %dx; push %bx; push %sp; push %bp; push %si; push %di.
编辑:修复:一个有效的替代(使用lea),请注意x86处理器是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.
编辑:修复:有效的替代(使用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但丢弃它(英特尔指令集 - popa/popad).让我们pop进入bx/ 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.
编辑: push段寄存器,例如.pushw %ds- > pushw %ax; pushw %ax; movw %ds, %ax; movw %ax, 2(%rsp); popw %ax.
编辑: pop段寄存器,例如.popw %ds- > pushw %ax; movw 2(%rsp), %ax; movw %ax, %ds; popw %ax.
编辑: inc %reg16 - > add $1, %reg16,例如.inc %ax- > add $1, %ax.
编辑: dec %reg16 - > sub $1, %reg16,例如.dec %ax- > sub $1, %ax.
编辑: inc %reg32 - > add $1, %reg64,例如.inc %eax- > add $1, %rax.
编辑: dec %reg32 - > sub $1, %reg64,例如.dec %eax- > sub $1, %rax.
编辑: aaa - >?
编辑: aad - >?
编辑: aam - >?
编辑: aas - >?
编辑: arpl - >?
编辑: bound - >?
编辑: daa - >?
编辑: das - >?
编辑: lahf - >?
编辑: sahf - >?
编辑修复:任何带有直接操作数的命令,在64位模式下不适合32位操作数大小,例如.pushl $0xDEADBEEF- > pushq %rax; pushq %rax; movq $0xDEADBEEF, %rax; movq %rax, 8(%rsp); popq %rax.
ret使用立即操作数:我认为在这种情况下,必须回溯源代码以查看最后push编辑操作数的大小,并相应地采取行动,例如.pushl %eax; ret 4- > pushq %rax; ret 8.
编辑:: 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位代码(以长模式运行)需要进行哪些其他转换?
| 归档时间: |
|
| 查看次数: |
2770 次 |
| 最近记录: |