间接返回值地址

逆向工程 艾达 C++ 调用约定 arm64
2021-06-17 15:01:19

我有usercall我不完全理解的调用约定,它返回std::string但 IDA 将其识别为void.

我注意到每个 calle 都是x8/w8wikipedia之后读取的

x8:用于保存间接返回值地址

有人可以解释“间接返回值地址”吗?

来自 https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019

返回值

整数值在 x0 中返回。

浮点值在 s0、d0 或 v0 中返回,视情况而定。

HFA 和 HVA 值在 s0-s3、d0-d3 或 v0-v3 中返回,视情况而定。

值返回的类型根据它们是否具有某些属性进行不同的处理。具有所有这些属性的类型,

它们由 C++14 标准定义聚合,也就是说,它们没有用户提供的构造函数,没有私有或受保护的非静态数据成员,没有基类,也没有虚函数,并且它们有一个简单的副本——赋值运算符,并且它们有一个简单的析构函数,使用以下返回样式:

小于或等于 8 个字节的类型在 x0 中返回。小于或等于 16 个字节的类型在 x0 和 x1 中返回,其中 x0 包含低位 8 个字节。

对于大于 16 字节的类型,调用者应保留足够大小和对齐的内存块来保存结果。内存块的地址应作为附加参数传递给 x8 中的函数。被调用者可以在子程序执行期间的任何时候修改结果内存块。被调用者不需要保留存储在 x8 中的值。

所有其他类型都使用此约定:

调用者应保留一个足够大小和对齐的内存块来保存结果。内存块的地址应作为附加参数传递给 x0 中的函数,如果 $this 在 x0 中传递,则应将其作为 x1 传递。被调用者可以在子程序执行期间的任何时候修改结果内存块。被调用者返回 x0 中内存块的地址。

更新 2:

来自ARM 文档

有特殊用途的寄存器

• X8 是间接结果寄存器。这用于传递间接结果的地址位置,例如,函数返回大型结构的地方。...

...该结构包含超过 16 个字节。根据 AArch64 的 AAPCS,返回的对象将写入 XR 指向的内存中。

1个回答

来自https://github.com/Siguza/ios-resources/blob/master/bits/arm64.md

如果 >128 位,则指向写入返回值的位置的 x8 指针,否则暂存寄存器

因此,似乎 x8 用于传递一个地址,如果它太大,则返回值将落在该地址上,而不是直接返回值,因此我认为是间接的。

我找不到官方文档,因为我几乎没有加载 ARM 页面。