在PE头部,在IMAGE_NT_HEADERS结构中的FileHeader成员中指定了后面的OptionalHeader成员的大小!
IMAGE_NT_HEADERS的结构定义如下:typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
FileHeader成员是IMAGE_FILE_HEADER结构的一个数据,定义如下:typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
其中的SizeOfOptionalHeader就是指定了后面的IMAGE_OPTIONAL_HEADER32 OptionalHeader;的大小!
就这个大小而言,其常值都是0xE0,但是总有例外。由于这个值决定了后面的区块表的定位,就微软本身而言,也没有用0xE0这个固定值来定位,我们可以通过一个获取首个区块表位置的一个宏来看出:#define IMAGE_FIRST_SECTION64( ntheader ) ((PIMAGE_SECTION_HEADER) \
((ULONG_PTR)ntheader + \
FIELD_OFFSET( IMAGE_NT_HEADERS64, OptionalHeader ) + \
((PIMAGE_NT_HEADERS64)(ntheader))->FileHeader.SizeOfOptionalHeader \
))
那么这个值是不是任意设定的呢?
当SizeOfOptionalHeader大于或者等于0xE0时,程序叫是能正常运行起来!看雪的《软件加密技术内幕》的第2章提供了一个示例,将SizeOfOptionalHeader这个值设为0xD0,书本上说这个程序能在Windows9x/2000下很好的运行!
不过可惜,在我的WinXP Sp3上完全不能运行!如图:
难道是PE格式进行了修正?这个测试程序完全可以用其他的PE文件格式分析结构,但不能运行。是不是SizeOfOptionalHeader这个值必须是大于或者等于0xE0的值??
查看了一下“Microsoft Portable Executable and Common Object File Format Specification-Revision 8.1”,只找到了下面一些相关的说明:
“For image files, this header is required. ”
对镜像文件,这个头(即OptionalHeader)是必须的。
“Note that the size of the optional header is not fixed. The SizeOfOptionalHeader field in the COFF header must be used to valIDAte that a probe into the file for a particular data directory does not go beyond SizeOfOptionalHeader. ”
注意:可选头的大小是不固定的。在COFF头的 SizeOfOptionalHeader 域必须被用于验证,尤其是研究一个没有超出SizeOfOptionalHeader大小的特殊的数据目录。
再次查找了一些资料,在Matt Pietrek的“An In-Depth Look into the Win32 Portable Executable File Format”一文里
(链接见:http://msdn.microsoft.com/en-us/magazine/cc301805.aspx,翻译成中文是:深入剖析 Win32 可移植可执行文件格式 ):
在表述IMAGE_NT_HEADERS 文件头结构的表格里写了这么一句:
IMAGE_FILE_HEADER 结构后面的可选数据的大小。在PE 文件中,这个可选数据就是 IMAGE_OPTIONAL_HEADER。这个大小在32位和64位文件中是不同的。对于32位 PE文件来说,它通常是 224;对于64位PE32+文件来说,它通常是 240。但是,它们只是最小值,可能有更大的值。
这里引用的是SmartTech的译文,我们可以对比一下原文:
The size of the optional data that follows the IMAGE_FILE_HEADER. In PE files, this data is the IMAGE_OPTIONAL_HEADER. This size is different depending on whether it's a 32 or 64-bit file. For 32-bit PE files, this field is usually 224. For 64-bit PE32+ files, it's usually 240. However, these sizes are just minimum values, and larger values could appear.
留意红色的部分,这表明了 SizeOfOptionalHeader的最小取值是0xE0! 那么《软件加密技术内幕》一书的测试程序设SizeOfOptionHeader为0xD0可以在Win9X/2000上跑起来??或者是那里的加载程序的检测的不严格??如果如此,这样也可以解释为什么在我的XP SP3上跑起来了,呵呵!
附件为《软件加密技术内幕》一书提供的测试程序!
转自:iawen的Blog
链接:http://www.iawen.com/read.php/218.htm |