IDA Pro:从非标准 powerpc 堆栈寄存器定义局部变量

逆向工程 艾达 拆卸 电源
2021-07-05 04:54:44

我正在使用 IDA pro 6.95(付费版)来重新编写一些 PowerPC 代码。PowerPC 通常r1用作堆栈指针,因此 IDA 从r1. 参数传递中r3r4r5,等这个问题我有,我看到这一点:

.text: foo:
.text:.set back_chain, -0x30                     // Stack frame
.text: .set var_4, -4
.text: .set sender_lr,  4
<<<function preamble snipped>>>
.text:               mr        r31, r1        // Copy stack pointer to r31
.text:               stw       r3, 8(r31)     // All local variables are relative
.text:               stw       r4, 0xC(r31)   //  to r31, instead of r1, so IDA
                                              //  doesn't recognize them.

我想看看这个:

.text: foo:
.text:.set back_chain, -0x30                     // Stack frame
.text: .set var_C, -C
.text: .set var_8, -8
.text: .set var_4, -4
.text: .set sender_lr,  4
<<<function preamble snipped>>>
.text:                  mr        r31, r1        // Copy stack pointer to r31
.text:                  stw       r3, var_8(r31) // All local variables are
.text:                  stw       r4, var_C(r31) //  recognized and nameable.

我想要的是将8(r31)函数中的所有(例如)局部变量引用转换为正常var_8(r31)语法。我不想手动更改每个引用。有没有办法:

  • 说服 IDA 那r31是堆栈指针?
  • 在一个命令中全部更改8(31)var_8(r31)
  • 否则以我没有想到的方式获得我正在寻找的效果?
2个回答

免责声明:我不会在这里创建一个工作代码示例,我也没有在 PowerPC 上针对您的特定目的进行测试。青年会

我可以想到两种方法来做到这一点。首先是手动方法,通过使用一些 IDAPython 魔法来手动强制所有偏移量基于r31堆栈帧结构。第二个(可能使用的)就是为此使用指定的 API。

你需要:

  1. 获取您正在运行的函数的隐藏堆栈帧结构 ID
    这可以通过ida_frame.get_frame使用所需函数内的任何地址调用该函数来轻松完成此函数返回一个 ID,用于在 IDB 中标识此结构。

  2. 逐条检查指令并确定所有取消引用r31
    这里有很多方法。从获取反汇编字符串和解析实际文本到操作数特定的 API 等等。所以我将把它作为读者的第一个练习。

  3. 将这些取消引用设置为取消引用堆栈结构
    OffOpEx也是一个例子,有几个 API 可供选择如果您需要随时创建新的堆栈变量,也有多个函数可以做到这一点。

第二种方法是使用为此目的设计的两个 API 之一。这两个 API 被称为idc.define_local_varida_frame.add_regvar

define_local_var 定义如下:

def define_local_var(start, end, location, name):
    """
    Create a local variable
    @param start: start of address range for the local variable
    @param end: end of address range for the local variable
    @param location: the variable location in the "[bp+xx]" form where xx is
                     a number. The location can also be specified as a
                     register name.
    @param name: name of the local variable
    @return: 1-ok, 0-failure
    @note: For the stack variables the end address is ignored.
           If there is no function at 'start' then this function.
           will fail.
    """

如果需要,将完成定位堆栈结构和定义新成员的所有工作。这可能是您想玩的第一件事,但是您仍然需要迭代所有指令并r31手动识别偏移量。

add_regvar函数被调用define_local_var并负责将创建的变量define_local_var应用于指令。你可以在这里阅读更多关于它的信息

我遇到了类似的问题,并找到了以下解决方法:

  1. 创建字段偏移量等于您的r31偏移量的特定结构
  2. 对每个有趣的指令使用“结构偏移(T)”。