PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头3
《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相关推荐
- PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头1
本文将讨论PE文件中非常重要的一部分信息.(转载请指明来源于breakSoftware的CSDN博客) 首先说一下VC中对应的数据结构."签名.COFF文件头和可选文件头"这三部分 ...
- PE文件和COFF文件格式分析——签名、COFF文件头和可选文件头2
之前的博文中介绍了IMAGE_FILE_HEADER结构,现在来讨论比较复杂的"可选文件头"结构体.(转载请指明来自breaksoftware的csdn博客)先看下其声明 type ...
- PE文件和COFF文件格式分析——RVA和RA相互计算
之前几节一直是理论性质的东西非常多.本文将会讲到利用之前的知识得出一个一个非常有用的一个应用.(转载请指明来源于breaksoftware的csdn博客) 首先我们说下磁盘上A.exe文件和正在内存中 ...
- PE文件和COFF文件格式分析——节信息
在<PE文件和COFF文件格式分析--签名.COFF文件头和可选文件头3>中,我们看到一些区块的信息都有偏移指向.而我们本文讨论的节信息是没有任何偏移指向的,所以它是紧跟在可选文件头后面的 ...
- PE文件和COFF文件格式分析——导出表的应用——一种摘掉Inline钩子(Unhook)的方法
在日常应用中,某些程序往往会被第三方程序下钩子(hook).如果被下钩子的进程是我们的进程,并且第三方钩子严重影响了我们的逻辑和流程,我们就需要把这些钩子摘掉(Unhook).本件讲述一种在32位系统 ...
- PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL
通过导出表隐性加载DLL?导出表?加载DLL?还隐性?是的.如果觉得不可思议,可以先看<PE文件和COFF文件格式分析--导出表>中关于"导出地址表"的详细介绍.(转载 ...
- PE文件和COFF文件格式分析——导出表的应用——一种插件模型
可能在很多人想想中,只有DLL才有导出表,而Exe不应该有导出表.而在<PE文件和COFF文件格式分析--导出表>中,我却避开了这个话题.我就是想在本文中讨论下载Exe中存在导出表的场景. ...
- PE文件和COFF文件格式分析——导出表
在之前的<PE可选文件头>相关博文中我们介绍了可选文件头中很多重要的属性,而其中一个非常重要的属性是(转载请指明来源于breaksoftware的CSDN博客) IMAGE_DATA_DI ...
- PE文件和COFF文件格式分析--概述
刚工作的时候,我听说某某大牛在做病毒分析时,只是用notepad打开病毒文件,就能大致猜到病毒的工作原理.当时我是佩服的很啊,同时我也在心中埋下了一个种子:我也得有这天.随着后来的工作进行,一些任务的 ...
最新文章
- 替代还是扩展:云的下一站真是雾计算?
- 吃透Java中的动态代理
- 大话WiFi省电模式
- 带你学python基础:文件读写,俗称IO操作
- 「博客之星」评选,诚信的互投啊,留链定回
- qt自带的文档系统软件叫什么名字_翻译 | 为什么QObject子类不可复制?
- java day11【final、权限、内部类、引用类型】
- java vector pair_STL: list ,set ,pair.map的使用
- python需要编译_Python编译安装
- Go语言躲坑经验总结
- ArcGIS+Google Earth Pro 经纬度标点地图
- bitlocker正在加密 c盘_win10不能分盘,硬盘提示Bitlocker已加密解决方法
- Codeforces 887D - Ratings and Reality Shows
- 计算机主机电源键,按电脑主机机箱电源键后,却没有任何反应疑难问题
- 计算机应用文摘版面费,数值计算与计算机应用发表论文期刊级别
- 硬盘突然变raw格式_硬盘变成raw格式解决办法
- 巨量算数 Data解密
- 工作、求职需要记住的英文缩写,offer讨论避免尴尬
- 图案设计灵感怎么写_设计的灵感来源
- 复仇者联盟4影评数据分析
热门文章
- PyTorch框架:(3)使用PyTorch框架构构建神经网络分类任务
- 这才是Matlab的正确打开方式!——Matlab矩阵、绘图、函数计算与数据读取
- 为什么我的python程序编译器没有行代号_为什么我的python字典没有附加新变量呢?...
- linux 删除含有关键词的文件_误删除Linux系统文件了?这个方法教你解决
- 在VirtualBox 5.0.12 for Linux版本上安装CentOS 6.6 x86_64系统
- 在CentOS 6.3 64bit上使用 smartmontools和MageCli 监测硬盘的健康状态
- python threading模块多线程源码示例(一)
- 3Dmax+V-Ray学习建筑可视化教程
- uboot引导kernel - 3 -uboot给内核传参详解
- 二分法:search insert position 插入位置