用C++表示简单的汇编代码,而不是函数

UnT*_*aDe 0 c++ hook inline-assembly

我正在尝试为某些win32 api函数编写一个trampoline挂钩,当我将JMP指令写入原始函数的开头时,我希望它跳转到codecave而不是调用函数.

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

PUSH 14
MOV EAX, 12345678
...
Run Code Online (Sandbox Code Playgroud)

我将其修补为:

JMP 87654321
NOP
NOP
Run Code Online (Sandbox Code Playgroud)

以下功能的地址:

int HookFunc(int param)
{
    DoStuff(param);
    return ExecuteOriginal(param);
}
Run Code Online (Sandbox Code Playgroud)

ExceuteOriginal看起来像这样:

unsigned long address = AddressOfOriginalFunction + 7;

int ExceuteOriginal(int param)
{
    __asm
    {
        PUSH 0x14
        MOV EAX, 0x12345678
        JMP address
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Jon*_*art 6

解: __declspec(naked)

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

例:

__declspec( naked ) int ExceuteOriginal(int param)
{
    __asm
    {
        PUSH 14
        MOV EAX, 0x12345678
        JMP address
    }
}
Run Code Online (Sandbox Code Playgroud)