PE格式的问题:SizeOfImage到底是如何计算的?

boodweb 2002-01-27 02:35:36
以前我问过这方面的问题,brider回答了我:
brider() 回复于2001-8-24 14:12:48 得20分
实际上sizeofimage是最后一个节的VirtualAddress加上VirtualSize再对齐,看看那些编译器编出来的PE文件。
但是最近又我仔细研究了一下,发现情况似乎不是这样的,因为windows的loader在载入exe时,似乎并不关心VirtualSize的,因为你可以把它置为0而不会出错。
“The Portable Executable File Format from Top to Bottom”中这么说:“PhysicalAddress or VirtualSize. The second field is a union field that is not currently used. ”
那LUEVELSMEYER文中例子的SizeOfImage到底是怎么计算出来的呢?

SectionAlignment 20 00 00 00 ; 32-bytes-alignment
FileAlignment 20 00 00 00 ; 32-bytes-alignment
SizeOfImage c0 00 00 00 ; sum of all section sizes

section header (code), starting at 0x138:
Name 2e 63 6f 64 65 00 00 00 ; ".code"
VirtualSize 00 00 00 00 ; unused
VirtualAddress a0 01 00 00 ; RVA to code section
SizeOfRawData 20 00 00 00 ; size of code
PointerToRawData a0 01 00 00 ; file offset to code section
PointerToRelocations 00 00 00 00 ; unused
PointerToLinenumbers 00 00 00 00 ; unused
NumberOfRelocations 00 00 ; unused
NumberOfLinenumbers 00 00 ; unused
Characteristics 20 00 00 60 ; code, executable, readable

section header (data), starting at 0x160:
Name 2e 64 61 74 61 00 00 00 ; ".data"
VirtualSize 00 00 00 00 ; unused
VirtualAddress c0 01 00 00 ; RVA to data section
SizeOfRawData a0 00 00 00 ; size of data section
PointerToRawData c0 01 00 00 ; file offset to data section
PointerToRelocations 00 00 00 00 ; unused
PointerToLinenumbers 00 00 00 00 ; unused
NumberOfRelocations 00 00 ; unused
NumberOfLinenumbers 00 00 ; unused
Characteristics 40 00 00 c0 ; initialized, readable, writeable

(padding)
00 00 00 00 00 00 ; padding
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00

code section, starting at 0x1a0:
6A 00 ; push 0x00000000
68 d0 01 10 00 ; push offset _written
6A 0D ; push 0x0000000d
68 c0 01 10 00 ; push offset hello_string
6A F5 ; push 0xfffffff5
2E FF 15 28 02 10 00 ; call dword ptr cs:__imp__GetStdHandle@4
50 ; push eax
2E FF 15 24 02 10 00 ; call dword ptr cs:__imp__WriteConsoleA@20
C3 ; ret

data section, beginning at 0x1c0:
68 65 6C 6C 6F 2C 20 77 6F 72 6C 64 0A ; "hello, world\n"
00 00 00 ; padding to align _written
00 00 00 00 ; _written
padding:
00 00 00 00 00 00 00 00 00 00 00 00 ; padding
...全文
378 点赞 收藏 10
写回复
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
vBin 2002-01-31
哦,原来如此。

你可以再参照一样其它的编译器编译出的EXE文件他的SIZEOFIMAGE是多大。

回复
boodweb 2002-01-31
我只是想搞清楚PE的结构,尽量避免出现理解上的错误,不是钻牛角尖
回复
boodweb 2002-01-30
嗯,的确,在用编译器编译出的文件中(我用的是MASM32 v6),都是照你说的那样,SizeOfImage = 最后节的VirtualAddress + 其SizeOfRawData + 按照SectionAlignment所需要的对齐字节数,但是:
1. 将SizeOfImage改大仍可以运行
2. 将SizeOfImage在一定范围内改小也可以运行,有一个临界值,一旦小于此值,在2000下就不能运行了
回复
boodweb 2002-01-30
嗯,的确,在用编译器编译出的文件中(我用的是MASM32 v6),都是照你说的那样,SizeOfImage = 最后节的VirtualAddress + 其SizeOfRawData + 按照SectionAlignment所需要的对齐字节数,但是:
1. 将SizeOfImage改大仍可以运行
2. 将SizeOfImage在一定范围内改小也可以运行,有一个临界值,一旦小于此值,在2000下就不能运行了
回复
vBin 2002-01-30
这个值对你很重要吗?
为什么扣得这么紧呢?
回复
vBin 2002-01-28
而且当时我在编写我那个程序时,改EXE文件,除了改这个,还有许多地方需要改。
否则2000下也无法运行。这个在许多程序中都是这样。

我希望你不要老是专注你现在看的程序,往别的程序上看看。
回复
vBin 2002-01-28
是吗?我当时改大一点2000就出错,只有我算出的那个值才没问题。
可能跟程序本身有关。
回复
boodweb 2002-01-28
sorry!!!
SizeOfRawData不应该变,原来后面的Import Directory等内容也要算在里面
SizeOfRawData a0 00 00 00 ; size of data section

回复
boodweb 2002-01-27
哦,对不起,文中有两个地方写错了
SizeOfImage c0 01 00 00 ; sum of all section sizes
^^

SizeOfRawData 20 00 00 00 ; size of data section
^^

To vBin:
你加加看:最后一个section是.data,RVA=0x01c0加上.data的实际大小再对齐就应该再加0x20,得到的结果是0x00x01e0阿,可这个0x01c0在2000的确可以运行;
另外,我也试过在2000将SizeOfImage改大(改成0x200),但是仍然可以运行阿!
回复
vBin 2002-01-27
还有哪里不对吗?

跟你这样说吧,最后一个块的RVA+最后一个块的实际大小再对齐,这样铁定没错。
我以前不是这样算的,在2000中没问题。

我试过改过PE文件中一个数,就像SIZEOFIMAGE在98中写多点没事,但是在2000中写多些
程序就会出错不运行的。 98中还是蛮宽容的。
回复
发动态
发帖子
汇编语言
创建于2007-08-27

2.0w+

社区成员

汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
申请成为版主
社区公告
暂无公告