From 8b3b560b06f1489d0ab0e1c63a1d38972229168d Mon Sep 17 00:00:00 2001 From: SmokelessCPU Date: Thu, 4 Aug 2022 11:19:06 +0200 Subject: [PATCH] Upload file --- README.md | 1 + SmokelessRuntimeEFIPatcher.dsc | 34 ++ SmokelessRuntimeEFIPatcher/OpCode.c | 126 +++++ SmokelessRuntimeEFIPatcher/Opcode.h | 29 ++ .../SmokelessRuntimeEFIPatcher.c | 430 ++++++++++++++++++ .../SmokelessRuntimeEFIPatcher.inf | 47 ++ SmokelessRuntimeEFIPatcher/Utility.c | 231 ++++++++++ SmokelessRuntimeEFIPatcher/Utility.h | 37 ++ 8 files changed, 935 insertions(+) create mode 100644 README.md create mode 100755 SmokelessRuntimeEFIPatcher.dsc create mode 100644 SmokelessRuntimeEFIPatcher/OpCode.c create mode 100644 SmokelessRuntimeEFIPatcher/Opcode.h create mode 100755 SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.c create mode 100755 SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.inf create mode 100644 SmokelessRuntimeEFIPatcher/Utility.c create mode 100644 SmokelessRuntimeEFIPatcher/Utility.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..ded35ed --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# SmokelessRuntimeEFIPatcher diff --git a/SmokelessRuntimeEFIPatcher.dsc b/SmokelessRuntimeEFIPatcher.dsc new file mode 100755 index 0000000..6324658 --- /dev/null +++ b/SmokelessRuntimeEFIPatcher.dsc @@ -0,0 +1,34 @@ +[Defines] + PLATFORM_NAME = SmokelessRuntimeEFIPatcherPkg + PLATFORM_GUID = 435762d8-e678-46f0-a3d2-5c041a3a1368 + PLATFORM_VERSION = 0.01 + DSC_SPECIFICATION = 0x00010006 + OUTPUT_DIRECTORY = Build/SmokelessRuntimeEFIPatcher + SUPPORTED_ARCHITECTURES = IA32|X64|EBC|ARM|AARCH64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + +[LibraryClasses] + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf +[Components] + SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.inf diff --git a/SmokelessRuntimeEFIPatcher/OpCode.c b/SmokelessRuntimeEFIPatcher/OpCode.c new file mode 100644 index 0000000..e1165b6 --- /dev/null +++ b/SmokelessRuntimeEFIPatcher/OpCode.c @@ -0,0 +1,126 @@ +#include "Opcode.h" +#include "Utility.h" +EFI_STATUS LoadFS(EFI_HANDLE ImageHandle, CHAR8 *FileName, EFI_LOADED_IMAGE_PROTOCOL **ImageInfo, EFI_HANDLE *AppImageHandle) +{ + UINTN ExitDataSize; + UINTN NumHandles; + UINTN Index; + EFI_HANDLE *SFS_Handles; + EFI_STATUS Status = EFI_SUCCESS; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + Status = + gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &NumHandles, &SFS_Handles); + + if (Status != EFI_SUCCESS) + { + Print(L"Could not find handles - %r\n", Status); + return Status; + } + Print(L"No of Handle - %d\n", NumHandles); + + for (Index = 0; Index < NumHandles; Index++) + { + Status = gBS->OpenProtocol( + SFS_Handles[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&BlkIo, + ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (Status != EFI_SUCCESS) + { + Print(L"Protocol is not supported - %r\n", Status); + return Status; + } + CHAR16 FileName16[255] = {0}; + UnicodeSPrint(FileName16, sizeof(FileName16), L"%a", FileName); + FilePath = FileDevicePath(SFS_Handles[Index], FileName16); + Status = gBS->LoadImage(FALSE, ImageHandle, FilePath, (VOID *)NULL, 0, + AppImageHandle); + + if (Status != EFI_SUCCESS) + { + Print(L"Could not load the image on Handle %d - %r\n", Index, Status); + continue; + } + else + { + Print(L"Loaded the image with success on Handle %d\n", Index); + // Print (L"Loaded the image with success\n"); + Status = gBS->OpenProtocol(*AppImageHandle, &gEfiLoadedImageProtocolGuid, + (VOID **)ImageInfo, ImageHandle, (VOID *)NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + return Status; + } + } + return Status; +} +EFI_STATUS LoadFV(EFI_HANDLE ImageHandle, CHAR8 *FileName, EFI_LOADED_IMAGE_PROTOCOL **ImageInfo, EFI_HANDLE *AppImageHandle, EFI_SECTION_TYPE Section_Type) +{ + EFI_STATUS Status = EFI_SUCCESS; + + CHAR16 FileName16[255] = {0}; + UnicodeSPrint(FileName16, sizeof(FileName16), L"%a", FileName); + UINT8 *Buffer = NULL; + UINTN BufferSize = 0; + Status = LocateAndLoadFvFromName(FileName16, Section_Type, &Buffer, &BufferSize); + + Status = gBS->LoadImage(FALSE, ImageHandle, (VOID *)NULL, Buffer, BufferSize, + AppImageHandle); + if (Buffer != NULL) + FreePool(Buffer); + if (Status != EFI_SUCCESS) + { + Print(L"Could not Locate the image from FV %r \n", Status); + } + else + { + Print(L"Loaded the image with success from FV\n"); + // Print (L"Loaded the image with success\n"); + Status = gBS->OpenProtocol(*AppImageHandle, &gEfiLoadedImageProtocolGuid, + (VOID **)ImageInfo, ImageHandle, (VOID *)NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + } + + return Status; +}; +EFI_STATUS Exec(EFI_HANDLE *AppImageHandle) +{ + UINTN ExitDataSize; + EFI_STATUS Status = gBS->StartImage(*AppImageHandle, &ExitDataSize, (CHAR16 **)NULL); + Print(L"\tImage Retuned - %r %x\n", Status); + return Status; +} + +EFI_STATUS FindLoadedImageFromName(EFI_HANDLE ImageHandle, CHAR8 *FileName, EFI_LOADED_IMAGE_PROTOCOL **ImageInfo) +{ + EFI_STATUS Status; + UINTN HandleSize = 0; + EFI_HANDLE *Handles; + CHAR16 FileName16[255] = {0}; + UnicodeSPrint(FileName16, sizeof(FileName16), L"%a", FileName); + Status = gBS->LocateHandle(ByProtocol, &gEfiLoadedImageProtocolGuid, NULL, &HandleSize, NULL); + if (Status == EFI_BUFFER_TOO_SMALL) + { + Handles = AllocateZeroPool(HandleSize * sizeof(EFI_HANDLE)); + Status = gBS->LocateHandle(ByProtocol, &gEfiLoadedImageProtocolGuid, NULL, &HandleSize, Handles); + Print(L"Retrived %d Handle, with %r\n\r", HandleSize, Status); + } + + for (UINTN i = 0; i < HandleSize; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiLoadedImageProtocolGuid, ImageInfo); + if (Status == EFI_SUCCESS) + { + CHAR16 *String = FindLoadedImageFileName(*ImageInfo); + if (String != NULL) + { + if (StrCmp(FileName16, String) == 0) + { + Print(L"Found %s at Address 0x%X\n\r", String, (*ImageInfo)->ImageBase); + return EFI_SUCCESS; + } + } + } + } + return EFI_NOT_FOUND; +} \ No newline at end of file diff --git a/SmokelessRuntimeEFIPatcher/Opcode.h b/SmokelessRuntimeEFIPatcher/Opcode.h new file mode 100644 index 0000000..5766725 --- /dev/null +++ b/SmokelessRuntimeEFIPatcher/Opcode.h @@ -0,0 +1,29 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS LoadFS(EFI_HANDLE ImageHandle, CHAR8 *FileName,EFI_LOADED_IMAGE_PROTOCOL **ImageInfo, EFI_HANDLE *AppImageHandle); +EFI_STATUS LoadFV(EFI_HANDLE ImageHandle, CHAR8 *FileName, EFI_LOADED_IMAGE_PROTOCOL **ImageInfo, EFI_HANDLE *AppImageHandle, EFI_SECTION_TYPE Section_Type); +EFI_STATUS FindLoadedImageFromName(EFI_HANDLE ImageHandle, CHAR8 *FileName, EFI_LOADED_IMAGE_PROTOCOL **ImageInfo); +EFI_STATUS Exec(EFI_HANDLE *AppImageHandle); \ No newline at end of file diff --git a/SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.c b/SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.c new file mode 100755 index 0000000..957ea1d --- /dev/null +++ b/SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.c @@ -0,0 +1,430 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Utility.h" +#include "Opcode.h" +#define SREP_VERSION L"0.1" + +EFI_BOOT_SERVICES *_gBS = NULL; +EFI_RUNTIME_SERVICES *_gRS = NULL; + +enum +{ + OFFSET = 1, + PATTERN, + REL_NEG_OFFSET, + REL_POS_OFFSET +}; + +enum OPCODE +{ + NO_OP, + LOADED, + LOAD_FS, + LOAD_FV, + PATCH, + EXEC +}; + +struct OP_DATA +{ + enum OPCODE ID; + CHAR8 *Name; + BOOLEAN Name_Dyn_Alloc; + UINT64 PatterType; + BOOLEAN PatterType_Dyn_Alloc; + INT64 ARG3; + BOOLEAN ARG3_Dyn_Alloc; + UINT64 ARG4; + BOOLEAN ARG4_Dyn_Alloc; + UINT64 ARG5; + BOOLEAN ARG5_Dyn_Alloc; + UINT64 ARG6; + BOOLEAN ARG6_Dyn_Alloc; + UINT64 ARG7; + BOOLEAN ARG7_Dyn_Alloc; + struct OP_DATA *next; + struct OP_DATA *prev; +}; + +VOID Add_OP_CODE(struct OP_DATA *Start, struct OP_DATA *opCode) +{ + struct OP_DATA *next = Start; + while (next->next != NULL) + { + next = next->next; + } + next->next = opCode; + opCode->prev = next; +} + +VOID PrintOPChain(struct OP_DATA *Start) +{ + struct OP_DATA *next = Start; + while (next != NULL) + { + Print(L"OPCODE : "); + switch (next->ID) + { + case NO_OP: + Print(L"NOP\n\r"); + break; + case LOADED: + Print(L"LOADED\n\r"); + break; + case LOAD_FS: + Print(L"LOAD_FS\n\r"); + Print(L"\t FileName %a\n\r", next->Name); + break; + case LOAD_FV: + Print(L"LOAD_FV\n\r"); + Print(L"\t FileName %a\n\r", next->Name); + break; + case PATCH: + Print(L"PATCH\n\r"); + break; + case EXEC: + Print(L"EXEC\n\r"); + break; + + default: + break; + } + next = next->next; + } +} + +VOID PrintDump(UINT16 Size, UINT8 *DUMP) +{ + for (UINT16 i = 0; i < Size; i++) + { + if (i % 0x10 == 0) + { + Print(L"\n\t"); + } + Print(L"%02x ", DUMP[i]); + } + Print(L"\n\t"); +} + +EFI_STATUS EFIAPI SREPEntry(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_STATUS Status; + EFI_HANDLE_PROTOCOL HandleProtocol; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; + EFI_FILE *Root; + EFI_FILE *ConfigFile; + CHAR16 FileName[255]; + + Print(L"Welcome to SREP (Smokeless Runtime EFI Patcher) %s\n\r", SREP_VERSION); + + HandleProtocol = SystemTable->BootServices->HandleProtocol; + HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (void **)&LoadedImage); + HandleProtocol(LoadedImage->DeviceHandle, &gEfiSimpleFileSystemProtocolGuid, (void **)&FileSystem); + FileSystem->OpenVolume(FileSystem, &Root); + + UnicodeSPrint(FileName, sizeof(FileName), L"%a", "SREP_Config.cfg"); + Status = Root->Open(Root, &ConfigFile, FileName, EFI_FILE_MODE_READ, 0); + if (Status != EFI_SUCCESS) + { + Print(L"Failed on Opening SREP_Config : %r\n\r", Status); + return Status; + } + Print(L"Opened SREP_Config\n\r"); + EFI_GUID gFileInfo = EFI_FILE_INFO_ID; + EFI_FILE_INFO *FileInfo = NULL; + UINTN FileInfoSize = 0; + Status = ConfigFile->GetInfo(ConfigFile, &gFileInfo, &FileInfoSize, &FileInfo); + if (Status == EFI_BUFFER_TOO_SMALL) + { + FileInfo = AllocatePool(FileInfoSize); + Status = ConfigFile->GetInfo(ConfigFile, &gFileInfo, &FileInfoSize, FileInfo); + if (Status != EFI_SUCCESS) + { + Print(L"Failed Getting SREP_Config Info: %r\n\r", Status); + return Status; + } + } + UINTN ConfigDataSize = FileInfo->FileSize + 1; // Add Last null Terminalto + Print(L"Config Size: 0x%x\n\r", ConfigDataSize); + CHAR8 *ConfigData = AllocateZeroPool(ConfigDataSize); + FreePool(FileInfo); + + Status = ConfigFile->Read(ConfigFile, &ConfigDataSize, ConfigData); + if (Status != EFI_SUCCESS) + { + Print(L"Failed on Reading SREP_Config : %r\n\r", Status); + return Status; + } + Print(L"Parsing Config\n\r"); + ConfigFile->Close(ConfigFile); + Print(L"Stripping NewLine, Carriage and tab Return\n\r"); + for (UINTN i = 0; i < ConfigDataSize; i++) + { + if (ConfigData[i] == '\n' || ConfigData[i] == '\r' || ConfigData[i] == '\t') + { + ConfigData[i] = '\0'; + } + } + UINTN curr_pos = 0; + + struct OP_DATA *Start = AllocateZeroPool(sizeof(struct OP_DATA)); + struct OP_DATA *Prev_OP; + Start->ID = NO_OP; + Start->next = NULL; + BOOLEAN NullByteSkipped = FALSE; + while (curr_pos < ConfigDataSize) + { + + if (curr_pos != 0 && !NullByteSkipped) + curr_pos += AsciiStrLen(&ConfigData[curr_pos]); + if (ConfigData[curr_pos] == '\0') + { + curr_pos += 1; + NullByteSkipped = TRUE; + continue; + } + NullByteSkipped = FALSE; + Print(L"Current Parsing %a\n\r", &ConfigData[curr_pos]); + if (AsciiStrStr(&ConfigData[curr_pos], "End")) + { + Print(L"End OP Detected\n\r"); + continue; + } + if (AsciiStrStr(&ConfigData[curr_pos], "Op")) + { + Print(L"OP Detected\n\r"); + curr_pos += 3; + Print(L"Commnand %a \n\r", &ConfigData[curr_pos]); + if (AsciiStrStr(&ConfigData[curr_pos], "LoadFromFS")) + { + Prev_OP = AllocateZeroPool(sizeof(struct OP_DATA)); + Prev_OP->ID = LOAD_FS; + Add_OP_CODE(Start, Prev_OP); + continue; + } + if (AsciiStrStr(&ConfigData[curr_pos], "LoadFromFV")) + { + Prev_OP = AllocateZeroPool(sizeof(struct OP_DATA)); + Prev_OP->ID = LOAD_FV; + Add_OP_CODE(Start, Prev_OP); + continue; + } + if (AsciiStrStr(&ConfigData[curr_pos], "Loaded")) + { + Prev_OP = AllocateZeroPool(sizeof(struct OP_DATA)); + Prev_OP->ID = LOADED; + Add_OP_CODE(Start, Prev_OP); + continue; + } + if (AsciiStrStr(&ConfigData[curr_pos], "Patch")) + { + Prev_OP = AllocateZeroPool(sizeof(struct OP_DATA)); + Prev_OP->ID = PATCH; + Add_OP_CODE(Start, Prev_OP); + continue; + } + + if (AsciiStrStr(&ConfigData[curr_pos], "Exec")) + { + Prev_OP = AllocateZeroPool(sizeof(struct OP_DATA)); + Prev_OP->ID = EXEC; + Add_OP_CODE(Start, Prev_OP); + continue; + } + Print(L"Commnand %a Invalid \n\r", &ConfigData[curr_pos]); + return EFI_INVALID_PARAMETER; + } + if ((Prev_OP->ID == LOAD_FS || Prev_OP->ID == LOAD_FV || Prev_OP->ID == LOADED) && Prev_OP->Name == 0) + { + Print(L"Found File %a \n\r", &ConfigData[curr_pos]); + UINTN FileNameLength = AsciiStrLen(&ConfigData[curr_pos]) + 1; + CHAR8 *FileName = AllocateZeroPool(FileNameLength); + CopyMem(FileName, &ConfigData[curr_pos], FileNameLength); + Prev_OP->Name = FileName; + Prev_OP->Name_Dyn_Alloc = TRUE; + continue; + } + if (Prev_OP->ID == PATCH && Prev_OP->PatterType == 0) + { + if (AsciiStrStr(&ConfigData[curr_pos], "Offset")) + { + Print(L"Found Offset\n\r"); + Prev_OP->PatterType = OFFSET; + } + if (AsciiStrStr(&ConfigData[curr_pos], "Pattern")) + { + Print(L"Found Pattern\n\r"); + Prev_OP->PatterType = PATTERN; + } + if (AsciiStrStr(&ConfigData[curr_pos], "RelNegOffset")) + { + Print(L"Found Offset\n\r"); + Prev_OP->PatterType = REL_NEG_OFFSET; + } + if (AsciiStrStr(&ConfigData[curr_pos], "RelPosOffset")) + { + Print(L"Found Offset\n\r"); + Prev_OP->PatterType = REL_POS_OFFSET; + } + continue; + } + + // this new itereration whe are just in from of the Pattern + if (Prev_OP->ID == PATCH && Prev_OP->PatterType != 0 && Prev_OP->ARG3 == 0) + { + if (Prev_OP->PatterType == OFFSET || Prev_OP->PatterType == REL_NEG_OFFSET || Prev_OP->PatterType == REL_POS_OFFSET) + { + Print(L"Decode Offset\n\r"); + Prev_OP->ARG3 = AsciiStrHexToUint64(&ConfigData[curr_pos]); + } + if (Prev_OP->PatterType == PATTERN) + { + Prev_OP->ARG3 = 0xFFFFFFFF; + Prev_OP->ARG6 = AsciiStrLen(&ConfigData[curr_pos]) / 2; + Print(L"Found %d Bytes\n\r", Prev_OP->ARG6); + Prev_OP->ARG7 = AllocateZeroPool(Prev_OP->ARG6); + AsciiStrHexToBytes(&ConfigData[curr_pos], Prev_OP->ARG6 * 2, Prev_OP->ARG7, Prev_OP->ARG6); + } + continue; + } + + if (Prev_OP->ID == PATCH && Prev_OP->PatterType != 0 && Prev_OP->ARG3 != 0) + { + + Prev_OP->ARG4 = AsciiStrLen(&ConfigData[curr_pos]) / 2; + Print(L"Found %d Bytes\n\r", Prev_OP->ARG4); + Prev_OP->ARG5_Dyn_Alloc = TRUE; + Prev_OP->ARG5 = AllocateZeroPool(Prev_OP->ARG4); + AsciiStrHexToBytes(&ConfigData[curr_pos], Prev_OP->ARG4 * 2, Prev_OP->ARG5, Prev_OP->ARG4); + Print(L"Patch Byte\n\r"); + PrintDump(Prev_OP->ARG4, Prev_OP->ARG5); + continue; + } + } + FreePool(ConfigData); + // PrintOPChain(Start); + // dispatch + struct OP_DATA *next; + EFI_HANDLE AppImageHandle; + EFI_LOADED_IMAGE_PROTOCOL *ImageInfo; + INT64 BaseOffset; + for (next = Start; next != NULL; next = next->next) + { + switch (next->ID) + { + case NO_OP: + // Print(L"NOP\n\r"); + break; + case LOADED: + Print(L"LOADED\n\r"); + Status = FindLoadedImageFromName(ImageHandle, next->Name, &ImageInfo); + Print(L"Loaded Image %r -> %x\n\r", Status, ImageInfo->ImageBase); + break; + case LOAD_FS: + Status = LoadFS(ImageHandle, next->Name, &ImageInfo, &AppImageHandle); + Print(L"Loaded Image %r -> %x\n\r", Status, ImageInfo->ImageBase); + // Print(L"\t FileName %a\n\r", next->ARG2); + break; + case LOAD_FV: + Status = LoadFV(ImageHandle, next->Name, &ImageInfo, &AppImageHandle, EFI_SECTION_PE32); + Print(L"Loaded Image %r -> %x\n\r", Status, ImageInfo->ImageBase); + break; + case PATCH: + Print(L"Patching Image Size %x: \n\r", ImageInfo->ImageSize); + PrintDump(next->ARG6, next->ARG7); + + PrintDump(next->ARG6, ((UINT8 *)ImageInfo->ImageBase) + 0x1A383); + // PrintDump(0x200, (UINT8 *)(LoadedImage->ImageBase)); + if (next->PatterType == PATTERN) + { + + Print(L"Finding Offset\n\r"); + for (UINTN i = 0; i < ImageInfo->ImageSize - next->ARG6; i += 1) + { + if (CompareMem(((UINT8 *)ImageInfo->ImageBase) + i, next->ARG7, next->ARG6) == 0) + { + next->ARG3 = i; + Print(L"Found at %x\n\r", i); + break; + } + } + if (next->ARG3 == 0xFFFFFFFF) + { + Print(L"No Patter Found\n\r"); + goto cleanup; + } + } + if (next->PatterType == REL_POS_OFFSET) + { + next->ARG3 = BaseOffset + next->ARG3; + } + if (next->PatterType == REL_NEG_OFFSET) + { + next->ARG3 = BaseOffset - next->ARG3; + } + BaseOffset = next->ARG3; + Print(L"Offset %x\n\r", next->ARG3); + // PrintDump(next->ARG4+10,ImageInfo->ImageBase + next->ARG3 -5 ); + CopyMem(ImageInfo->ImageBase + next->ARG3, next->ARG5, next->ARG4); + Print(L"Patched\n\r"); + // PrintDump(next->ARG4+10,ImageInfo->ImageBase + next->ARG3 -5 ); + break; + case EXEC: + Exec(&AppImageHandle); + Print(L"EXEC %r\n\r", Status); + break; + + default: + break; + } + } +cleanup: + for (next = Start; next != NULL; next = next->next) + { + if (next->Name_Dyn_Alloc) + FreePool((VOID *)next->Name); + if (next->PatterType_Dyn_Alloc) + FreePool((VOID *)next->PatterType); + if (next->ARG3_Dyn_Alloc) + FreePool((VOID *)next->ARG3); + if (next->ARG4_Dyn_Alloc) + FreePool((VOID *)next->ARG4); + if (next->ARG5_Dyn_Alloc) + FreePool((VOID *)next->ARG5); + if (next->ARG6_Dyn_Alloc) + FreePool((VOID *)next->ARG6); + if (next->ARG7_Dyn_Alloc) + FreePool((VOID *)next->ARG7); + } + next = Start; + while (next->next != NULL) + { + struct OP_DATA *tmp = next; + next = next->next; + FreePool(tmp); + } + return EFI_SUCCESS; + // FindBaseAddressFromName(L"H2OFormBrowserDxe"); + // UINT8 *Buffer = NULL; + // UINTN BufferSize = 0; + // LocateAndLoadFvFromName(L"SetupUtilityApp", EFI_SECTION_PE32, &Buffer, &BufferSize); +} \ No newline at end of file diff --git a/SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.inf b/SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.inf new file mode 100755 index 0000000..f67fdce --- /dev/null +++ b/SmokelessRuntimeEFIPatcher/SmokelessRuntimeEFIPatcher.inf @@ -0,0 +1,47 @@ +[Defines] + INF_VERSION = 0x00010006 + BASE_NAME = SmokelessRuntimeEFIPatcher + FILE_GUID = 24ba59e6-8d34-4fe4-83a0-da8e478ecbfe + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 0.1 + ENTRY_POINT = SREPEntry + + + UEFI_HII_RESOURCE_SECTION = TRUE +[Sources] + SmokelessRuntimeEFIPatcher.c + Utility.c + OpCode.c +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + CryptoPkg/CryptoPkg.dec +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + BaseLib + HiiLib + MemoryAllocationLib + BaseMemoryLib + DebugLib + BaseCryptLib + PrintLib + UefiLib + DevicePathLib + +[Protocols] + gEfiLoadedImageProtocolGuid ## CONSUMES + gEfiSimpleFileSystemProtocolGuid ## CONSUMES + gEfiLoadFileProtocolGuid ## CONSUMES + gEfiHiiConfigAccessProtocolGuid ## CONSUMES + gEfiSerialIoProtocolGuid ## CONSUMES + gEfiDevicePathToTextProtocolGuid ## CONSUMES + gEfiFirmwareVolume2ProtocolGuid + gEdkiiFormBrowserEx2ProtocolGuid + gEdkiiFormBrowserExProtocolGuid + gEfiHiiPopupProtocolGuid + gEdkiiFormDisplayEngineProtocolGuid +[Guids] + gEfiAcpiTableGuid + gEfiAcpi20TableGuid + gEfiDxeServicesTableGuid \ No newline at end of file diff --git a/SmokelessRuntimeEFIPatcher/Utility.c b/SmokelessRuntimeEFIPatcher/Utility.c new file mode 100644 index 0000000..7f63828 --- /dev/null +++ b/SmokelessRuntimeEFIPatcher/Utility.c @@ -0,0 +1,231 @@ +#include "Utility.h" +CHAR16 * +FindLoadedImageFileName( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage) +{ + EFI_GUID *NameGuid; + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; + VOID *Buffer; + UINTN BufferSize; + UINT32 AuthenticationStatus; + + if ((LoadedImage == NULL) || (LoadedImage->FilePath == NULL)) + { + return NULL; + } + + NameGuid = EfiGetNameGuidFromFwVolDevicePathNode((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)LoadedImage->FilePath); + + if (NameGuid == NULL) + { + return NULL; + } + + // + // Get the FirmwareVolume2Protocol of the device handle that this image was loaded from. + // + Status = gBS->HandleProtocol(LoadedImage->DeviceHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv); + + // + // FirmwareVolume2Protocol is PI, and is not required to be available. + // + if (EFI_ERROR(Status)) + { + return NULL; + } + + // + // Read the user interface section of the image. + // + Buffer = NULL; + Status = Fv->ReadSection(Fv, NameGuid, EFI_SECTION_USER_INTERFACE, 0, &Buffer, &BufferSize, &AuthenticationStatus); + + if (EFI_ERROR(Status)) + { + return NULL; + } + + // + // ReadSection returns just the section data, without any section header. For + // a user interface section, the only data is the file name. + // + return Buffer; +} + +UINT8 *FindBaseAddressFromName(CHAR16 **Name) +{ + EFI_STATUS Status; + UINTN HandleSize = 0; + EFI_HANDLE *Handles; + + Status = gBS->LocateHandle(ByProtocol, &gEfiLoadedImageProtocolGuid, NULL, &HandleSize, NULL); + if (Status == EFI_BUFFER_TOO_SMALL) + { + Handles = AllocateZeroPool(HandleSize * sizeof(EFI_HANDLE)); + Status = gBS->LocateHandle(ByProtocol, &gEfiLoadedImageProtocolGuid, NULL, &HandleSize, Handles); + Print(L"Retrived %d Handle, with %r\n\r", HandleSize, Status); + } + + EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocol; + for (UINTN i = 0; i < HandleSize; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiLoadedImageProtocolGuid, &LoadedImageProtocol); + if (Status == EFI_SUCCESS) + { + CHAR16 *String = FindLoadedImageFileName(LoadedImageProtocol); + if (String != NULL) + { + if (StrCmp(Name, String) == 0) + { + Print(L"Found %s at Address 0x%X\n\r", String, LoadedImageProtocol->ImageBase); + return LoadedImageProtocol->ImageBase; + } + } + } + } + return NULL; +} + +EFI_STATUS LoadandRunImage(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable, CHAR16 *FileName, EFI_HANDLE *AppImageHandle) +{ + UINTN ExitDataSize; + UINTN NumHandles; + UINTN Index; + EFI_HANDLE *SFS_Handles; + EFI_STATUS Status = EFI_SUCCESS; + EFI_BLOCK_IO_PROTOCOL *BlkIo; + EFI_DEVICE_PATH_PROTOCOL *FilePath; + + Status = + gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &NumHandles, &SFS_Handles); + + if (Status != EFI_SUCCESS) + { + Print(L"Could not find handles - %r\n", Status); + return Status; + } + Print(L"No of Handle - %d\n", NumHandles); + + for (Index = 0; Index < NumHandles; Index++) + { + Status = gBS->OpenProtocol( + SFS_Handles[Index], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&BlkIo, + ImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); + + if (Status != EFI_SUCCESS) + { + Print(L"Protocol is not supported - %r\n", Status); + return Status; + } + + FilePath = FileDevicePath(SFS_Handles[Index], FileName); + Status = gBS->LoadImage(FALSE, ImageHandle, FilePath, (VOID *)NULL, 0, + AppImageHandle); + + if (Status != EFI_SUCCESS) + { + Print(L"Could not load the image on Handle %d - %r\n", Index, Status); + continue; + } + else + { + Print(L"Loaded the image with success on Handle %d\n", Index); + } + + Status = gBS->StartImage(*AppImageHandle, &ExitDataSize, (CHAR16 **)NULL); + Print(L"\tImage Retuned - %r %x\n", Status, Status); + if (Status != EFI_SUCCESS) + { + return EFI_NOT_FOUND; + } + return EFI_SUCCESS; + } + return EFI_SUCCESS; +} + +// TODO add in the dumping SectionInstance +EFI_STATUS +LocateAndLoadFvFromName(CHAR16 *Name, EFI_SECTION_TYPE Section_Type, UINT8 **Buffer, UINTN *BufferSize) +{ + EFI_STATUS Status; + EFI_HANDLE *HandleBuffer; + UINTN NumberOfHandles; + UINT32 FvStatus; + EFI_FV_FILE_ATTRIBUTES Attributes; + UINTN Size; + UINTN Index; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance; + + FvStatus = 0; + + // + // Locate protocol. + // + Status = gBS->LocateHandleBuffer( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &NumberOfHandles, + &HandleBuffer); + if (EFI_ERROR(Status)) + { + // + // Defined errors at this time are not found and out of resources. + // + return Status; + } + + // + // Looking for FV with ACPI storage file + // + Print(L"Found %d Instances\n\r", NumberOfHandles); + for (Index = 0; Index < NumberOfHandles; Index++) + { + + // + // Get the protocol on this handle + // This should not fail because of LocateHandleBuffer + + Status = gBS->HandleProtocol( + HandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&FvInstance); + ASSERT_EFI_ERROR(Status); + + EFI_FV_FILETYPE FileType = EFI_FV_FILETYPE_ALL; + EFI_FV_FILE_ATTRIBUTES FileAttributes; + UINTN FileSize; + EFI_GUID NameGuid = {0}; + VOID *Keys = AllocateZeroPool(FvInstance->KeySize); + while (TRUE) + { + FileType = EFI_FV_FILETYPE_ALL; + ZeroMem(&NameGuid, sizeof(EFI_GUID)); + Status = FvInstance->GetNextFile(FvInstance, Keys, &FileType, &NameGuid, &FileAttributes, &FileSize); + if (Status != EFI_SUCCESS) + { + // Print(L"Breaking Cause %r\n\r", Status); + break; + } + VOID *String; + UINTN StringSize = 0; + UINT32 AuthenticationStatus; + String = NULL; + Status = FvInstance->ReadSection(FvInstance, &NameGuid, EFI_SECTION_USER_INTERFACE, 0, &String, &StringSize, &AuthenticationStatus); + if (StrCmp(Name, String) == 0) + { + + Print(L"Guid :%g, FileSize %d, Name : %s, Type %d \n\r", NameGuid, FileSize, String, FileType); + + Status = FvInstance->ReadSection(FvInstance, &NameGuid, Section_Type, 0, Buffer, BufferSize, &AuthenticationStatus); + Print(L"Result Cause %r\n\r", Status); + FreePool(String); + return EFI_SUCCESS; + } + FreePool(String); + } + } + return EFI_NOT_FOUND; +} \ No newline at end of file diff --git a/SmokelessRuntimeEFIPatcher/Utility.h b/SmokelessRuntimeEFIPatcher/Utility.h new file mode 100644 index 0000000..de4bcea --- /dev/null +++ b/SmokelessRuntimeEFIPatcher/Utility.h @@ -0,0 +1,37 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +CHAR16 * +FindLoadedImageFileName( + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage); + +EFI_STATUS LoadandRunImage(EFI_HANDLE ImageHandle, + EFI_SYSTEM_TABLE *SystemTable, + CHAR16 *FileName, + EFI_HANDLE *AppImageHandle); + +UINT8 * FindBaseAddressFromName(CHAR16 **Name); + +EFI_STATUS LocateAndLoadFvFromName(CHAR16 *Name, EFI_SECTION_TYPE Section_Type,UINT8 **Buffer,UINTN *BufferSize);