C#理论:将一个JMP写入asm中的编解码器

让我们假设我已经使用VirtualAllocEx (它返回地址)分配了我的codecave放置的地址,并使用WriteProcessMemory()将我的代码写入该地址。

这是问题:

如何写一个跳转到我的编解码器? 我知道跳转以“ E9 ”开头,但是如何将VirtualAllocEx返回的地址转换为正确的UInt32(dword),以便调试器/编译器能够理解指令?

例如:

我在地址00402020 (原生应用程序的OEP)。 我写了一个跳转到004028CF (空位)“ JMP 004028CF ”。 以字节为单位的指令如下所示:

 CPU Disasm Address Hex dump Command Comments 00402020 E9 AA080000 JMP 004028CF 

E9 ”是我们表明JMP的方式。 怎么样“ AA080000 ”,我该如何生成呢?

我需要做类似的事情,所以我可以将JMP初始化为我的codecave,它将位于VirtualAllocEx()返回的地址。

任何帮助将不胜感激!

提前致谢。

E9是相对跳转,因此后面的32位只是当前指令指针的偏移量。 有关详细信息,请参阅英特尔 ®64 和IA-32架构软件开发人员手册第2A卷:指令集参考,AM页549ff。 有关更多信息,请参阅英特尔®64和IA-32架构软件开发人员手册 。

因此,从00402020跳到004028CF的操作码应该如下。

     E9 00 00 08 AA
 Offset = DestinationAddress - CurrentInstructionPointer 000008AA = 004028CF - 00402025 

执行跳转指令时,指令指针已设置为下一条指令。 因此,跳转指令和当前指令指针值的偏移量相差5。

 CurrentInstructionPointer = AddressOfJumpInstruction + 5 

UPDATE

修正了有关当前指令指针值的错误。 谢谢jn。

获取相对偏移量只是减去地址:

 uint32_t patch_address = (uint32_t) VirtualAlloc(...); uint32_t jmp_offset = patch_address - (current_offset + current_len); 

注意:current_len在x86 E9 JMP指令上是5个字节。 有关更多信息,请参阅此post上的post:

VirtualAlloc C ++,注入了dll,asm