C# 理论:将 JMP 写入 asm 中的 codecave

发布于 2024-07-18 03:36:23 字数 744 浏览 8 评论 0原文

假设我已经使用 VirtualAllocEx 分配了放置 codecave 的地址(它返回地址),并使用 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() 返回的地址处。

任何帮助将不胜感激!

提前致谢。

Lets assume I've allocated the address where my codecave is placed using VirtualAllocEx (it returns the address) and I write my code into that address using WriteProcessMemory().

Here's the question:

How do I write a jump to my codecave? I know that jumps start with "E9", but how do I convert the address returned by VirtualAllocEx into a correct UInt32 (dword) so the debugger/compiler will understand the instruction?

For example:

I'm at address 00402020 (OEP of the native app). I write a jump to 004028CF (empty place) "JMP 004028CF". The instruction in bytes looks like this:

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

"E9" is how we indicate a JMP. What about "AA080000", how do I generate this?

I need to do something similar so I can initialize a JMP to my codecave, which will be located at an address returned by VirtualAllocEx().

Any help will be gratefully appreciated!

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夕色琉璃 2024-07-25 03:36:23

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

更新

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

E9 is a relative jump so the later 32 bits are just an offset to the current instruction pointer. See Intel® 64 and IA-32 Architectures Software Developer’s Manual Volume 2A: Instruction Set Reference, A-M pages 549ff for details. For more information see Intel® 64 and IA-32 Architectures Software Developer's Manuals.

So the opcode to jump from 00402020 to 004028CF should be the following.

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

When the jump instruction is executed, the instruction pointer is already set to the next instruction. So the offset of the jump instruction and the current instruction pointer value differ by 5.

CurrentInstructionPointer = AddressOfJumpInstruction + 5

UPDATE

Corrected error about the current instruction pointer value. Thanks jn.

2024-07-25 03:36:23

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

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

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

VirtualAlloc C++,注入的dll,asm< /a>

to get the relative offset just subtract the addresses:

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

note: current_len is 5 bytes on x86 E9 JMP instruction. see my post on this thread for more information:

VirtualAlloc C++ , injected dll, asm

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文