来自 编程 2019-10-07 11:20 的文章
当前位置: 澳门太阳娱乐手机登录 > 编程 > 正文

输入表结构和输入地址表

在 PE文件头的 IMAGE_OPTIONAL_HEADE凯雷德 结构中的 DataDirectory(数据目录表) 的第二个分子就是指向输入表的。各样被链接进来的 DLL文件都分别对应贰个IMAGE_IMPORT_DESCRubiconIPTO奥迪Q5 (简称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) 的 IID 作为完成的标识。

上面只摘录相当重大的字段:

OriginalFirstThunk

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

Name

它象征DLL 名称的相持虚地址(译注:相对四个用null作为实现符的ASCII字符串的一个HavalVA,该字符串是该导入DLL文件的称号。如:KEXC60NEL32.DLL)。

FirstThunk

它含有由IMAGE_THUNK_DATA定义的 first thunk数组的虚地址,通过loader用函数虚地址初始化thunk。

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

 

上边来批注下OriginalFirstThunk和FirstThunk。就个人领会来讲:

1. 在文书中时,他们都分别针对贰个索罗德VA地址。这么些地址调换成文件中,分别对应八个以 IMAGE_THUNK_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_DESC昂CoraIPTOENCORE以0填充表示结束:

那么一旦贰个个查看各样DLL对应的多寡就能够找到,可是从前作者把装有的数据都看了下,在首先个DLL中

依赖第4个DLL描述的 OriginalFirstThunk 的 0x2350 转换能够领略,_IMAGE_THUNK_DATA32 在文书的 0x1150处,FirstThunk 指向的数据一致:

澳门太阳娱乐在线网址 8

于是就得到了文件中的 MessageBoxA 的音讯。

澳门太阳娱乐在线网址,说起底,在内部存款和储蓄器中 FirstThunk 所指地方上的_IMAGE_THUNK_DATA32 数组被 Windows 加载后被重写后就成了轶事中的 IAT ,Import Address Table,输入地址表。使用 OllyDbg 查看运维时景况:

澳门太阳娱乐在线网址 9

本文由澳门太阳娱乐手机登录发布于编程,转载请注明出处:输入表结构和输入地址表

关键词: