# 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;
}