• PE 新增节


    新增节后,需要修改以下信息

    1、添加一个新节,可以复制一份,最好是拥有可执行属性的节,如.text

    2、在节表区,新增节的后面,填充一个节,用零填充

    3、修改标准PE头中NumberOfSections中节的数量,我这里原来5个,现在6个了

    4、修改SizeOfImage的大小,这里自己新增了0x1000,原本是27000,现在改为28000

    5、在原有数据的后面,新增一个节的数据(大小为内存对齐的整倍数)

    6、修正新增节表的属性,比如.text段的一般都为可执行属性,0x60000020


    Name:名字随便修改,不能超过八个字节。

    VirtualSize:申请的新节空间大小,比如1000

    VirtualAddress:等于上一个节的VirtualAddress + SizeOfRawData,VirtualAddress为在内存中的起始地址

    SizeOfRawData:当前节在文件中对齐后的大小,这里设置为0x1000

    这里SizeOfRawData和VirtualSize一样大小的原因是当前PE程序的内存对齐大小和文件对齐大小是相同的!

    PointerToRawData:等于上一个节的PointerToRawData + SizeOfRawData,当前节 数据在文件中的起始地址就是 上个节 在文件中对齐后的大小SizeOfRawData 加上 上个节 数据在文件中的起始地址PointerToRawData

    PointerToRelocation:设置成零

    PointerToLineNumbers:设置成零

    NumberOfLineRelocations:设置成零

    NumberOfLineNumbers:设置成零

    Characteristics:块属性0x20000060为可执行

    实现的代码:

    void AddNewSection(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 isOk;
    	DWORD NewLength=0;
    	PVOID LastSection = NULL;
    	PVOID CodeSection = NULL;
    
    	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);
    
    	//判断是否可以容纳相应的节表
    	isOk = (DWORD)pImageOptionalHeader->SizeOfHeaders - ((DWORD)pImageDosHeader->e_lfanew + IMAGE_SIZEOF_FILE_HEADER + pImageFileHeader->SizeOfOptionalHeader + 40*pImageFileHeader->NumberOfSections);
    	if(isOk < 80){
    		printf("空间太小 无法进行添加!");
    		return;
    	}
    
    	//生成对应的内存大小的空间
    	NewLength += *OldBufferSize + 0x1000;
    	*pNewBuffer = (PVOID)malloc(NewLength);
    	ZeroMemory(*pNewBuffer,NewLength);
    
    	//拷贝之前内存空间 到 当前新生成的内存空间
    	memcpy(*pNewBuffer,pFileBuffer,*OldBufferSize);
    
    	//获取新的结构体
    	pImageDosHeader = (PIMAGE_DOS_HEADER)(*pNewBuffer);
    	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);
    
    	// pImageFileHeader->NumberOfSections修改
    	pImageFileHeader->NumberOfSections = pImageFileHeader->NumberOfSections + 1;
    	
    	// pImageOptionalHeader->SizeOfImage修改
    	pImageOptionalHeader->SizeOfImage = (DWORD)pImageOptionalHeader->SizeOfImage + 0x1000;
    
    	// 复制代码段的节数据到 当前最后一个节数据后面
    	CodeSection = (PVOID)(&pImageSectionHeaderGroup[0]);
    	LastSection = (PVOID)(DWORD)(&pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-1]);
    	memcpy(LastSection,CodeSection,40);
    	
    	//修正相关属性
     	NewSec = (PIMAGE_SECTION_HEADER)LastSection;
    	strcpy(NewSec,".NewSec");
    	NewSec->Misc.VirtualSize = 0x1000;
    	NewSec->SizeOfRawData = 0x1000;
    	NewSec->VirtualAddress = pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-2].VirtualAddress + pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-2].SizeOfRawData;
    	NewSec->PointerToRawData = pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-2].PointerToRawData + pImageSectionHeaderGroup[pImageFileHeader->NumberOfSections-2].SizeOfRawData;
    	*OldBufferSize = NewLength;
    }
    

    参考文章:https://www.cnblogs.com/iBinary/p/9735276.html

  • 相关阅读:
    数据库管理
    CodeSmith的运用正在完善中,待续
    各搜索引擎搜索代码
    浏览器本地存储
    QQ在线代码生成
    6组Alpha冲刺4/6
    结对编程作业
    camera相关
    数电、模电相关
    usb协议学习
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/12319418.html
Copyright © 2020-2023  润新知