x86 / x64使用相对跳跃从子例程返回



我需要写一些我将写入另一个过程的地址空间(已经在运行(

本质上,我想做的是每次调用此组件时,它将比较堆栈的值与预定义值,然后如果它匹配预定的值,我想调用一个函数,它的指针将很难被编码到组件中,如果没有,我希望大会本质上什么都不做,所以返回。

到目前为止,我有以下操作(只是要发布X86的摘要以使事情变得简单(

mov eax, [esp+0x04] ; this is the value from the stack
cmp eax, 0x01 ; this is the predefined value I am comparing to

如上所述,如果EAX中的值匹配0x01,我希望它跳到函数(预定义的指针,因此可以进行硬码进入汇编(,否则我希望sub例程返回。问题是我不使用标签,我不知道该怎么做,我不相信我将能够使用,因为这将在另一个过程的上下文中执行,因此地址不会从0开始(对于组件,我将打电话。(

我听说您可以相对跳跃,但是我在这些行实施某些方面遇到了麻烦。

有人可以向我展示如何使用相对跳跃或其他方法来实现这一目标?

您正在将其注入已经运行的过程中,因此在复制此过程时,您肯定有可用的源和目标地址。

x86条件分支可提供32位rel32位移,相对于分支指令的 END 。即,如果分支条件为真,则它们在常规设置RIP =本指令结束后进行RIP += rel32

jz rel32是使有条件的尾随到另一个功能的好方法,或者掉入ret指令。

有关OPCODES,请参见https://www.felixcloutier.com/x86/jcc。$确切地在NASM中工作?有一个手动编码call rel32的示例,以及由此产生的机器代码。

还将跳跃命令写入x86-64二进制文件,以进行另一个Q& a关于分支编码。

    mov   eax, [esp+0x04]
    cmp   eax, 1
    db 0x0f, 0x84      ; opcode for je rel32
branch_offset: dd 0    ; the rel32 itself
    ; fall-through path
    ret

将其组装到机器代码中后,您应该编写代码以修改该dword(又称int32_t(0一旦知道目标过程中的源和目标地址。0只是一个占位符。

(je +0将仅转到ZF是否设置的下一个指令。(

,或者如果您知道源地址和目标地址,则可以在组装时间为您完成数学:

    bits 64
    org  0x12345             ; this block of code will start at this address
    cmp  dword [rsp+4], 1
    je   0x123456
    ret

将其组装成平坦的二进制文件,给了我们:

$ yasm -f bin -l /dev/stdout jz.asm
     1                                 %line 1+1 jz.asm
     2                                 [bits 64]
     3                                 [org 0x12345]
     4                                 
     5 00000000 837C240401              cmp dword [rsp+4], 1
     6 00000005 0F84FD101100            je 0x123456
     7 0000000B C3                      ret
     8                                 
     9 0000000C B854230100              mov eax, $

ORG指令似乎不适用于NASM,只有Yasm。我不知道为什么。

mov指令在那里查看汇编器认为其组装的地址。使用NASM,我们获得B8[0C000000],而不是预期的54 23 01 00作为mov指令的直接(其自己的地址(。


如果您提前知道相对位移是一个组装时间常数(但不是绝对地址(,那也很好。

在NASM语法中,je +0x555555汇编到0F 84 55 55 55 00

,但不是yasm:在yasm +0x555555中只是绝对地址0x555555作为分支目标。


相关:

  • 如何为MASM中接近直接的亲戚呼叫/JMP编写绝对目标(TL:DR您不能(
  • 在X86机器代码中调用绝对指针 - 显示如何编码相对分支,并在无法完成jcc rel32工作的情况下将地址移动到寄存器并使用jmp reg

最新更新