小甲鱼PE详解之IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用(PE详解03)

咱接着往下讲解IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用!

(视频教程:http://fishc.com/a/shipin/jiemixilie/

接着我们来谈谈 IMAGE_OPTIONAL_HEADER
结构,正如名字的意思,这是一个可选映像头,是一个可选的结构,但是呢,实际上上节课我们讲解的 IMAGE_FILE_HEADER 结构远远不足以来定义 PE 文件的属性。因此,这些属性在 IMAGE_OPTIONAL_HEADER 结构中进行定义。

因此这两个结构联合起来,才是一个完整的 “PE文件结构” 。

那么我们接着就应该顺理成章地来谈谈
IMAGE_OPTIONAL_HEADER32 结构的定义:(啥?结构不会,先看看小甲鱼童鞋的《零基础入门学习C语言》关于结构方面的章节吧~)

typedef struct _IMAGE_OPTIONAL_HEADER 
{
    //
    // 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    MajorOperatingSystemVersion;  // 要求操作系统最低版本号的主版本号
+42h    WORD    MinorOperatingSystemVersion;  // 要求操作系统最低版本号的副版本号
+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结构得到导入表的位置和大小。

时间: 2024-10-29 19:06:21

小甲鱼PE详解之IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用(PE详解03)的相关文章

PE详解之IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用(PE详解03)

咱接着往下讲解IMAGE_OPTIONAL_HEADER32 结构定义即各个属性的作用! (视频教程:http://fishc.com/a/shipin/jiemixilie/) 接着我们来谈谈 IMAGE_OPTIONAL_HEADER 结构,正如名字的意思,这是一个可选映像头,是一个可选的结构,但是呢,实际上上节课我们讲解的 IMAGE_FILE_HEADER 结构远远不足以来定义 PE 文件的属性.因此,这些属性在 IMAGE_OPTIONAL_HEADER 结构中进行定义. 因此这两个结

小甲鱼PE详解之IMAGE_NT_HEADERS结构定义即各个属性的作用(PE详解02)

PE Header 是PE相关结构NT映像头(IMAGE_NT_HEADER)的简称,里边包含着许多PE装载器用到的重要字段.下边小甲鱼将为大家详细讲解哈~ (视频教程:http://fishc.com/a/shipin/jiemixilie/) 首先是IMAGE_NT_HEADERS 结构的定义:(啥?结构不会,先看看小甲鱼童鞋的<零基础入门学习C语言>关于结构方面的章节吧~) IMAGE_NT_HEADERS STRUCT { +0hDWORDSignature  // +4h  IMAG

PE详解之IMAGE_DOS_HEADER结构定义即各个属性的作用(PE详解01)

小甲鱼在这里为大家做好了详细的注释,免得大家一头雾水,另外可以结合小甲鱼<加密系列>-系统篇-PE结构详解视频教程学习~若有纰漏之处还望大家不吝指正. (视频教程:http://fishc.com/a/shipin/jiemixilie/) (注:最左边是文件头的偏移量.) IMAGE_DOS_HEADER STRUCT { +0h WORD e_magic   // Magic DOS signature MZ(4Dh 5Ah)     DOS可执行文件标记 +2h   WORD  e_cb

PE详解之IMAGE_NT_HEADERS结构定义即各个属性的作用(PE详解02)

首先是IMAGE_NT_HEADERS 结构的定义:(啥?结构不会,先看看小甲鱼童鞋的<零基础入门学习C语言>关于结构方面的章节吧~) IMAGE_NT_HEADERS STRUCT { +0hDWORDSignature  // +4h  IMAGE_FILE_HEADER FileHeader // +18hIMAGE_OPTIONAL_HEADER32OptionalHeader   // } IMAGE_NT_HEADERS ENDS Signature 字段: 在一个有效的 PE 文

小甲鱼PE详解之IMAGE_DOS_HEADER结构定义即各个属性的作用(PE详解01)

(注:最左边是文件头的偏移量.) IMAGE_DOS_HEADER STRUCT { +0h  WORD  e_magic  // Magic DOS signature MZ(4Dh 5Ah)     DOS可执行文件标记 +2h  WORD  e_cblp //Bytes on last page of file +4h  WORD  e_cp  //Pages in file +6h  WORD  e_crlc  //Relocations +8h  WORD  e_cparhdr   /

小甲鱼PE详解之区块表(节表)和区块(节)续(PE详解05)

这一讲我们结合实例来谈谈区块表的定义以及各个属性的含义. 首先,我们先用之前学过的一点知识在二进制文件中手动翻找区块表,这样做的好处是可以使你很快的对PE结构牢记于心.学来的东西就是能用的东西,不能用的理论是空谈,是瞎扯. (具体过程演示大伙可参考小甲鱼的视频教程:<解密系列>系统篇.第五讲) 这里我们经过千辛万苦终于找到了我们的区块表了(当然将来我会教大家写一个自己的工具,让工具去找,现在让大家自己动手是为了增强感觉!),现在我们联系上一章节提到的区块表的结构对各个成员进行详细的分析: ty

小甲鱼PE详解之输入表(导出表)详解(PE详解09)

小甲鱼PE详解之输出表(导出表)详解(PE详解09) 当PE 文件被执行的时候,Windows 加载器将文件装入内存并将导入表(Export Table) 登记的动态链接库(一般是DLL 格式)文件一并装入地址空间,再根据DLL 文件中的函数导出信息对被执行文件的IAT 进行修正. ( 基础补充:很多朋友可能看到这里会有点懵,各位看官请允许小甲鱼啰嗦一下,照顾初学者.我们都明白Windows 在加载一个程序后就在内存中为该程序开辟一个单独的虚拟地址空间,这样的话在各个程序自己看来,自己就拥有几乎

小甲鱼PE详解之基址重定位详解(PE详解10)

今天有一个朋友发短消息问我说“老师,为什么PE的格式要讲的这么这么细,这可不是一般的系哦”.其实之所以将PE结构放在解密系列继基础篇之后讲并且尽可能细致的讲,不是因为小甲鱼没事找事做,主要原因是因为PE结构非常重要,再说做这个课件的确是很费神的事哈.在这里再次强调一下,只要是windows操作程序,其就要遵循PE格式,再说人家看雪的网址就是www.pediy.com. 简单的讲是可以,但是怕就怕有些朋友知识点遗漏了或者错误理解意思.不能深刻体会等,这样的效果是不好的~所以,小甲鱼尽管这系列视频可

小甲鱼PE详解之区块描述、对齐值以及RVA详解(PE详解06)

很多朋友喜欢听小甲鱼的PE详解,因为他们觉得课堂上老师讲解的都是略略带过,绕得大家云里雾里~刚好小甲鱼文采也没课堂上的教授讲的那么好,只能以比较通俗的话语来给大家描述~ 通常,区块中的数据在逻辑上是关联的.PE 文件一般至少都会有两个区块:一个是代码块,另一个是数据块.每一个区块都需要有一个截然不同的名字,这个名字主要是用来表达区块的用途.例如有一个区块 叫.rdata,表明他是一个只读区块.注意:区块在映像中是按起始地址(RVA)来排列的,而不是按字母表顺序. 另外,使用区块名字只是人们为了认