扩大节-合并节-数据目录

  1. 扩大最后一个节
  2. 合并节

扩大最后一个节

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

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <windows.h>
#include <memory.h>

int GetFilesize(FILE* fptr);
char* ReadFilea(const char* Filepath); 

//返回对齐后的大小
DWORD alignment(DWORD alignment_value, DWORD addend) {
    int t = addend / alignment_value;
    int res_value = addend % alignment_value;
    if (t < 0 || (t == 1 && res_value == 0))
        return alignment_value;
    return (t+1)*alignment_value;
} 

bool enlarge(char* path) {
    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;
    
    char* pFileBuffer = ReadFilea(path);
    if (!pFileBuffer) {
        printf("读取文件失败");
        return false;
    }
    pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer;
    pNTHeader = (PIMAGE_NT_HEADERS)(pFileBuffer + (pDosHeader->e_lfanew));
    pPEHeader = (PIMAGE_FILE_HEADER)(pFileBuffer + (pDosHeader->e_lfanew) + 4);
    pOptionHeader = (PIMAGE_OPTIONAL_HEADER32)(pFileBuffer + (pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER);
    pSectionHeader = (PIMAGE_SECTION_HEADER)(pFileBuffer + (pDosHeader->e_lfanew) + 4 + IMAGE_SIZEOF_FILE_HEADER + pPEHeader->SizeOfOptionalHeader);
     
    for (size_t i = 0; i<pPEHeader->NumberOfSections-1; i++) 
        pSectionHeader++;
    DWORD max = (pSectionHeader->PointerToRawData > pSectionHeader->Misc.VirtualSize ? pSectionHeader->SizeOfRawData : pSectionHeader->Misc.VirtualSize);
    pSectionHeader->SizeOfRawData = max + 0x1000;
    pSectionHeader->Misc.VirtualSize = max + 0x1000;
    pOptionHeader->SizeOfImage = alignment(0x1000,pOptionHeader->SizeOfImage + 0x1000);
    
    int filesize = pSectionHeader->PointerToRawData + pSectionHeader->SizeOfRawData;
    char* newBuffer = (char*)malloc(filesize);
    memset(newBuffer, 0, filesize);
    memcpy(newBuffer, pFileBuffer, filesize);
    FILE* nFp;
    nFp2 = fopen("D:\\ipmsg\\IPMsgnew_2_4.exe","wb");
    fwrite(newBuffer, filesize, 1, nFp);
    fclose(nFp);
    free(newBuffer);
    free(pFileBuffer);
    newBuffer = NULL; pFileBuffer = NULL;
    
}
char* ReadFilea(const char* Filepath) {
    FILE* fptr = NULL;
    fptr = fopen(Filepath,"rb");
    if (!fptr) {
        printf("文件打开失败\n");
        return NULL;
    } 
    int filesize = 0;
    filesize = GetFilesize(fptr);
    if (filesize == 0) {
        printf("获取文件大小失败\n");
        return NULL;
    }
    char* FileBuffer = (char*)malloc(filesize);
    if (!FileBuffer) {
        printf("开辟空间失败\n");
        return NULL;
    }
    //读取文件内容到内存 
    size_t n = fread(FileBuffer, 1, filesize, fptr);
    if (!n) {
        printf("读取数据失败\n");
        free(FileBuffer); FileBuffer = NULL;
        fclose(fptr);
        return NULL;
    }
    fclose(fptr);
    return FileBuffer;
}

int GetFilesize(FILE* fptr) {
    int num = 0;
    fseek(fptr, 0, SEEK_END);
    num = ftell(fptr);
    fseek(fptr, 0, SEEK_SET);
    return num;
}

int main() {
    char* path = (char*)"D:\\ipmsg\\IPMsg_2_4.exe";
    enlarge(path);
    return 0;
}

合并节

1、拉伸到内存
2、将第一个节的内存大小、文件大小改成一样
Max = SizeOfRawData>VirtualSize?SizeOfRawData:VirtualSize
SizeOfRawData = VirtualSize = 最后一个节的VirtualAddress + Max - SizeOfHeaders内存对齐后的大小
3、将第一个节的属性改为包含所有节的属性
4、修改节的数量为1


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1666739907@qq.com
github