vxug-VXAPI/VX-API/AddSectionToPeFile.cpp

186 lines
6.0 KiB
C++

#include "Win32Helper.h"
DWORD AlignSection(_In_ DWORD Size, _In_ DWORD Align, _In_ DWORD Address)
{
if (!(Size % Align))
return Address + Size;
return Address + (Size / Align + 1) * Align;
}
BOOL AddSectionToPeFileW(_In_ LPCWSTR Path, _In_ LPCWSTR SectionName, _In_ DWORD SectionSizeInBytes)
{
BOOL bFlag = FALSE;
HANDLE hHandle = INVALID_HANDLE_VALUE;
LONGLONG SizeOfTargetBinary = 0L;
PBYTE FileBuffer = NULL;
PIMAGE_DOS_HEADER Dos = NULL;
PIMAGE_NT_HEADERS Nt = NULL;
PIMAGE_FILE_HEADER File = NULL;
PIMAGE_OPTIONAL_HEADER Optional = NULL;
PIMAGE_SECTION_HEADER Section = NULL;
WORD Offset = ERROR_SUCCESS;
DWORD SectionCharacteristics = ERROR_SUCCESS;
CHAR DisposeableObject[32] = { 0 };
if (WCharStringToCharString(DisposeableObject, (PWCHAR)SectionName, StringLengthW(SectionName)) == 0)
goto EXIT_ROUTINE;
if(IsPeSectionW(Path, SectionName))
return TRUE;
SizeOfTargetBinary = GetFileSizeFromPathW((PWCHAR)Path, FILE_ATTRIBUTE_NORMAL);
if (SizeOfTargetBinary == INVALID_FILE_SIZE)
goto EXIT_ROUTINE;
hHandle = CreateFileW(Path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hHandle == INVALID_HANDLE_VALUE)
goto EXIT_ROUTINE;
FileBuffer = (PBYTE)HeapAlloc(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, SizeOfTargetBinary);
if (FileBuffer == NULL)
goto EXIT_ROUTINE;
if (!ReadFile(hHandle, FileBuffer, (DWORD)SizeOfTargetBinary, NULL, NULL))
goto EXIT_ROUTINE;
if (!RtlLoadPeHeaders(&Dos, &Nt, &File, &Optional, &FileBuffer))
goto EXIT_ROUTINE;
Section = (PIMAGE_SECTION_HEADER)(FileBuffer + Dos->e_lfanew + sizeof(IMAGE_NT_HEADERS));
Offset = File->NumberOfSections;
RtlZeroMemory(&Section[Offset], sizeof(IMAGE_SECTION_HEADER));
RtlCopyMemory(&Section[Offset].Name, DisposeableObject, StringLengthA(DisposeableObject));
Section[Offset].Misc.VirtualSize = AlignSection(SectionSizeInBytes, Optional->SectionAlignment, 0);
Section[Offset].VirtualAddress = AlignSection(Section[Offset - 1].Misc.VirtualSize, Optional->SectionAlignment, Section[Offset - 1].VirtualAddress);
Section[Offset].SizeOfRawData = AlignSection(SectionSizeInBytes, Optional->FileAlignment, 0);
Section[Offset].PointerToRawData = AlignSection(Section[Offset - 1].SizeOfRawData, Optional->FileAlignment, Section[Offset - 1].PointerToRawData);
SectionCharacteristics = IMAGE_SCN_MEM_WRITE |
IMAGE_SCN_CNT_CODE |
IMAGE_SCN_CNT_UNINITIALIZED_DATA |
IMAGE_SCN_MEM_EXECUTE |
IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_READ;
Section[Offset].Characteristics = SectionCharacteristics;
if (SetFilePointer(hHandle, Section[Offset].PointerToRawData + Section[Offset].SizeOfRawData, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
goto EXIT_ROUTINE;
if (!SetEndOfFile(hHandle))
goto EXIT_ROUTINE;
Optional->SizeOfImage = Section[Offset].VirtualAddress + Section[Offset].Misc.VirtualSize;
File->NumberOfSections += 1;
if (SetFilePointer(hHandle, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
goto EXIT_ROUTINE;
if (!WriteFile(hHandle, FileBuffer, (DWORD)SizeOfTargetBinary, NULL, NULL))
goto EXIT_ROUTINE;
bFlag = TRUE;
EXIT_ROUTINE:
if (FileBuffer)
HeapFree(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, FileBuffer);
if (hHandle)
CloseHandle(hHandle);
return bFlag;
}
BOOL AddSectionToPeFileA(_In_ LPCSTR Path, _In_ LPCSTR SectionName, _In_ DWORD SectionSizeInBytes)
{
BOOL bFlag = FALSE;
HANDLE hHandle = INVALID_HANDLE_VALUE;
LONGLONG SizeOfTargetBinary = 0L;
PBYTE FileBuffer = NULL;
PIMAGE_DOS_HEADER Dos = NULL;
PIMAGE_NT_HEADERS Nt = NULL;
PIMAGE_FILE_HEADER File = NULL;
PIMAGE_OPTIONAL_HEADER Optional = NULL;
PIMAGE_SECTION_HEADER Section = NULL;
WORD Offset = ERROR_SUCCESS;
DWORD SectionCharacteristics = ERROR_SUCCESS;
if (IsPeSectionA(Path, SectionName))
return TRUE;
SizeOfTargetBinary = GetFileSizeFromPathA((PCHAR)Path, FILE_ATTRIBUTE_NORMAL);
if (SizeOfTargetBinary == INVALID_FILE_SIZE)
goto EXIT_ROUTINE;
hHandle = CreateFileA(Path, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hHandle == INVALID_HANDLE_VALUE)
goto EXIT_ROUTINE;
FileBuffer = (PBYTE)HeapAlloc(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, SizeOfTargetBinary);
if (FileBuffer == NULL)
goto EXIT_ROUTINE;
if (!ReadFile(hHandle, FileBuffer, (DWORD)SizeOfTargetBinary, NULL, NULL))
goto EXIT_ROUTINE;
if (!RtlLoadPeHeaders(&Dos, &Nt, &File, &Optional, &FileBuffer))
goto EXIT_ROUTINE;
Section = (PIMAGE_SECTION_HEADER)(FileBuffer + Dos->e_lfanew + sizeof(IMAGE_NT_HEADERS));
Offset = File->NumberOfSections;
RtlZeroMemory(&Section[Offset], sizeof(IMAGE_SECTION_HEADER));
RtlCopyMemory(&Section[Offset].Name, SectionName, StringLengthA(SectionName));
Section[Offset].Misc.VirtualSize = AlignSection(SectionSizeInBytes, Optional->SectionAlignment, 0);
Section[Offset].VirtualAddress = AlignSection(Section[Offset - 1].Misc.VirtualSize, Optional->SectionAlignment, Section[Offset - 1].VirtualAddress);
Section[Offset].SizeOfRawData = AlignSection(SectionSizeInBytes, Optional->FileAlignment, 0);
Section[Offset].PointerToRawData = AlignSection(Section[Offset - 1].SizeOfRawData, Optional->FileAlignment, Section[Offset - 1].PointerToRawData);
SectionCharacteristics = IMAGE_SCN_MEM_WRITE |
IMAGE_SCN_CNT_CODE |
IMAGE_SCN_CNT_UNINITIALIZED_DATA |
IMAGE_SCN_MEM_EXECUTE |
IMAGE_SCN_CNT_INITIALIZED_DATA |
IMAGE_SCN_MEM_READ;
Section[Offset].Characteristics = SectionCharacteristics;
if (SetFilePointer(hHandle, Section[Offset].PointerToRawData + Section[Offset].SizeOfRawData, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
goto EXIT_ROUTINE;
if (!SetEndOfFile(hHandle))
goto EXIT_ROUTINE;
Optional->SizeOfImage = Section[Offset].VirtualAddress + Section[Offset].Misc.VirtualSize;
File->NumberOfSections += 1;
if (SetFilePointer(hHandle, 0, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
goto EXIT_ROUTINE;
if (!WriteFile(hHandle, FileBuffer, (DWORD)SizeOfTargetBinary, NULL, NULL))
goto EXIT_ROUTINE;
bFlag = TRUE;
EXIT_ROUTINE:
if (FileBuffer)
HeapFree(GetProcessHeapFromTeb(), HEAP_ZERO_MEMORY, FileBuffer);
if (hHandle)
CloseHandle(hHandle);
return bFlag;
}