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
...全文
1533 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
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中还是蛮宽容的。

21,497

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧