6

假设我已经分配了放置我的 codecave 的地址VirtualAllocEx(它返回地址),并且我使用WriteProcessMemory().

这是问题:

我如何写一个跳转到我的codecave?我知道跳转以“ 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().

任何帮助将不胜感激!

提前致谢。

4

2 回答 2

4

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

所以从 00402020 跳转到 004028CF 的操作码应该如下。

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

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

CurrentInstructionPointer = AddressOfJumpInstruction + 5

更新

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

于 2009-04-24T18:35:06.433 回答
1

要获得相对偏移量,只需减去地址:

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

注意:current_len 在 x86 E9 JMP 指令上为 5 个字节。有关更多信息,请参阅我在此线程上的帖子:

VirtualAlloc C++,注入 dll,asm

于 2011-08-10T09:29:27.293 回答