diff --git a/EDK2/build_shim.sh b/EDK2/build_shim.sh
new file mode 100644
index 00000000..edefa4d2
--- /dev/null
+++ b/EDK2/build_shim.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+if [ -z "$1" ]; then
+ EDKARCH=X64
+ postfix=x64
+elif [ "$1" = "ia32" ]; then
+ EDKARCH=IA32
+ postfix=ia32
+ shift
+elif [ "$1" = "aa64" ]; then
+ EDKARCH=AARCH64
+ postfix=aa64
+ shift
+fi
+
+cd edk2-edk2-stable201911
+
+rm -rf ./Conf/.cache
+rm -f ./Conf/.AutoGenIdFile.txt
+
+VTEFI_PATH=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VtoyShim/VtoyShim/OUTPUT/VtoyShim.efi
+DST_PATH=../../INSTALL/EFI/BOOT/fb${postfix}.efi
+
+
+rm -f $VTEFI_PATH
+rm -f $DST_PATH
+
+unset WORKSPACE
+source ./edksetup.sh
+
+if [ "$EDKARCH" = "AARCH64" ]; then
+ PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin \
+ GCC48_AARCH64_PREFIX=aarch64-linux-gnu- \
+ build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 -m MdeModulePkg/Application/VtoyShim/VtoyShim.inf
+else
+ build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 -m MdeModulePkg/Application/VtoyShim/VtoyShim.inf
+fi
+
+if [ -e $VTEFI_PATH ]; then
+ objcopy \
+ --add-section .sbat="MdeModulePkg/Application/VtoyShim/sbat.csv" \
+ --set-section-flags .sbat=alloc,load,readonly,data \
+ "$VTEFI_PATH" "$DST_PATH"
+
+ objcopy --adjust-section-vma .sbat=0x1000 "$DST_PATH"
+
+ echo -e '\n\n====================== SUCCESS ========================\n\n'
+
+ cd ..
+else
+ echo -e '\n\n====================== FAILED ========================\n\n'
+ cd ..
+ exit 1
+fi
+
diff --git a/EDK2/buildedk.sh b/EDK2/buildedk.sh
index e001303b..14823c07 100644
--- a/EDK2/buildedk.sh
+++ b/EDK2/buildedk.sh
@@ -19,3 +19,7 @@ sh ./build.sh aa64 || exit 1
echo '======== build EDK2 for x86_64-efi ==============='
sh ./build.sh || exit 1
+
+echo '======== build EDK2 for x86_64-efi ==============='
+sh ./build_shim.sh || exit 1
+
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c
index 65342013..3ca80f62 100644
--- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c
@@ -1231,6 +1231,32 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle)
return EFI_SUCCESS;
}
+#if defined (MDE_CPU_X64)
+STATIC BOOLEAN EFIAPI CheckVtoyShim(VOID)
+{
+ UINT8 SecureBoot = 0;
+ UINTN DataSize;
+ EFI_STATUS Status;
+ EFI_GUID Guid = VTOY_SHIM_POLICY_GUID;
+ VOID *Prot = NULL;
+
+ DataSize = sizeof(SecureBoot);
+ Status = gST->RuntimeServices->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL,
+ &DataSize, &SecureBoot);
+ if (!EFI_ERROR(Status) && SecureBoot)
+ {
+ Status = gBS->LocateProtocol(&Guid, NULL, (VOID**)&Prot);
+ if (EFI_ERROR(Status))
+ {
+ VtoyDebug("Failed to locate Vtoy Shim Protocol %lx\r\n", Status);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+#endif
+
EFI_STATUS EFIAPI VentoyEfiMain
(
IN EFI_HANDLE ImageHandle,
@@ -1240,6 +1266,15 @@ EFI_STATUS EFIAPI VentoyEfiMain
EFI_STATUS Status = EFI_SUCCESS;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *Protocol;
+#if defined (MDE_CPU_X64)
+ /* check that Ventoy Shim must exist */
+ if (!CheckVtoyShim())
+ {
+ sleep(5);
+ return EFI_NOT_FOUND;
+ }
+#endif
+
g_sector_flag_num = 512; /* initial value */
g_sector_flag = AllocatePool(g_sector_flag_num * sizeof(ventoy_sector_flag));
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h
index 40ba6b13..35fd5e45 100644
--- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h
@@ -23,6 +23,8 @@
#define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1]
+#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }};
+
#define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }}
typedef enum ventoy_chain_type
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf
index 374efdd7..36ec0ab0 100644
--- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf
@@ -24,6 +24,10 @@
VERSION_STRING = 1.0
ENTRY_POINT = VentoyEfiMain
+
+[BuildOptions]
+ # Force standard GNU ld to pack and align ELF segments to 4KB page boundaries
+ GCC:*_*_*_DLINK_FLAGS = -Wl,-z,common-page-size=0x1000 -Wl,-z,max-page-size=0x1000
[Sources]
Ventoy.h
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c
new file mode 100644
index 00000000..88476d68
--- /dev/null
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.c
@@ -0,0 +1,709 @@
+/******************************************************************************
+ * VtoyShim.c
+ *
+ * Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define CUR_SBAT_VER 1
+
+STATIC EFI_GUID gVtoySbatGUID = { 0xf755068a, 0xe04f, 0x452b, { 0x9d, 0x6d, 0x7c, 0x55, 0x96, 0xb3, 0xc0, 0x7d }};
+STATIC EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *gDpToText = NULL;
+STATIC EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *gTextToDp = NULL;
+STATIC EFI_SECURITY_FILE_AUTHENTICATION_STATE gSysSecFileAuth = NULL;
+STATIC EFI_SECURITY2_FILE_AUTHENTICATION gSysSec2FileAuth = NULL;
+STATIC BOOLEAN gVtoyByPassSB = FALSE; /* must be FALSE by default for revoke */
+STATIC VTOY_SHIM gVtoyShimProtocol;
+STATIC EFI_HANDLE gVtoyShimProtHandle;
+STATIC SHIM_LOCK *gShimLock = NULL;
+
+STATIC VOID EFIAPI VtoyLog(CONST CHAR16 *Format, ...)
+{
+ VA_LIST Marker;
+ CHAR16 Buffer[512];
+ UINTN BufLen = 0;
+
+ Buffer[0] = 0;
+ VA_START(Marker, Format);
+ BufLen = UnicodeVSPrint(Buffer, sizeof(Buffer), Format, Marker);
+ VA_END(Marker);
+
+ if (gST->ConOut && gST->ConOut->OutputString)
+ {
+ gST->ConOut->OutputString(gST->ConOut, Buffer);
+ }
+}
+
+
+STATIC VOID EFIAPI DumpDevicePath(const EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ CHAR16 *DPStr = NULL;
+
+ DPStr = gDpToText->ConvertDevicePathToText(DevicePath, TRUE, TRUE);
+ if (DPStr)
+ {
+ vLog(L"%s", DPStr);
+ gBS->FreePool(DPStr);
+ }
+ else
+ {
+ vLog(L"NULL");
+ }
+}
+
+STATIC VOID EFIAPI ShowSBWarning(BOOLEAN Reboot, const EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ UINTN Index = 0;
+
+ vLog(L"\r\n=======================================================");
+ vLog(L"=======================================================\r\n");
+
+ DumpDevicePath(DevicePath);
+
+ vLog(L"\r\n####### Security Boot Violation ##########\r\n");
+
+ vLog(L"=======================================================");
+ vLog(L"=======================================================");
+
+ if (Reboot)
+ {
+ vLog(L"\r\n###### Press Enter to reboot... ######");
+ gST->ConIn->Reset(gST->ConIn, FALSE);
+ gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &Index);
+ gRT->ResetSystem(EfiResetWarm, EFI_SECURITY_VIOLATION, 0, NULL);
+ }
+ else
+ {
+ VtoySleep(5);
+ }
+}
+
+
+STATIC VOID * EFIAPI FindShimFuncAddr(UINT64 FuncOffset)
+{
+ EFI_STATUS Status;
+ SHIM_IMAGE_LOADER *ImgLoader = NULL;
+ EFI_GUID ShimImgLoaderGuid = SHIM_IMAGE_LOADER_GUID;
+
+ Status = gBS->LocateProtocol(&ShimImgLoaderGuid, NULL, (VOID **)&ImgLoader);
+ if (EFI_ERROR(Status) || !ImgLoader || !ImgLoader->LoadImage)
+ {
+ vLog(L"Failed to locate shim image loader protocol %lx %p", Status, ImgLoader);
+ return NULL;
+ }
+
+ if (NM_SHIM_LOAD_IMAGE_OFFSET > FuncOffset)
+ {
+ return (UINT8 *)ImgLoader->LoadImage - (NM_SHIM_LOAD_IMAGE_OFFSET - FuncOffset);
+ }
+ else
+ {
+ return (UINT8 *)ImgLoader->LoadImage + (FuncOffset - NM_SHIM_LOAD_IMAGE_OFFSET);
+ }
+}
+
+
+EFI_STATUS EFIAPI LaunchRealGrub(EFI_HANDLE ImageHandle, CONST CHAR16 *FileName)
+{
+ EFI_STATUS Status;
+ UINTN BufferSize = 0;
+ CHAR16 *DevDpStr = NULL;
+ CHAR16 *NewDpStr = NULL;
+ EFI_HANDLE ChildHandle = NULL;
+ EFI_LOADED_IMAGE_PROTOCOL *Li = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceDP = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *TargetDp = NULL;
+
+ Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID**)&Li);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to locate loaded image protocol %lx", Status);
+ return Status;
+ }
+
+ DeviceDP = DevicePathFromHandle(Li->DeviceHandle);
+ if (!DeviceDP || !IsDevicePathValid(DeviceDP, 0))
+ {
+ vLog(L"Failed to get device path of device handle %p", Li->DeviceHandle);
+ Status = EFI_NOT_FOUND;
+ goto END;
+ }
+
+ DevDpStr = gDpToText->ConvertDevicePathToText(DeviceDP, FALSE, TRUE);
+ if (!DevDpStr)
+ {
+ vLog(L"Failed to convert device path to text");
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ BufferSize = (StrLen(DevDpStr) + 64) * sizeof(CHAR16);
+ NewDpStr = (CHAR16 *)AllocatePool(BufferSize);
+ if (!NewDpStr)
+ {
+ vLog(L"Failed to alloc new device path string buffer size:%lu", BufferSize);
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ UnicodeSPrint(NewDpStr, BufferSize, L"%s/EFI/BOOT/%s", DevDpStr, FileName);
+
+ TargetDp = gTextToDp->ConvertTextToDevicePath(NewDpStr);
+ if (!TargetDp)
+ {
+ vLog(L"Failed to convert new text <%s> to device path", NewDpStr);
+ Status = EFI_NOT_FOUND;
+ goto END;
+ }
+
+ Status = gBS->LoadImage(FALSE, ImageHandle, TargetDp, NULL, 0, &ChildHandle);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to LoadImage %lx", Status);
+ goto END;
+ }
+
+
+ Status = gBS->StartImage(ChildHandle, NULL, NULL);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to StartImage %lx", Status);
+ gBS->UnloadImage(ChildHandle);
+ goto END;
+ }
+
+
+END:
+
+ CheckBSFreePool(DevDpStr);
+ CheckFreePool(NewDpStr);
+ CheckBSFreePool(TargetDp);
+
+ return Status;
+}
+
+
+
+STATIC EFI_STATUS EFIAPI ReadAuthFile
+(
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst,
+ VOID **Buffer,
+ UINT32 *Size
+)
+{
+ EFI_STATUS Status;
+ UINTN TmpSize = 0;
+ CHAR16 *DpStr = NULL;
+ EFI_HANDLE Handle = NULL;
+ EFI_DEVICE_PATH *DevPath = NULL;
+ EFI_DEVICE_PATH *TmpPath = NULL;
+ EFI_FILE_IO_INTERFACE *FileIO = NULL;
+ EFI_FILE *File = NULL;
+ EFI_FILE *Root = NULL;
+ UINT8 *FileData = NULL;
+ EFI_FILE_INFO *FInfo = NULL;
+ UINT8 Buf[1024];
+
+ DevPath = TmpPath = DuplicateDevicePath(DevicePathConst);
+ if (!DevPath)
+ {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ Status = gBS->LocateDevicePath(&gEfiSimpleFileSystemProtocolGuid, &DevPath, &Handle);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to locate simple file protocol %lx", Status);
+ goto END;
+ }
+
+ DpStr = gDpToText->ConvertDevicePathToText(DevPath, FALSE, TRUE);
+ if (!DpStr)
+ {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ Status = gBS->HandleProtocol(Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&FileIO);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to handle simple file protocol %lx", Status);
+ goto END;
+ }
+
+ Status = FileIO->OpenVolume(Handle, &Root);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to open drive volume (%lx)\n", Status);
+ goto END;
+ }
+
+ Status = Root->Open(Root, &File, DpStr, EFI_FILE_MODE_READ, 0);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to open file (%s) (%lx)\n", DpStr, Status);
+ goto END;
+ }
+
+ FInfo = (EFI_FILE_INFO *)Buf;
+ TmpSize = sizeof(Buf);
+ ZeroMem(FInfo, sizeof(EFI_FILE_INFO));
+
+ Status = File->GetInfo(File, &gEfiFileInfoGuid, &TmpSize, FInfo);
+ if (EFI_ERROR(Status) || FInfo->FileSize == 0 || FInfo->FileSize >= 0xFFFFFFFFUL)
+ {
+ vLog(L"Failed to open file (%s) (%lx) Size(%ld)\n", DpStr, Status, (UINTN)FInfo->FileSize);
+ goto END;
+ }
+
+ FileData = AllocatePool(FInfo->FileSize);
+ if (!FileData)
+ {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto END;
+ }
+
+ TmpSize = FInfo->FileSize;
+ Status = File->Read(File, &TmpSize, FileData);
+ if (EFI_ERROR(Status) || TmpSize != (UINTN)FInfo->FileSize)
+ {
+ vLog(L"Failed to read file (%lx) Read:%ld Size:%ld\n", Status, TmpSize, (UINTN)FInfo->FileSize);
+ goto END;
+ }
+
+
+END:
+
+ if (File)
+ {
+ File->Close(File);
+ }
+
+ if (Root)
+ {
+ Root->Close(Root);
+ }
+
+ CheckFreePool(TmpPath);
+ CheckBSFreePool(DpStr);
+
+ if (EFI_ERROR(Status))
+ {
+ CheckFreePool(FileData);
+ }
+ else
+ {
+ *Buffer = FileData;
+ *Size = (UINT32)FInfo->FileSize;
+ }
+
+ return Status;
+}
+
+
+STATIC BOOLEAN VtoyCheckRevoke(VOID *Buffer, UINTN Size)
+{
+ UINT32 uiVer = 0;
+ EFI_IMAGE_DOS_HEADER *DosHead = (EFI_IMAGE_DOS_HEADER *)Buffer;
+
+ if (Size > sizeof(EFI_IMAGE_DOS_HEADER))
+ {
+ if (CompareMem(DosHead->e_res2, &gVtoySbatGUID, 16) == 0)
+ {
+ CopyMem(&uiVer, DosHead->e_res2 + 8, 4);
+ if (uiVer < CUR_SBAT_VER)
+ {
+ vLog(L"Ventoy EFI file revoke (%u < %u)", uiVer, CUR_SBAT_VER);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+STATIC EFI_STATUS EFIAPI SecurityPolicyAuth
+(
+ const EFI_SECURITY_ARCH_PROTOCOL *This,
+ UINT32 AuthenticationStatus,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePathConst
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN bRevokeChkOK = TRUE;
+ UINT32 Size = 0;
+ VOID *Buffer = NULL;
+
+ /* Just return OK if the user choose to bypass SB */
+ if (gVtoyByPassSB)
+ {
+ return EFI_SUCCESS;
+ }
+
+ /*
+ * Step 1:
+ * Use original UEFI firmware auth API.
+ * If it's OK, it may be signed with Microsoft UEFI CA. (e.g. bootmgr/shim/...)
+ */
+ if (gSysSecFileAuth)
+ {
+ Status = gSysSecFileAuth(This, AuthenticationStatus, DevicePathConst);
+ if (!EFI_ERROR(Status))
+ {
+ return EFI_SUCCESS;
+ }
+ }
+
+
+ /*
+ * Step 2:
+ * Use shim verify API.
+ * If it's OK, it may be signed with a MOK key. (e.g. Ventoy EFI files)
+ */
+ if (gShimLock && gShimLock->Verify)
+ {
+ Status = ReadAuthFile(DevicePathConst, &Buffer, &Size);
+ if (!EFI_ERROR(Status))
+ {
+ Status = gShimLock->Verify(Buffer, Size);
+ if (!EFI_ERROR(Status))
+ {
+ bRevokeChkOK = VtoyCheckRevoke(Buffer, Size);
+ if (bRevokeChkOK)
+ {
+ FreePool(Buffer);
+ return EFI_SUCCESS;
+ }
+ }
+ FreePool(Buffer);
+ }
+ }
+
+ ShowSBWarning(!bRevokeChkOK, DevicePathConst);
+
+ return EFI_SECURITY_VIOLATION;
+}
+
+STATIC EFI_STATUS EFIAPI Security2PolicyAuth
+(
+ const EFI_SECURITY2_ARCH_PROTOCOL *This,
+ const EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ VOID *FileBuffer,
+ UINTN FileSize,
+ BOOLEAN BootPolicy
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN bRevokeChkOK = TRUE;
+
+ /* Just return OK if the user choose to bypass SB */
+ if (gVtoyByPassSB)
+ {
+ return EFI_SUCCESS;
+ }
+
+ /*
+ * Step 1:
+ * Use original UEFI firmware auth API.
+ * If it's OK, it may be signed with Microsoft UEFI CA. (e.g. bootmgr/shim/...)
+ */
+ if (gSysSec2FileAuth)
+ {
+ Status = gSysSec2FileAuth(This, DevicePath, FileBuffer, FileSize, BootPolicy);
+ if (!EFI_ERROR(Status))
+ {
+ return EFI_SUCCESS;
+ }
+ }
+
+
+ /*
+ * Step 2:
+ * Use shim verify API.
+ * If it's OK, it may be signed with a MOK key. (e.g. Ventoy EFI files)
+ */
+ if (gShimLock && gShimLock->Verify)
+ {
+ if (FileBuffer && FileSize > 0 && FileSize < 0xFFFFFFFFUL)
+ {
+ Status = gShimLock->Verify(FileBuffer, (UINT32)FileSize);
+ if (!EFI_ERROR(Status))
+ {
+ bRevokeChkOK = VtoyCheckRevoke(FileBuffer, FileSize);
+ if (bRevokeChkOK)
+ {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+
+ ShowSBWarning(!bRevokeChkOK, DevicePath);
+
+ return EFI_SECURITY_VIOLATION;
+}
+
+
+STATIC EFI_STATUS EFIAPI HookSecurityPolicy(VOID)
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ EFI_SECURITY_ARCH_PROTOCOL *Security = NULL;
+ EFI_SECURITY2_ARCH_PROTOCOL *Security2 = NULL;
+
+ Status = gBS->LocateProtocol(&gEfiSecurityArchProtocolGuid, NULL, (VOID **)&Security);
+ Status2 = gBS->LocateProtocol(&gEfiSecurity2ArchProtocolGuid, NULL, (VOID **)&Security2);
+ if (EFI_ERROR(Status) && EFI_ERROR(Status2))
+ {
+ vLog(L"Failed to locate security or security2 protocol. %lx %lx %p %p",
+ Status, Status2, Security, Security2);
+ return EFI_NOT_FOUND;
+ }
+
+ if (Security2)
+ {
+ gSysSec2FileAuth = Security2->FileAuthentication;
+ Security2->FileAuthentication = Security2PolicyAuth;
+ }
+
+ if (Security)
+ {
+ gSysSecFileAuth = Security->FileAuthenticationState;
+ Security->FileAuthenticationState = SecurityPolicyAuth;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC VOID EFIAPI UnHookSecurityPolicy(VOID)
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+ EFI_SECURITY_ARCH_PROTOCOL *Security = NULL;
+ EFI_SECURITY2_ARCH_PROTOCOL *Security2 = NULL;
+
+ if (!gSysSec2FileAuth && !gSysSecFileAuth)
+ {
+ return;
+ }
+
+ Status = gBS->LocateProtocol(&gEfiSecurityArchProtocolGuid, NULL, (VOID **)&Security);
+ Status2 = gBS->LocateProtocol(&gEfiSecurity2ArchProtocolGuid, NULL, (VOID **)&Security2);
+ if (EFI_ERROR(Status) && EFI_ERROR(Status2))
+ {
+ vLog(L"Failed to locate security or security2 protocol. %lx %lx %p %p",
+ Status, Status2, Security, Security2);
+ return;
+ }
+
+ if (Security2 && gSysSec2FileAuth)
+ {
+ Security2->FileAuthentication = gSysSec2FileAuth;
+ gSysSec2FileAuth = NULL;
+ }
+
+ if (Security && gSysSecFileAuth)
+ {
+ Security->FileAuthenticationState = gSysSecFileAuth;
+ gSysSecFileAuth = NULL;
+ }
+}
+
+STATIC VOID EFIAPI VtoyByPassSB(VOID)
+{
+ gVtoyByPassSB = TRUE;
+}
+
+STATIC VOID EFIAPI VtoyCheckSB(VOID)
+{
+ gVtoyByPassSB = FALSE;
+}
+
+STATIC VOID EFIAPI UnInstallVtoyShimProtocol(VOID)
+{
+ EFI_GUID Guid = VTOY_SHIM_POLICY_GUID;
+
+ if (gVtoyShimProtHandle)
+ {
+ gBS->UninstallProtocolInterface(gVtoyShimProtHandle, &Guid, &gVtoyShimProtocol);
+ gVtoyShimProtHandle = NULL;
+ }
+}
+
+STATIC EFI_STATUS EFIAPI InstallVtoyShimProtocol(VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID Guid = VTOY_SHIM_POLICY_GUID;
+ VTOY_SHIM *Prot = NULL;
+
+ gVtoyShimProtocol.ByPassSB = VtoyByPassSB;
+ gVtoyShimProtocol.CheckSB = VtoyCheckSB;
+
+ Status = gBS->LocateProtocol(&Guid, NULL, (VOID**)&Prot);
+ if (!EFI_ERROR(Status))
+ {
+ vLog(L"Ventoy shim already loaded, cannot be nested.");
+ return EFI_ALREADY_STARTED;
+ }
+
+ Status = gBS->InstallProtocolInterface(&gVtoyShimProtHandle, &Guid,
+ EFI_NATIVE_INTERFACE, &gVtoyShimProtocol);
+ if (EFI_ERROR(Status))
+ {
+ vLog(L"Failed to install protocol %lx", Status);
+ }
+
+ return Status;
+}
+
+STATIC BOOLEAN EFIAPI IsSecureBootEnabled(VOID)
+{
+ UINT8 SecureBoot = 0;
+ UINTN DataSize;
+ EFI_STATUS Status;
+
+ DataSize = sizeof(SecureBoot);
+ Status = gST->RuntimeServices->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL,
+ &DataSize, &SecureBoot);
+ if (EFI_ERROR(Status))
+ {
+ return FALSE;
+ }
+
+ return SecureBoot ? TRUE : FALSE;
+}
+
+STATIC EFI_STATUS EFIAPI EnvInit(VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID Guid = SHIM_LOCK_GUID;
+
+ Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID**)&gDpToText);
+ if (EFI_ERROR(Status) || !gDpToText || !gDpToText->ConvertDevicePathToText)
+ {
+ vLog(L"Failed to locate PathToText Protocol %lx", Status);
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol(&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID**)&gTextToDp);
+ if (EFI_ERROR(Status) || !gTextToDp || !gTextToDp->ConvertTextToDevicePath)
+ {
+ vLog(L"Failed to locate PathFromText Protocol %lx", Status);
+ return Status;
+ }
+
+ Status = gBS->LocateProtocol(&Guid, NULL, (VOID**)&gShimLock);
+ if (EFI_ERROR(Status) || !gShimLock)
+ {
+ vLog(L"Failed to locate SHIM LOCK Protocol %lx", Status);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS EFIAPI VtoyShimEfiMain
+(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ unhook_system_services_pf Func = NULL;
+
+ /* If secure boot is not enabled, nothing needed, just launch Ventoy grub */
+ if (!IsSecureBootEnabled())
+ {
+ return LaunchRealGrub(ImageHandle, REAL_GRUB_FILE);
+ }
+
+ Status = EnvInit();
+ if (EFI_ERROR(Status))
+ {
+ vErr(L"Failed to prepare env");
+ return Status;
+ }
+
+ Status = InstallVtoyShimProtocol();
+ if (EFI_ERROR(Status))
+ {
+ vErr(L"Failed to install ventoy shim protocol");
+ return Status;
+ }
+
+
+ /*
+ * IMPORTANT: All recent shim implementations hook the UEFI Boot Services
+ * (e.g. LoadImage, StartImage) to enforce signature verification.
+ *
+ * We must restore the original system service pointers here. If we fail to do this,
+ * we will be unable to launch Ventoy-signed EFI binaries or any other unsigned
+ * EFI applications later, even when the user has explicitly opted to disable
+ * all Secure Boot validation checks.
+ *
+ * To the best of my knowledge, there is no official way to remove these hooks.
+ * This is a tricky hack that relies on shim's internal implementation details.
+ * It may break in future versions of shim, and a better approach may exist.
+ *
+ */
+ Func = FindShimFuncAddr(NM_UNHOOK_SYSTEM_SERVICES_OFFSET);
+ if (!Func)
+ {
+ vErr(L"Can not find shim unhook_system_services");
+ Status = EFI_NOT_FOUND;
+ goto END;
+ }
+
+ Func(); /* call shim unhook_system_services() */
+
+
+ /* Hook the system security policy */
+ Status = HookSecurityPolicy();
+ if (EFI_ERROR(Status))
+ {
+ vErr(L"Failed to hook system security policy");
+ goto END;
+ }
+
+ /* Finally launch Ventoy grub */
+ Status = LaunchRealGrub(ImageHandle, REAL_GRUB_FILE);
+
+END:
+
+ /* UnHook system security policy */
+ UnHookSecurityPolicy();
+
+ UnInstallVtoyShimProtocol();
+
+ return Status;
+}
+
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h
new file mode 100644
index 00000000..052cbd5f
--- /dev/null
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.h
@@ -0,0 +1,121 @@
+/******************************************************************************
+ * VtoyShim.h
+ *
+ * Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: BSD-2-Clause-Patent
+ *
+ */
+
+#ifndef __VTOYSHIM_H__
+#define __VTOYSHIM_H__
+
+#if defined (MDE_CPU_IA32)
+#define REAL_GRUB_FILE L"grubia32_real.efi"
+#elif defined (MDE_CPU_X64)
+#define REAL_GRUB_FILE L"grubx64_real.efi"
+#elif defined (MDE_CPU_AARCH64)
+#define REAL_GRUB_FILE L"grubaa64_real.efi"
+#else
+#error "Not supported now"
+#endif
+
+
+/* The following definations are copied from shim source code */
+
+#define SHIM_LOCK_GUID {0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } };
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_VERIFY) (
+ IN VOID *buffer,
+ IN UINT32 size
+ );
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_HASH) (
+ IN char *data,
+ IN int datasize,
+ PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ UINT8 *sha256hash,
+ UINT8 *sha1hash
+ );
+
+typedef
+EFI_STATUS
+(*EFI_SHIM_LOCK_CONTEXT) (
+ IN VOID *data,
+ IN unsigned int datasize,
+ PE_COFF_LOADER_IMAGE_CONTEXT *context
+ );
+
+typedef struct _SHIM_LOCK {
+ EFI_SHIM_LOCK_VERIFY Verify;
+ EFI_SHIM_LOCK_HASH Hash;
+ EFI_SHIM_LOCK_CONTEXT Context;
+} SHIM_LOCK;
+
+
+
+#define SHIM_IMAGE_LOADER_GUID {0x1f492041, 0xfadb, 0x4e59, {0x9e, 0x57, 0x7c, 0xaf, 0xe7, 0x3a, 0x55, 0xab } }
+
+typedef struct _SHIM_IMAGE_LOADER {
+ EFI_IMAGE_LOAD LoadImage;
+ EFI_IMAGE_START StartImage;
+ EFI_EXIT Exit;
+ EFI_IMAGE_UNLOAD UnloadImage;
+} SHIM_IMAGE_LOADER;
+
+typedef VOID (*unhook_system_services_pf)(VOID);
+
+
+/*
+ * The two offset here are extract from the shim file which used in Ventoy.
+ * nm BOOTX64.EFI | grep shim_load_image
+ * nm BOOTX64.EFI | grep unhook_system_services
+ *
+ * It means that they must be updated every time Ventoy update the shim file.
+ *
+ */
+#define NM_SHIM_LOAD_IMAGE_OFFSET 0x2dc12
+#define NM_UNHOOK_SYSTEM_SERVICES_OFFSET 0x2e278
+
+
+
+
+#define VtoySleep(sec) gBS->Stall(1000000 * (sec))
+#define vLog(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__)
+#define vErr(fmt, ...) VtoyLog(fmt "\r\n", ##__VA_ARGS__); VtoySleep(5)
+
+#define CheckFreePool(p) \
+do { \
+ if (p) { \
+ FreePool(p); \
+ (p) = NULL; \
+ }\
+} while (0)
+
+#define CheckBSFreePool(p) \
+do { \
+ if (p) { \
+ gBS->FreePool(p); \
+ (p) = NULL; \
+ }\
+} while (0)
+
+
+
+#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }};
+
+
+typedef VOID (EFIAPI *VTOY_BYPASS_SB)(VOID);
+typedef VOID (EFIAPI *VTOY_CHECK_SB)(VOID);
+typedef struct _VTOY_SHIM{
+ VTOY_BYPASS_SB ByPassSB;
+ VTOY_BYPASS_SB CheckSB;
+} VTOY_SHIM;
+
+CONST UINT8 * ventoy_get_der_data(UINT32 *Len);
+
+#endif
+
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf
new file mode 100644
index 00000000..5ed232bb
--- /dev/null
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/VtoyShim.inf
@@ -0,0 +1,83 @@
+#************************************************************************************
+# Copyright (c) 2026, longpanda
+#
+# 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 3 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, see .
+#
+#************************************************************************************
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = VtoyShim
+ FILE_GUID = 6d7c7406-b32c-461f-8454-ddaa5243d93d
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = VtoyShimEfiMain
+
+[BuildOptions]
+ # Force standard GNU ld to pack and align ELF segments to 4KB page boundaries
+ GCC:*_*_*_DLINK_FLAGS = -Wl,-z,common-page-size=0x1000 -Wl,-z,max-page-size=0x1000
+
+[Sources]
+ VtoyShim.h
+ VtoyShim.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ DevicePathLib
+ DebugLib
+
+[Guids]
+ gEfiGlobalVariableGuid
+ gShellVariableGuid
+ gEfiVirtualCdGuid
+ gEfiFileInfoGuid
+
+[Protocols]
+ gEfiSecurityArchProtocolGuid
+ gEfiSecurity2ArchProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiBlockIoProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiDevicePathToTextProtocolGuid
+ gEfiDevicePathFromTextProtocolGuid
+ gEfiSimpleFileSystemProtocolGuid
+ gEfiRamDiskProtocolGuid
+ gEfiAbsolutePointerProtocolGuid
+ gEfiAcpiTableProtocolGuid
+ gEfiBlockIo2ProtocolGuid
+ gEfiBusSpecificDriverOverrideProtocolGuid
+ gEfiComponentNameProtocolGuid
+ gEfiComponentName2ProtocolGuid
+ gEfiDriverBindingProtocolGuid
+ gEfiDiskIoProtocolGuid
+ gEfiDiskIo2ProtocolGuid
+ gEfiGraphicsOutputProtocolGuid
+ gEfiHiiConfigAccessProtocolGuid
+ gEfiHiiFontProtocolGuid
+ gEfiLoadFileProtocolGuid
+ gEfiLoadFile2ProtocolGuid
+ gEfiLoadedImageProtocolGuid
+ gEfiLoadedImageDevicePathProtocolGuid
+ gEfiPciIoProtocolGuid
+ gEfiSerialIoProtocolGuid
+ gEfiSimpleTextInProtocolGuid
+ gEfiSimpleTextInputExProtocolGuid
+ gEfiSimpleTextOutProtocolGuid
+
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sbat.csv b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sbat.csv
new file mode 100644
index 00000000..6f07aa04
--- /dev/null
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyShim/sbat.csv
@@ -0,0 +1,2 @@
+sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
+ventoy-shim,1,Ventoy,ventoy-shim,1.0,https://www.ventoy.net/
\ No newline at end of file
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c
index 65212c23..f5ff0066 100644
--- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c
@@ -7,12 +7,12 @@
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 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, see .
*
@@ -41,7 +41,7 @@ STATIC CONST CHAR16 *gCurFeature= NULL;
STATIC CHAR16 *gCmdLine = NULL;
STATIC grub_env_printf_pf g_env_printf = NULL;
-STATIC VtoyUtilFeature gFeatureList[] =
+STATIC VtoyUtilFeature gFeatureList[] =
{
{ L"fix_windows_mmap", FixWindowsMemhole },
{ L"show_efi_drivers", ShowEfiDrivers },
@@ -93,7 +93,7 @@ VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...)
}
STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle)
-{
+{
CHAR16 *pPos = NULL;
CHAR16 *pCmdLine = NULL;
EFI_STATUS Status = EFI_SUCCESS;
@@ -117,7 +117,7 @@ STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle)
gST->ConOut->OutputString(gST->ConOut, L"\r\n##########################");
return EFI_SUCCESS;
}
-
+
if (StrStr(pCmdLine, L"debug"))
{
gVtoyDebugPrint = TRUE;
@@ -139,12 +139,38 @@ STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle)
}
gCurFeature = pPos + StrLen(L"feature=");
-
+
gCmdLine = pCmdLine;
-
+
return EFI_SUCCESS;
}
+#if defined (MDE_CPU_X64)
+STATIC BOOLEAN EFIAPI CheckVtoyShim(VOID)
+{
+ UINT8 SecureBoot = 0;
+ UINTN DataSize;
+ EFI_STATUS Status;
+ EFI_GUID Guid = VTOY_SHIM_POLICY_GUID;
+ VOID *Prot = NULL;
+
+ DataSize = sizeof(SecureBoot);
+ Status = gST->RuntimeServices->GetVariable(L"SecureBoot", &gEfiGlobalVariableGuid, NULL,
+ &DataSize, &SecureBoot);
+ if (!EFI_ERROR(Status) && SecureBoot)
+ {
+ Status = gBS->LocateProtocol(&Guid, NULL, (VOID**)&Prot);
+ if (EFI_ERROR(Status))
+ {
+ gST->ConOut->OutputString(gST->ConOut, L"Can not locate Vtoy Shim\r\n");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+#endif
+
EFI_STATUS EFIAPI VtoyUtilEfiMain
(
IN EFI_HANDLE ImageHandle,
@@ -153,7 +179,16 @@ EFI_STATUS EFIAPI VtoyUtilEfiMain
{
UINTN i;
UINTN Len;
-
+
+#if defined (MDE_CPU_X64)
+ /* check that Ventoy Shim must exist */
+ if (!CheckVtoyShim())
+ {
+ gBS->Stall(5 * 1000000);
+ return EFI_NOT_FOUND;
+ }
+#endif
+
ParseCmdline(ImageHandle);
for (i = 0; gCurFeature && i < ARRAY_SIZE(gFeatureList); i++)
@@ -170,7 +205,7 @@ EFI_STATUS EFIAPI VtoyUtilEfiMain
if (gCmdLine)
{
FreePool(gCmdLine);
- gCmdLine = NULL;
+ gCmdLine = NULL;
}
return EFI_SUCCESS;
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h
index f0c9b258..5e228be8 100644
--- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h
@@ -7,20 +7,22 @@
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 3 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, see .
*
*/
-
+
#ifndef __VTOYUTIL_H__
#define __VTOYUTIL_H__
+#define VTOY_SHIM_POLICY_GUID {0x90a29d14, 0x3968, 0x48fe, { 0x85, 0x81, 0x6b, 0x7f, 0x7d, 0xc4, 0x70, 0x55 }};
+
#pragma pack(1)
typedef EFI_STATUS (*VTOY_UTIL_PROC_PF)(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine);
@@ -44,14 +46,14 @@ typedef struct ventoy_grub_param
grub_env_set_pf grub_env_set;
ventoy_grub_param_file_replace file_replace;
ventoy_grub_param_file_replace img_replace[VTOY_MAX_CONF_REPLACE];
- grub_env_printf_pf grub_env_printf;
+ grub_env_printf_pf grub_env_printf;
}ventoy_grub_param;
#pragma pack()
typedef struct VtoyUtilFeature
{
- CONST CHAR16 *Cmd;
+ CONST CHAR16 *Cmd;
VTOY_UTIL_PROC_PF MainProc;
}VtoyUtilFeature;
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf
index c422b7d1..1100c758 100644
--- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf
@@ -23,7 +23,10 @@
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = VtoyUtilEfiMain
-
+
+[BuildOptions]
+ # Force standard GNU ld to pack and align ELF segments to 4KB page boundaries
+ GCC:*_*_*_DLINK_FLAGS = -Wl,-z,common-page-size=0x1000 -Wl,-z,max-page-size=0x1000
[Sources]
VtoyUtil.h
diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc
index c27b6d17..66172f2d 100644
--- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc
+++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc
@@ -205,6 +205,7 @@
[Components]
MdeModulePkg/Application/Ventoy/Ventoy.inf
MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf
+ MdeModulePkg/Application/VtoyShim/VtoyShim.inf
MdeModulePkg/Application/VDiskChain/VDiskChain.inf
MdeModulePkg/Application/HelloWorld/HelloWorld.inf
MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf