在 PE文件头的 IMAGE_OPTIONAL_HEADEGL450 布局中的 DataDirectory(数据目录表卡塔尔(英语:State of Qatar)的第二个成员就是指向输入表的。各类被链接进来的 DLL文件都各自对应多个IMAGE_IMPORT_DESC揽胜IPTOLX570 (简单的称呼IID卡塔尔国 数组构造。

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
    } DUMMYUNIONNAME;
    DWORD   TimeDateStamp;                  // 0 if not bound,
                                            // -1 if bound, and real datetime stamp
                                            // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                            // O.W. date/time stamp of DLL bound to (Old BIND)

    DWORD   ForwarderChain;                 // -1 if no forwarders
    DWORD   Name;
    DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

在这里个
IID数组中,并不曾建议有微微个项(就是未有明显指明有些许个链接文件卡塔尔国,但它提及底是以八个全为NULL(0卡塔尔(英语:State of Qatar)的 IID 作为达成的标识。

下边只摘录举足轻重的字段:

在 PE文件头的 IMAGE。OriginalFirstThunk

在 PE文件头的 IMAGE。它指向first thunk,IMAGE_THUNK_DATA,该 thunk 拥有 Hint 和 Function
name 的地址。

Name

它意味着DLL
名称的相持虚地址(译注:相对一个用null作为达成符的ASCII字符串的三个XC90VA,该字符串是该导入DLL文件的名目。如:KELacrosseNEL32.DLL)。

FirstThunk

它富含由IMAGE_在 PE文件头的 IMAGE。THUNK_DATA定义的 first
thunk数组的虚地址,通过loader用函数虚地址开头化thunk。

在Orignal First Thunk缺席下,它指向first thunk:Hints和The Function
names的thunks。

 

上边来声明下OriginalFirstThunk和FirstThunk。就个人知道来说:

1.
在文书中时,他们都分别针对八个RubiconVA地址。这么些地方转换来文件中,分别对应七个以
IMAGE_在 PE文件头的 IMAGE。THUNK_在 PE文件头的 IMAGE。DATA 为要素的的数组,那七个数组是以二个填写为 0
的IMAGE_THUNK_DATA作为完成标记符。即使他们那五个表地点分裂,但实际上内容是大同小异的。那个时候,各样IMAGE_THUNK_DATA 成分指向的是贰个记下了函数名和相对应的DLL文件名的
IMAGE_IMPORT_BY_NAME结构体。

  1. 为什么会有五个后生可畏律的数组呢?是有缘由的:

OriginalFirstThunk 指向的数组常常可以称作  hint-name table,即 HNT ,他在 PE
加载到内部存款和储蓄器中时被保留了下来且长久不会被修正。不过在 Windows 加载过 PE
到内部存款和储蓄器之后,Windows 会重写 FirstThunk
所指向的数组成分中的内容,使得数组中每一个 IMAGE_THUNK_DATA
不再代表针对带有函数描述的 IMAGE_THUNK_DATA
成分,而是径直指向了函数地址。当时,FirstThunk
所指向的数组就叫做输入地址表(Import Address Table ,即平日说的
IAT)。

重写前:

澳门葡亰娱乐场手机版 1

重写后:

 澳门葡亰娱乐场手机版 2

(以上两张图纸来源于:)

typedef struct _IMAGE_THUNK_DATA32 {
    union {
        DWORD ForwarderString;      // PBYTE  指向一个转向者字符串的RVA
        DWORD Function;             // PDWORD 被输入的函数的内存地址
         DWORD Ordinal;              // 被输入的 API 的序数值
         DWORD AddressOfData;        // PIMAGE_IMPORT_BY_NAME   指向 IMAGE_IMPORT_BY_NAME
    } u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;

根据 _IMAGE_THUNK_DATA32 所指虚构地址转到文件地方能够赢得实质上的
_IMAGE_IMPORT_BY_NAME 数据

typedef struct _IMAGE_IMPORT_BY_NAME {
    WORD   Hint;     // 序号 

    CHAR   Name[1];  // 实际上是一个可变长的以0为结尾的字符串

} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

 

比方说有前后相继:

澳门葡亰娱乐场手机版 3

澳门葡亰娱乐场手机版,文字版:

#include <windows.h>
int WINAPI WinMain(_In_ HINSTANCE hInstance, 
    _In_opt_ HINSTANCE hPrevInstance,
    _In_ LPSTR lpCmdLine,
    _In_ int nShowCmd)
{
    MessageBoxA(0, "hello", "my message", MB_OK);
    SetWindowTextA(0, "Si Wang");

    return 0;
}

此程序选择了七个 Windows API : MessageBoxA 和 SetWindowTextA

编写翻译得到程序(为简化表明,区段地点由软件总计出):

澳门葡亰娱乐场手机版 4

澳门葡亰娱乐场手机版 5

咱俩试着寻觅 MessageBoxA。首先解析 PE 头文件,找到导出表在文书中的地点:

澳门葡亰娱乐场手机版 6

输入表地点在 .rdata 区段内, 0x2264 – 0x二零零三 = 0x0264
获得偏移量。加上文件地方 0x0E00 获得实质上文件偏移量(0x0E00 + 0x264 =
0x1064):0x1064。

接下去查看 0x1064 处:

澳门葡亰娱乐场手机版 7

能够赢得七个 DLL 的叙说,最终多个_IMAGE_IMPORT_DESCHighlanderIPTOENVISION以0填充表示结束:

那正是说只要贰个个翻看各类DLL对应的数量就会找到,但是在此以前本人把全部的数码都看了下,在第二个DLL中

遵照第多少个DLL描述的 OriginalFirstThunk 的 0x2350
调换能够知晓,_IMAGE_THUNK_DATA32 在文件的 0x1150处,FirstThunk
指向的数额豆蔻年华致:

澳门葡亰娱乐场手机版 8

于是乎就拿走了文件中的 MessageBoxA 的音信。

最终,在内部存款和储蓄器中 FirstThunk 所指地方上的_IMAGE_THUNK_DATA32 数组被
Windows 加载后被重写后就成了逸事中的 IAT ,Import Address
Table,输入地址表。使用 OllyDbg 查看运维时意况:

澳门葡亰娱乐场手机版 9