《PE2》中介绍了一些可选文件头中重要的属性,为了全面起见,本文将会讲解那些不是那么重要的属性。虽然不重要,但是还是可以发现很多好玩的情况。首先看一下32位的可选文件头详细定义。(转载请指明来源于breaksoftware的CSDN博客)

typedef struct _IMAGE_OPTIONAL_HEADER {//// Standard fields.//WORD    Magic;BYTE    MajorLinkerVersion;BYTE    MinorLinkerVersion;DWORD   SizeOfCode;DWORD   SizeOfInitializedData;DWORD   SizeOfUninitializedData;DWORD   AddressOfEntryPoint;DWORD   BaseOfCode;DWORD   BaseOfData;//// NT additional fields.//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;

64位版本和32位版本很类似:没有BaseOfCode属性;ImageBase、SizeofStackReserve、SizeOfStackCommit、SizeOfHeapReserve和SizeOfHeapCommit等5个属性由32位版的DWORD改成ULONGLONG。看下详细的64位版定义

typedef struct _IMAGE_OPTIONAL_HEADER64 {WORD        Magic;BYTE        MajorLinkerVersion;BYTE        MinorLinkerVersion;DWORD       SizeOfCode;DWORD       SizeOfInitializedData;DWORD       SizeOfUninitializedData;DWORD       AddressOfEntryPoint;DWORD       BaseOfCode;ULONGLONG   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;ULONGLONG   SizeOfStackReserve;ULONGLONG   SizeOfStackCommit;ULONGLONG   SizeOfHeapReserve;ULONGLONG   SizeOfHeapCommit;DWORD       LoaderFlags;DWORD       NumberOfRvaAndSizes;IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;

Magic字段是可选文件头幻数,0x10b是32位版,0x20b是64位版。注意该属性不能说明这个文件是64位文件还是32位文件,至于判断是多少位文件的方案我在《PE2》中已经有了说明。

MajorLinkerVersion和MinorLinkerVersion分别对应于链接器的版本号,比如我电脑上VS2005编译的文件的这两个版本号是8.0;VS2008编译的是9.0;VS2010编译的是10.0。

MajorOperatingSystemVersion和MinorOperatingSystemVersion是所需要的最低的系统版本号的主版本号和次版本号。我看了下我电脑上文件,基本上是4.0。

MajorImageVersion和MinorImageVersion是映像文件的主版本号和次版本号。注意:我们在资源中定义的文件版本号不是通过这两个属性来体现的!目前我也没找到在VC工程设置中可以设置这两个属性的地方。

Subsystem是该文件运行于的子系统信息。一般我们在windows平台上遇到的是2,它对应于IMAGE_SUBSYSTEM_WINDOWS_GUI。

MajorSubsystemVersion和MinorSubsystemVersion是子系统的版本号。熟悉windows的朋友应该知道,微软刚开始设计系统时,是设计成一个平台性质——可以运行3个子系统(OS/2、POSIX和Windows)的系统。这个就是这两个属性的由来。

SectionAlignment是当映像文件加载到内存中时节的对齐值,该大小使用字节来衡量的。它必须要大于我们之后介绍的FileAlignment。它的默认值是相应系统的页面大小。

FileAlignment 是映像文件节中的对齐值,它也是用字节来衡量的。英文文档中说该字段的值要在2^9 ~ 2^16之间,我扫描了下我的系统,发现我系统中文件并不是如此,特别是sys文件,它们的FileAlignment小于2^9(512)。

SizeOfCode是文件中代码段的总共大小。要注意一点,这个大小和.text的大小不一定一致,因为有些代码可能还保存在其他节中。如我电脑上AliAppLoader.exe文件,其SizeOfCode大小是0x1D600,而.text节大小只有0x1D400,另外的0x200是在.orpc这个节中。
        SizeOfInitializedData是文件中所有已经初始化数据节的大小。和SizeOfCode一样,初始化数据不一定只在一个节中。

SizeOfUninitializedData是文件中所有未初始化数据节的大小。和SizeOfCode一样,未初始化数据不一定只在一个节中。

Win32VersionValue是保留字段,应该为0。那么目前这个字段就是程序不关心的了,我们可以利用这个位置保存一些私密信息。

SizeOfImage的官方说明是该映像文件被加载入内存时的大小,理论上它应该是SectionAlignment的倍数。但是实际并非如此,我发现我电脑上很多文件的该字段不是SectionAlignment的倍数,而有时SizeOfImage是该文件在磁盘上的大小。可以见得这个不是一个关键字段。

        if ( m_lpFileEnd - m_lpFileStart != m_dwSizeOfImage ) {_ASSERT(FALSE);}

SizeOfHeaders的官方解释是MS-DOS占位程序、PE文件头和节头的总大小,且其应该是FileAlignment的倍数。但是实际上,我发现我电脑上很多文件的该字段并非FileAlignment的倍数。

        DWORD dwHeaderSize = (DWORD)(m_lpPEStart - m_lpFileStart) + (DWORD)(sizeof(IMAGE_FILE_HEADER)) + (DWORD) ( m_FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER));DWORD dwTmp = m_dwFileAlignment - 1;dwHeaderSize = (dwHeaderSize + dwTmp) &~dwTmp;if ( dwHeaderSize != m_dwSizeOfHeaders ) {//_ASSERT(FALSE);}

CheckSum字段是映像文件的校验和。其计算算法保存在imagehlp.dll中,导出函数名为CheckSumMappedFile。我发现我电脑上很多文件的该PE字段和计算出来的不等。官方解释说当驱动程序、在引导时被加载的Dll以及加载到关键windows进程中的DLL都需要校验该字段以确认其合法性。

typedef PIMAGE_NT_HEADERS(WINAPI *PCheckSumMappedFile)( PVOID, DWORD, PDWORD, PDWORD );HMODULE hModule = LoadLibrary(L"imagehlp.dll");if ( NULL == hModule ) {_ASSERT(FALSE);}PCheckSumMappedFile pCheckSumMappedFile = (PCheckSumMappedFile) GetProcAddress( hModule, "CheckSumMappedFile" );if ( NULL == pCheckSumMappedFile ) {_ASSERT(FALSE);}DWORD dwHeaderSum = 0;DWORD dwCheckSum = 0;PIMAGE_NT_HEADERS lpImgNtHeader = pCheckSumMappedFile( m_lpFileStart, (DWORD)(m_lpFileEnd - m_lpFileStart), &dwHeaderSum, &dwCheckSum );if ( m_dwCheckSum != dwCheckSum ) {// 不等的很多//_ASSERT(FALSE);}if ( NULL != hModule ) {FreeLibrary(hModule);hModule = NULL;}

SizeOfStackReserve、SizeOfStackCommit、SizeOfHeapReserve和SizeOfHeapCommit分别对应于保留的栈大小、提交的栈大小、保留的堆大小和提交的堆大小。

LoaderFlags字段是保留字段,应该为0,当然你可以不把它设为0。

NumberOfRvaAndSizes是用来指明DataDirectory元素的个数。这儿我们要说一下,我们在IMAGE_FILE_HEADER::SizeOfOptionalHeader得到了可选文件头的大小,而影响可选文件头大小的就是DataDirectory元素的个数(NumberOfRvaAndSizes),那么IMAGE_FILE_HEADER::SizeOfOptionalHeader和NumberOfRvaAndSizes之间应该存在着一种换算关系。的确,理论上 换算关系是:

SizeOfOptionalHeader == offsetof(IMAGE_OPTIONAL_HEADER32(64),NumberOfRvaAndSizes) + NumberOfRvaAndSizes * sizeof(IMAGE_DATA_DIRECTORY)

我跑了下我电脑上的所有文件,发现这个关系是一直成立的。这应该是种强关系。
        DllCharacteristics是属性字段,我们看个官方说明

Constant

Value

Description

0x0001

Reserved, must be zero.

0x0002

Reserved, must be zero.

0x0004

Reserved, must be zero.

0x0008

Reserved, must be zero.

IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE

0x0040

DLL can be relocated at load time.

IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY

0x0080

Code Integrity checks are enforced.

IMAGE_DLL_CHARACTERISTICS_NX_COMPAT

0x0100

Image is NX compatible.

IMAGE_DLLCHARACTERISTICS_ NO_ISOLATION

0x0200

Isolation aware, but do not isolate the image.

IMAGE_DLLCHARACTERISTICS_ NO_SEH

0x0400

Does not use structured exception (SE) handling. No SE handler may be called in this image.

IMAGE_DLLCHARACTERISTICS_ NO_BIND

0x0800

Do not bind the image.

0x1000

Reserved, must be zero.

IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER

0x2000

A WDM driver.

IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE

0x8000

Terminal Server aware.

MAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE是说Dll可以在加载时被重定向,我发现我电脑上文件SDKDBLib.dll是特例,它没有设置这个属性,这个文件也没有设置IMAGE_DLLCHARACTERISTICS_ NO_SEH,即该文件不使用SEH。

PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头3相关推荐

  1. PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1

    本文将讨论PE文件中非常重要的一部分信息.(转载请指明来源于breakSoftware的CSDN博客) 首先说一下VC中对应的数据结构."签名.COFF文件头和可选文件头"这三部分 ...

  2. PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头2

    之前的博文中介绍了IMAGE_FILE_HEADER结构,现在来讨论比较复杂的"可选文件头"结构体.(转载请指明来自breaksoftware的csdn博客)先看下其声明 type ...

  3. PE文件和COFF文件格式分析——RVA和RA相互计算

    之前几节一直是理论性质的东西非常多.本文将会讲到利用之前的知识得出一个一个非常有用的一个应用.(转载请指明来源于breaksoftware的csdn博客) 首先我们说下磁盘上A.exe文件和正在内存中 ...

  4. PE文件和COFF文件格式分析——节信息

    在<PE文件和COFF文件格式分析--签名.COFF文件头和可选文件头3>中,我们看到一些区块的信息都有偏移指向.而我们本文讨论的节信息是没有任何偏移指向的,所以它是紧跟在可选文件头后面的 ...

  5. PE文件和COFF文件格式分析——导出表的应用——一种摘掉Inline钩子(Unhook)的方法

    在日常应用中,某些程序往往会被第三方程序下钩子(hook).如果被下钩子的进程是我们的进程,并且第三方钩子严重影响了我们的逻辑和流程,我们就需要把这些钩子摘掉(Unhook).本件讲述一种在32位系统 ...

  6. PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL

    通过导出表隐性加载DLL?导出表?加载DLL?还隐性?是的.如果觉得不可思议,可以先看<PE文件和COFF文件格式分析--导出表>中关于"导出地址表"的详细介绍.(转载 ...

  7. PE文件和COFF文件格式分析——导出表的应用——一种插件模型

    可能在很多人想想中,只有DLL才有导出表,而Exe不应该有导出表.而在<PE文件和COFF文件格式分析--导出表>中,我却避开了这个话题.我就是想在本文中讨论下载Exe中存在导出表的场景. ...

  8. PE文件和COFF文件格式分析——导出表

    在之前的<PE可选文件头>相关博文中我们介绍了可选文件头中很多重要的属性,而其中一个非常重要的属性是(转载请指明来源于breaksoftware的CSDN博客) IMAGE_DATA_DI ...

  9. PE文件和COFF文件格式分析--概述

    刚工作的时候,我听说某某大牛在做病毒分析时,只是用notepad打开病毒文件,就能大致猜到病毒的工作原理.当时我是佩服的很啊,同时我也在心中埋下了一个种子:我也得有这天.随着后来的工作进行,一些任务的 ...

最新文章

  1. 替代还是扩展:云的下一站真是雾计算?
  2. 吃透Java中的动态代理
  3. 大话WiFi省电模式
  4. 带你学python基础:文件读写,俗称IO操作
  5. 「博客之星」评选,诚信的互投啊,留链定回
  6. qt自带的文档系统软件叫什么名字_翻译 | 为什么QObject子类不可复制?
  7. java day11【final、权限、内部类、引用类型】
  8. java vector pair_STL: list ,set ,pair.map的使用
  9. python需要编译_Python编译安装
  10. Go语言躲坑经验总结
  11. ArcGIS+Google Earth Pro 经纬度标点地图
  12. bitlocker正在加密 c盘_win10不能分盘,硬盘提示Bitlocker已加密解决方法
  13. Codeforces 887D - Ratings and Reality Shows
  14. 计算机主机电源键,按电脑主机机箱电源键后,却没有任何反应疑难问题
  15. 计算机应用文摘版面费,数值计算与计算机应用发表论文期刊级别
  16. 硬盘突然变raw格式_硬盘变成raw格式解决办法
  17. 巨量算数 Data解密
  18. 工作、求职需要记住的英文缩写,offer讨论避免尴尬
  19. 图案设计灵感怎么写_设计的灵感来源
  20. 复仇者联盟4影评数据分析

热门文章

  1. PyTorch框架:(3)使用PyTorch框架构构建神经网络分类任务
  2. 这才是Matlab的正确打开方式!——Matlab矩阵、绘图、函数计算与数据读取
  3. 为什么我的python程序编译器没有行代号_为什么我的python字典没有附加新变量呢?...
  4. linux 删除含有关键词的文件_误删除Linux系统文件了?这个方法教你解决
  5. 在VirtualBox 5.0.12 for Linux版本上安装CentOS 6.6 x86_64系统
  6. 在CentOS 6.3 64bit上使用 smartmontools和MageCli 监测硬盘的健康状态
  7. python threading模块多线程源码示例(一)
  8. 3Dmax+V-Ray学习建筑可视化教程
  9. uboot引导kernel - 3 -uboot给内核传参详解
  10. 二分法:search insert position 插入位置