编写一个函数蹦床 [英] Writing a Trampoline Function

查看:285
本文介绍了编写一个函数蹦床的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已成功地覆盖函数的前几个字节存储器和它迂回到我自己的功能。现在我在回过来的真正功能创建一个功能蹦床弹跳控制问题。

I have managed to overwrite the first few bytes of a function in memory and detour it to my own function. I'm now having problems creating a trampoline function to bounce control back over to the real function.

这是第二部分,我的问题<一href=\"http://stackoverflow.com/questions/8089887/hot-patching-a-function/8089958#8089958\">here.

This is a second part to my question here.

BYTE *buf = (BYTE*)VirtualAlloc(buf, 12, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
void (*ptr)(void) = (void (*)(void))buf;

vm_t* VM_Create( const char *module, intptr_t (*systemCalls)(intptr_t *), vmInterpret_t interpret )
{
    MessageBox(NULL, L"Oh Snap! VM_Create Hooked!", L"Success!", MB_OK);

    ptr();

    return NULL;//control should never get this far
}

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

    //save the original bytes
    memset(buf, 0x90, sizeof(buf));
    memcpy(buf, (void*)0x00477C3E, 7);

    //finish populating the buffer with the jump instructions to the original functions
    BYTE *jmp2 = (BYTE*)malloc(5);
    int32_t offset2 = ((int32_t)0x00477C3E+7) - ((int32_t)&buf+12);
    memset((void*)jmp2, 0xE9, 1);
    memcpy((void*)(jmp2+1), &offset2, sizeof(offset2));
    memcpy((void*)(buf+7), jmp2, 5);

    VirtualProtect((void*)0x00477C3E, 7, PAGE_EXECUTE_READ, &dwBackup);
}

0x00477C3E是已被覆盖的函数的地址。原函数的ASM被保存到 BUF 之前,我在写他们。然后我的5个字节JMP指令被添加到 BUF 来回到原来的函数的其余部分。

0x00477C3E is the address of the function that has been overwritten. The asm for the original function are saved to buf before i over write them. Then my 5 byte jmp instruction is added to buf to return to the rest of the original function.

在PTR()被调用时出现问题,程序崩溃。当调试崩溃在看起来并不像我的 PTR()功能,但双重检查我的偏移计算看起来是正确的网站。

The problem arises when ptr() is called, the program crashes. When debugging the site it crashes at does not look like my ptr() function, however double checking my offset calculation looks correct.

请注意:被省略多余的code键使一切都通过阅读更容易

NOTE: superfluous code is omitted to make reading through everything easier

编辑:这是 PTR()函数看起来像在OllyDbg的

This is what the ptr() function looks like in ollydbg

0FFB0000   55               PUSH EBP
0FFB0001   57               PUSH EDI
0FFB0002   56               PUSH ESI
0FFB0003   53               PUSH EBX
0FFB0004   83EC 0C          SUB ESP,0C
0FFB0007  -E9 F1484EFD      JMP 0D4948FD

所以,就像我的偏移量计算是错误的它会出现。

So it would appear as though my offset calculation is wrong.

推荐答案

所以,你的buf []结束了含两件事情:

So your buf[] ends up containing 2 things:


    从最初的说明
  • 7第一字节

  • JMP

然后控制转移到buf中。难道保证了前7个字节仅包含完整的说明?如果没有,你可能会崩溃,同时或执行这些7个字节开始最后的未完成的指令后。

Then you transfer control to buf. Is it guaranteed that the first 7 bytes contain only whole instructions? If not, you can crash while or after executing the last, incomplete instruction beginning in those 7 bytes.

能够保证所有的这些7个字节的指令没有做任何EIP-相对计算(其中包括与EIP-相对寻址如跳转指令和调用为主)?如果没有,继续在原有的功能将无法正常工作,最终可能会崩溃的程序。

Is it guaranteed that the instructions in those 7 bytes do not do any EIP-relative calculations (this includes instructions with EIP-relative addressing such as jumps and calls primarily)? If not, continuation in the original function won't work properly and probably will end up crashing the program.

原有的功能是否采取任何参数?如果是这样,简单地做 PTR(); 将与垃圾的原code工作从寄存器和/或栈(取决于调用约定),并采取可能会崩溃。

Does the original function take any parameters? If it does, simply doing ptr(); will make that original code work with garbage taken from the registers and/or stack (depends on the calling convention) and can crash.

修改:还有一件事。使用 BUF + 12 而不是&放大器; BUF + 12 。在您的code BUF 是一个指针,而不是数组。

EDIT: One more thing. Use buf+12 instead of &buf+12. In your code buf is a pointer, not array.

这篇关于编写一个函数蹦床的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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