一丶为何扩大节spa
上面咱们讲了,空白区添加咱们的代码.可是有的时候.咱们的空白区不够了怎么办.因此须要进行扩大节.3d
扩大节其实很简单.修改节数据对齐后的大小便可. 而且在PE文件中添加0数据进行填充便可.调试
首先看一下咱们的节表code
typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //8个字节名字.本身能够起.编译器也能够给定.不重要. union { DWORD PhysicalAddress; DWORD VirtualSize; //节数据没有对齐后的大小.也就是没有对齐.节数据有多大. } Misc; DWORD VirtualAddress; //加载到内存中的第一个字节的地址.也就是虚拟地址.节在内存中哪里开始.内存中的VA + ImageBase 才是真正的节开始位置 DWORD SizeOfRawData; //修改这个属性的值,便可扩大节.而且在PE文件中添加相应的0数据进行填充. DWORD PointerToRawData; //在文件中的偏移.是文件对齐成员倍数. DWORD PointerToRelocations; //一下都是调试相关. DWORD PointerToLinenumbers; // WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; //节的属性 } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
二丶扩大节实战以及注意问题blog
PE扩大节的时候通常是最后一个节.缘由是本身不用修正偏移等各项属性了.若是是最后一个节扩大就很简单了.内存
咱们节表要修改的属性就是将节对齐后的数据进行修改便可.编译器
公式: 设一块咱们添加的控件为x的倍数io
设要修改后的值为M编译
那么 M = (节.sizeofRawData 或者 节.VirtualSize 按照对齐后大小对齐) + X便可.class
看公式很复杂,其实就是节的对齐后的数据.按照内存对齐后修改.而且加上咱们新空间的大小便可.
例如原来大小: 0x600, 你要扩大0x100个字节. 那么 修改后的值就为 0x700. 0x700要按照内存对齐进行存放.
还要修改扩展头中的 SizeofImage(内存PE镜像大小)
三丶扩大节实战
1.添加数据
随便找一个PE文件.在最后文件偏移处添加数据. 好比咱们要扩大0x1000.那么添加0x1000大小.
开始位置89f0 添加0x1000大小. 那么结束位置是 0x99F0
为了确认咱们的节数据会映射到内存.咱们0数据咱们填充为FFFF
2.修改节表属性
由于咱们添加了0x1000个字节大小.因此须要修改文件中节表的对齐后的大小. 也就是 节.sizeofRawToData
此时咱们没有修改以前.
,没有修改以前数据大小是0x0600.那么内存中节映射也不会有咱们的FFFF数据. 观看内存节起始位置为0x01c000 那么咱们去内存中
节数据位置看看.是否有咱们的FFF填充的数据
并无咱们的FF数据. 咱们修改文件节对齐数据为 0x1600.由于加了0x1000的数据.
再次在内存中查看已经有咱们映射的内存了. 第一个是F0结尾.下方是咱们的数据.
可是注意,修改以后并不能直接查看.由于PE无法运行.咱们必须修改扩展头中的sizeofImage属性.这样咱们的内存镜像大小才是真正的大小.
我是修改过了.节才会映射到内存中.因此能够查看.
3.修改SizeofImage属性
个人SzieofImage属性.原值就是按照内存对齐进行存放的.也就是0x01D000. 因此当我增长0x1000个字节的数据.其实并无超过SizeofImage的对其值.因此能够映射到内存那种.若是加了数据超过了SizeofImage
那么咱们就须要进行内存对齐了. 加上咱们扩展后的数据.而后进行内存对齐.
4.程序运行.
程序能够正常运行.而且咱们添加的数据也映射到内存中了.