返回介绍

8.3 使用结构体模板

发布于 2024-10-11 21:05:42 字数 3231 浏览 0 评论 0 收藏 0

有两种方法可对反汇编代码清单中的结构体定义加以利用。首先,你可以重新格式化内存引用,将类似于 [ebx+8] 的数字结构体偏移量转换成诸如 [ebx+ch8_struct.field4] 之类的符号式引用,从而提高它们的可读性。后一种符号式引用提供了更多有关引用内容的信息。因为 IDA 使用一种层次表示法,因此,你可以清楚地知道,程序访问的是什么类型的结构体,访问的是该结构体中的哪一个字段。当程序通过指针来引用结构体时,这种应用结构体模板的技术最有用。第二种应用结构体模板的方法是,提供其他可应用于栈和全局变量的数据类型。

为了理解如何将结构体定义应用于指令操作数,我们把每个定义看成类似于一组枚举常量。例如,图 8-5 中 ch8_struct 的定义可以用下面的伪 C 代码表示:

enum {  
   ch8_struct.field1 = 0,  
   ch8_struct.field2 = 4,  
   ch8_struct.field3 = 6,  
   ch8_struct.field4 = 8,  
   ch8_struct.field5 = 16  
};

对于这样一个定义,你可将操作数中使用的任何常量值转换成其对应的符号形式。如图 8-7 是一个正在进行中的此类操作。内存引用 [ecx+10h] 可能访问的是 ch8_struct 中的 field5 字段。

图 8-7 应用结构体偏移量

在图 8-7 中,右击 10h,即可在上下文菜单中看到 Structure offset(结构体偏移量)选项,它提供 3 种形式对指令操作数进行格式化。这 3 种形式全部是从包含一个偏移量为 16 的字段的结构体集合中提取出来的。

作为格式化内存引用的另一种方法,可以将栈和全局变量格式化成整个结构体。要将栈变量格式化成结构体,双击该变量,打开详细栈帧视图,然后使用 Edit ▶ Struct Var (ALT+Q)命令显示一组已知的结构体,如图 8-8 所示。

图 8-8 选择结构体对话框

选择其中一个结构体,可将栈中对应的字节数组合成对应的结构体类型,并将所有相关内存引用重新格式化成结构体引用。下面的代码摘自前面分析的栈分配的结构体示例:

.text:00401006                 mov     [ebp+var_18], 10  
.text:0040100D                 mov     [ebp+var_14], 20  
.text:00401013                 mov     [ebp+var_12], 30  
.text:00401017                 mov     [ebp+var_10], 40  
.text:0040101E                 fld     ds:dbl_40B128  
.text:00401024                 fstp    [ebp+var_8]

记得前面得出结论, var_18 实际上是一个大小为 24 字节的结构体的第一个字段。上述代码的详细栈帧如图 8-9 所示。

图 8-9 格式化之前的栈分配的结构体

选择 var_18 并将其格式化成 ch8_struct (Edit ▶ Struct Var),会将以 var_18 开头的 24 个字节( ch8_struct 的大小)折叠成一个变量,并得到如图 8-10 所示的重新格式化后的栈窗口。在这个例子中,对 var_18 应用结构体模板将生成一条警告消息,指出在将 var_18 转换为结构体的过程中,有一些变量将会遭到破坏。基于我们前面的分析,我们已经意识到这种情况,因此,我们只需认可该警告消息,完成操作即可。

图 8-10 格式化之后的栈分配的结构体

重新格式化之后,IDA 认识到,任何对分配给 var_18 的 24 个字节块的内存引用,都必须引用该结构体中的一个字段。如果 IDA 发现这样一个引用,它会尽一切努力,将这个内存引用与结构体变量中的一个已定义的字段关联起来。在这个特例中,反汇编代码清单会自动进行重新格式化,以合并结构体布局,如下所示:

.text:00401006                 mov     [ebp+var_18.field1], 10  
.text:0040100D                 mov     [ebp+var_18.field2], 20  
.text:00401013                 mov     [ebp+var_18.field3], 30  
.text:00401017                 mov     [ebp+var_18.field4], 40  
.text:0040101E                 fld     ds:dbl_40B128  
.text:00401024                 fstp    [ebp+var_18.field5]  

在反汇编代码清单中使用结构体表示法的好处在于,它从总体上提高了反汇编代码清单的可读性。在重新格式化后的窗口中使用字段名称,能够更加准确地反映源代码是如何操纵数据的。

将全局变量格式化成结构体的过程与格式化栈变量所使用的过程几乎完全相同。要进行格式化,选择要格式化的变量,或者表示结构体开头部分的地址,再使用 Edit ▶ Struct Var (ALT+Q)选择合适的结构体类型即可。作为针对未定义的全局数据(不是栈数据)的备选方案,你可以使用 IDA 的上下文菜单选择要查看的结构体选项,并选择要应用于所选地址的可用结构体模板。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文