【问题标题】:How to do a naked function and inline assembler in x64 Visual C++如何在 x64 Visual C++ 中执行裸函数和内联汇编程序
【发布时间】:2014-12-25 14:15:58
【问题描述】:

我正在使用裸函数和内联汇编器代理方法调用。

__declspec(naked) void ProxyFunction()
{
    static const unsigned int addressofRealFunction = 0x0041b200;
    __asm
    {
        jmp [addressofRealFunction];
    }
}

如何将其转换为 x64?在 Visual Studio 中,没有用于 x64 的内联汇编程序或裸函数。

Naked 删除了大会的序言和尾声。我需要这个来确保堆栈帧在调用中保持等效。

你会怎么做?

【问题讨论】:

  • 会做什么?我会使用更好的编译器,例如 gcc 或 clang 支持 __attribute__((naked)) 和内联 asm(尽管使用与 MSVC 不同的语法)。

标签: c++ c visual-studio assembly


【解决方案1】:

尝试直接编译:

void ProxyFunction()
{
    RealFunction();
}

查看编译器是否将其优化为裸跳转。可能会。

【讨论】:

  • 一个问题是代理函数可能在寄存器或堆栈中传递参数。我不能用参数调用 RealFunction,因为它是未知的,必须跳转到它并假设代理的调用者设置了正确的调用约定。
  • 你首先想要完成什么?
  • 绝对会将其编译为跳转,并且它将为 x86-32 和 x86-64 构建执行此操作。因此,这是您应该始终编写它的方式。 The original code using inline asm is slower and larger, thus actually a pessimization。我无法想象为什么在调试版本中不会优化这会是一个问题,@han。它将改为 call 指令。这意味着它会更慢,但功能相同。在调试版本中,谁在乎?
  • 如果没有优化或使用 -RTCs 或 -JMC 等标志,这将失败。
【解决方案2】:

如果 Microsoft 建议将 masm 用于此类任务对您不起作用,那么一种方法是查看分配页面,在其上设置可执行属性,然后使用直接内存写入将操作码放置在偏移开始处在页面的开头。

【讨论】:

    猜你喜欢
    • 2017-05-03
    • 1970-01-01
    • 2011-02-19
    • 2012-11-10
    • 2021-12-05
    • 1970-01-01
    • 2012-11-17
    • 1970-01-01
    相关资源
    最近更新 更多