IDA 设置结构数组以使用枚举值

逆向工程 艾达
2021-07-04 10:58:05

如何告诉 IDA 结构中数组的索引是什么?我想我需要告诉它使用枚举,但我不确定如何。我正在研究实用逆向工程并遵循第 3 章中的 x86 Rootkit 演练。

它通过在此处反转 DriverObject 函数指针的设置进行演练:

01: .text:00010643   mov     ecx, [ebp+DriverObject]
02: .text:00010646   mov     dword ptr [ecx+38h], offset sub_10300
03: .text:0001064D   mov     edx, [ebp+DriverObject]
04: .text:00010650   mov     dword ptr [edx+40h], offset sub_10300
05: .text:00010657   mov     eax, [ebp+DriverObject]
06: .text:0001065A   mov     dword ptr [eax+70h], offset sub_10300
07: .text:00010661   mov     ecx, [ebp+DriverObject]
08: .text:00010664   mov     dword ptr [ecx+34h], offset sub_10580

接下来,我定义了一个 Driver_Object 结构,IDA 获取了 MajorFunction 偏移量

.text:00010643 mov     ecx, [ebp+DriverObject]
.text:00010646 mov     [ecx+_DRIVER_OBJECT.MajorFunction], offset sub_10300
.text:0001064D mov     edx, [ebp+DriverObject]
.text:00010650 mov     [edx+(_DRIVER_OBJECT.MajorFunction+8)], offset sub_10300
.text:00010657 mov     eax, [ebp+DriverObject]
.text:0001065A mov     [eax+(_DRIVER_OBJECT.MajorFunction+38h)], offset sub_10300
.text:00010661 mov     ecx, [ebp+DriverObject]
.text:00010664 mov     [ecx+_DRIVER_OBJECT.DriverUnload], offset driverUnload

MajorFunction 被定义为一个数组,但我想让 IDA 显示这些偏移量代表什么。wdm.h 定义偏移量如下:

#define IRP_MJ_CREATE                   0x00
#define IRP_MJ_CREATE_NAMED_PIPE        0x01
#define IRP_MJ_CLOSE                    0x02
...

基本上,我希望在反汇编中看到类似以下内容:

.text:0001064D mov     edx, [ebp+DriverObject]
.text:00010650 mov     [edx+(_DRIVER_OBJECT.MajorFunction+IRP_MJ_CLOSE)], offset sub_10300
.text:00010657 mov     eax, [ebp+DriverObject]
.text:0001065A mov     [eax+(_DRIVER_OBJECT.MajorFunction+IRP_MJ_DEVICE_CONTROL)], offset sub_10300

IDA 的 Driver Object 定义如下:

struct __declspec(align(4)) _DRIVER_OBJECT
{
  ...
  void (__stdcall *DriverUnload)(_DRIVER_OBJECT *);
  int (__stdcall *MajorFunction[28])(_DEVICE_OBJECT *, _IRP *);
};
1个回答

我不认为你可以直接在 IDA 中做到这一点,尽管 Hex-Rays 做到了。例如,在 PE 标头IMAGE_DATA_DIRECTORY DataDirectory[16]数组中,各个元素的名称由#define诸如IMAGE_DIRECTORY_ENTRY_EXPORT. 在这里,我们看到了对 index 元素的访问0

访问 pe->DataDirectory 0

很高兴看到枚举元素的符号名称0我们可以简单地将光标放在 上0,按下m,然后将常量更改为枚举元素,就像我们在反汇编列表中所做的那样:

将索引更改为枚举元素

反汇编列表中有针对您的特定示例的解决方法。你可以声明一个新的结构类型——比如说DRIVER_CALLBACK_FUNCTIONS,,像这样:

struct DRIVER_CALLBACK_FUNCTIONS {
  int (__stdcall *IRP_MJ_CREATE)(_DEVICE_OBJECT *, _IRP *);
  int (__stdcall *IRP_MJ_CREATE_NAMED_PIPE)(_DEVICE_OBJECT *, _IRP *);
  int (__stdcall *IRP_MJ_CLOSE)(_DEVICE_OBJECT *, _IRP *);
  // ... all 28 functions ...
};

然后修改定义_DRIVER_OBJECT:将MajorFunction[28]数组的定义改为DRIVER_CALLBACK_FUNCTIONS改为。