PE:AddNewSection

DWORD AddNewSection(IN PVOID pFileBuffer, OUT PVOID* pNewFileBuffer)
{
    PIMAGE_DOS_HEADER pDosHeader = NULL;
    PIMAGE_NT_HEADERS pNTHeader = NULL;
    PIMAGE_FILE_HEADER pPEHeader = NULL;
    PIMAGE_OPTIONAL_HEADER32 pOptionHeader = NULL;
    PIMAGE_SECTION_HEADER pSectionHeader = NULL;

    if(!pFileBuffer)
    {
        printf("FileBuffer无效!\n");
        free(pFileBuffer);
        return;
    }
    if(*(PWORD)pFileBuffer != IMAGE_DOS_SIGNATURE)
    {
        printf("不是有效的PE文件\n");
        free(pFileBuffer);
        return;
    }
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)(pDosHeader + pDosHeader->e_lfanew);
    pPEHeader = (PIMAGE_FILE_HEADER)(pNTHeader + 4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER)(pPEHeader + IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)(pOptionHeader + pPEHeader->SizeOfOptionalHeader);
    //判断是否有足够的空间添加一个节表
    if((pOptionHeader->SizeOfHeaders - (pDosHeader->e_lfanew + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader + IMAGE_SIZEOF_SECTION_HEADER * pPEHeader->NumberOfSections)) < IMAGE_SIZEOF_SECTION_HEADER * 2)
    {
       printf("添加节表空间不足\n");
       free(pFileBuffer);
       return;
    }
    //计算添加节后的大小sizeOfFileBuffer
    DWORD sizeOfNewFileBuffer = 0;
    DWORD sizeOfSections = 0;
    DWORD sizeOfFileBuffer = 0;
    PIMAGE_SECTION_HEADER pTemOfSectionHeader = pSectionHeader;
    for(int i=0;i<pPEHeader->NumberOfSections;pTemOfSectionHeader++,i++)
    {
        sizeOfSections += pTemOfSectionHeader->PointerToRawData;
    }
    sizeOfFileBuffer = sizeOfSections + pOptionHeader->SizeOfHeaders;
    sizeOfNewFileBuffer = sizeOfFileBuffer + pOptionHeader->FileAlignment;//增加一个文件对齐长度的大小的节
    //分配新的缓冲区
    PVOID pTemOfNewFileBuffer = NULL;
    pTemOfNewFileBuffer = malloc(sizeOfNewFileBuffer);
    if(!pTemOfNewFileBuffer)
    {
        printf("pTemOfNewFileBuffer分配失败!\n");
        free(pFileBuffer);
        return;
    }
    //复制PE文件到新的缓冲区
    memset(pTemOfNewFileBuffer,0,sizeOfNewFileBuffer);
    memcpy(pTemOfNewFileBuffer,pFileBuffer,sizeOfFileBuffer);
    //添加新节表并修改属性
    //通过上面的循环后,pTemOfSectionHeader是新节表的RVA
    PIMAGE_SECTION_HEADER pNewSectionHeader = (PIMAGE_SECTION_HEADER)(((DWORD)pTemOfSectionHeader - (DWORD)pFileBuffer) + (DWORD)pNewFileBuffer);
    memset(pNewSectionHeader,0,0x80);//填充两个节表大小的0
    memcpy(pNewSectionHeader->Name,"new",sizeof("new"));
    pNewSectionHeader->Misc.VirtualSize = pOptionHeader->FileAlignment;
    pNewSectionHeader->VirtualAddress = (pNewSectionHeader - 1)->VirtualAddress + pOptionHeader->SectionAlignment;
    pNewSectionHeader->SizeOfRawData = pOptionHeader->FileAlignment;
    pNewSectionHeader->PointerToRawData = (pNewSectionHeader - 1)->PointerToRawData + (pNewSectionHeader - 1)->SizeOfRawData;
    pNewSectionHeader->Characteristics = pNewSectionHeader->Characteristics||0x60000020;
    //修改NumberOfSections和sizeofimage
    pPEHeader->NumberOfSections += 1;
    pOptionHeader->SizeOfImage += pOptionHeader->FileAlignment;

    *pNewFileBuffer = pTemOfNewFileBuffer;
    pTemOfNewFileBuffer = NULL;
    free(pFileBuffer);
    return sizeOfNewFileBuffer;
}

  
  
1、判断是否有足够的空间,可以添加一个节表.
判断条件:
SizeOfHeader - (DOS + 垃圾数据 + PE标记 + 标准PE头 + 可选PE头 + 已存在节表)
>= 2个节表的大小
2、需要修改的数据
1) 添加一个新的节(可以copy一份)
2) 在新增节表后面 填充一个节大小的0;
3) 修改PE头中节的数量
4) 修改sizeOfImage的大小
5) 再原有数据的最后,新增一个节的数据(内存对齐的整数倍).
6)修正新增节表的属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值