在C ++中执行简单的汇编代码而不在函数中

时间:2014-06-18 05:11:10

标签: c++ hook inline-assembly

我试图在某个win32 api函数中编写一个trampoline挂钩,当我将JMP指令写入原始函数的开头时,我希望它跳转到编解码而不是调用函数。

原始函数start在OllyDBG中如下所示:

PUSH 14
MOV EAX, 12345678
...

我将其修补为:

JMP 87654321
NOP
NOP

以下功能的地址:

int HookFunc(int param)
{
    DoStuff(param);
    return ExecuteOriginal(param);
}

ExceuteOriginal看起来像这样:

unsigned long address = AddressOfOriginalFunction + 7;

int ExceuteOriginal(int param)
{
    __asm
    {
        PUSH 0x14
        MOV EAX, 0x12345678
        JMP address
    }
}

执行被覆盖的代码并在修补后的代码后立即跳转到原始函数。问题在于,由于它是一个函数,它会使堆栈陷入困境,因为调用者应该清理它并且函数而不是返回,跳转到另一个函数的代码。我猜这就是程序崩溃的原因。

有没有办法使用Visual C ++编译器将汇编代码放在程序的代码部分而不将其放在函数中?这样我就可以跳到那里,执行任何操作,然后返回,而不会有弄乱堆栈的风险。

1 个答案:

答案 0 :(得分:6)

解决方案:__declspec(naked)

  

对于使用naked属性声明的函数,编译器生成没有prolog和epilog代码的代码。您可以使用此功能使用内联汇编程序代码编写自己的prolog / epilog代码序列。

示例:

__declspec( naked ) int ExceuteOriginal(int param)
{
    __asm
    {
        PUSH 14
        MOV EAX, 0x12345678
        JMP address
    }
}