PE文件格式学习:可选头的大小SizeOfOptionalHeader
在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 本帖最后由 bester 于 2009-3-4 00:35 编辑
我没有《软件加密技术内幕》这本书,也不清楚SizeOfOptionalHeader的值在32的系统下是不是一直都是0xE0大小,我只能跟LZ讲,我见到的程序一般这个的大小都是0xE0,所以我把它理解为SizeOfOptionalHeader在32系统下大小固定为0xE0,由于我没有软件加密技术内幕》这本书,所以,我只能给你解释如下:
1、这个SizeOfOptionalHeader的值是Optonal头和Data_Directories大小的和!
我没有《软件加密技术内幕》这本书,也不清楚SizeOfOptionalHeader的值在32的系统下是不是一直都是0xE0大小,我只能跟LZ讲,我见到的程序一般这个的大小都是0xE0,所以我把它理解为SizeOfOptionalHeader在32系统下大小固定为0xE0,由于我没有软件加密技术内幕》这本书,所以,我只能给你解释如下:
这个SizeOfOptionalHeader的值是Optonal头和Data_Directories大小的总和,下图是你在附件中的那个EXE程序:
由此图可见,这个程序的SizeOfOptionalHeader值也是0xE0的,之所以出现0xD0的情况可能是由于当时的编辑人员疏忽导致的!
另外,在微软倡导的PE文件格式中,各个数据结构中成员的数量是固定(可选头虽然是可选的,但是它也是必须有的),所以,这个SizeOfOptionalHeader的大小一般情况下它也是固定的!
很高兴论坛里能有像LZ这样好学,而又细心的朋友,既然LZ在学习PE文件结构,不如直接将自己的所学,写成一个帖子,每有收获都贴一个出来,自己受益并与他人分享,最后形成一个专题,多好……
希望LZ能多多分享自己的所学,毕竟多交流才是进步最快的方法!
最后,祝你成功! 我没有《软件加密技术内幕》这本书,也不清楚SizeOfOptionalHeader的值在32的系统下是不是一直都是0xE0大小,我只能跟LZ讲,我见到的程序一般这个的大小都是0xE0,所以我把它理解为SizeOfOptionalHeader在32系统下大 ...
bester 发表于 2009-3-4 00:32 http://bbs.52pojie.cn/images/common/back.gif
SizeOfOptionalHeader固定下来是错误的,你参看MS的官方文档就明白了!
MS官方处理这个值时,也没有采取固定值,通过IMAGE_FIRST_SECTION这个宏的设计方法也可见一二了!
另外,你如果需要一个大于0xE0值的SizeOfOptionalHeader,是很容易得到的,而且也运行的很好!
到于你说那个0xD0是笔误,更不可能,因为配套的程序里就是0xD0。书可以笔误,程序不会也写错吧!
另外说在Win9X/2000下能正常运行也是可能的(我没测试,写作人员不会连简单的双击也省略的吧!)
我的看法只是个人搜索的一些资料整理,还没有确定的说法,毕竟官方的文档上没有找到! SizeOfOptionalHeader的值是Optonal头和Data_Directories大小的总和
这个说法是有些偏颇的!
下面的图是我修改的一个PE文件所显示的,SizeOfOptionalHeader的大小就是0xF0:
程序也能正常的运行!你可以下载测试! 本帖最后由 bester 于 2009-3-4 12:59 编辑
很欣赏LZ这种学习的精神,不过,也希望LZ好好看我的帖子,我没有说它固定是0xE0,只是说,由于它一般情况下都是0xE0,所以我可以这么理解为它固定为0xE0!
至于它为什么一般都是0xE0,我在上面写的很清楚,因为Optonal头和Data_Directories两个结构一般都是固定的,所以,他们的大小也一般都是固定的,具体的你可以查阅WINNT.H文件的结构定义!
再说,你引用的书里也写的很清楚:However, these sizes are just minimum values, and larger values could appear.
你可以算一下,你上面贴出来的两个附件程序中,SizeOfOptionalHeader的值是Optonal头和Data_Directories大小的总和是不是0xE0,你改成0xF0也是没错的,因为他们的和是0xE0,只要比这个值大就好,原因是因为:
在运行一个WINPE文件的时候,系统会根据这些结构的定义来在内存中分配各种空间断,各种信息放在哪个位置,这个0xE0正好就是OptionalHeader的全部元素的大小,你给它分配个0xF0,是没有问题的,因为这个空间更足以存放OptionalHeader这个结构,改成0xD0,分配的内存空间就不够了,所以不行!
至于你说SizeOfOptionalHeader的值是Optonal头和Data_Directories大小的总和,这个说法是有些偏颇的,这个也不可避免的,因为我不是这个方面的专家,也不是搞语文的,用词可能不准确,但这个是我的理解,而且这个说法貌似没有什么错误,我只能给你解释如下:
其中的SizeOfOptionalHeader就是指定了后面的IMAGE_OPTIONAL_HEADER32 OptionalHeader;的大小!
上面引自LZ的首贴,Data_Directories是IMAGE_OPTIONAL_HEADER32结构成员,如果LZ说我说的不片面了,那你是不是就是在跟你自己的帖子较真呢,呵呵!
另外,第一个附件程序的IMAGE_OPTIONAL_HEADER32 大小明明是0xE0,可是它的SizeOfOptionalHeader大小却是:0xD0,再加上这个书的特别之处:他是教大家PE文件格式的,所以需要作者做相应的修改,出现失误是理所当然的事!
当然,我没在windows2000测试它能不能跑起来,但是在XP下肯定是不可以的……
我上面讲的,仅是我在很早以前时候学PE文件格式时的一个理解,可能我理解的是完全错误的,我表述的也有可能用词上面用的不准确,还往明白的大牛指正!
另外,希望LZ不要太过死板,灵活运用…… 真是雪中送炭啊
看到这篇文章我笑了
页:
[1]