首页 > 解决方案 > 使用 MOV 和 JMP 的汇编替代方案

问题描述

目前我有这段代码可以使用 MOV 和 JMP 将我的函数地址放入内存中。我的问题是我可以使用 MOV 或 JMP 的替代品吗?这可以用 LEA 来完成吗?如果可以,怎么做?谢谢!

BYTE orig[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 12 bytes being replaced

BYTE code[] = { 0x48, 0xB8 }; //MOV RAX
BYTE code_end[] = { 0xFF, 0xE0 }; // JMP RAX

RtlSecureZeroMemory(&orig, sizeof(orig));
memcpy((PVOID)((ULONG_PTR)orig), &code, sizeof(code));

uintptr_t hook_address = reinterpret_cast<uintptr_t>(kernel_function_address);

memcpy((PVOID)((ULONG_PTR)orig + sizeof(code)), &hook_address, sizeof(void*));
memcpy((PVOID)((ULONG_PTR)orig + sizeof(code) + sizeof(void*)), code_end, sizeof(code_end));

标签: assemblyx86-64

解决方案


是的,它可以用LEA. 因为我假设这是在 Windows 操作系统上,所以同一用户模式进程模块中的地址永远不会超过 32 位偏移量。(无论如何,您都不应尝试修改内核内存,否则会产生严重后果)。这意味着使用的 32 位偏移量LEA就足够了。为此,首先选择一个寄存器,为简单起见,让我们选择RCX. 然后像这样引用跳转目标:

LEA RCX, MY_JUMP_TARGET

这将有效地为您提供比 10 字节 mov 更短的组件并节省空间。在此之后,只需跳转:

JMP RCX

. 那替代品JMP呢?您可以使用如下CALL指令:

CALL RCX

事实上,您实际上可以将整个事情简化为单个CALLor JMP,因为这些指令不仅支持通用寄存器作为操作数,还支持直接偏移:

CALL MY_JUMP_TARGET

或者

JMP MY_JUMP_TARGET

(请注意:使用CALL指令会将返回地址压入堆栈,因此您需要将其与 . 匹配RET。)

PS。我不会提供您可以粘贴的可复制粘贴解决方案,这不是 Stack Overflow 的工作方式。


推荐阅读