PE文件,导入表定位

使用16进制编辑器,在PE文件种定位到导入表的过程。


1.  前64字节MZ文件头,最后的4个字节是PE文件头的位置。

2.  找到PE文件头。

3.  PE文件头第24字节偏移处是可选头。

4.  可选头0x70偏移处是IMAGE_DATA_DIRECTORY数组

5.  该数组长64字节,第二个元素为导入表的IMAGE_DATA_DIRECTORY

6.  导入表的IMAGE_DATA_DIRECTORY的前32位是导入表的RVA

7.  查节表确定导入表在哪个节,然后利用节表获得导入表的文件偏移

8.  定位到导入表

9.  导入表为一个IMAGE_IMPORT_DESCRIPTOR数组,每个被导入的文件对应一项,定义如下:

typedef struct _IMAGE_IMPORT_DESCRIPTOR {

DWORD    OriginalFirstThunk;

DWORD    TimeDateStamp;

DWORD     ForwarderChain;

DWORD     Name;

DWORD      FirstThunk;

}IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;

成员含义如下:

OriginalFirstThunk

它指向first thunk,IMAGE_THUNK_DATA,该thunk拥有Hint和Function name的地址。

TimeDateStamp

如果那里有绑定的话它包含时间/数据戳(time/data stamp)。如果它是0,就没有绑定在被导入的DLL中发生。在最近,它被设置为0xFFFFFFFF以表示绑定发生。

ForwarderChain

在老版的绑定中,它引用API的第一个forwarder chain(传递器链表)。它可被设置为0xFFFFFFFF以代表没有forwarder。

Name

它表示DLL 名称的相对虚地址(译注:相对一个用null作为结束符的ASCII字符串的一个RVA,该字符串是该导入DLL文件的名称,如:KERNEL32.DLL)。

FirstThunk

它包含由IMAGE_THUNK_DATA定义的 first thunk数组的虚地址,通过loader用函数虚地址初始化thunk。在Orignal First Thunk缺席下,它指向first thunk:Hints和The Function names的thunks。

10.    从Name成员可以得到被导入文件名的RVA,利用节表可以获得文件偏移,可以看到被导入文件的名称。

11.    从OriginalFirstThunk可以得到IMAGE_THUNK_DATA结构数组的RVA,利用节表得到其文件偏移。IMAGE_THUNK_DATA结构定义为:

typedef struct _IMAGE_THUNK_DATA32 {

PIMAGE_IMPORT_BY_NAME  AddressOfData;

} IMAGE_THUNK_DATA32;

12.    从中得到IMAGE_IMPORT_BY_NAME结构的RVA,利用节表得到文件偏移。IMAGE_IMPORT_BY_NAME结构定义为:

typedef struct _IMAGE_IMPORT_BY_NAME {

WORD    Hint;

BYTE    Name[1];

}IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

成员含义如下:

Hint

指示本函数在其所驻留DLL的引出表中的索引号。该域被PE装载器用来在DLL的引出表里快速查询函数。该值不是必须的,一些连接器将此值设为0。

Name1

含有引入函数的函数名。函数名是一个ASCIIZ字符串。注意这里虽然将Name1的大小定义成字节,其实它是可变尺寸域,只不过我们没有更好方法来表示结构中的可变尺 寸域。

你可能感兴趣的:(文档格式)