创建一个新的节表

# define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;

#define IMAGE_SIZEOF_SIZE_NAME  8

typedef struct _Section_Header
{
    BYTE Name[IMAGE_SIZEOF_SIZE_NAME];
    union
    {
        DWORD PhysicalAddress;
        DWORD VirtualSize;
    }Misc;
    DWORD VirtualAddress;
    DWORD SizeOfRawData;
    DWORD PointerToRawData;
    DWORD PointerToReloacation;
    DWORD PointerToLinenumbers;
    DWORD NumberOfRelocations;
    WORD NumberOflinenumbers;
    WORD Characteristics;

}Section_Header;

typedef struct _PE_Information
{
    DWORD Dos_Header_e_lfanew;
    WORD File_Header_NumberOfSections;
    WORD File_Header_SizeOfOptionHeader;
    DWORD File_Header_Offset;
    DWORD Optional_Header_SizeOfImage;
    DWORD Optional_Header_SizeOfHeaders;
    DWORD Optional_Header_Offset;
    DWORD Section_Header_Offset;
}PE_Information;

int File_Length(FILE* pf, int* length)
{
    int ret = 0;

    fseek(pf, 0, SEEK_END);
    *length = ftell(pf);
    fseek(pf, 0, SEEK_SET);

    return 0;

}

int File_Read(const char* path, void** pFile, int* length)
{
    int ret = 0;
    int len;

    FILE* pf = fopen(path, "rb");
    if (!pf)
    {
        ret = -1;
        printf("File Open Error");
        return ret;
    }

    ret = File_Length(pf, &len);
    if (ret != 0)
    {
        ret = -1;
        printf("File_Length Error");
        return ret;
    }

    void* add = malloc(len + 0x1000);
    if (!add)
    {
        ret = -1;
        printf("malloc add error");
        return ret;
    }

    memset(add, 0, len + 0x1000);
    fread(add, len, 1, pf);
    fclose(pf);

    *length = len;
    *pFile = add;

    return ret;
}

int Get_PE_Information(void* pFile, PE_Information* PE)
{
    int ret = 0;

    memcpy(&PE->Dos_Header_e_lfanew, (BYTE*)pFile + 0x3c, sizeof(DWORD));

    PE->File_Header_Offset = PE->Dos_Header_e_lfanew + 0x4;
    memcpy(&PE->File_Header_NumberOfSections, (BYTE*)pFile + PE->File_Header_Offset + 0x2, sizeof(WORD));
    memcpy(&PE->File_Header_SizeOfOptionHeader, (BYTE*)pFile + PE->File_Header_Offset + 0x10, sizeof(WORD));

    PE->Optional_Header_Offset = PE->File_Header_Offset + 0x14;
    PE->Section_Header_Offset = PE->Optional_Header_Offset + PE->File_Header_SizeOfOptionHeader;

    memcpy(&PE->Optional_Header_SizeOfImage, (BYTE*)pFile + PE->Optional_Header_Offset + 0x38, sizeof(DWORD));
    memcpy(&PE->Optional_Header_SizeOfHeaders, (BYTE*)pFile + PE->Optional_Header_Offset + 0x3c, sizeof(DWORD));

    return ret;
}

int Get_Section(void* pFile, PE_Information* PE, Section_Header*** SectionGroup)
{
    int ret = 0;

    Section_Header** SectionG = nullptr;
    SectionG = (Section_Header**)malloc(sizeof(Section_Header*) * (PE->File_Header_NumberOfSections));
    if (SectionG == nullptr)
    {
        ret = -1;
        printf("malloc SectionG error");
        return ret;
    }
    memset(SectionG, 0, sizeof(Section_Header*) * PE->File_Header_NumberOfSections);

    for (int i = 0; i < PE->File_Header_NumberOfSections; i++)
    {
        SectionG[i] = (Section_Header*)malloc(sizeof(Section_Header));
        if (!SectionG[i])
        {
            ret = -1;
            printf("malloc SectionG[i] error");
            return ret;
        }
        memset(SectionG[i], 0, sizeof(Section_Header));
        memcpy(SectionG[i], (BYTE*)pFile + PE->Section_Header_Offset + sizeof(Section_Header) * i, sizeof(Section_Header));
    }

    *SectionGroup = SectionG;

    return ret;
}

int Create_Section(void* pFile, PE_Information* PE, Section_Header** SectionGroup)
{
    int ret = 0;

    //判断
    DWORD space = PE->Optional_Header_SizeOfHeaders - PE->Section_Header_Offset - sizeof(Section_Header) * PE->File_Header_NumberOfSections;
    if (space < sizeof(Section_Header) * 2)
    {
        ret = -1;
        printf("空间不足\n");
        return ret;
    }

    //将第一个节区的内容复制到最后一个节区
    memcpy((BYTE*)pFile + PE->Section_Header_Offset + sizeof(Section_Header) * PE->File_Header_NumberOfSections, (BYTE*)pFile + PE->Section_Header_Offset, sizeof(Section_Header));
    //将下28个字节变为0
    memset((BYTE*)pFile + PE->Section_Header_Offset + sizeof(Section_Header) * (PE->File_Header_NumberOfSections + 1), 0, sizeof(Section_Header));

    //修改NumberOfSections
    WORD* p1 = (WORD*)((BYTE*)pFile + PE->File_Header_Offset + 0x2);
    *p1 = PE->File_Header_NumberOfSections + 1;
    PE->File_Header_NumberOfSections += 1;

    //修改SizeOfImage
    int addsize = 0x1000;
    DWORD* p2 = (DWORD*)((BYTE*)pFile + PE->Optional_Header_Offset + 0x38);
    *p2 = PE->Optional_Header_SizeOfImage + 0x1000;
    PE->Optional_Header_SizeOfImage += 0x1000;


    //修改节表
    Section_Header* pSection = (Section_Header*)((BYTE*)pFile + PE->Section_Header_Offset +sizeof(Section_Header)*(PE->File_Header_NumberOfSections-1));
    memset(pSection, 0x6161616161616161, 8);
    pSection->SizeOfRawData = 0x1000;
    pSection->Misc.VirtualSize = 0x1000;
    DWORD address = SectionGroup[PE->File_Header_NumberOfSections - 2]->Misc.VirtualSize + SectionGroup[PE->File_Header_NumberOfSections - 2]->VirtualAddress;
    while (address % 0x1000 != 0)
    {
        address += 1;
    }
    pSection->VirtualAddress = address;
    pSection->PointerToRawData = SectionGroup[PE->File_Header_NumberOfSections - 2]->PointerToRawData + SectionGroup[PE->File_Header_NumberOfSections - 2]->SizeOfRawData;

    return ret;

}

int File_Copy(void* pFile, PE_Information* PE, int length)
{
    int ret = 0;

    FILE* pf = fopen("file5.exe", "wb");
    fwrite(pFile, length + 0x1000, 1, pf);

    return ret;
}

int main()
{
    int ret = 0;
    int length = 0;
    void* pFile = nullptr;
    const char* path = "C:/WinHex/WinHex.exe";

    ret = File_Read(path, &pFile, &length);
    if (ret != 0)
    {
        printf("File_Read error");
    }

    PE_Information PE;
    ret = Get_PE_Information(pFile, &PE);
    if (ret != 0)
    {
        printf("Get_PE_Information error");
    }

    Section_Header** SectionGroup;
    ret = Get_Section(pFile, &PE, &SectionGroup);
    if (ret != 0)
    {
        printf("GetSection error");
    }

    ret = Create_Section(pFile, &PE, SectionGroup);
    if (ret != 0)
    {
        printf("Create_Section error");
    }
    ret = File_Copy(pFile, &PE, length);

    

    return 0;
}

 

posted @ 2021-03-15 19:36  Yanmo  阅读(86)  评论(0)    收藏  举报