# define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int DWORD;
# define IMAGE_SIZEOF_SHORT_NAME 8
# define ShellCodeLength 0x12
# define FunctionAddress 0x767F1930
BYTE ShellCode[] = {
0x6A, 0x00,
0x6A, 0x00,
0x6A, 0x00,
0x6A, 0x00,
0xE8, 0x00, 0x00, 0x00, 0x00,
0xE9, 0x00, 0x00, 0x00, 0x00
};
typedef struct _Section_Header
{
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
}Section_Header;
typedef struct _PE_Information
{
DWORD DOS_e_lfanew;
WORD File_Header_NumberOfSections;
WORD File_Header_SizeOfOptionalHeader;
DWORD File_Header_Offset;
DWORD Optional_Header_Offset;
DWORD Optional_Header_ImageBase;
DWORD Optional_Header_AddressOfEntryPoint;
DWORD Optional_Header_SizeOfHeader;
DWORD Optional_Header_SizeOfImage;
DWORD Section_Header_Offset;
}PE_Information;
int File_Length(FILE* pf, int* len)
{
int ret = 0;
fseek(pf, 0, SEEK_END);
*len = ftell(pf);
fseek(pf, 0, SEEK_SET);
return ret;
}
int File_Read(const char* path, int* len, void** pFile)
{
int ret = 0;
int length = 0;
FILE* pf = fopen(path, "rb");
if (!pf)
{
ret = -1;
printf("File Open Error");
return ret;
}
ret = File_Length(pf, &length);
if (ret != 0)
{
ret = -1;
printf("File_Length Error");
return ret;
}
void* add = malloc(length);
if (!add)
{
ret = -1;
printf("malloc add error");
return ret;
}
memset(add, 0, length);
fread(add,length,1,pf);
fclose(pf);
*pFile = add;
*len = length;
return ret;
}
int Get_PE_Information(PE_Information* PE, void* pFile)
{
int ret = 0;
memcpy(&PE->DOS_e_lfanew, (BYTE*)pFile + 0x3c, sizeof(DWORD));
PE->File_Header_Offset = PE->DOS_e_lfanew + 0x4;
memcpy(&PE->File_Header_NumberOfSections, (BYTE*)pFile + PE->File_Header_Offset + 0x2, sizeof(WORD));
memcpy(&PE->File_Header_SizeOfOptionalHeader, (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_SizeOfOptionalHeader;
memcpy(&PE->Optional_Header_AddressOfEntryPoint, (BYTE*)pFile + PE->Optional_Header_Offset + 0x10, sizeof(DWORD));
memcpy(&PE->Optional_Header_ImageBase, (BYTE*)pFile + PE->Optional_Header_Offset + 0x1c, sizeof(DWORD));
memcpy(&PE->Optional_Header_SizeOfHeader, (BYTE*)pFile + PE->Optional_Header_Offset + 0x3c, sizeof(DWORD));
memcpy(&PE->Optional_Header_SizeOfImage, (BYTE*)pFile + PE->Optional_Header_Offset + 0x38, sizeof(DWORD));
return ret;
}
int Get_Section_Header(PE_Information* PE, void* pFile, Section_Header*** SectionGroup)
{
int ret = 0;
Section_Header** SectionG = nullptr;
SectionG = (Section_Header**)malloc(sizeof(Section_Header*) * PE->File_Header_NumberOfSections);
if (!SectionG)
{
ret = -1;
printf("malloc SectionG error");
return ret;
}
for (int i = 0; i < PE->File_Header_NumberOfSections; i++)
{
SectionG[i] = (Section_Header*)malloc(sizeof(Section_Header));
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 Image_Read(void** pImage, PE_Information* PE, void* pFile, Section_Header** SectionGroup)
{
int ret = 0;
void* add2 = malloc(PE->Optional_Header_SizeOfImage);
if (!add2)
{
printf("malloc add2 error");
ret = -1;
return ret;
}
memset(add2, 0, PE->Optional_Header_SizeOfImage);
memcpy(add2, pFile, PE->Optional_Header_SizeOfHeader);
for (int i = 0; i < PE->File_Header_NumberOfSections; i++)
{
memcpy((BYTE*)add2 + SectionGroup[i]->VirtualAddress, (BYTE*)pFile + SectionGroup[i]->PointerToRawData, SectionGroup[i]->SizeOfRawData);
}
*pImage = add2;
return ret;
}
int ShellCode_Insert(void* pImage, PE_Information* PE, Section_Header** SectionGroup,int i)
{
int ret = 0;
//判断是否有空间
int space = SectionGroup[i]->SizeOfRawData - SectionGroup[i]->Misc.VirtualSize;
if (space < ShellCodeLength)
{
ret = -1;
printf("空间不足");
return ret;
}
//判断该节区数据是否可执行,如果不可执行,修改节区数据
DWORD* pC = (DWORD*)((BYTE*)pImage + PE->Section_Header_Offset + 0x24 + sizeof(Section_Header) * i);
*pC = 0xC00000C0;
//将ShellCode复制进去
DWORD* p6A = (DWORD*)((BYTE*)pImage + SectionGroup[i]->VirtualAddress+SectionGroup[i]->Misc.VirtualSize);
memcpy(p6A, ShellCode, ShellCodeLength);
//修改ShellCodeE8
DWORD NextAddress1 = SectionGroup[i]->VirtualAddress + SectionGroup[i]->Misc.VirtualSize + PE->Optional_Header_ImageBase+0xD;
DWORD X1 = FunctionAddress - NextAddress1;
DWORD* pE8 =(DWORD*) ((BYTE*)p6A + 0x9);
*pE8 = X1;
//修改ShellCodeE9
DWORD NextAddress2 = NextAddress1 + 0x5;
DWORD TrueAddress = PE->Optional_Header_ImageBase + PE->Optional_Header_AddressOfEntryPoint;
DWORD X2 = TrueAddress - NextAddress2;
DWORD* pE9 = (DWORD*)((BYTE*)pE8 + 0x5);
*pE9 = X2;
//修改AddressOfEntryPoint
DWORD ReturnAddress = SectionGroup[i]->VirtualAddress + SectionGroup[i]->Misc.VirtualSize;
DWORD* p = (DWORD*)((BYTE*)pImage + PE->Optional_Header_Offset + 0x10);
*p = ReturnAddress;
return ret;
}
void File_Copy(void* pImage, PE_Information* PE, Section_Header** SectionGroup,int length)
{
void* add3 = malloc(length);
memset(add3, 0, length);
memcpy(add3, pImage, PE->Optional_Header_SizeOfHeader);
for (int i = 0; i < PE->File_Header_NumberOfSections; i++)
{
memcpy((BYTE*)add3 + SectionGroup[i]->PointerToRawData,(BYTE*) pImage + SectionGroup[i]->VirtualAddress, SectionGroup[i]->SizeOfRawData);
}
FILE* pp = fopen("file.exe","wb");
fwrite(add3, length, 1, pp);
}
int main()
{
int ret = 0;
void* pFile = nullptr;
const char* path = "C:/WinHex/WinHex.exe";
int length = 0;
PE_Information PE;
ret = File_Read(path, &length, &pFile);
if (ret !=0)
{
printf("File_Read Error");
}
ret = Get_PE_Information(&PE, pFile);
if (ret!=0)
{
printf("Get_PE_Information Error");
}
Section_Header** SectionGroup = nullptr;
ret = Get_Section_Header(&PE, pFile, &SectionGroup);
if (ret != 0)
{
printf("Get_Section_Header error");
}
void* pImage = nullptr;
ret = Image_Read(&pImage, &PE, pFile, SectionGroup);
if (ret != 0)
{
printf("Image_Read error");
}
int i = 0;
std::cin << i;
ret = ShellCode_Insert(pImage, &PE, SectionGroup, i);
if (ret != 0)
{
printf("ShellCode_Insert error");
}
File_Copy(pImage, &PE, SectionGroup, length);
}