热补丁A功能 [英] Hot Patching A Function

查看:146
本文介绍了热补丁A功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想热补丁内存中的exe文件,提供源代码,但我这样做是为了学习目的。 (所以请任何意见建议我修改原始来源或使用走弯路或任何其他库)

I'm trying to hot patch an exe in memory, the source is available but I'm doing this for learning purposes. (so please no comments suggesting i modify the original source or use detours or any other libs)

下面是我有问题的功能。

Below are the functions I am having problems with.

vm_t* VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), vmInterpret_t interpret )
{
    MessageBox(NULL, L"Oh snap! We hooked VM_Create!", L"Success!", MB_OK);
    return NULL;
}

void Hook_VM_Create(void)
{

    DWORD dwBackup;
    VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READWRITE, &dwBackup);

    //Patch the original VM_Create to jump to our detoured one.
    BYTE *jmp = (BYTE*)malloc(5);
    uint32_t offset = 0x00477C3E - (uint32_t)&VM_Create; //find the offset of the original function from our own
    memset((void*)jmp, 0xE9, 1);
    memcpy((void*)(jmp+1), &offset, sizeof(offset));
    memcpy((void*)0x00477C3E, jmp, 5);

    free(jmp);
}

我有一个函数VM_Create,我想叫,而不是原来的功能。我还没有写蹦床所以它崩溃(如预期)。然而,消息框不会弹出,我绕道原始虚拟机创建我自己的。我相信这是我覆盖原始指令的方式。

I have a function VM_Create that I want to be called instead of the original function. I have not yet written a trampoline so it crashes (as expected). However the message box does not popup that I have detoured the original VM create to my own. I believe it is the way I'm overwriting the original instructions.

推荐答案

我可以看到的几个问题。

I can see a few issues.

我认为 0x00477C3E 是原始的 VM_Create 函数的地址。你真的应该不难code这一点。使用&放大器; VM_Create 来代替。当然,这将意味着你需要使用不同的名称为您的替换功能。

I assume that 0x00477C3E is the address of the original VM_Create function. You really should not hard code this. Use &VM_Create instead. Of course this will mean that you need to use a different name for your replacement function.

正确计算偏移。你有迹象错了。更重要的是偏移的指令,而不是一开始的的结束的被应用到指令指针。所以,你需要通过5(指令的大小)来接班。偏移量应该是一个符号整数也。

The offset is calculated incorrectly. You have the sign wrong. What's more the offset is applied to the instruction pointer at the end of the instruction and not the beginning. So you need to shift it by 5 (the size of the instruction). The offset should be a signed integer also.

在理想情况下,如果你考虑到我的第一点code是这样的:

Ideally, if you take into account my first point the code would look like this:

int32_t offset = (int32_t)&New_VM_Create - ((int32_t)&VM_Create+5);

感谢汉斯帕桑特在原始版本修复我自己的愚蠢错误的标志!

Thanks to Hans Passant for fixing my own silly sign error in the original version!

如果你的工作,你需要做的算术64位的,一旦你已经计算出的偏移量,它截断为64位计算机上一个32位的偏移量。

If you are working on a 64 bit machine you need to do your arithmetic in 64 bits and, once you have calculated the offset, truncate it to a 32 bit offset.

另一个细微差别是,你应该内存复位到被只读写过新的 JMP 指令后,并调用的 FlushInstructionCache

Another nuance is that you should reset the memory to being read-only after having written the new JMP instruction, and call FlushInstructionCache.

这篇关于热补丁A功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆