创建具有已知大小的结构
有时候你知道结构的大小,但实际布局还不清楚。例如,当为结构分配的内存大小是固定(malloc(0x598)
)的时候:
在这种情况下,你可以快速地创建一个 dummy 结构,然后在分析与之配合工作的代码时进行修改。在这里可以使用几种不同的方法。
方法 1:单一数组
这是最快的选项,但使结构修改有点别扭。
-
创建结构体(转到结构视图,按Ins并指定名称); -
创建数组(将光标定位在结构的开头,按 * 并输入大小(十进制或十六进制)
创建成功后,只有一个数组
当需要在中间创建一个字段时,按 * 调整数组大小,使其在字段之前结束,然后创建字段,然后在其后创建另一个数组,以再次填充结构体到完整大小。
方法 2:中间有很大的间隙
-
创建结构体(进入结构视图,按Ins并指定一个名称); -
创建一个字节字段(按D); -
添加一个间隔(Ctrl-E或右键单击选择“Expand struct type..”),并输入大小减 1; -
(可选但建议)在现在位于结构体末尾的field_0上,按N,Del,Enter。这将重置名称以匹配实际偏移量,并且不会妨碍在需要时在偏移量0处创建另一个field_0。
在间隙中创建字段,转到结构体中的特定偏移量(对于大结构体,可以使用G键跳转偏移)。
方法 3:填充 dummy 字段
-
创建结构体(转到结构视图,按Ins键并指定名称); -
创建一个虚拟字段(例如 dword); -
按 * 键并输入大小(如果与字节大小不同则除以字段大小)。取消选中“作为数组创建”并单击确定。
方法 4:从代码中自动生成字段
使用中间有间隙的结构(上述方法2)在分析使用固定寄存器基础的函数时尤其有用。例如,此函数使用rbx作为结构的基础:
ATI6000Controller::initializeProjectDependentResources(void) proc near
push rbp
mov rbp, rsp
push rbx
sub rsp, 8
mov rbx, rdi
lea rax, `vtable for'NI40SharedController
mov rdi, rbx ; this
call qword ptr [rax+0C30h]
test eax, eax
jnz loc_25CD
mov rax, [rbx+168h]
mov [rbx+4B8h], rax
mov rax, [rbx+178h]
mov [rbx+4C0h], rax
mov rax, [rbx+150h]
mov [rbx+4C8h], rax
mov [rbx+4B0h], rbx
mov rax, [rbx+448h]
mov [rbx+4D0h], rax
mov rcx, [rbx+170h]
mov [rbx+4D8h], rcx
mov rcx, [rax]
mov [rbx+4E0h], rcx
mov eax, [rax+8]
mov [rbx+4E8h], rax
call NI40PowerPlayManager::createPowerPlayManager(void)
mov [rbx+450h], rax
test rax, rax
jnz short loc_2585
mov eax, 0E00002BDh
jmp short loc_25CD
---------------------------------------------------------------
loc_2585:
mov rcx, [rax]
lea rsi, [rbx+4B0h]
...
自动为所有基于 rbx 的访问创建字段:
-
选择所有使用 rbx 的指令; -
从上下文菜单中选择“Structure offset”(或按T键); -
在对话框中,确保“寄存器”设置为rbx,选择创建的结构(红色叉表示当前匹配偏移量处没有字段); -
从右侧窗格的上下文菜单中选择“Add missing fields”。
你可以然后对这个结构中的所有其他函数重复这个操作,以创建其他缺失的字段。
原文始发于微信公众号(二进制磨剑):IDA 技巧(12)速学!逆向结构体的必会操作
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论