• PE 扩大节


    适用条件:有的时候空白区不够需要进行扩大节

    以对最后一个节扩大0x1000为例子:

    为什么要扩大最后一个节呢?如果扩大最后的一个节之前的话,那么相对于当前扩大的节后面也会相应的变化,节表中每个节数据的信息都要相对应的纠正,相对比较繁琐!

    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;
    

    扩大节其实很简单,修改节数据对齐后的大小就可以了,并且在PE文件中添加任意数据进行填充

    步骤如下:

    1、分配一块新的空间,大小为S

    2、将最后一个节的SizeOfRawData和VirtualSize都改成N

    N = (SizeOfRawData 或者 VirtualSize内存对齐后的值) + S

    3、最后修改PE扩展头中的SizeofImage(内存PE镜像大小)


    实现过程:

    1、最后面插入0x1000字节大小,数据用0来填充

    2、先观察是否文件对齐和内存对齐相同,如下图发现是不同的

    2、那么继续,来到最后个节的节表部分,在该节中的virtualSize(内存中当前节没有对齐的实际大小)和 SizeOfRawData(文件中当前节对齐的大小)二者中选最大的值,然后再最大的值上添加0x1000,然后把两个都改为最大的值

    3、最后来到PE扩展头中的SizeofImage(内存PE镜像大小)成员进行修改,先按照内存对齐进行存放 然后再加上0x1000大小

    实现逻辑:

    逻辑顺序:
    
    1、拉伸到内存						
    						
    2、分配一块新的空间:SizeOfImage + Ex						
    						
    3、将最后一个节的SizeOfRawData和VirtualSize改成N						
    						
       SizeOfRawData = VirtualSize = N						
    						
       N = (SizeOfRawData或者VirtualSize 内存对齐后的值) + Ex						
    						
    4、修改SizeOfImage大小						
    					
       SizeOfImage = SizeOfImage + Ex
    

    实现代码:

    void ExpandSection(PVOID pFileBuffer,PDWORD OldBufferSize,PVOID* pNewBuffer){
    
    	PIMAGE_DOS_HEADER pImageDosHeader = NULL;
    	PIMAGE_FILE_HEADER pImageFileHeader = NULL;
    	PIMAGE_OPTIONAL_HEADER32 pImageOptionalHeader = NULL;
    	PIMAGE_SECTION_HEADER pImageSectionHeaderGroup = NULL;
    	PIMAGE_SECTION_HEADER NewSec = NULL;
    
    	DWORD TheBiggerOfSizeOfRawDataOrVirtualSize = 0;
    	DWORD NewLength=0;
    	
    	pImageDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    	pImageFileHeader = (PIMAGE_FILE_HEADER)((DWORD)pImageDosHeader + pImageDosHeader->e_lfanew + 4);
    	pImageOptionalHeader = (PIMAGE_OPTIONAL_HEADER32)((DWORD)pImageFileHeader + sizeof(IMAGE_FILE_HEADER));
    	pImageSectionHeaderGroup = (PIMAGE_SECTION_HEADER)((DWORD)pImageOptionalHeader + pImageFileHeader->SizeOfOptionalHeader);
    
    	
    	//生成对应的内存大小的空间
    	NewLength += *OldBufferSize + 0x1000;
    	*pNewBuffer = (PVOID)malloc(NewLength);
    	ZeroMemory(*pNewBuffer,NewLength);
    	
    	//拷贝之前内存空间 到 当前新生成的内存空间
    	memcpy(*pNewBuffer,pFileBuffer,*OldBufferSize);
    
    	//修改节数据的偏移
    	if(pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-1].Misc.VirtualSize > pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-1].SizeOfRawData){
    		TheBiggerOfSizeOfRawDataOrVirtualSize = pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-1].Misc.VirtualSize;
    	}else{
    		TheBiggerOfSizeOfRawDataOrVirtualSize = pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-1].SizeOfRawData;
    	}
    
    	pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-1].Misc.VirtualSize = TheBiggerOfSizeOfRawDataOrVirtualSize;
    	pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-1].SizeOfRawData = TheBiggerOfSizeOfRawDataOrVirtualSize;
    
    	// pImageOptionalHeader->SizeOfImage修改
    	pImageOptionalHeader->SizeOfImage = (DWORD)pImageOptionalHeader->SizeOfImage + 0x1000;
    
    	*OldBufferSize = NewLength;
    }
    
  • 相关阅读:
    pip 笔记
    Codeforces Round #739
    leetcode周赛 248
    AcWing周赛 6
    AcWing周赛 5
    算法提高--最长上升子序列一
    算法提高--数字三角形模型
    数据结构--线段树
    leetcode周赛 243
    AcWing周赛 1
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/12319386.html
Copyright © 2020-2023  润新知