PE文件学习一
前言
最近学了免杀,正好把之前零散的东西整合了一下,本篇文章就先把PE文件的结构记录一下。
PE文件总体结构
DOS部首
DOS部首分为两部分,DOS Header
和DOS Stub
DOS Header
|
|
因为历史遗留问题,早期的Windows程序是运行在DOS系统(16位)上的,所以该部分主要是给DOS用的(向下兼容),目前在32位或64位Windows系统使用的成员是:
- e_magic
- e_lfanew
成员 | 数据宽度 | 注释 | 说明 | 值 |
---|---|---|---|---|
e_magic | WORD(2字节) | Magic Number | PE文件判断标识 | 4d 5a, ASCII = ‘MZ’ |
e_lfanew | LONG(4字节) | File address of new exe header | 存储PE头首地址 | 不定 |
DOS Stub
DOS Stub在32位及以上的Windows系统中同样无效
PE文件头 (PE_NT_HEADER)
PE文件头主要由三部分组成:
- PE文件头标志
- PE文件表头/标准PE头
- PE文件表头可选部分/拓展PE头
32位结构体
|
|
64位结构体
|
|
PE文件头标志 (Signature)
PE文件头标志 | 对应C语言变量 | 数据宽度 | 值 | 说明 |
---|---|---|---|---|
“PW”,0,0 | Signature | DWORD(4字节) | 50 45 00 00,ASCII = “PE " | PE文件标识符 |
PE文件表头 (PE_FILE_HEADER)
结构体代码
|
|
成员详情
成员 | 数据宽度 | 说明 | 值 |
---|---|---|---|
Machine | WORD(2字节) | 程序支持的CPU | 任意: 0;intel 386以及后续: 14C; x64: 8664 |
NumberOfSections | WORD(2字节) | 节的数量 | 不大于96 |
TimeDateStamp | DWORD(4字节) | 编译器填写的时间戳 | 与文件属性里面(创建时间、修改时间)无关 |
PointerToSymbolTable | DWORD(4字节) | 指向符号表 | 调试相关 |
NumberOfSymbols | DWORD(4字节) | 符号表中的符号个数 | 调试相关 |
SizeOfOptionalHeader | WORD(2字节) | 可选PE头大小 | 32位PE文件: 0xE0; 64位PE文件: 0xF0 |
Characteristics | WORD(2字节) | 文件属性 | 由数据位拼接而成 |
Machine
计算机的体系结构类型
值 | 含义 |
---|---|
IMAGE_FILE_MACHINE_I386 = 0x014c | x86 |
IMAGE_FILE_MACHINE_IA64 = 0x0200 | Intel IPF |
IMAGE_FILE_MACHINE_AMD64 = 0x8664 | x64 |
NumberOfSections
节数。表示PE文件头后面节表的数量
TimeDateStamp
Image时间戳的低32位
PointerToSymbolTable
符号表的偏移量,以字节为单位,如果不存在COFF符号表,则为零
NumberOfSymbols
符号表中的符号数
SizeOfOptionalHeader
拓展PE头的大小,以字节为单位
Characteristics
Image的文件属性
数据位 | 常量符号 | 为1时的含义 |
---|---|---|
0 | IMAGE_FILE_RELOCS_STRIPPED | 文件中不存在重定位信息 |
1 | IMAGE_FILE_EXECUTABLE_IMAGE | 文件是可执行的 |
2 | IMAGE_FILE_LINE_NUMS_STRIPPED | 不存在行信息 |
3 | IMAGE_FILE_LOCAL_SYMS_STRIPPED | 不存在符号信息 |
4 | IMAGE_FILE_AGGRESSIVE_WS_TRIM | 调整工作集 |
5 | IMAGE_FILE_LARGE_ADDRESS_AWARE | 应用程序可处理大于2GB的地址 |
6 | 保留 | |
7 | IMAGE_FILE_BYTES_REVERSED_LO | 小尾方式 |
8 | IMAGE_FILE_32BIT_MACHINE | 只在32位平台上运行 |
9 | IMAGE_FILE_DEBUG_STRIPPED | 不包含调试信息 |
10 | IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP | 不能从移动硬盘运行 |
11 | IMAGE_FILE_NET_RUN_FROM_SWAP | 不能从网络运行 |
12 | IMAGE_FILE_SYSTEM | 系统文件(如驱动程序),不能直接运行 |
13 | IMAGE_FILE_DLL | 这是一个DLL文件 |
14 | IMAGE_FILE_UP_SYSTEM_ONLY | 文件不能在多处理器计算机上运行 |
15 | IMAGE_FILE_BYTES_REVERSED_HI | 大尾方式 |
PE文件拓展头 (PE_OPTIONAL_HEADER)
32位结构体
|
|
64位结构体
|
|
成员详情
成员 | 数据宽度 | 说明 |
---|---|---|
Magic | WORD(2字节) | 镜像文件的状态,可用于判断程序是32位还是64位 |
MajorLinkerVersion | BYTE(1字节) | 链接器的主要版本号 |
MinorLinkerVersion | BYTE(1字节) | 链接器的次要版本号 |
SizeOfCode | DWORD(4字节) | 代码段的大小 |
SizeOfInitializedData | DWORD(4字节) | 初始化数据段的大小 |
SizeOfUninitializedData | DWORD(4字节) | 未初始化数据段的大小 |
AddressOfEntryPoint | DWORD(4字节) | 程序入口 |
BaseOfCode | DWORD(4字节) | 代码开始的基址 |
BaseOfData | DWORD(4字节) | 数据开始的基址 |
ImageBase | DWORD(4字节) | 内存镜像的基址 |
SectionAlignment | DWORD(4字节) | 内存对齐 |
FileAlignment | WORD(2字节) | 文件对齐 |
MajorOperatingSystemVersion | WORD(2字节) | 标识操作系统版本号,主版本号 |
MinorOperatingSystemVersion | WORD(2字节) | 标识操作系统版本号,次版本号 |
MajorImageVersion | WORD(2字节) | PE文件自身的版本号 |
MinorImageVersion | WORD(2字节) | PE文件自身的版本号 |
MajorSubsystemVersion | WORD(2字节) | 运行所需子系统版本号 |
MinorSubsystemVersion | WORD(2字节) | 运行所需子系统版本号 |
Win32VersionValue | DWORD(4字节) | 子系统版本的值,必须为0 |
SizeOfImage | DWORD(4字节) | Image大小 |
SizeOfHeaders | DWORD(4字节) | 所有头+节表按照文件对齐后的大小 |
CheckSum | DWORD(4字节) | 校验和 |
Subsystem | WORD(2字节) | 子系统 |
DllCharacteristic | WORD(2字节) | 文件特性,不只是针对DLL文件的 |
SizeOfStackReserve | DWORD(4字节) | 初始化时保留的栈大小 |
SizeOfStackCommit | DWORD(4字节) | 初始化时实际提交的栈大小 |
SizeOfHeapReserve | DWORD(4字节) | 初始化时保留的堆大小 |
SizeOfHeapCommit | DWORD(4字节) | 初始化时提交的堆大小 |
LoaderFlags | DWORD(4字节) | 调试相关 |
NumberOfRvaAndSizes | DWORD(4字节) | 目录项数目 |
DataDirectory[16] | IMAGE_DATA_DIRECTORY[16]=128字节 | 指向数据目录中第一个IMAGE_DATA_DIRECTORY结构的指针(数据目录项) |
Magic
镜像文件的状态,该成员可以是以下值
值 | 含义 |
---|---|
IMAGE_NT_OPTIONAL_HDR_MAGIC | 该文件是一个可执行的映像 |
IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b | 该文件是一个可执行的映像(32位) |
IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b | 该文件是一个可执行的映像(64位) |
IMAGE_ROM_OPTIONAL_HDR_MAGIC = 0x107 | 该文件是ROM镜像 |
MajorLinkerVersion
链接器版本号
MinorLinkerVersion
链接器次要版本
SizeOfCode
代码段的大小(以字节为单位),如果有多个代码段,则为所有这些代码段的综合。是文件对齐后的大小,编译器填的
SizeOfInitializedData
初始化数据段的大小(以字节为单位),如果有多个代码段,则为所有这些数据段的总和。是文件对齐后的大小,编译器填的
SizeOfUninitializedData
未初始化数据段的大小(以字节为单位),如果有多个未初始化数据段,则为所有这些数据段的总和。是文件对齐后的大小,编译器填的
AddressOfEntryPoint
一个指向入口点函数的指针,相对于Image的基址
- 对于可执行文件,这是起始地址
- 对于设备驱动程序,这是初始化函数的地址
- 入口点函数对于dll是可选。当没有入口点存在时,该成员为零
BaseOfCode
指向代码段开头的指针,相当于ImageBase。编译器填的
BaseOfData
指向数据段开头的指针,相对于ImageBase。编译器填的
ImageBase
Image(PE文件)载入内存时第一个字节的首选地址。该值是64K字节的倍数
- dll的默认值是0x10000000
- 应用程序的默认值0x00400000
- Windows CE上的默认值0x00010000
SectionAlignment
加载到内存中的节的对齐方式,以字节为单位
FileAlignment
Image(PE文件)中各节的原始数据(以字节为单位)的对齐方式。该值应该是512到64k(包括)之间2的幂。
MajorOperatingSystemVersion
所需操作系统的主要版本号
MinorOperatingSystemVersion
所需操作系统的次要版本号
MajorImageVersion
镜像(PE文件)的主版本号
MinorImageVersion
镜像(PE文件)的次要版本号
MajorSubsystemVersion
子系统的主要版本号
Win32VersionValue
该成员保留的,并且必须为0
SizeOfImage
Image的大小,以字节为单位,包括所有头。必须是多个SectionAlignment
内存中整个PE文件的映射的尺寸,可比实际的值大,必须是SectionAlignment的整数倍
SizeOfHeaders
DOS部首+PE文件头+节表按照文件对齐后的大小
CheckSum
Image(PE文件)校验和
Subsystem
运行此映像所需的子系统。
宏定义 | 值 | 含义 |
---|---|---|
IMAGE_SUBSYSTEM_UNKNOWN | 0 | 未知的子系统 |
IMAGE_SUBSYSTEM_NATIVE | 1 | 不需要子系统(设备驱动程序和本机系统进程) |
IMAGE_SUBSYSTEM_WINDOWS_GUI | 2 | Windows图形用户界面子系统 |
IMAGE_SUBSYSTEM_WINDOWS_CUI | 3 | Windows字符模式用户界面(CUI)子系统 |
IMAGE_SUBSYSTEM_OS2_CUI | 5 | OS/2 CUI子系统 |
IMAGE_SUBSYSTEM_POSIX_CUI | 7 | POSIX CUI子系统 |
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI | 9 | Windows CE系统 |
IMAGE_SUBSYSTEM_EFI_APPLICATION | 10 | 可扩展固件接口(EFI)应用程序 |
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER | 11 | 带有引导服务的EFI驱动程序 |
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER | 12 | 带有运行时服务的EFI驱动程序 |
IMAGE_SUBSYSTEM_EFI_ROM | 13 | EFI ROM镜像 |
IMAGE_SUBSYSTEM_XBOX | 14 | Xbox系统 |
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION | 16 | 启动应用程序 |
DllCharacteristics
Image的DLL特性
宏定义 | 值 | 含义 |
---|---|---|
无 | 0x0001 | 保留,必须为0 |
无 | 0x0002 | 保留,必须为0 |
无 | 0x0004 | 保留,必须为0 |
无 | 0x0008 | 保留,必须为0 |
IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA | 0x0020 | 具有64位地址空间的ASLR |
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | 0x0040 | DLL可以在加载时重新定位 |
IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY | 0x0080 | 强制进行代码完整性检查。如果你设置了这个标志,并且section只包含未初始化的数据,那么将该section的IMAGE_SECTION_HEADER的PointerToRawData成员设置为0;否则,由于无法验证数字签名,Image将无法加载 |
IMAGE_DLLCHARACTERISTICS_NX_COMPAT | 0x0100 | 该映像与数据执行预防(DEP)兼容 |
IMAGE_DLLCHARACTERISTICS_NO_ISOLATION | 0x0200 | 映像可以被隔离,但不应该被隔离 |
IMAGE_DLLCHARACTERISTICS_NO_SEH | 0x0400 | 该映像不使用结构化异常处理(SEH)。在此映像中不能调用任何处理程序 |
IMAGE_DLLCHARACTERISTICS_NO_BIND | 0x0800 | 不要绑定映像 |
IMAGE_DLL_CHARACTERISTICS_APPCONTAINER | 0x1000 | 映像应该在AppContainer中执行 |
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER | 0x2000 | 一个WDM驱动 |
IMAGE_DLL_CHARACTERISTICS_GUARD_CF | 0x4000 | 映像支持控制流保护(Control Flow Guard) |
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE | 0x8000 | 该映像是终端服务器感知的 |
SizeOfStackReserve
为堆栈保留的字节数
SizeOfStackCommit
要提交给堆栈的字节数
SizeOfHeapReserve
为本地保留的字节数
SizeOfHeapCommit
要为本地堆提交的字节数
LoaderFlags
null
NumberOfRvaAndSizes
可选头的其余部分中的目录条目数
DataDirectory
指向数据目录第一个IMAGE_DATA_DIRECTORY结构的指针
所需目录条目的索引号,该参数可以是以下值之一
宏定义 | 值 | 含义 |
---|---|---|
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE | 7 | 特定于体系结构的数据,预留为0 |
IMAGE_DIRECTORY_ENTRY_BASERELOC | 5 | 基地址重定位表 |
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT | 11 | 绑定导入表 |
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR | 14 | COM描述符表 |
IMAGE_DIRECTORY_ENTRY_DEBUG | 6 | 调试表 |
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT | 13 | 延迟导入表 |
IMAGE_DIRECTORY_ENTRY_EXCEPTION | 3 | 异常表 |
IMAGE_DIRECTORY_ENTRY_EXPORT | 0 | 导出表 |
MAGE_DIRECTORY_ENTRY_GLOBALPTR | 8 | 全局指针的相对虚拟地址 |
IMAGE_DIRECTORY_ENTRY_IAT | 12 | 导入地址表 |
IMAGE_DIRECTORY_ENTRY_IMPORT | 1 | 导入表 |
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG | 10 | 加载配置表 |
IMAGE_DIRECTORY_ENTRY_RESOURCE | 2 | 资源表 |
IMAGE_DIRECTORY_ENTRY_SECURITY | 4 | 安全表 |
IMAGE_DIRECTORY_ENTRY_TLS | 9 | 线程本地存储表 |
节表 (PE_SECTION_HEADER)
|
|
成员详情
成员 | 数据宽度 | 说明 |
---|---|---|
Name | BYTE[8]=8字节 | 节名称 |
Misc.PhysicalAddress | DWORD(4字节) | 节的文件地址 |
Misc.VirtualSize | DWORD(4字节) | 节的虚拟大小 |
VirtualAddress | DWORD(4字节) | 节在内存中的偏移地址 |
SizeOfRawData | DWORD(4字节) | 节在文件中对齐后的尺寸 |
PointerToRawData | DWORD(4字节) | 节区在文件中的偏移 |
PointerToRelocations | DWORD(4字节) | .obj文件有效 |
PointerToLinenumbers | DWORD(4字节) | 调试相关 |
NumberOfRelocations | WORD(2字节) | .obj文件有效 |
NumberOfLinenumbers | WORD(2字节) | 行号表中行号的数量 |
Characteristics | DWORD(4字节) | 节的属性 |
Name
ASCII字符串,代表节的名字
Misc.PhysicalAddress
文件地址
Misc.VirtualSize
节加载到内存时的大小,以字节为单位
VirualAddress
在内存中的偏移地址,加上ImageBase才是内存中的真正地址
SizeOfRawData
磁盘上初始化数据的大小,以字节为单位。这个值必须是IMAGE_OPTIONAL_HEADER结构文件对齐FileAlignment成员的倍数。如果该值小于VirtualSize成员,则节的其余部分将被填充为0.如果该节只包含未初始化的数据,则该成员为零
PointerToRawData
节区在文件中的偏移,又被称为FOA: File Offset Address
文件偏移地址
PointerToRelocations
指向该节重定位项开始的文件指针。在.obj
文件中使用,指向重定位表的指针
PointerToLinenumbers
行号表的位置
NumberOfRelocations
重定位表的个数
NumberOfLinenumbers
行号表中行号的数量
Characteristics
节的特征
宏定义 | 值 | 含义 |
---|---|---|
无 | 0x00000000 | 保留 |
无 | 0x00000001 | 保留 |
无 | 0x00000002 | 保留 |
无 | 0x00000004 | 保留 |
IMAGE_SCN_TYPE_NO_PAD | 0x00000008 | 该节不得填塞至下一边界线。这个标志过时了,被IMAGE_SCN_ALIGN_1BYTES取代 |
无 | 0x00000010 | 保留 |
IMAGE_SCN_CNT_CODE | 0x00000020 | 该节包含可执行代码 |
IMAGE_SCN_CNT_INITIALIZED_DATA | 0x00000040 | 该节包含初始化的数据 |
IMAGE_SCN_CNT_UNINITIALIZED_DATA | 0x00000080 | 该节包含未初始化的数据 |
IMAGE_SCN_LNK_OTHER | 0x00000100 | 保留 |
IMAGE_SCN_LNK_INFO | 0x00000200 | 该节包含解释或其他信息。这只对object files有效 |
无 | 0x00000400 | 保留 |
IMAGE_SCN_LNK_REMOVE | 0x00000800 | 该节将不会成为image的一部分。这只对object files有效 |
IMAGE_SCN_LNK_COMDAT | 0x00001000 | 该节包含COMDAT数据。这只对object files有效。 |
无 | 0x00002000 | 保留 |
IMAGE_SCN_NO_DEFER_SPEC_EXC | 0x00004000 | 该节包含重置TLB项中的speculative异常处理位 |
IMAGE_SCN_GPREL | 0x00008000 | 该节包含通过全局指针引用的数据 |
无 | 0x00010000 | 保留 |
IMAGE_SCN_MEM_PURGEABLE | 0x00020000 | 保留 |
IMAGE_SCN_MEM_LOCKED | 0x00040000 | 保留 |
IMAGE_SCN_MEM_PRELOAD | 0x00080000 | 保留 |
IMAGE_SCN_ALIGN_1BYTES | 0x00100000 | 在1字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_2BYTES | 0x00200000 | 在2字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_4BYTES | 0x00300000 | 在4字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_8BYTES | 0x00400000 | 在8字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_16BYTES | 0x00500000 | 在16字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_32BYTES | 0x00600000 | 在32字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_64BYTES | 0x00700000 | 在64字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_128BYTES | 0x00800000 | 在128字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_256BYTES | 0x00900000 | 在256字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_512BYTES | 0x00A00000 | 在512字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_1024BYTES | 0x00B00000 | 在1024字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_2048BYTES | 0x00C00000 | 在2048字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_4096BYTES | 0x00D00000 | 在4096字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_ALIGN_8192BYTES | 0x00E00000 | 在8192字节的边界上对齐数据。这只对object files有效 |
IMAGE_SCN_LNK_NRELOC_OVFL | 0x01000000 | 该节包含扩展的重新定位。该节的重定位计数超过了节头中为其保留的16位。如果节头中的NumberOfRelocations字段为0xffff,则实际的重定位计数存储在第一次重定位的VirtualAddress字段中。如果设置了IMAGE_SCN_LNK_NRELOC_OVFL,并且该section中的重定位值小于0xffff,则会产生错误 |
IMAGE_SCN_MEM_DISCARDABLE | 0x02000000 | 该节可以根据需要丢弃 |
IMAGE_SCN_MEM_NOT_CACHED | 0x04000000 | 不能缓存该节 |
IMAGE_SCN_MEM_NOT_PAGED | 0x08000000 | 该节不能分页 |
IMAGE_SCN_MEM_SHARED | 0x10000000 | 该节可以在内存中共享 |
IMAGE_SCN_MEM_EXECUTE | 0x20000000 | 该节可以作为代码执行 |
IMAGE_SCN_MEM_READ | 0x40000000 | 该节可以读 |
IMAGE_SCN_MEM_WRITE | 0x80000000 | 该节可以写 |
导出表 (DataDirectory[0])
|
|
成员详情
成员 | 数据宽度 | 说明 |
---|---|---|
Characteristics | DWORD(4字节) | 标志,未用 |
TimeDateStamp | DWORD(4字节) | 时间戳 |
MajorVersion | WORD(2字节) | 未用 |
MinorVersion | WORD(2字节) | 未用 |
Name | DWORD(4字节) | 指向该导出表的文件名字符串 |
Base | DWORD(4字节) | 导出函数起始序号 |
NumberOfFunctions | DWORD(4字节) | 所有导出函数的个数 |
NumberOfNames | DWORD(4字节) | 以函数名字导出的函数个数 |
AddressOfFunctions | DWORD(4字节) | 导出函数地址表RVA |
AddressOfNames | DWORD(4字节) | 导出函数名称表RVA |
AddressOfNameOrdinals | DWORD(4字节) | 导出函数序号表RVA |
Characteristics
未使用,固定填充为0
TimeDateStamp
Image时间戳的低32位。表示链接器创建Image的日期和时间
MajorVersion
未使用,固定值填充0
MinorVersion
null
Name
指示的地址指向了一个"\0"
结尾的字符串,字符串记录了导出表所在的文件的最初文件名
Base
导出函数号的起始值。DLL中第一个导出函数并不是从0开始,相当于是个偏移量,需要加上AddressOfFunctions才是最终的函数地址
NumberOfFunctions
该字段定义了文件中导出函数的总个数
NumberOfNames
该字段记录了所有定义名字函数的个数,如果该值位0,则表示所有的函数都没有定义名字
AddressOfFunctions
该指针指向了全部导出函数的入口地址的起始
AddressOfNames
该指针指向一连串的DWORD值,这些值指向了对应的定义了函数名的字符串地址
AddressOfNameOrdinals
该值也是个指针,与AddressOfNames是一一对应关系。AddressOfNameOrdinals指向了该函数在AddressOfFunctions中的索引值
导入表 (DataDirectory[1])
导入表通常包含多个模块,所以导入表可能有多个。程序运行时,需要依赖几个模块,就对应几张导入表
|
|
成员详情
成员 | 数据宽度 | 说明 |
---|---|---|
Characteristics | DWORD(4字节) | 标志 为0表示结束 没有导入描述符了 |
OriginalFirstThunk | DWORD(4字节) | RVA指向IMAGE_THUNK_DATA结构数组(桥1) |
TimeDateStamp | DWORD(4字节) | 时间戳 |
ForwarderChain | DWORD(4字节) | 链表的前一个结构 |
Name | DWORD(4字节) | RVA,指向DLL名字,该名字以’’\0’‘结尾 |
FirstThunk | DWORD(4字节) | RVA指向IMAGE_THUNK_DATA结构数组(桥2) |
Characteristics
标志位0表示结束,没有导入描述符
IMAGE_THUNK_DATA
OriginalFirstThunk
和FirstThunk
都指向IMAGE_THUNK_DATA
结构数组
IMAGE_THUNK_DATA有两种解释:
- DWORD最高位为0,那么该数值是一个RVA,指向IMAGE_IMPORT_BY_NAME结构,表示函数是以字符串类型的函数名导入的
- DWORD最高位为1,那么该数值的低31位就是函数的导出函数的序号
IMAGE_IMPORT_BY_NAME结构
|
|
- Hint: 导出函数地址表的索引编号,可能为空不一定准确,由编译器决定
- Name: 这个是一个以
"\0"
结尾的字符串,表示函数名
OriginalFirstThunk
该字段指向一个包含了一些列结构的数组:IMAGE_THUNK_DATA,简称为桥1
桥1所指向的地址列表被定义为INT(Import Name Table)
导入名称表
TimeDateStamp
时间戳
ForwarderChain
链表的前一个结构
Name
这里的Name是一个RVA,它指向该结构对应的DLL文件的名称,而这个名称是以"\0"
结尾的ANSI字符串
ANSI编码是一种对ASCII码的拓展
FirstThunk
与OriginalFirstThunk相同,它指向的链表定义了针对Name这个动态链接库引入的所有导入函数,简称桥2
桥2所指向的地址列表被定义为: IAT (Import Address Table) 导入地址表
重定位表 (DataDirectory[5])
|
|