[英]Implementing reflection in x86 assembly (editing the program whilst running)
我想编写一个汇编程序,该程序一旦加载到内存中,就会在其自身上编写新指令,但是由于对指令指针和其他汇编概念有些疑问,我不确定100%如何进行。 我的假设方法是:
_func:
push rip ; Not allowed to push RIP, how can I read from RIP?
jmp stage1
stage2:
mov eax, 0
ret
stage1:
pop rbx
; How many times should I increment rbx to point to ‘mov eax, 0’?
; Assuming this is done:
;Move opcodes for ‘mov eax, 1’ into memory where ‘mov eax, 0’ located
mov [rbx], 0xB8
mov [rbx+1], 0x01
mov [rbx+2], 0x00
mov [rbx+3], 0x00
mov [rbx+4], 0x00
jmp stage2
当跳转到阶段2时,它将遇到操作码“ B8 01 00 00 00”,而不是“ mov eax,0”,并解释为“ mov eax,1”。 我的一般方法是否正确,有人可以在代码中填补这一空白吗?
额外的困惑/问题
RBX是指向指令行的第一个字节还是“整行”? 上述方法是正确的还是我应该写的:
mov [rbx], B801000000h
操作系统: Mac OS X 10.9 汇编程序: NASM
在16位“实模式”下,这样做很简单。 当我开始汇编程序编程时,我使用反射实现了一个循环。
但是,在16或32位“保护模式”或“长模式”(64位)下,这比较棘手:
在这些模式下,可以防止内存被覆盖。 由于使用“奔腾Pro”处理器,因此还可以保护内存免受执行。
Windows和Linux都使用这些功能,因此默认情况下可以修改的内存不能包含可执行代码,并且包含可执行代码的内存也不能被覆盖。
您必须分配可写和可执行的内存(或更改现有内存的内存访问)。 请参阅Windows中的“ VirtualAlloc”和“ VirtualProtect”功能或Linux中的“ mmap”和“ mprotect”。 然后,您必须将代码移动到该内存中。
顺便说一句:以下命令是错误的:
jmp stage1
它必须是“ call”而不是“ jmp”,因为“ jmp”不会“将”返回地址压入堆栈。
在16位“实模式”中:
mov bx, stage2 ; NASM get offset address
mov cs:[bx], 0xB8
mov cs:[bx+1], 0x01
mov cs:[bx+2], 0x00
mov cs:[bx+3], 0x00
mov cs:[bx+4], 0x00
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.