diff --git a/UefiApplication/main.c b/UefiApplication/main.c
index c13bdaa..d413fbd 100644
--- a/UefiApplication/main.c
+++ b/UefiApplication/main.c
@@ -87,6 +87,12 @@ EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE* Syst
EFI_DEVICE_PATH* RuntimeDriverDevicePath = NULL;
EFI_HANDLE RuntimeDriverHandle = NULL;
+ //
+ // Clear screen and make pretty
+ //
+ gST->ConOut->ClearScreen( gST->ConOut );
+ gST->ConOut->SetAttribute( gST->ConOut, EFI_GREEN | EFI_BACKGROUND_LIGHTGRAY );
+
//
// Locate the runtime driver
//
diff --git a/UefiDriver/UefiDriver.vcxproj b/UefiDriver/UefiDriver.vcxproj
index bb61bdb..f9dbeaa 100644
--- a/UefiDriver/UefiDriver.vcxproj
+++ b/UefiDriver/UefiDriver.vcxproj
@@ -30,6 +30,8 @@
UefiDriverEntryPoint.lib;BaseCryptLib.lib;IntrinsicLib.lib;%(AdditionalDependencies)
EFI Runtime
+ true
+ true
copy /Y "$(TargetDir)$(TargetName).efi" "G:\efi\boot\rtdriver.efi"
@@ -40,6 +42,7 @@
__UD_STANDALONE__;_UNICODE;UNICODE;%(PreprocessorDefinitions)
4706;4055;4054
+ Disabled
@@ -58,6 +61,7 @@
+
diff --git a/UefiDriver/UefiDriver.vcxproj.filters b/UefiDriver/UefiDriver.vcxproj.filters
index be2a76b..6e9e58a 100644
--- a/UefiDriver/UefiDriver.vcxproj.filters
+++ b/UefiDriver/UefiDriver.vcxproj.filters
@@ -87,6 +87,9 @@
include
+
+ include
+
diff --git a/UefiDriver/arc.h b/UefiDriver/arc.h
new file mode 100644
index 0000000..518fa67
--- /dev/null
+++ b/UefiDriver/arc.h
@@ -0,0 +1,888 @@
+#pragma once
+
+//
+// Bullshit thats not defined in EFI library
+//
+typedef union _LARGE_INTEGER
+{
+ struct
+ {
+ UINT32 LowPart;
+ INT32 HighPart;
+ };
+ struct
+ {
+ UINT32 LowPart;
+ INT32 HighPart;
+ } u;
+ UINT64 QuadPart;
+} LARGE_INTEGER;
+
+typedef union _ULARGE_INTEGER
+{
+ struct
+ {
+ UINT32 LowPart;
+ UINT32 HighPart;
+ };
+ struct
+ {
+ UINT32 LowPart;
+ UINT32 HighPart;
+ } u;
+ UINT64 QuadPart;
+} ULARGE_INTEGER;
+
+typedef struct _UNICODE_STRING
+{
+ UINT16 Length;
+ UINT16 MaximumLength;
+ CHAR16* Buffer;
+} UNICODE_STRING;
+
+//
+// Define DEVICE_FLAGS
+//
+
+typedef struct _DEVICE_FLAGS
+{
+ UINT32 Failed : 1;
+ UINT32 ReadOnly : 1;
+ UINT32 Removable : 1;
+ UINT32 ConsoleIn : 1;
+ UINT32 ConsoleOut : 1;
+ UINT32 Input : 1;
+ UINT32 Output : 1;
+} DEVICE_FLAGS, *PDEVICE_FLAGS;
+
+//
+// Define configuration routine types.
+//
+// Configuration information.
+//
+
+typedef enum _CONFIGURATION_TYPE
+{
+ ArcSystem,
+ CentralProcessor,
+ FloatingPointProcessor,
+ PrimaryIcache,
+ PrimaryDcache,
+ SecondaryIcache,
+ SecondaryDcache,
+ SecondaryCache,
+ EisaAdapter,
+ TcAdapter,
+ ScsiAdapter,
+ DtiAdapter,
+ MultiFunctionAdapter,
+ DiskController,
+ TapeController,
+ CdromController,
+ WormController,
+ SerialController,
+ NetworkController,
+ DisplayController,
+ ParallelController,
+ PointerController,
+ KeyboardController,
+ AudioController,
+ OtherController,
+ DiskPeripheral,
+ FloppyDiskPeripheral,
+ TapePeripheral,
+ ModemPeripheral,
+ MonitorPeripheral,
+ PrinterPeripheral,
+ PointerPeripheral,
+ KeyboardPeripheral,
+ TerminalPeripheral,
+ OtherPeripheral,
+ LinePeripheral,
+ NetworkPeripheral,
+ SystemMemory,
+ DockingInformation,
+ RealModeIrqRoutingTable,
+ RealModePCIEnumeration,
+ MaximumType
+} CONFIGURATION_TYPE, *PCONFIGURATION_TYPE;
+
+typedef enum _CONFIGURATION_CLASS
+{
+ SystemClass,
+ ProcessorClass,
+ CacheClass,
+ AdapterClass,
+ ControllerClass,
+ PeripheralClass,
+ MemoryClass,
+ MaximumClass
+} CONFIGURATION_CLASS, *PCONFIGURATION_CLASS;
+
+typedef struct _CONFIGURATION_COMPONENT
+{
+ CONFIGURATION_CLASS Class;
+ CONFIGURATION_TYPE Type;
+ DEVICE_FLAGS Flags;
+ UINT16 Version;
+ UINT16 Revision;
+ UINT32 Key;
+ union
+ {
+ UINT32 AffinityMask;
+ struct
+ {
+ UINT16 Group;
+ UINT16 GroupIndex;
+ };
+ };
+ UINT32 ConfigurationDataLength;
+ UINT32 IdentifierLength;
+ INT8* Identifier;
+} CONFIGURATION_COMPONENT, *PCONFIGURATION_COMPONENT;
+
+//
+// Define configuration data structure used in all systems.
+//
+typedef struct _CONFIGURATION_COMPONENT_DATA
+{
+ struct _CONFIGURATION_COMPONENT_DATA *Parent;
+ struct _CONFIGURATION_COMPONENT_DATA *Child;
+ struct _CONFIGURATION_COMPONENT_DATA *Sibling;
+ CONFIGURATION_COMPONENT ComponentEntry;
+ VOID* ConfigurationData;
+} CONFIGURATION_COMPONENT_DATA, *PCONFIGURATION_COMPONENT_DATA;
+
+
+
+typedef struct _NLS_DATA_BLOCK
+{
+ VOID* AnsiCodePageData;
+ VOID* OemCodePageData;
+ VOID* UnicodeCaseTableData;
+} NLS_DATA_BLOCK, *PNLS_DATA_BLOCK;
+
+typedef struct _VHD_DISK_SIGNATURE
+{
+ UINT32 ParentPartitionNumber;
+ UINT8 BootDevice[1];
+} VHD_DISK_SIGNATURE, *PVHD_DISK_SIGNATURE;
+
+typedef struct _ARC_DISK_SIGNATURE
+{
+ LIST_ENTRY ListEntry;
+ UINT32 Signature;
+ CHAR8* ArcName;
+ UINT32 CheckSum;
+ BOOLEAN ValidPartitionTable;
+ BOOLEAN xInt13;
+ BOOLEAN IsGpt;
+ UINT8 Reserved;
+ UINT8 GptSignature[16];
+ PVHD_DISK_SIGNATURE VhdSignature;
+} ARC_DISK_SIGNATURE, *PARC_DISK_SIGNATURE;
+
+typedef struct _ARC_DISK_INFORMATION
+{
+ LIST_ENTRY DiskSignatures;
+} ARC_DISK_INFORMATION, *PARC_DISK_INFORMATION;
+
+typedef struct _I386_LOADER_BLOCK
+{
+ VOID* CommonDataArea;
+ UINT32 MachineType; // Temporary only
+ UINT32 VirtualBias;
+} I386_LOADER_BLOCK, *PI386_LOADER_BLOCK;
+
+typedef struct _ARM_LOADER_BLOCK
+{
+ UINT64 VirtualBias;
+ VOID* KdCpuBuffer;
+} ARM_LOADER_BLOCK, *PARM_LOADER_BLOCK;
+
+typedef struct _VIRTUAL_EFI_RUNTIME_SERVICES
+{
+ //
+ // (Virtual) Entry points to each of the EFI Runtime services.
+ //
+ EFI_GET_TIME GetTime;
+ EFI_SET_TIME SetTime;
+ EFI_GET_WAKEUP_TIME GetWakeupTime;
+ EFI_SET_WAKEUP_TIME SetWakeupTime;
+ EFI_SET_VIRTUAL_ADDRESS_MAP SetVirtualAddressMap;
+ EFI_CONVERT_POINTER ConvertPointer;
+ EFI_GET_VARIABLE GetVariable;
+ EFI_GET_NEXT_VARIABLE_NAME GetNextVariableName;
+ EFI_SET_VARIABLE SetVariable;
+ EFI_GET_NEXT_HIGH_MONO_COUNT GetNextHighMonotonicCount;
+ EFI_RESET_SYSTEM ResetSystem;
+ EFI_UPDATE_CAPSULE UpdateCapsule;
+ EFI_QUERY_CAPSULE_CAPABILITIES QueryCapsuleCapabilities;
+ EFI_QUERY_VARIABLE_INFO QueryVariableInfo;
+} VIRTUAL_EFI_RUNTIME_SERVICES, *PVIRTUAL_EFI_RUNTIME_SERVICES;
+
+typedef struct _EFI_FIRMWARE_INFORMATION
+{
+ UINT32 FirmwareVersion;
+ PVIRTUAL_EFI_RUNTIME_SERVICES VirtualEfiRuntimeServices;
+
+ //
+ // The return value from SetVirtualAddressMap call.
+ //
+ EFI_STATUS SetVirtualAddressMapStatus;
+
+ //
+ // Number of mappings missed if any due to change in firmware
+ // runtime memory map (for debugging).
+ //
+ UINT32 MissedMappingsCount;
+
+ //
+ // The firmware resource list identifies firmware components that can
+ // be updated via WU.
+ //
+ LIST_ENTRY FirmwareResourceList;
+
+ //
+ // The EFI memory map.
+ //
+ VOID* EfiMemoryMap;
+ UINT32 EfiMemoryMapSize;
+ UINT32 EfiMemoryMapDescriptorSize;
+
+} EFI_FIRMWARE_INFORMATION, *PEFI_FIRMWARE_INFORMATION;
+
+typedef struct _PCAT_FIRMWARE_INFORMATION
+{
+ UINT32 PlaceHolder;
+} PCAT_FIRMWARE_INFORMATION, *PPCAT_FIRMWARE_INFORMATION;
+
+typedef struct _FIRMWARE_INFORMATION_LOADER_BLOCK
+{
+ struct
+ {
+ //
+ // If set to TRUE, indicates that the system is running on EFI firmware.
+ //
+ UINT32 FirmwareTypeEfi : 1;
+
+ //
+ // A flag indicating whether EFI runtime service calls must be routed through IUM.
+ //
+ UINT32 EfiRuntimeUseIum : 1;
+
+ //
+ // A flag indicating whether EFI runtime code and data pages are
+ // separate and protected with RW or RX protections.
+ //
+ UINT32 EfiRuntimePageProtectionEnabled : 1;
+
+ //
+ // A flag indicating whether the firmware supports code and data page
+ // separation with restricted protections.
+ //
+ UINT32 EfiRuntimePageProtectionSupported : 1;
+
+ #if defined (_ARM64_) || defined(_WIN64)
+ //
+ // If set to TRUE, indicates that the system EFI was started in EL2
+ // and therefore has something running there (hypervisor/microvisor).
+ // Also, this is where APs will start (EL2), and need to be directed
+ // to EL1 properly before they can start in the HLOS.
+ //
+ UINT32 FirmwareStartedInEL2 : 1;
+ UINT32 Reserved : 27;
+ #else
+ UINT32 Reserved : 28;
+ #endif
+
+ };
+
+ union
+ {
+ EFI_FIRMWARE_INFORMATION EfiInformation;
+ PCAT_FIRMWARE_INFORMATION PcatInformation;
+ } u;
+
+} FIRMWARE_INFORMATION_LOADER_BLOCK, *PFIRMWARE_INFORMATION_LOADER_BLOCK;
+
+//
+// Internal boot flags definitions.
+//
+#define INTERNAL_BOOT_FLAGS_NONE 0x00000000
+#define INTERNAL_BOOT_FLAGS_UTC_BOOT_TIME 0x00000001
+#define INTERNAL_BOOT_FLAGS_RTC_BOOT_TIME 0x00000002
+#define INTERNAL_BOOT_FLAGS_NO_LEGACY_SERVICES 0x00000004
+
+typedef struct _PROFILE_PARAMETER_BLOCK
+{
+ UINT16 Status;
+ UINT16 Reserved;
+ UINT16 DockingState;
+ UINT16 Capabilities;
+ UINT32 DockID;
+ UINT32 SerialNumber;
+} PROFILE_PARAMETER_BLOCK;
+
+typedef struct _LOADER_PERFORMANCE_DATA
+{
+ UINT64 StartTime;
+ UINT64 EndTime;
+} LOADER_PERFORMANCE_DATA, *PLOADER_PERFORMANCE_DATA;
+
+//
+// The SORTPP tool can't handle array sizes expressed in terms of enums
+// This hack can be removed when the tool is fixed
+//
+#define BOOT_ENTROPY_SOURCE_DATA_SIZE (64)
+#define BOOT_RNG_BYTES_FOR_NTOSKRNL (1024)
+#define BOOT_SEED_BYTES_FOR_CNG (48)
+
+//
+// Entropy result codes and source IDs
+// for Boot entropy sources are defined both in arc.h and
+// ntexapi.h. These two copies must be kept identical.
+//
+typedef enum _BOOT_ENTROPY_SOURCE_RESULT_CODE
+{
+ BootEntropySourceStructureUninitialized = 0,
+ BootEntropySourceDisabledByPolicy = 1,
+ BootEntropySourceNotPresent = 2,
+ BootEntropySourceError = 3,
+ BootEntropySourceSuccess = 4,
+} BOOT_ENTROPY_SOURCE_RESULT_CODE, *PBOOT_ENTROPY_SOURCE_RESULT_CODE;
+
+typedef enum _BOOT_ENTROPY_SOURCE_ID
+{
+ BootEntropySourceNone = 0,
+ BootEntropySourceSeedfile = 1,
+ BootEntropySourceExternal = 2,
+ BootEntropySourceTpm = 3,
+ BootEntropySourceRdrand = 4,
+ BootEntropySourceTime = 5,
+ BootEntropySourceAcpiOem0 = 6,
+ BootEntropySourceUefi = 7,
+ BootEntropySourceCng = 8,
+ BootMaxEntropySources = 8,
+} BOOT_ENTROPY_SOURCE_ID;
+
+//
+// Boot entropy information
+// This is the data that Boot passes to NT that contains the
+// entropy & RNG information.
+// These are the Boot versions of these structures.
+// The name contains the string 'LDR' to distinguish it from the
+// OS loader equivalents in ntexapi_h.w
+//
+
+typedef struct _BOOT_ENTROPY_SOURCE_LDR_RESULT
+{
+ BOOT_ENTROPY_SOURCE_ID SourceId;
+ UINT64 Policy;
+ BOOT_ENTROPY_SOURCE_RESULT_CODE ResultCode;
+ EFI_STATUS ResultStatus;
+ UINT64 Time; // in BlArchGetPerformanceCounter() units
+ UINT32 EntropyLength;
+ UINT8 EntropyData[BOOT_ENTROPY_SOURCE_DATA_SIZE];
+} BOOT_ENTROPY_SOURCE_LDR_RESULT, *PBOOT_ENTROPY_SOURCE_LDR_RESULT;
+
+//
+// The constant BootMaxEntropySources is defined both in arc.w and ntexapi_h.w.
+// If these ever get out of sync, different components will disagree on the value,
+// and thus on the size of the array below.
+// To help detect this type of bug we add a field with this constant so that the
+// CHKed builds can assert on it.
+//
+typedef struct _BOOT_ENTROPY_LDR_RESULT
+{
+ UINT32 maxEntropySources;
+ BOOT_ENTROPY_SOURCE_LDR_RESULT EntropySourceResult[BootMaxEntropySources];
+ UINT8 SeedBytesForCng[BOOT_SEED_BYTES_FOR_CNG];
+ UINT8 RngBytesForNtoskrnl[BOOT_RNG_BYTES_FOR_NTOSKRNL];
+} BOOT_ENTROPY_LDR_RESULT, *PBOOT_ENTROPY_LDR_RESULT;
+
+//
+// Hypervisor specific loader parameters.
+//
+typedef struct _LOADER_PARAMETER_HYPERVISOR_EXTENSION
+{
+ //
+ // Hypervisor crashdump pages if present.
+ //
+ UINT32 HypervisorCrashdumpAreaPageCount;
+ UINT64 HypervisorCrashdumpAreaSpa;
+ //
+ // Hypervisor launch status.
+ //
+ UINT64 HypervisorLaunchStatus;
+ UINT64 HypervisorLaunchStatusArg1;
+ UINT64 HypervisorLaunchStatusArg2;
+ UINT64 HypervisorLaunchStatusArg3;
+ UINT64 HypervisorLaunchStatusArg4;
+} LOADER_PARAMETER_HYPERVISOR_EXTENSION, *PLOADER_PARAMETER_HYPERVISOR_EXTENSION;
+
+typedef struct _LOADER_BUGCHECK_PARAMETERS
+{
+ //
+ // Bugcheck parameters passed to the kernel.
+ //
+ UINT32 BugcheckCode;
+ UINT64 BugcheckParameter1;
+ UINT64 BugcheckParameter2;
+ UINT64 BugcheckParameter3;
+ UINT64 BugcheckParameter4;
+} LOADER_BUGCHECK_PARAMETERS, *PLOADER_BUGCHECK_PARAMETERS;
+
+//
+// EFI Offline crashdump configuration table definition.
+//
+#define OFFLINE_CRASHDUMP_VERSION_1 1
+#define OFFLINE_CRASHDUMP_VERSION_2 2
+#define OFFLINE_CRASHDUMP_VERSION_MAX OFFLINE_CRASHDUMP_VERSION_2
+
+typedef struct _OFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V2
+{
+ UINT32 Version;
+ UINT32 AbnormalResetOccurred;
+ UINT32 OfflineMemoryDumpCapable;
+ //
+ // Version_2 additional members.
+ //
+ PHYSICAL_ADDRESS ResetDataAddress;
+ UINT32 ResetDataSize;
+} OFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V2, *POFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V2;
+
+//
+// Original first version definition. Now only used in winload.efi when interfacing with firmware, and in
+// sysinfo.c when interfacing with higher level sw above the kernel, to maintain backward compatibility.
+//
+typedef struct _OFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V1
+{
+ UINT32 Version;
+ UINT32 AbnormalResetOccurred;
+ UINT32 OfflineMemoryDumpCapable;
+} OFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V1, *POFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V1;
+
+typedef OFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V2 OFFLINE_CRASHDUMP_CONFIGURATION_TABLE;
+typedef POFFLINE_CRASHDUMP_CONFIGURATION_TABLE_V2 POFFLINE_CRASHDUMP_CONFIGURATION_TABLE;
+
+//
+// Code Integrity specific loader paramets.
+//
+typedef struct _LOADER_PARAMETER_CI_EXTENSION
+{
+ //
+ // Offset and size of various serialized data.
+ //
+ UINT32 RevocationListOffset;
+ UINT32 RevocationListSize;
+ UINT8 SerializedData[1];
+} LOADER_PARAMETER_CI_EXTENSION, *PLOADER_PARAMETER_CI_EXTENSION;
+
+typedef struct _LOADER_HIVE_RECOVERY_INFO
+{
+ struct
+ {
+ //
+ // 1 if the hive was recovered by the boot loader, 0 otherwise.
+ //
+ UINT32 Recovered : 1;
+ //
+ // 1 if recovery from a legacy log file was performed, 0 otherwise.
+ //
+ UINT32 LegacyRecovery : 1;
+ //
+ // 1 if this hive was loaded as part of a soft reboot and encountered
+ // a sharing violation during the load (causing it to be loaded from
+ // a copy). 0 otherwise.
+ //
+ UINT32 SoftRebootConflict : 1;
+ //
+ // The most recent log from which recovery was performed as an
+ // HFILE_TYPE.
+ //
+ // i.e. For legacy recovery the individual log file recovery was
+ // performed from, otherwise the log from which the highest
+ // sequence numbered entry was from.
+ //
+ UINT32 MostRecentLog : 3;
+ UINT32 Spare : ((sizeof( UINT32 ) * 8) - 5);
+ };
+
+ //
+ // The sequence number that should be used for the next log entry.
+ //
+ UINT32 LogNextSequence;
+ //
+ // The minimum sequence number in the most recent log.
+ //
+ UINT32 LogMinimumSequence;
+ //
+ // The file offset at which the next log entry should be written in the
+ // most recent log.
+ //
+ UINT32 LogCurrentOffset;
+} LOADER_HIVE_RECOVERY_INFO, *PLOADER_HIVE_RECOVERY_INFO;
+
+typedef struct _LOADER_PARAMETER_EXTENSION
+{
+ UINT32 Size; // set to sizeof (struct _LOADER_PARAMETER_EXTENSION)
+ PROFILE_PARAMETER_BLOCK Profile;
+
+ //
+ // Errata Manager inf file.
+ //
+ VOID* EmInfFileImage;
+ UINT32 EmInfFileSize;
+
+ //
+ // Pointer to the triage block, if present.
+ //
+ VOID* TriageDumpBlock;
+
+ struct _HEADLESS_LOADER_BLOCK *HeadlessLoaderBlock;
+
+ struct _SMBIOS3_TABLE_HEADER *SMBiosEPSHeader;
+
+ VOID* DrvDBImage; // Database used to identify "broken" drivers.
+ UINT32 DrvDBSize;
+
+ // If booting from the Network (PXE) then we will
+ // save the Network boot params in this loader block
+ struct _NETWORK_LOADER_BLOCK *NetworkLoaderBlock;
+
+ #if defined(_X86_)
+ //
+ // Pointers to IRQL translation tables that reside in the HAL
+ // and are exposed to the kernel for use in the "inlined IRQL"
+ // build
+ //
+ PUCHAR HalpIRQLToTPR;
+ PUCHAR HalpVectorToIRQL;
+ #endif
+
+ //
+ // Firmware Location
+ //
+ LIST_ENTRY FirmwareDescriptorListHead;
+
+ //
+ // Pointer to the in-memory copy of override ACPI tables. The override
+ // table file is a simple binary file with one or more ACPI tables laid
+ // out one after another.
+ //
+ VOID* AcpiTable;
+
+ //
+ // Size of override ACPI tables in bytes.
+ //
+ UINT32 AcpiTableSize;
+
+ //
+ // Various informational flags passed to OS via OS Loader.
+ //
+ struct
+ {
+ //
+ // Variables describing the success of the previous boot - whether
+ // booting into the OS was successful, and whether the arc from boot to
+ // runtime to shutdown was successful. Various types of system crashes
+ // will cause one or both of these to be FALSE.
+ //
+ UINT32 LastBootSucceeded : 1;
+ UINT32 LastBootShutdown : 1;
+
+ //
+ // A flag indicating whether the platform supports access to IO ports.
+ //
+ UINT32 IoPortAccessSupported : 1;
+
+ //
+ // A flag indicating whether or not the boot debugger persisted
+ // through kernel initialization.
+ //
+ UINT32 BootDebuggerActive : 1;
+
+ //
+ // A flag indicating whether the system must enforce strong code
+ // guarantees.
+ //
+ UINT32 StrongCodeGuarantees : 1;
+
+ //
+ // A flag indicating whether the system must enforce hard strong code
+ // guarantees.
+ //
+ UINT32 HardStrongCodeGuarantees : 1;
+
+ //
+ // A flag indicating whether SID sharing disabled.
+ //
+ UINT32 SidSharingDisabled : 1;
+
+ //
+ // A flag indicating whether TPM was intialized successfully or not
+ // by the OS loader during boot.
+ //
+ UINT32 TpmInitialized : 1;
+
+ //
+ // A flag indicating whether the VSM code page has been configured and
+ // is usable.
+ //
+ UINT32 VsmConfigured : 1;
+
+ //
+ // A flag indicating whether IUM is enabled.
+ //
+ UINT32 IumEnabled : 1;
+
+ //
+ // A flag indicating whether we're booting from SMB
+ //
+ UINT32 IsSmbboot : 1;
+
+ //
+ // The remainder of the bits are reserved.
+ //
+ UINT32 Reserved : 21;
+ };
+
+ //
+ // Loader runtime performance data.
+ //
+ PLOADER_PERFORMANCE_DATA LoaderPerformanceData;
+
+ //
+ // Boot application persistent data.
+ //
+ LIST_ENTRY BootApplicationPersistentData;
+
+ //
+ // Windows Memory Diagnostic Test Results.
+ //
+ VOID* WmdTestResult;
+
+ //
+ // Boot entry identifier.
+ //
+ GUID BootIdentifier;
+
+ //
+ // The number of pages to reserve for the resume application to use as
+ // scratch space. This should correspond to the boot environment's memory
+ // footprint.
+ //
+ UINT32 ResumePages;
+
+ //
+ // The crash dump header, if present.
+ //
+ VOID* DumpHeader;
+
+ //
+ // Boot graphics context.
+ //
+ VOID* BgContext;
+
+ //
+ // NUMA node locality information and group assignment data.
+ //
+ VOID* NumaLocalityInfo;
+ VOID* NumaGroupAssignment;
+
+ //
+ // List of hives attached by loader
+ //
+ LIST_ENTRY AttachedHives;
+
+ //
+ // Number of entries in the MemoryCachingRequirements map.
+ //
+ UINT32 MemoryCachingRequirementsCount;
+
+ //
+ // List of MEMORY_CACHING_REQUIREMENTS for the system.
+ //
+ VOID* MemoryCachingRequirements;
+
+ //
+ // Result of the Boot entropy gathering.
+ //
+ BOOT_ENTROPY_LDR_RESULT BootEntropyResult;
+
+ //
+ // Computed ITC/TSC frequency of the BSP in hertz.
+ //
+ UINT64 ProcessorCounterFrequency;
+
+ //
+ // Hypervisor specific information.
+ //
+ LOADER_PARAMETER_HYPERVISOR_EXTENSION HypervisorExtension;
+
+ //
+ // Hardware configuration ID used to uniquelly identify the system.
+ //
+ GUID HardwareConfigurationId;
+
+ //
+ // List of HAL_EXTENSION_MODULE_ENTRY structures.
+ //
+ LIST_ENTRY HalExtensionModuleList;
+
+ //
+ // Contains most recent time from firmware, bootstat.dat and ntos build time.
+ //
+ LARGE_INTEGER SystemTime;
+
+ //
+ // Contains cycle counter timestamp at the time SystemTime value was read.
+ //
+ UINT64 TimeStampAtSystemTimeRead;
+
+ //
+ // Boot Flags that are passed to the SystemBootEnvironmentInformation class.
+ //
+ UINT64 BootFlags;
+
+ //
+ // Internal only flags that are passed to the kernel.
+ //
+ UINT64 InternalBootFlags;
+
+ //
+ // Pointer to the in-memory copy of the Wfs FP data.
+ //
+ VOID* WfsFPData;
+
+ //
+ // Size of Wfs FP data in bytes.
+ //
+ UINT32 WfsFPDataSize;
+
+ //
+ // Loader bugcheck parameters for the kernel or extensions to act upon
+ //
+ LOADER_BUGCHECK_PARAMETERS BugcheckParameters;
+
+ //
+ // API set schema data.
+ //
+ VOID* ApiSetSchema;
+ UINT32 ApiSetSchemaSize;
+ LIST_ENTRY ApiSetSchemaExtensions;
+
+ //
+ // The system's firmware version according to ACPI's FADT,
+ // SMBIOS's BIOS information table, and EFI's system table respectively.
+ //
+ UNICODE_STRING AcpiBiosVersion;
+ UNICODE_STRING SmbiosVersion;
+ UNICODE_STRING EfiVersion;
+
+ //
+ // Debugger Descriptor
+ //
+ struct _DEBUG_DEVICE_DESCRIPTOR *KdDebugDevice;
+
+ //
+ // EFI Offline crashdump configuration table.
+ //
+ OFFLINE_CRASHDUMP_CONFIGURATION_TABLE OfflineCrashdumpConfigurationTable;
+
+ //
+ // Manufacturing mode profile name.
+ //
+ UNICODE_STRING ManufacturingProfile;
+
+ //
+ // BBT Buffer to enable precise event based sampling.
+ //
+ VOID* BbtBuffer;
+
+ //
+ // Registry values to be passed to the kernel for calculation of Xsave Buffer Size on Intel platforms
+ //
+ #if defined(_X86_) || defined (_AMD64_) || defined (_WIN64)
+ UINT64 XsaveAllowedFeatures;
+ UINT32 XsaveFlags;
+ #endif
+
+ //
+ // Boot options used by the OS loader.
+ //
+ VOID* BootOptions;
+
+ //
+ // Boot sequence tracking for reliability reporting.
+ //
+ UINT32 BootId;
+
+ //
+ // Code Integrity configuration.
+ //
+ PLOADER_PARAMETER_CI_EXTENSION CodeIntegrityData;
+ UINT32 CodeIntegrityDataSize;
+
+ LOADER_HIVE_RECOVERY_INFO SystemHiveRecoveryInfo;
+} LOADER_PARAMETER_EXTENSION, *PLOADER_PARAMETER_EXTENSION;
+
+typedef struct _LOADER_PARAMETER_BLOCK
+{
+ UINT32 OsMajorVersion;
+ UINT32 OsMinorVersion;
+ UINT32 Size;
+ UINT32 OsLoaderSecurityVersion;
+ LIST_ENTRY LoadOrderListHead;
+ LIST_ENTRY MemoryDescriptorListHead;
+ //
+ // Define the Core, TPM Core and Core Extensions driver lists. The
+ // lists are organized as follows:
+ //
+ // 1. Core Drivers: This list consists of drivers that ELAM drivers and
+ // 3rd party Core Extensions depend upon (e.g. WDF, CNG.sys). All
+ // drivers in this group should be MS-supplied and thus MS-signed.
+ //
+ // 2. ELAM drivers. This list consists of 3rd party ELAM drivers. These
+ // drivers need to be signed with ELAM certificate.
+ //
+ // 3. Core Extensions: This list consists of 3rd party drivers (viz.
+ // Platform Extensions and Tree drivers) that TPM Core drivers
+ // depend upon. These drivers need to be signed with Core Extension
+ // certificate.
+ //
+ // 4. TPM Core: This list consists of TPM driver and bus drivers (e.g.
+ // ACPI, PCI) that are necessary to enumerate TPM. All drivers in
+ // this group should be MS-supplied and thus MS-signed.
+ //
+ // 5. Boot Driver: This list contains the rest of the boot drivers.
+ //
+ LIST_ENTRY BootDriverListHead;
+ LIST_ENTRY EarlyLaunchListHead;
+ LIST_ENTRY CoreDriverListHead;
+ LIST_ENTRY CoreExtensionsDriverListHead;
+ LIST_ENTRY TpmCoreDriverListHead;
+ UINT64 KernelStack;
+ UINT64 Prcb;
+ UINT64 Process;
+ UINT64 Thread;
+ UINT32 KernelStackSize;
+ UINT32 RegistryLength;
+ VOID* RegistryBase;
+ PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
+ UINT8* ArcBootDeviceName;
+ UINT8* ArcHalDeviceName;
+ UINT8* NtBootPathName;
+ UINT8* NtHalPathName;
+ UINT8* LoadOptions;
+ PNLS_DATA_BLOCK NlsData;
+ PARC_DISK_INFORMATION ArcDiskInformation;
+ PLOADER_PARAMETER_EXTENSION Extension;
+ union
+ {
+ I386_LOADER_BLOCK I386;
+ ARM_LOADER_BLOCK Arm;
+ } u;
+ FIRMWARE_INFORMATION_LOADER_BLOCK FirmwareInformation;
+} LOADER_PARAMETER_BLOCK, *PLOADER_PARAMETER_BLOCK;
\ No newline at end of file
diff --git a/UefiDriver/drvmain.c b/UefiDriver/drvmain.c
index 359bbd9..489a763 100644
--- a/UefiDriver/drvmain.c
+++ b/UefiDriver/drvmain.c
@@ -46,9 +46,21 @@ CHAR8 *gEfiCallerBaseName = "UefiDriver";
#define BOOTMGFW_EFI_PATH L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"
static EFI_HANDLE gWindowsImagehandle;
+static EFI_LOADED_IMAGE* gLocalImageInfo;
+
// Inside hooks.asm
-VOID* FindPattern( VOID* ImageBase, UINT32 ImageSize, UINT8* Pattern, UINT32 PatternSize );
+VOID* FindPattern( VOID* ImageBase, UINT32 ImageSize, const UINT8* Pattern, UINT32 PatternSize );
+
+
+//
+// OslArchTransferToKernel hook
+//
+VOID EFIAPI hkOslArchTransferToKernel( VOID *KernelParams, VOID *KiSystemStartup )
+{
+ __debugbreak( );
+ oOslArchTransferToKernel( KernelParams, KiSystemStartup );
+}
//
// Our ImgArchEfiStartBootApplication hook which takes the winload Image Base as a parameter so we can patch the kernel
@@ -86,32 +98,29 @@ EFI_STATUS EFIAPI hkImgArchEfiStartBootApplication( PBL_APPLICATION_ENTRY AppEnt
EFI_STATUS EfiStatus = EFI_SUCCESS;
UINT8* Found = NULL;
- VOID* ArchpChildAppEntryRoutine = (VOID*)((UINT8*)ImageBase + HEADER_VAL_T( NtHdr, AddressOfEntryPoint ));
- Print( L"ArchpChildAppEntryRoutine = %lx\r\n", ArchpChildAppEntryRoutine );
-
// Find right location to patch
- Found = FindPattern( ImageBase, ImageSize, sigOslArchTransferToKernel, sizeof( sigOslArchTransferToKernel ) );
- if (Found)
+ EfiStatus = UtilFindPattern( sigOslArchTransferToKernelCall, 0xCC, sizeof( sigOslArchTransferToKernelCall ), ImageBase, ImageSize, (VOID**)&Found );
+ if (EfiStatus == EFI_SUCCESS)
{
Print( L"Found OslArchTransferToKernel call at %lx\r\n", Found );
-
+
// Get original from call instruction
oOslArchTransferToKernel = (tOslArchTransferToKernel)UtilCallAddress( Found );
Print( L"OslArchTransferToKernel at %lx\r\n", oOslArchTransferToKernel );
- Print( L"OslArchTransferToKernelHook at %lx\r\n", &OslArchTransferToKernelHook );
-
+ Print( L"OslArchTransferToKernelHook at %lx\r\n", &hkOslArchTransferToKernel );
+
// Backup original function bytes before patching
- OslArchTransferToKernelPatchLocation = (VOID*)Found;
- CopyMem( (VOID*)OslArchTransferToKernelBackup, (VOID*)Found, 5 );
-
+ OslArchTransferToKernelCallPatchLocation = (VOID*)Found;
+ CopyMem( (VOID*)OslArchTransferToKernelCallBackup, (VOID*)Found, 5 );
+
// display original code
Print( L"Original:\r\n" );
UtilDisassembleCode( (UINT8*)Found, (VOID*)Found, 5 );
-
+
// Do patching
*(UINT8*)Found = 0xE8;
- *(UINT32*)(Found + 1) = UtilCalcRelativeCallOffset( (VOID*)Found, (VOID*)&OslArchTransferToKernelHook );
-
+ *(UINT32*)(Found + 1) = UtilCalcRelativeCallOffset( (VOID*)Found, (VOID*)&hkOslArchTransferToKernel );
+
// Display patched code
Print( L"Patched:\r\n" );
UtilDisassembleCode( (UINT8*)Found, (VOID*)Found, 5 );
@@ -122,6 +131,8 @@ EFI_STATUS EFIAPI hkImgArchEfiStartBootApplication( PBL_APPLICATION_ENTRY AppEnt
}
}
+ UtilPrintLoadedImageInfo( gLocalImageInfo );
+
Print( L"Press any key to continue..." );
UtilWaitForKey( );
@@ -192,11 +203,13 @@ EFI_STATUS PatchWindowsBootManager( IN VOID* LocalImageBase, IN EFI_HANDLE BootM
EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable )
{
EFI_STATUS efiStatus;
- EFI_LOADED_IMAGE* Image;
EFI_DEVICE_PATH* WinBootMgrDevicePath;
- // Clear screen
+ //
+ // Clear screen and make pretty
+ //
gST->ConOut->ClearScreen( gST->ConOut );
+ gST->ConOut->SetAttribute( gST->ConOut, EFI_GREEN | EFI_BACKGROUND_LIGHTGRAY );
//
// Install required driver binding components
@@ -211,10 +224,10 @@ EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *Syst
Print( L"\r\n\r\n" );
Print( L"%s", BOOTKIT_TITLE1 );
Print( L"%s", BOOTKIT_TITLE2 );
- efiStatus = gBS->HandleProtocol( ImageHandle, &gEfiLoadedImageProtocolGuid, &Image );
+ efiStatus = gBS->HandleProtocol( ImageHandle, &gEfiLoadedImageProtocolGuid, &gLocalImageInfo );
if (EFI_ERROR( efiStatus ))
goto Exit;
- UtilPrintLoadedImageInfo( Image );
+ UtilPrintLoadedImageInfo( gLocalImageInfo );
//
// Locate
@@ -229,7 +242,7 @@ EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *Syst
efiStatus = ImageLoad( ImageHandle, WinBootMgrDevicePath, &gWindowsImagehandle );
if (EFI_ERROR( efiStatus ))
goto Exit;
- efiStatus = PatchWindowsBootManager( Image->ImageBase, gWindowsImagehandle );
+ efiStatus = PatchWindowsBootManager( gLocalImageInfo->ImageBase, gWindowsImagehandle );
if (EFI_ERROR( efiStatus ))
goto Exit;
Print( L"Patched!\r\n" );
diff --git a/UefiDriver/hook.asm b/UefiDriver/hook.asm
index ed6bee0..9557736 100644
--- a/UefiDriver/hook.asm
+++ b/UefiDriver/hook.asm
@@ -19,8 +19,8 @@
;*********************************************************************
; Public symbols
; Saved OslArchTransferToKernel location and bytes from before the patch
-public OslArchTransferToKernelBackup
-public OslArchTransferToKernelPatchLocation
+public OslArchTransferToKernelCallBackup
+public OslArchTransferToKernelCallPatchLocation
;*********************************************************************
; .data section
@@ -29,14 +29,11 @@ public OslArchTransferToKernelPatchLocation
ALIGN 16
; Saved OslArchTransferToKernel bytes from before the patch
-OslArchTransferToKernelBackup db 5 dup(0)
-OslArchTransferToKernelPatchLocation dq 0
+OslArchTransferToKernelCallBackup db 5 dup(0)
+OslArchTransferToKernelCallPatchLocation dq 0
; Original OslArchTransferToKernel address
extern oOslArchTransferToKernel:dq
-; Winload functions
-extern EfiStall:dq
-extern EfiConOutOutputString:dq
; Kernel patch patterns
@@ -87,6 +84,8 @@ PrintStringTest ENDP
; VOID __fastcall OslArchTransferToKernel(VOID *KernelParams, VOID *KiSystemStartup)
;
OslArchTransferToKernelHook PROC
+ ; debug break point
+ db 0CCh
; Save registers to do our kernel patching
push r15
push r14
@@ -113,8 +112,8 @@ OslArchTransferToKernelHook PROC
; Before we do anything lets restore the original function bytes
restore_bytes:
- lea rsi, OslArchTransferToKernelBackup
- mov rdi, OslArchTransferToKernelPatchLocation
+ lea rsi, OslArchTransferToKernelCallBackup
+ mov rdi, OslArchTransferToKernelCallPatchLocation
mov rcx, 5 ; our patch size was 5 bytes
rep movsb byte ptr [rdi], byte ptr [rsi] ; restore bytes
diff --git a/UefiDriver/hook.h b/UefiDriver/hook.h
index 05b1adb..6ae29c3 100644
--- a/UefiDriver/hook.h
+++ b/UefiDriver/hook.h
@@ -12,7 +12,7 @@ EFI_STATUS PrintTestString( VOID );
// ImgArchEfiStartBootApplication hook
//
typedef EFI_STATUS( EFIAPI *tImgArchEfiStartBootApplication )(PBL_APPLICATION_ENTRY AppEntry, VOID* ImageBase, UINT32 ImageSize, UINT8 BootOption, PBL_RETURN_ARGUMENTS ReturnArguments);
-static UINT8 sigImgArchEfiStartBootApplicationCall[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x48, 0x8B, 0xCE, 0x8B, 0xD8, 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x41 };
+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;
@@ -21,22 +21,20 @@ 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];
+UINT8 sigOslArchTransferToKernelCall[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0xEB, 0xFE }; // 48 8B 45 A8 33 FF
+VOID* OslArchTransferToKernelCallPatchLocation;
+UINT8 OslArchTransferToKernelCallBackup[5];
tOslArchTransferToKernel oOslArchTransferToKernel = NULL;
-extern VOID* OslArchTransferToKernelHook;
+VOID* OslArchTransferToKernelHook;
//
-// Winload calls
+// OslLoadImage hook
//
-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;
+UINT8 sigOslLoadImageCall[] = { 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, 0x48, 0x63, 0xCC, 0x85, 0xCC, 0x0F, 0x89 };
+typedef EFI_STATUS( EFIAPI *tOslLoadImage )(UINT64 DataTableIndex, UINT32 LoadFlags, CHAR16 *ImagePath, CHAR16 *ImageName, UINT32 ImageFlags, VOID* Base, UINT32 Size);
+VOID* OslLoadImageCallPatchLocation = NULL;
+UINT8 OslLoadImageCallBackup[5] = { 0 };
+tOslLoadImage oOslLoadImage = NULL;
//
@@ -95,5 +93,5 @@ UINTN sigNxSetBitSize = sizeof( sigNxSetBit );
// INIT:000000014074BAAA C3 retn
// INIT:000000014074BAAA KeInitAmd64SpecificState endp
UINT8 sigInitPatchGuard[] = { 0x75, 0x2D, 0x0F, 0xB6, 0x15 };
-UINTN sigInitPatchGuardSize = sizeof( sigInitPatchGuard );
+UINTN sigInitPatchGuardSize = 5;