使用MOV和JMP的汇编替代方法

问题描述

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

BYTE orig[] = { 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));

解决方法

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

LEA RCX,MY_JUMP_TARGET

与10字节mov相比,这将有效地缩短组装时间并节省空间。之后,只需跳转:

JMP RCX

JMP的替代方案呢?您可以像这样使用CALL指令:

CALL RCX

事实上,实际上,您可以将整个内容简化为单个CALLJMP,因为这些指令不仅支持通用寄存器作为操作数,而且还支持直接偏移量: / p>

CALL MY_JUMP_TARGET

JMP MY_JUMP_TARGET

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

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