在PE中添加,删除SECTION

在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例子:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值