关于IMAGE_OPTIONAL_HEADER.SectionAlignment与IMAGE_OPTIONAL_HEADER.FileAlignment 以及内存映射的字节对齐
2012-02-26 15:23
701 查看
关于IMAGE_OPTIONAL_HEADER.SectionAlignment与IMAGE_OPTIONAL_HEADER.FileAlignment 以及内存映射的字节对齐
的关系.
一. PE格式(包括文件中和内存中)是怎么分块对齐的?
PE的大概格式是:
IMAGE_DOS_HEADER +
Stub +
IMAGE_NT_HEADERS +
IMAGE_SECTION_HEADER * n
Section 0
Section 1
...
Section n
分块对齐是这样分的:
------Block 1---------------------
IMAGE_DOS_HEADER +
Stub +
IMAGE_NT_HEADERS +
IMAGE_SECTION_HEADER * n
------Block 2---------------------
Section 0
------Block 3---------------------
Section 1
------Block 4---------------------
...
------Block 5---------------------
Section n
----------------------------------
从Block1 到 Block5都要按指定大小对齐.
其中, PE文件存储在磁盘的对齐是按照IMAGE_OPTIONAL_HEADER.FileAlignment对齐;
PE文件运行的时候再内存中是按照IMAGE_OPTIONAL_HEADER.SectionAlignment对齐.
用VC6生成一个Exe文件, 查看FileAlignment和SectionAlignment, 默认都是0x1000(4k).
一般Block 1比0x1000小的, 所以Block 2的ROF为0x1000.
而运行装载后, Block 2 的RVA一般为0x401000. (PE从0x400000开始装载的).
用VC2008生成一个Exe文件, 查看FileAlignment默认是0x200, SectionAlignment默认都是0x1000.
所以, 假设Block 1大小为0x2E6, 那么, 所以Block 2的ROF为0x400.
而运行装载后, Block 2 的RVA为0x401000. (PE从0x400000开始装载的).
而我们用CreateFileMapping打开一个文件时, 也是把文件加载到内存, 这个也是要对齐的,
但是这种对齐是针对整个文件的(这个也是基于0x1000对齐的).
区别是CreateFileMapping的对齐是针对这个文件的, 而PE文件运行装载的内存对齐是针对块的, 例如上面说的Block 1 ---- Block 5,
http://bbs.pediy.com/archive/index.php?t-90067.html
/ALIGN指定节的内存对齐属性,要更改节的文件对齐,
可以指定一个未公开的链接器选项"/FILEALIGN:#"来指定,例如"/FILEALIGN:0x1000"
#pragma comment(linker, "/ALIGN:0x1000")
#pragma comment(linker, "/FILEALIGN:0x1000") // 验证了, 写在代码里没效
在 VC2008 中这样写就说第2行是无效指令,只能在项目属性的|连接器|命令行|附加选项里写.
我用VC2008修改如下
(FileAlignment默认是0x200, SectionAlignment默认是0x1000)
1.
SectionAlignment(/ALIGN:0x1000)
FileAlignment(/FILEALIGN:0x1000)
可以运行(其实这个配置就VC6的默认配置)
2.
SectionAlignment(/ALIGN:0x200)
FileAlignment(/FILEALIGN:0x1000)
报不是Win32应用程序.
3.
/ALIGN指定节的内存对齐属性,要更改节的文件对齐,就是用/OPT:WIN98,可以指定4k对齐,如果是OPT:NOWIN98,就是512字节对齐.
vs 2008 已经不支持了。
在VC6.0下
FileAlignment和SectionAlignment, 默认都是0x1000(4k).
1.
SectionAlignment(/ALIGN:0x200)
可以运行(只改SectionAlignment, FileAlignment自动变成了0x200)
(有这个警告LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run)
2.
SectionAlignment(/ALIGN:0x200)
FileAlignment(/FILEALIGN:0x1000)
可以运行(FileAlignment自动变成了0x200)(也就是说再VC6.0中/FILEALIGN:0x1000是无效的)
(有这个警告LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run)
3.
SectionAlignment(/ALIGN:0x1000)
FileAlignment(/OPT:WIN98)
可以运行(SectionAlignment 0x1000, FileAlignment 0x200)
(有这个警告LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run)
的关系.
一. PE格式(包括文件中和内存中)是怎么分块对齐的?
PE的大概格式是:
IMAGE_DOS_HEADER +
Stub +
IMAGE_NT_HEADERS +
IMAGE_SECTION_HEADER * n
Section 0
Section 1
...
Section n
分块对齐是这样分的:
------Block 1---------------------
IMAGE_DOS_HEADER +
Stub +
IMAGE_NT_HEADERS +
IMAGE_SECTION_HEADER * n
------Block 2---------------------
Section 0
------Block 3---------------------
Section 1
------Block 4---------------------
...
------Block 5---------------------
Section n
----------------------------------
从Block1 到 Block5都要按指定大小对齐.
其中, PE文件存储在磁盘的对齐是按照IMAGE_OPTIONAL_HEADER.FileAlignment对齐;
PE文件运行的时候再内存中是按照IMAGE_OPTIONAL_HEADER.SectionAlignment对齐.
用VC6生成一个Exe文件, 查看FileAlignment和SectionAlignment, 默认都是0x1000(4k).
一般Block 1比0x1000小的, 所以Block 2的ROF为0x1000.
而运行装载后, Block 2 的RVA一般为0x401000. (PE从0x400000开始装载的).
用VC2008生成一个Exe文件, 查看FileAlignment默认是0x200, SectionAlignment默认都是0x1000.
所以, 假设Block 1大小为0x2E6, 那么, 所以Block 2的ROF为0x400.
而运行装载后, Block 2 的RVA为0x401000. (PE从0x400000开始装载的).
而我们用CreateFileMapping打开一个文件时, 也是把文件加载到内存, 这个也是要对齐的,
但是这种对齐是针对整个文件的(这个也是基于0x1000对齐的).
区别是CreateFileMapping的对齐是针对这个文件的, 而PE文件运行装载的内存对齐是针对块的, 例如上面说的Block 1 ---- Block 5,
http://bbs.pediy.com/archive/index.php?t-90067.html
/ALIGN指定节的内存对齐属性,要更改节的文件对齐,
可以指定一个未公开的链接器选项"/FILEALIGN:#"来指定,例如"/FILEALIGN:0x1000"
#pragma comment(linker, "/ALIGN:0x1000")
#pragma comment(linker, "/FILEALIGN:0x1000") // 验证了, 写在代码里没效
在 VC2008 中这样写就说第2行是无效指令,只能在项目属性的|连接器|命令行|附加选项里写.
我用VC2008修改如下
(FileAlignment默认是0x200, SectionAlignment默认是0x1000)
1.
SectionAlignment(/ALIGN:0x1000)
FileAlignment(/FILEALIGN:0x1000)
可以运行(其实这个配置就VC6的默认配置)
2.
SectionAlignment(/ALIGN:0x200)
FileAlignment(/FILEALIGN:0x1000)
报不是Win32应用程序.
3.
/ALIGN指定节的内存对齐属性,要更改节的文件对齐,就是用/OPT:WIN98,可以指定4k对齐,如果是OPT:NOWIN98,就是512字节对齐.
vs 2008 已经不支持了。
在VC6.0下
FileAlignment和SectionAlignment, 默认都是0x1000(4k).
1.
SectionAlignment(/ALIGN:0x200)
可以运行(只改SectionAlignment, FileAlignment自动变成了0x200)
(有这个警告LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run)
2.
SectionAlignment(/ALIGN:0x200)
FileAlignment(/FILEALIGN:0x1000)
可以运行(FileAlignment自动变成了0x200)(也就是说再VC6.0中/FILEALIGN:0x1000是无效的)
(有这个警告LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run)
3.
SectionAlignment(/ALIGN:0x1000)
FileAlignment(/OPT:WIN98)
可以运行(SectionAlignment 0x1000, FileAlignment 0x200)
(有这个警告LINK : warning LNK4108: /ALIGN specified without /DRIVER or /VXD; image may not run)
相关文章推荐
- 关于PE文件格式中IMAGE_OPTIONAL_HEADER.FileAlignment的一些说明
- FCKeditor关于图片上传出现错误“ 提示没有权限 Type=Image” 以及出现"this connector is disabled Please check the"editor/filemanager/connectors/aspx/conf
- 关于sizeof与#pragma pack 以及网络上关于字节对齐的一点感想
- 关于位域的字节内存储顺序、字节对齐、字节序以及符号
- 关于位域的字节内存储顺序、字节对齐、字节序以及符号
- C_语法概念_sizeof()功能:计算数据空间的字节数以及字节对齐问题
- 关于内存字节对齐
- 关于导入GPUimage到工程以及简单使用
- struct 字节对齐问题(不包含struct嵌套的讨论以及修改机器的对齐方式的时候),更详细的请参考收藏
- 关于struct和union存储的内存字节对齐的问题
- VC++中关于字节对齐的问题
- PE文件详解三:节表(区块表)IMAGE_SECTION_HEADER结
- 关于字节对齐
- 字节对齐(强制对齐以及自然对齐)
- 【转载】 -- 关于C编译器里字节对齐的问题
- 关于TileBrush中Viewbox,Viewport以及Stretch,AlignmentX/Y的详细研究
- UITableView中关于viewForHeaderInSection的一点小坑
- headerfile头文件的使用和.pch 以及 宏定义
- 关于字节对齐问题在通信程序中的开发经验
- 一篇关于字节对齐的非常好的文章