从一个函数调用另一个函数

Call naked function from one to another?

本文关键字:函数调用 另一个 函数 一个      更新时间:2023-10-16

当我试图将declspec(裸)函数调用到另一个函数时,我得到了一个错误根据函数原型,它必须返回一个值,但是当我试图返回一个值时,我得到了另一个错误,说裸函数不能返回值。

__declspec(naked) void bar()    {
    __asm   {
        nop
        ret
    }
}
__declspec(naked) NTSTATUS WINAPI foo(int a, int b) {
    bar();
    return NTSTATUS(1);
}

所有这些都是合理的,因为裸函数不会为函数创建堆栈帧,因此除非程序员显式创建堆栈帧,否则调用另一个函数是错误的。然而,当我试图创建一个堆栈帧并以正确的方式进行堆栈对齐时,我会遇到一个错误。

如何正确地从一个裸函数调用另一个?

裸函数不支持返回语句

以下规则和限制适用于裸函数:

  • 不允许使用return语句

您应该自己处理堆栈帧返回值,例如

__declspec( naked ) void bar()    {
    __asm   {
        nop
        ret
    }
}
__declspec(naked) bool foo(int a, int b) {
    bar();
    __asm   {
        mov al,1
        ret
    }
}
int main() {
    bool return_value = foo(2, 2);
    std::cout << return_value; // 1
}

裸函数意味着编译器不会为您编写序言(设置esp和ebp)和尾声(重置esp和eb p)。由于编译器并没有编写结束语,所以您不能要求它使用"return"关键字为您返回一些值。//序言

// simple prologue
      push ebp
      mov ebp, esp
// simple epilogue
      mov eax, ret_var  //by default eax holds return value
      mov esp, ebp
      pop ebp