IDA技巧(107)多重返回值

admin 2025年2月7日15:40:38评论10 views字数 1091阅读3分38秒阅读模式

    Hex-Rays反编译器最初是为了解析C代码而创建的,因此其伪代码输出主要使用C语法。然而,输入的二进制文件可能是用其他语言编译的:C++、Pascal、Basic、ADA等。虽然大多数代码可以用C语言表示而没有实际问题,但有些代码有其特殊性,需要语言扩展或通过用户输入来处理。

    还有一些语言使用的方式与标准编译的C代码非常不同,因此需要特别处理。例如,Go使用的调用约定(基于栈或寄存器)与标准C调用约定非常不同,因此需要为其在IDA中添加自定义支持。

多重返回值

即使有自定义调用约定,IDA的类型系统仍然存在一个基本限制(截至IDA 8.0):一个函数只能返回一个值。然而,即使在其他C风格的程序中,你也可能遇到返回多个值的函数。一个例子是编译器助手如idivmod/uidivmod

它们同时返回除法运算的商和余数。反编译器知道标准的(例如ARM EABI的__aeabi_idivmod),但你可能会遇到非标准实现,或使用类似方法的无关函数(例如手动用汇编编写的函数)。

因为反编译器不期望函数返回多个值,你可能需要检查反汇编或查看调用位置来识别这样的函数。例如,这里是一个反编译的ARM32代码片段,似乎使用了未定义的寄存器值:

IDA技巧(107)多重返回值

该函数似乎修改了R1寄存器,尽管通常返回值(对于32位类型)放在R0中。可能这是一个等价的divmod函数,它在R0中返回商,在R1中返回余数?

为了解决这个问题,我们可以使用一个人工结构体和一个自定义调用约定,指定它应该放置的寄存器和/或栈位置。例如,将这样的结构体添加到本地类型:

ounter(lineounter(lineounter(lineounter(lineounter(linestructdivmod_t{int quot;int rem;};

并设置函数原型:divmod_t __usercall my_divmod@<R1:R0>(int@<R0>, int@<R1>);

然后反编译器将调用后的寄存器值解释为结构体字段:

IDA技巧(107)多重返回值

类似的方法可以用于原生支持多重返回值函数的语言:Go、Swift、Rust等。

学习资源

立即关注【二进制磨剑】公众号

👉👉👉【IDA 技巧合集】👈👈👈
👉👉👉【Github 安全项目合集】👈👈👈
零基础学习 IDA 逆向
【课程完结!内容揭秘!】7 天打造 IDA 9.0 大师:从零基础到逆向精英
🔥🔥🔥 第二期 Android 内核逆向🔥🔥🔥🔥
【课程完结!内容揭秘】第 2 期-Android 逆向内核攻防
🔥🔥🔥 第三期 程序混淆十讲🔥🔥🔥🔥
【课程】第 3 期-程序混淆十讲【早鸟报名开启】

原文始发于微信公众号(二进制磨剑):IDA技巧(107)多重返回值

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月7日15:40:38
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   IDA技巧(107)多重返回值https://cn-sec.com/archives/3709664.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息