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