繁体   English   中英

在x86汇编中实现反射(在运行时编辑程序)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM