PE文件中的IAT和IET

PE文件中的IAT和IET

IAT

IAT中文名叫导入地址表

在IAT中存放的是导入的函数的RVA数组,每个元素对应一个函数的地址(RVA)

通过这个RVA即可找到导入函数的位置

所以说我们必须先知道IAT在哪

1.找到可选头结构体的最后一个成员

可选头结构体的最后一个成员是DataDirectory

它是一个结构体数组

typedef struct _IMAGE_OPTIONAL_HEADER {
  WORD                 Magic;
  BYTE                 MajorLinkerVersion;
  BYTE                 MinorLinkerVersion;
  DWORD                SizeOfCode;
  DWORD                SizeOfInitializedData;
  DWORD                SizeOfUninitializedData;
  DWORD                AddressOfEntryPoint;
  DWORD                BaseOfCode;
  DWORD                BaseOfData;
  DWORD                ImageBase;
  DWORD                SectionAlignment;
  DWORD                FileAlignment;
  WORD                 MajorOperatingSystemVersion;
  WORD                 MinorOperatingSystemVersion;
  WORD                 MajorImageVersion;
  WORD                 MinorImageVersion;
  WORD                 MajorSubsystemVersion;
  WORD                 MinorSubsystemVersion;
  DWORD                Win32VersionValue;
  DWORD                SizeOfImage;
  DWORD                SizeOfHeaders;
  DWORD                CheckSum;
  WORD                 Subsystem;
  WORD                 DllCharacteristics;
  DWORD                SizeOfStackReserve;
  DWORD                SizeOfStackCommit;
  DWORD                SizeOfHeapReserve;
  DWORD                SizeOfHeapCommit;
  DWORD                LoaderFlags;
  DWORD                NumberOfRvaAndSizes;
  IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

它的每个元素是一个IMAGE_DATA_DIRECTORY(IDD)结构体

typedef struct _IMAGE_DATA_DIRECTORY {
  DWORD VirtualAddress;
  DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

2.找DataDirectory数组的第二个成员

在这里插入图片描述

上图就是DataDirectory数组,每个元素就是上面说的IDD结构体

我们找到第二个元素IMPORT Table

可以得到它的RVA和Size(对应的就是IDD结构体的VirtualAddress和Size成员)

3.通过找到的RVA我们转到IMPORT Table的地址

这个地址也是一个结构体数组,每个元素都是一个IMAGE_IMPORT_DESCRIPTOR(IID)结构体

该结构体有20个字节大小

typedef struct _IMAGE_IMPORT_DESCRIPTOR{
	union{
		DWORD Characteristics;
		DWORD OriginalFirstThunk;	//INT的RVA
	};
	DWORD TimeDateStamp;
	DWORD ForwarderChain;
	DWORD Name;						//导入的库的名称的RVA
	DWORD FirstThunk;				//IAT的RVA
}IMAGE_IMPORT_DESCRIPTOR;

通过该结构体的最后一个成员我们得到IAT的RVA

在这里插入图片描述

上图中蓝色部分即为IMPORT Table数组中的第一个元素

4.通过IID找IAT

找到IID后(这里我们选的是IMPORT Table数组中的第一个元素)

通过最后一个4字节成员0x1000(即IAT的RVA),找到IAT的地址

在这里插入图片描述

图中蓝色部分即为导入函数的RVA,

注意IAT是一个地址数组,数组元素全都是导入函数的RVA

这里,我们选第一个地址0xC1708,转到相应地址查看

在这里插入图片描述

可以看到导入函数的相应信息

注意:这里的相关信息是一个IMAGE_IMPORT_BY_NAME结构体(图中蓝色部分)

其实上面的IAT地址处是地址数组,也是IMAGE_IMPORT_BY_NAME结构体的指针数组

每个地址都是一个IMAGE_IMPORT_BY_NAME结构体的指针

IMAGE_IMPORT_BY_NAME结构体定义如下:

typedef struct _IMAGE_IMPORT_BY_NAME{
	WORD Hint;				//导入函数的源(就是一个标识)
	BYTE Name[1];			//导入函数的名称
}IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

IET

IET简单理解就是一个应用程序或库需要给别的程序用的函数,即导出函数表

怎么找到IET的导出函数的地址?

1.找可选头最后一个成员DataDirectory

找到DataDirectory[0]

DataDirectory的第一个元素就是EXPORT Table

在这里插入图片描述

通过其RVA转到相应地址

2.找到IET倒数第三个成员

在这里插入图片描述

上图蓝色部分即为IET,可以发现:

IET地址处只有一个结构体(IED,40个字节),与IAT地址处相比较,IAT地址处是一个结构体数组,每个元素都是一个20字节的IID结构体

IET地址处的结构体为IMAGE_EXPORT_DIRECTORY(IED)

IED结构体定义如下:

typedef struct _IMAGE_EXPORT_DIRECTORY{
	DWORD Characteristics;
	DWORD TimeDateStamp;
	WORD MajorVersion;
	WORD MinorVersion;
	DWORD Name;					//库的名称地址(RVA)
	DWORD Base;
	DWORD NumberOfFunctions;
	DWORD NumberOfNames;
	DWORD AddressOfFunctions;	//导出函数的起始地址(RVA)这个地址里面										是一个地址数组,每个地址就是一个导出函数的地址
	DWORD AddressOfNames;		//库中导出函数的名称地址(RVA)
	DWORD AddressOfNameOrdinals;
}IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

找到AddressOfFunctions的RVA

在这里插入图片描述

3.通过找到的AddressOfFunctions转到相应地址

转到B5A0C

在这里插入图片描述

这里我们随便选一个地址看看,如第一个4EF9A(RVA),将其加上文件映射基址(我的环境下是77DE0000),得到77E2EF9A(VA)
77E2EF9A这个地址在OD中即可找到相应导出函数(但是我的环境下不知道为什么OD不显示…请大神指点)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值