我想在应用程序中为我的编解码器保留空间。 我使用VirtualAlloc函数来保留这个空间。 我有X个问题。
我应该使用哪些参数(sllocation类型和保护)为代码洞穴分配内存?
作为返回值,我得到了我的编解码器的地址。在程序的其他部分我想要JMP到该编解码器。怎么做?我知道(纠正我,如果我错了)JMP采取偏离当前位置的agument nuber。但是我希望JMP能够进行编码。如何计算此偏移量。
答案 0 :(得分:6)
偶然发现了。要为我们其他人清除此主题:通过使用当前程序计数器地址减去补丁地址来计算编解码器补丁的相对JMP偏移量:
uint32_t patch_address = (uint32_t) VirtualAlloc(...);
uint32_t jmp_offset = patch_address - (current_offset + current_len);
注意:current_len 是JMP指令所需的字节数。这取决于它是短jmp(EB)还是长跳(E9)的事实。在您的示例中为2个字节,但常规JMP(E8 0x12345678)占用5个字节。
所以在这里我们看到你的例子不会轻易工作,因为你必须覆盖属于下一个MOV甚至CALL指令的下一个字节。这取决于您的编解码器与当前指令偏移量的距离更大,因为它是在地址空间中的不同区域中分配的。
所以你可以做的是将覆盖的7字节复制到洞穴中。这只有在你的补丁中不要乱用EDI寄存器时才有效(因为“MOV ECX,EDI”)。你必须纠正你覆盖的CALL地址。所以这可能不是放置编解码器的最佳位置,但它可行。
我编写了自己的挂钩库,它关注通用寄存器参数,堆栈清理和覆盖的asm填充,但我建议使用上面提到的框架。
的问候, 迈克尔
答案 1 :(得分:2)
在跳转后从指令的地址中减去跳转目标的地址将为您提供跳跃偏移。
答案 2 :(得分:0)
如果您没有这样的东西,请使用MS Detours,N-CodeHook等库。