什么样的函数创建了这种代码模式?

逆向工程 二元分析 反编译 吉德拉
2021-06-26 22:50:38

如果这是重复的,请道歉。不知道要搜索什么词,因为这就是问题所在。

我对逆向工程二进制文件比较陌生,在使用 Ghidra 时,我注意到它经常反编译二进制文件以生成以下功能:

void FUN_803adb50(void)
{
  int in_r11;
  undefined4 unaff_r26;
  undefined4 unaff_r27;
  undefined4 unaff_r28;
  undefined4 unaff_r29;
  undefined4 unaff_r30;
  undefined4 unaff_r31;
  
  *(undefined4 *)(in_r11 + -0x18) = unaff_r26;
  *(undefined4 *)(in_r11 + -0x14) = unaff_r27;
  *(undefined4 *)(in_r11 + -0x10) = unaff_r28;
  *(undefined4 *)(in_r11 + -0xc) = unaff_r29;
  *(undefined4 *)(in_r11 + -8) = unaff_r30;
  *(undefined4 *)(in_r11 + -4) = unaff_r31;
  return;
}

这是从以下反汇编创建的:


                     *                          FUNCTION                          *
                     **************************************************************
                     void __stdcall FUN_803adb50(void)
                       assume GQR0 = 0x0
                       assume GQR1 = 0x0
                       assume GQR2 = 0x40004
                       assume GQR3 = 0x50005
                       assume GQR4 = 0x60006
                       assume GQR5 = 0x70007
                       assume GQR6 = 0x0
                       assume GQR7 = 0x0
                       assume r13 = 0x805dd0e0
                       assume r2 = 0x805e6700
     void              <VOID>         <RETURN>
                     FUN_803adb50
803adb50 93 4b ff e8     stw        r26,-0x18(r11)
                     **************************************************************
                     *                          FUNCTION                          *
                     **************************************************************
                     undefined GetVCTypeSomething()
                       assume GQR0 = 0x0
                       assume GQR1 = 0x0
                       assume GQR2 = 0x40004
                       assume GQR3 = 0x50005
                       assume GQR4 = 0x60006
                       assume GQR5 = 0x70007
                       assume GQR6 = 0x0
                       assume GQR7 = 0x0
                       assume r13 = 0x805dd0e0
                       assume r2 = 0x805e6700
     undefined         r3:1           <RETURN>
                     GetVCTypeSomething
803adb54 93 6b ff ec     stw        r27,-0x14(r11)
803adb58 93 8b ff f0     stw        r28,-0x10(r11)
803adb5c 93 ab ff f4     stw        r29,-0xc(r11)
803adb60 93 cb ff f8     stw        r30,-0x8(r11)
803adb64 93 eb ff fc     stw        r31,-0x4(r11)
803adb68 4e 80 00 20     blr

它经常发生,它必须是某种常见的模式,总是带有许多带有“unaff_”前缀的未定义类型的变量,这些变量被分配给具有“in_”前缀的相同数量的变量。它们也通常出现在调用函数的开头。我的直觉是它与类结构有关(我不确定原始二进制文件是 C 还是 C++),但鉴于我的搜索没有运气,我想我会在这里问。

什么(如果有的话)会产生这种反编译代码的通用代码模式是什么?

如果有一种方法可以编辑函数定义以生成更清晰的内容,则可以加分。

2个回答

关于unaff_in_前缀(来源):

inunaff:这通常表示在写入之前读取寄存器(并且它不包含传递给函数的参数)

因此,如果您在反编译器中遇到它们,则意味着它们的值在它们在函数中初始化之前使用(它们包含先前分配的值,在先前的函数之一中)。要解决此问题,您可以将这些寄存器作为参数添加到此函数中(右键单击 -> edit function signature)。您可以在此处此处查看更多详细信息

至于您要求的模式r11,ARM 中寄存器(我想这是您的二进制文件的体系结构)用于访问放置在堆栈上的局部函数变量。因此,您的函数(可能是 6 个参数构造函数)似乎初始化了某个类(具有 6 个成员),它是原始代码中某个局部变量(在调用者函数中声明)的一种类型。

这是符合PPC EABI 的编译器用于减少代码大小的辅助函数来自ctrsavres.asm

/* Routines for saving integer registers, called by the compiler.  */
/* Called with r11 pointing to the stack header word of the caller of the */
/* function, just beyond the end of the integer save area.  */

因为它是由编译器调用的,所以它的行为不像普通的函数r11,而是直接访问,无需先设置(由调用者设置)。