首页
社区
课程
招聘
在PE中添加,删除SECTION
发表于: 2009-12-14 14:20 14079

在PE中添加,删除SECTION

2009-12-14 14:20
14079

在PE中添加,删除SECTION

这两天空闲,自己写了个添加,删除SECTION的程序,发现里面的技巧很多,需要注意的地方也很多,现把心得写上,希望能给正在学习PE文件的朋友提供方便。

关于PE的格式,PE的基本知识,请参看其他相关文章。

添加SECTION

添加SECTION的前提是在最后一个SECTION与第一个区块之间有足够的空间)添加一个新SECTION 40字节。通常情况下,是有40字节的空间的,但是如果没有就需要想办法腾出40字节空间来。
通常有2种方法腾空间

重新编排PE头
通常IMAGE_DOS_HEADER 和 IMAGE_NT_HEADER不是紧挨着,中间有一些其他数据,比如DOS占位程序,这些数据基本上没用,可以将NT头以及SECTION数据前移覆盖这些数据达到扩充PE头空余空间添加新SECTION。
IMAGE_DOS_HEADER 的e_flanew 指向NT头相对于文件头的偏移,将NT头前移,只需修改e_flanew的值即可。

优点:相对于扩充PE头,不需要修改所有SECTION的PointerToRawData指向,不用移动所有区块。
缺点:腾出来的尺寸只能加入有限的新SECTION.

扩充PE头
这种方法通常将SizeOfHeader的尺寸扩大文件对齐字节,0x200字节,然后把所有SECTION的PointerToRawData值得加上0x200字节,然后再将所有区块数据向后移动0x200字节。当然SizeOfHeader 也需要加0x200字节。

优点:使用这种方法可以实现无限的添加新SECTION。
缺点:需要改动的地方比较多。

注意绑定输入表
有了空间不一定就能添加新SECTION,还需要查看绑定输入表,绑定输入表和其他节表不同,绑定输入表紧挨着最后的一个SECTION存放,绑定输入表而且必须在PE头区内,由IMAGE_DATA_DIRECTORY[11]来指向。
我手上的PE编辑工具,LoardPE,PETools,StudPE都忽视了这个问题,添加SECTION后都覆盖了绑定输入表数据,而且也没有IMAGE_DATA_DIRECTORY[11],导致添加节区后PE文件不能运行。

如果不想保留绑定输入,那么添加SECTION的时候直接把IMAGE_DATA_DIRECTORY[11]内的数据置0.
如果想保留绑定输入表,那么就先把绑定数据拷贝出来,添加完SECTION再把数据复制到这个SECTION的后面,然后修改IMAGE_DATA_DIRECTORY[11]的指向就可以。

IMAGE_SECTION_HEADER 结构内容
Name                        新区块的名字,注意不能超过8字节大小。
VirtualAddress        虚拟地址;这个地址就是PE文件装载后,这个区块所在的内存地址。地址必须是"内存页对齐",必须紧挨着上一个区块。计算公式就是上一个区                                                        块的VirtualAddress + VirtualSize 内存页对齐后的值。
VirtualSize                区块内数据的实际大小;通过数据的实际大小,就可以计算出文件对齐后的数据大小。
SizeOfRawData                区块数据文件对齐后的数据大小。根据VirtualSize计算可计算出文件对齐后的尺寸。
PointerToRawData        区块相对于文件头的文件偏移, 在文件中两区块数据之间不必紧挨着,但起始地址必须是"文件对齐"的。
Characteristics        区块的属性,可根据添加区块的实际目的设置属性,拿不准就设置E0000060代表可读,可写,可执行,包含代码,包含初始化数据。

添加SECTION后还需要添加这个SCTION的区块数据,首先需要把文件尺寸扩大,扩大的尺寸就是区块数据文件对齐后的大小。

最后将IMAGE_OPTIONAL_HEADER32的SizeOfImage 加上新区块数据的VirtualAddress。
将IMAGE_FILE_HEADER 的NumberOfSection 加 1。

删除SECTION

删除一个SECTION,需要考虑的比较多;

删除SECTION不能根据名称删除,应该根据序号删除,因为允许存在同名的Section。

如果删除的Section位于中间位置,后面Section的PointerToRawData文件偏移可以向上移动,但是VirtualAddress虚拟地址就不能简单的向上移动了,因为如果某个节区的VA发生变化,那么这个节区里的所有RVA也会发生变化,而要修复这些RVA工作量就太大了。处理办法就是,把要删除的这个Section的上一个Section的VirtualSize扩大,也就是加上要删除的这个Section的VirtualSize,这样,后面的所有Section的VirtualAddress不变,只修正PointerToRawData就可以。当然SizeOfImage也就不用调整了,PE映像大小没变,只改变了PE文件大小。

如果删除的是最后一个Section,那么删除后将SizeOfImage减小就可以,不存在VA问题。

如果删除的Section和IMAGE_NT_HEADER的DATA_DIRECTORY有关,比如重定位表,TLS表,那么必须要清除数据目录的VirtualAddress,和VirtualSize。

最后,如果有绑定数据,需要在文件中上移一个IMAGE_SECTION_HEADER尺寸,然后修正数据目录表的指向。

附上一段小代码,一个完整的添加删除SECTION例子:


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (5)
雪    币: 31
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zui
2
哈~谢谢分享了~学习中
2009-12-15 03:14
0
雪    币: 74
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
很强, 用汇编写程序

学习了.支持..
2009-12-16 20:02
0
雪    币: 270
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
4
写的太好了,某些pe工具加上新节后就运行不了,原来是绑定表在作怪。
2010-3-2 12:25
0
雪    币: 216
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
牛X..学习了
2013-8-4 15:05
0
雪    币: 108
活跃值: (44)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
6
不错,学习了
2013-8-4 18:46
0
游客
登录 | 注册 方可回帖
返回
//