__return_ptr 在 IDA 中有什么作用?

逆向工程 艾达 x86 海湾合作委员会 调用约定
2021-06-22 21:12:38

假设我有这个程序:

struct A {
    int x;
};

struct A func1(int z) {
    struct A result;
    result.x = z+1;
    return result;
}

int main() {
    return func1(1).x;
}

在 linux 上用gcc -m32 -fno-stack-protectorfunc1 的结果编译它时,将作为堆栈指针返回。我可以使用 __return_ptr 以某种方式设置 func1 的类型,以便 IDA 理解此调用约定吗?我认为这将是 __return_ptr 的目的,如果不是它有什么作用?

1个回答

您的示例的“问题”是结构太小(四个字节),因此它适合寄存器并且实际上并未在堆栈上传递。来自Itanium C++ ABI(大多数 GCC 实现使用):

在以下情况下,出于调用目的,类型被认为是非平凡的:

  • 它有一个非平凡的复制构造函数、移动构造函数或析构函数,或者
  • 它的所有复制和移动构造函数都被删除。

此定义应用于类类型,旨在作为 [class.temporary]p3 中类型定义的补充,其中在传递或返回类型时允许额外的临时类型。对于 ABI 而言微不足道的类型将根据底层 C ABI 的规则进行传递和返回,例如在 registers 中通常这具有执行类型的简单副本的效果。

(强调我的)。

由于您的结构是微不足道的并且完全适合返回寄存器 ( eax),因此它不会在堆栈上传递,而是直接在eax. 所以这里不需要任何特别的东西。但是,如果你把它弄大一点,例如:

struct A {
    int x;
    int y;
    int z;
};

然后它不再适合并且必须在堆栈上传递。如果将结构添加到本地类型并为函数 ( struct A func1(int z))指定 C++ 原型,则 IDA 执行类型降低并将其转换为具有显式参数位置的 C 样式原型:

struct A *__cdecl func1(struct A *__return_ptr __struct_ptr retstr, int z)

它目前似乎__return_ptr没有被 IDA 或反编译器使用,只是给用户的一个注释,但理论上它可以用来使反编译的代码更接近原始 C++ 语法。