# 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); }
原文:https://www.cnblogs.com/yanmo/p/14533678.html