PE文件详解(一)--数据结构字段
来源:互联网 发布:巅峰阁软件帐号 编辑:程序博客网 时间:2024/06/09 16:30
DOS MZ头IMAGE_DOS_HEADER STRUCT :
IMAGE_DOS_HEADER STRUCT
typedef struct _IMAGE_FILE_HEADER
{
+04h WORD Machine; // 运行平台 +06h WORD NumberOfSections; // 文件的区块数目 +08h DWORDTimeDateStamp; // 文件创建日期和时间 +0Ch DWORD PointerToSymbolTable; // 指向符号表(主要用于调试) +10h DWORD NumberOfSymbols; // 符号表中符号个数(同上) +14h WORD SizeOfOptionalHeader; // IMAGE_OPTIONAL_HEADER32 结构大小 +16h WORD Characteristics; // 文件属性 } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
该结构如下图所示:
- IMAGE_FILE_MACHINE_I386
- 0x014c
x86
- IMAGE_FILE_MACHINE_IA64
- 0x0200
Intel Itanium
- IMAGE_FILE_MACHINE_AMD64
- 0x8664
x64
The characteristics of the image. This member can be one or more of the following values.
- IMAGE_FILE_RELOCS_STRIPPED
- 0x0001
Relocation information was stripped from the
file. The file must be loaded at its preferred
base address. If the base address is not
available, the loader reports an error.
- IMAGE_FILE_EXECUTABLE_IMAGE
- 0x0002
The file is executable (there are no unresolved
external references).
- IMAGE_FILE_LINE_NUMS_STRIPPED
- 0x0004
COFF line numbers were stripped from the
file.
- IMAGE_FILE_LOCAL_SYMS_STRIPPED
- 0x0008
COFF symbol table entries were stripped from
file.
- IMAGE_FILE_AGGRESIVE_WS_TRIM
- 0x0010
Aggressively trim the working set. This value is
obsolete as of Windows 2000.
- IMAGE_FILE_LARGE_ADDRESS_AWARE
- 0x0020
The application can handle addresses larger
than 2 GB.
- IMAGE_FILE_BYTES_REVERSED_LO
- 0x0080
The bytes of the word are reversed. This flag
is obsolete.
- IMAGE_FILE_32BIT_MACHINE
- 0x0100
The computer supports 32-bit words.
- IMAGE_FILE_DEBUG_STRIPPED
- 0x0200
Debugging information was removed and stored
separately in another file.
- IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
- 0x0400
If the image is on removable media, copy it to
and run it from the swap file.
- IMAGE_FILE_NET_RUN_FROM_SWAP
- 0x0800
If the image is on the network, copy it to and
run it from the swap file.
- IMAGE_FILE_SYSTEM
- 0x1000
The image is a system file.
- IMAGE_FILE_DLL
- 0x2000
The image is a DLL file. While it is an executable
file, it cannot be run directly.
- IMAGE_FILE_UP_SYSTEM_ONLY
- 0x4000
The file should be run only on a uniprocessor
computer.
- IMAGE_FILE_BYTES_REVERSED_HI
- 0x8000
The bytes of the word are reversed. This flag
is obsolete.
{
//
// Standard fields.
//
+18h WORD Magic; // 标志字, ROM 映像(0107h),普通可执行文件(010Bh)
+1Ah BYTE MajorLinkerVersion; // 链接程序的主版本号
+1Bh BYTE MinorLinkerVersion; // 链接程序的次版本号
+1Ch DWORD SizeOfCode; // 所有含代码的节的总大小
+20h DWORD SizeOfInitializedData; // 所有含已初始化数据的节的总大小
+24h DWORD SizeOfUninitializedData; // 所有含未初始化数据的节的大小
+28h DWORD AddressOfEntryPoint; // 程序执行入口RVA
+2Ch DWORD BaseOfCode; // 代码的区块的起始RVA
+30h DWORD BaseOfData; // 数据的区块的起始RVA
//
// NT additional fields. 以下是属于NT结构增加的领域。
//
+34h DWORD ImageBase; // 程序的首选装载地址
+38h DWORD SectionAlignment; // 内存中的区块的对齐大小
+3Ch DWORD FileAlignment; // 文件中的区块的对齐大小
+40h WORD MajorOperatingSystemVers
+42h WORD MinorOperatingSystemVers
+44h WORD MajorImageVersion; // 可运行于操作系统的主版本号
+46h WORD MinorImageVersion; // 可运行于操作系统的次版本号
+48h WORD MajorSubsystemVersion; // 要求最低子系统版本的主版本号
+4Ah WORD MinorSubsystemVersion; // 要求最低子系统版本的次版本号
+4Ch DWORD Win32VersionValue; // 莫须有字段,不被病毒利用的话一般为0
+50h DWORD SizeOfImage; // 映像装入内存后的总尺寸
+54h DWORD SizeOfHeaders; // 所有头 + 区块表的尺寸大小
+58h DWORD CheckSum; // 映像的校检和
+5Ch WORD Subsystem; // 可执行文件期望的子系统
+5Eh WORD DllCharacteristics; // DllMain()函数何时被调用,默认为 0
+60h DWORD SizeOfStackReserve; // 初始化时的栈大小
+64h DWORD SizeOfStackCommit; // 初始化时实际提交的栈大小
+68h DWORD SizeOfHeapReserve; // 初始化时保留的堆大小
+6Ch DWORD SizeOfHeapCommit; // 初始化时实际提交的堆大小
+70h DWORD LoaderFlags; // 与调试有关,默认为 0
+74h DWORD NumberOfRvaAndSizes; // 下边数据目录的项数,这个字段自Windows NT 发布以来 // 一直是16
+78h IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
// 数据目录表
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
事实上,这个结构中的大部分字段都不重要,大家可以从注释中理解它们的含义,小甲鱼将比较重要的字段在下边跟大家详细讲解。另外,这玩意千万不要去背啊,我们要把绝大多数的时间拿来改变,而不是记住。不用做笔记,把这篇文章转载到您的博客就行(最好注明:小甲鱼是帅哥)吼吼 ^_^
● AddressOfEntryPoint字段
指出文件被执行时的入口地址,这是一个RVA地址(RVA的含义在下一节中详细介绍)。如果在一个可执行文件上附加了一段代码并想让这段代码首先被执行,那么只需要将这个入口地址指向附加的代码就可以了。
● ImageBase字段
指出文件的优先装入地址。也就是说当文件被执行时,如果可能的话,Windows优先将文件装入到由ImageBase字段指定的地址中,只有指定的地址已经被**模块使用时,文件才被装入到**地址中。链接器产生可执行文件的时候对应这个地址来生成机器码,所以当文件被装入这个地址时不需要进行重定位操作,装入的速度最快,如果文件被装载到**地址的话,将不得不进行重定位操作,这样就要慢一点。
对于EXE文件来说,由于每个文件总是使用独立的虚拟地址空间,优先装入地址不可能被**模块占据,所以EXE总是能够按照这个地址装入,这也意味着EXE文件不再需要重定位信息。对于DLL文件来说,由于多个DLL文件全部使用宿主EXE文件的地址空间,不能保证优先装入地址没有被**的DLL使用,所以DLL文件中必须包含重定位信息以防万一。因此,在前面介绍的 IMAGE_FILE_HEADER 结构的 Characteristics 字段中,DLL 文件对应的 IMAGE_FILE_RELOCS_STRIPPED 位总是为0,而EXE文件的这个标志位总是为1。
在链接的时候,可以通过对link.exe指定/base:address选项来自定义优先装入地址,如果不指定这个选项的话,一般EXE文件的默认优先装入地址被定为00400000h,而DLL文件的默认优先装入地址被定为10000000h。
● SectionAlignment 字段和 FileAlignment字段
SectionAlignment字段指定了节被装入内存后的对齐单位。也就是说,每个节被装入的地址必定是本字段指定数值的整数倍。而FileAlignment字段指定了节存储在磁盘文件中时的对齐单位。
● Subsystem字段
指定使用界面的子系统,它的取值如表17.3所示。这个字段决定了系统如何为程序建立初始的界面,链接时的/subsystem:**选项指定的就是这个字段的值,在前面章节的编程中我们早已知道:如果将子系统指定为Windows CUI,那么系统会自动为程序建立一个控制台窗口,而指定为Windows GUI的话,窗口必须由程序自己建立。
界面子系统的取值和含义
取 值
Windows.inc中的预定义值
含 义
0
IMAGE_SUBSYSTEM_UNKNOWN
未知的子系统
1
IMAGE_SUBSYSTEM_NATIVE
不需要子系统(如驱动程序)
2
IMAGE_SUBSYSTEM_WINDOWS_GUI
Windows图形界面
3
IMAGE_SUBSYSTEM_WINDOWS_CUI
Windows控制台界面
5
IMAGE_SUBSYSTEM_OS2_CUI
OS2控制台界面
7
IMAGE_SUBSYSTEM_POSIX_CUI
POSIX控制台界面
8
IMAGE_SUBSYSTEM_NATIVE_WINDOWS
不需要子系统
9
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI
Windows CE图形界面
● DataDirectory字段
这个字段可以说是最重要的字段之一,它由16个相同的IMAGE_DATA_DIRECTORY结构组成,虽然PE文件中的数据是按照装入内存后的页属性归类而被放在不同的节中的,但是这些处于各个节中的数据按照用途可以被分为导出表、导入表、资源、重定位表等数据块,这16个IMAGE_DATA_DIRECTORY结构就是用来定义多种不同用途的数据块的(如表17.4所示)。IMAGE_DATA_DIRECTORY结构的定义很简单,它仅仅指出了某种数据块的位置和长度。
IMAGE_DATA_DIRECTORY STRUCT
VirtualAddress DWORD ? ;数据的起始RVA
isize DWORD ? ;数据块的长度
IMAGE_DATA_DIRECTORY ENDS
数据目录列表的含义
索 引
索引值在Windows.inc中的预定义值
对应的数据块
0
IMAGE_DIRECTORY_ENTRY_EXPORT
导出表
1
IMAGE_DIRECTORY_ENTRY_IMPORT
导入表
2
IMAGE_DIRECTORY_ENTRY_RESOURCE
资源
3
IMAGE_DIRECTORY_ENTRY_EXCEPTION
异常(具体资料不详)
4
IMAGE_DIRECTORY_ENTRY_SECURITY
安全(具体资料不详)
5
IMAGE_DIRECTORY_ENTRY_BASERELOC
重定位表
6
IMAGE_DIRECTORY_ENTRY_DEBUG
调试信息
7
IMAGE_DIRECTORY_ENTRY_ARCHITECTURE
版权信息
8
IMAGE_DIRECTORY_ENTRY_GLOBALPTR
具体资料不详
9
IMAGE_DIRECTORY_ENTRY_TLS
Thread Local Storage
10
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
具体资料不详
11
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT
具体资料不详
12
IMAGE_DIRECTORY_ENTRY_IAT
导入函数地址表
13
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
具体资料不详
14
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
具体资料不详
15
未使用
在PE文件中寻找特定的数据时就是从这些IMAGE_DATA_DIRECTORY结构开始的,比如要存取资源,那么必须从第3个IMAGE_DATA_DIRECTORY结构(索引为2)中得到资源数据块的大小和位置;同理,如果要查看PE文件导入了哪些DLL文件的哪些API函数,那就必须首先从第2个IMAGE_DATA_DIRECTORY结构得到导入表的位置和大小。
转:小甲鱼PE详解
- PE文件详解(一)--数据结构字段
- PE文件详解(一)
- PE文件简介(一)-数据结构
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解(一)基本概念
- PE文件结构详解<一>
- PE文件(一)
- PE文件结构详解(一)基本概念(转…
- PE格式详解(一)
- PE结构详解(一)
- C++11内存模型
- AFNetWorking Post请求 及 刷新网址 经典十大算法
- 3.2 Implement strStr()
- average presion(AP)
- Struts2 Action扩展名的三种修改方法
- PE文件详解(一)--数据结构字段
- TIP 链接错误 link error
- Linux下使用gcc和gdb调试程序
- 安卓自定义进度条
- 初探linux内核编程,参数传递以及模块间函数调用
- OPUS/SILK/SPEEX 音频编码比较
- linux_进程线程通信
- Excel中的datedif函数
- 实现android M 的直接分享