diff --git a/.github/workflows/build_common.yml b/.github/workflows/build_common.yml index 99b827b300..23b1cc29f3 100644 --- a/.github/workflows/build_common.yml +++ b/.github/workflows/build_common.yml @@ -135,6 +135,15 @@ jobs: SKIP_TESTS: 1 SKIP_PACKAGE: 1 + - name: Build SecurityPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: SecurityPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + build-windows: name: Windows VS2019 runs-on: windows-latest @@ -249,6 +258,15 @@ jobs: SKIP_TESTS: 1 SKIP_PACKAGE: 1 + - name: Build SecurityPkg + if: always() + run: ./efibuild.sh + env: + SELFPKG: SecurityPkg + ARCHS: IA32,X64 + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + build-linux-clangpdb: name: Linux CLANGPDB runs-on: ubuntu-22.04 @@ -373,6 +391,18 @@ jobs: SKIP_TESTS: 1 SKIP_PACKAGE: 1 + - name: Build SecurityPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: SecurityPkg + SELFPKG_DIR: SecurityPkg + TOOLCHAINS: CLANGPDB + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + build-linux-clangdwarf: name: Linux CLANGDWARF runs-on: ubuntu-22.04 @@ -497,6 +527,18 @@ jobs: SKIP_TESTS: 1 SKIP_PACKAGE: 1 + - name: Build SecurityPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: SecurityPkg + SELFPKG_DIR: SecurityPkg + TOOLCHAINS: CLANGDWARF + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 + build-linux-gcc5: name: Linux GCC runs-on: ubuntu-22.04 @@ -620,3 +662,15 @@ jobs: TARGETS: RELEASE,DEBUG,NOOPT SKIP_TESTS: 1 SKIP_PACKAGE: 1 + + - name: Build SecurityPkg + if: always() + run: docker compose run build-package + env: + SELFPKG: SecurityPkg + SELFPKG_DIR: SecurityPkg + TOOLCHAINS: GCC + ARCHS: IA32,X64 + TARGETS: RELEASE,DEBUG,NOOPT + SKIP_TESTS: 1 + SKIP_PACKAGE: 1 diff --git a/.gitmodules b/.gitmodules index 8186bf1de4..687f0824f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -23,9 +23,6 @@ [submodule "UnitTestFrameworkPkg/Library/GoogleTestLib/googletest"] path = UnitTestFrameworkPkg/Library/GoogleTestLib/googletest url = https://github.com/google/googletest.git -[submodule "UnitTestFrameworkPkg/Library/SubhookLib/subhook"] - path = UnitTestFrameworkPkg/Library/SubhookLib/subhook - url = https://github.com/Zeex/subhook.git [submodule "MdePkg/Library/BaseFdtLib/libfdt"] path = MdePkg/Library/BaseFdtLib/libfdt url = https://github.com/devicetree-org/pylibfdt.git diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py index e7428a7882..3c157d490e 100644 --- a/.pytool/CISettings.py +++ b/.pytool/CISettings.py @@ -230,8 +230,6 @@ def GetRequiredSubmodules(self): "BaseTools/Source/C/BrotliCompress/brotli", False)) rs.append(RequiredSubmodule( "RedfishPkg/Library/JsonLib/jansson", False)) - rs.append(RequiredSubmodule( - "UnitTestFrameworkPkg/Library/SubhookLib/subhook", False)) rs.append(RequiredSubmodule( "MdePkg/Library/BaseFdtLib/libfdt", False)) rs.append(RequiredSubmodule( diff --git a/ArmPkg/Library/CompilerIntrinsicsLib/memset.c b/ArmPkg/Library/CompilerIntrinsicsLib/memset.c index 3e45302fe6..03ddbfe953 100644 --- a/ArmPkg/Library/CompilerIntrinsicsLib/memset.c +++ b/ArmPkg/Library/CompilerIntrinsicsLib/memset.c @@ -29,10 +29,10 @@ __memset ( } // -// Other modules (such as CryptoPkg/IntrinsicLib) may provide another -// implementation of memset(), which may conflict with this one if this -// object was pulled into the link due to the definitions below. So make -// our memset() 'weak' to let the other implementation take precedence. +// Other modules (such as MdePkg/IntrinsicLib, formerly in CryptoPkg) may +// provide another implementation of memset(), which may conflict with this +// one if this object was pulled into the link due to the definitions below. +// So make our memset() 'weak' to let the other implementation take precedence. // __attribute__ ((__weak__, __alias__ ("__memset"))) void * diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc index 2881475b80..02a3d29b82 100644 --- a/ArmVirtPkg/ArmVirt.dsc.inc +++ b/ArmVirtPkg/ArmVirt.dsc.inc @@ -145,7 +145,7 @@ # # CryptoPkg libraries needed by multiple firmware features # - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc index 6a0104a3bb..5644349a2b 100644 --- a/CryptoPkg/CryptoPkg.dsc +++ b/CryptoPkg/CryptoPkg.dsc @@ -109,7 +109,7 @@ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf HashApiLib|CryptoPkg/Library/BaseHashApiLib/BaseHashApiLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64] RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf @@ -373,7 +373,6 @@ CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf CryptoPkg/Library/MbedTlsLib/MbedTlsLibFull.inf CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf - CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf CryptoPkg/Library/TlsLib/TlsLib.inf CryptoPkg/Library/TlsLibNull/TlsLibNull.inf CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf diff --git a/CryptoPkg/CryptoPkgMbedTls.dsc b/CryptoPkg/CryptoPkgMbedTls.dsc index 5d0ae6ff3f..0de6643159 100644 --- a/CryptoPkg/CryptoPkgMbedTls.dsc +++ b/CryptoPkg/CryptoPkgMbedTls.dsc @@ -88,7 +88,7 @@ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf [LibraryClasses.ARM] diff --git a/CryptoPkg/Readme.md b/CryptoPkg/Readme.md index 5a68dfb6ab..e699bd6b6c 100644 --- a/CryptoPkg/Readme.md +++ b/CryptoPkg/Readme.md @@ -267,7 +267,7 @@ TLS services are not typically used in SEC. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SecCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` ### PEI Phase Library Mappings @@ -283,7 +283,7 @@ TlsLib because TLS services are not typically used in PEI. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` If dynamic linking is used, then all PEIMs except CryptoPei use the following @@ -300,7 +300,7 @@ library mappings. The CryptoPei module uses the static linking settings. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf } ``` @@ -318,7 +318,7 @@ OpensslLib instance can be used. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` If dynamic linking is used, then all DXE Drivers except CryptoDxe use the @@ -336,7 +336,7 @@ settings. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibFull.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf } ``` @@ -353,7 +353,7 @@ TlsLib. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` If dynamic linking is used, then all SMM Drivers except CryptoSmm use the @@ -371,7 +371,7 @@ settings. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf } ``` @@ -388,7 +388,7 @@ TlsLib because TLS services are not typically used at runtime. BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf ``` ### PCD Configuration Settings diff --git a/EmulatorPkg/EmulatorPkg.dsc b/EmulatorPkg/EmulatorPkg.dsc index ab1feb3c8f..996cd01612 100644 --- a/EmulatorPkg/EmulatorPkg.dsc +++ b/EmulatorPkg/EmulatorPkg.dsc @@ -127,7 +127,7 @@ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc index f9f26c54bb..ec0f975e5f 100644 --- a/FmpDevicePkg/FmpDevicePkg.dsc +++ b/FmpDevicePkg/FmpDevicePkg.dsc @@ -58,7 +58,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index ba4298f736..9a91f49e7e 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -107,7 +107,7 @@ VariableFlashInfoLib|MdeModulePkg/Library/BaseVariableFlashInfoLib/BaseVariableFlashInfoLib.inf IpmiCommandLib|MdeModulePkg/Library/BaseIpmiCommandLibNull/BaseIpmiCommandLibNull.inf SpiHcPlatformLib|MdeModulePkg/Library/BaseSpiHcPlatformLibNull/BaseSpiHcPlatformLibNull.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf [LibraryClasses.IA32] AmdSvsmLib|UefiCpuPkg/Library/AmdSvsmLibNull/AmdSvsmLibNull.inf diff --git a/CryptoPkg/Library/IntrinsicLib/BaseIntrinsicLib.uni b/MdePkg/Library/IntrinsicLib/BaseIntrinsicLib.uni similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/BaseIntrinsicLib.uni rename to MdePkg/Library/IntrinsicLib/BaseIntrinsicLib.uni diff --git a/CryptoPkg/Library/IntrinsicLib/CopyMem.c b/MdePkg/Library/IntrinsicLib/CopyMem.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/CopyMem.c rename to MdePkg/Library/IntrinsicLib/CopyMem.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivModU64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivS64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivU64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c b/MdePkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathDivU64xU64Rem.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathFtol.c b/MdePkg/Library/IntrinsicLib/Ia32/MathFtol.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathFtol.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathFtol.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm b/MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLShiftS64.nasm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLldiv.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathLldiv.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLldiv.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLldiv.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLlmul.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathLlmul.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLlmul.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLlmul.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathLlshr.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathLlshr.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathLlshr.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathLlshr.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathModU64x64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathModU64x64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathModU64x64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathModU64x64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c b/MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c rename to MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.c diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm b/MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm rename to MdePkg/Library/IntrinsicLib/Ia32/MathRShiftU64.nasm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathUlldiv.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathUlldvrm.asm diff --git a/CryptoPkg/Library/IntrinsicLib/Ia32/MathUllrem.asm b/MdePkg/Library/IntrinsicLib/Ia32/MathUllrem.asm similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/Ia32/MathUllrem.asm rename to MdePkg/Library/IntrinsicLib/Ia32/MathUllrem.asm diff --git a/CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf b/MdePkg/Library/IntrinsicLib/IntrinsicLib.inf similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf rename to MdePkg/Library/IntrinsicLib/IntrinsicLib.inf diff --git a/CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c b/MdePkg/Library/IntrinsicLib/MemoryIntrinsics.c similarity index 100% rename from CryptoPkg/Library/IntrinsicLib/MemoryIntrinsics.c rename to MdePkg/Library/IntrinsicLib/MemoryIntrinsics.c diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 2e792d24b2..71791134c4 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -142,6 +142,8 @@ MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf MdePkg/Library/BaseFdtLib/BaseFdtLib.inf + MdePkg/Library/IntrinsicLib/IntrinsicLib.inf + [Components.IA32, Components.X64, Components.ARM, Components.AARCH64] # # Add UEFI Target Based Unit Tests diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 1a4111dcce..8452f2a0b5 100644 --- a/NetworkPkg/NetworkPkg.dsc +++ b/NetworkPkg/NetworkPkg.dsc @@ -57,7 +57,7 @@ !else BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf !endif DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf diff --git a/NetworkPkg/Test/NetworkPkgHostTest.dsc b/NetworkPkg/Test/NetworkPkgHostTest.dsc index 1772afb058..5d089b93e8 100644 --- a/NetworkPkg/Test/NetworkPkgHostTest.dsc +++ b/NetworkPkg/Test/NetworkPkgHostTest.dsc @@ -71,7 +71,7 @@ FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(TOOL_CHAIN_TAG) == VS2019 or $(TOOL_CHAIN_TAG) == VS2022 [LibraryClasses.X64] diff --git a/OvmfPkg/AmdSev/AmdSevX64.dsc b/OvmfPkg/AmdSev/AmdSevX64.dsc index c525ecac6c..83d3a3e3b5 100644 --- a/OvmfPkg/AmdSev/AmdSevX64.dsc +++ b/OvmfPkg/AmdSev/AmdSevX64.dsc @@ -184,7 +184,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf diff --git a/OvmfPkg/Bhyve/BhyveX64.dsc b/OvmfPkg/Bhyve/BhyveX64.dsc index fdb68f062f..31cfeb58e9 100644 --- a/OvmfPkg/Bhyve/BhyveX64.dsc +++ b/OvmfPkg/Bhyve/BhyveX64.dsc @@ -191,7 +191,7 @@ IoApicLib|PcAtChipsetPkg/Library/BaseIoApicLib/BaseIoApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/CloudHv/CloudHvX64.dsc b/OvmfPkg/CloudHv/CloudHvX64.dsc index 4fb3d9d38b..30ec8bd88c 100644 --- a/OvmfPkg/CloudHv/CloudHvX64.dsc +++ b/OvmfPkg/CloudHv/CloudHvX64.dsc @@ -202,7 +202,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/IntelTdx/IntelTdxX64.dsc b/OvmfPkg/IntelTdx/IntelTdxX64.dsc index 8ec772977b..81b09a00d8 100644 --- a/OvmfPkg/IntelTdx/IntelTdxX64.dsc +++ b/OvmfPkg/IntelTdx/IntelTdxX64.dsc @@ -185,7 +185,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf RngLib|MdeModulePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf diff --git a/OvmfPkg/Microvm/MicrovmX64.dsc b/OvmfPkg/Microvm/MicrovmX64.dsc index 1196ba98c9..2e7c1efb41 100644 --- a/OvmfPkg/Microvm/MicrovmX64.dsc +++ b/OvmfPkg/Microvm/MicrovmX64.dsc @@ -204,7 +204,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index aaaccdbced..028b049569 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -196,7 +196,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index 5aa1eece44..178df662cb 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -201,7 +201,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index aca19de02d..6be16a2d5c 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -216,7 +216,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc index be9d5073f2..49a5e7f2f1 100644 --- a/OvmfPkg/OvmfXen.dsc +++ b/OvmfPkg/OvmfXen.dsc @@ -188,7 +188,7 @@ LocalApicLib|UefiCpuPkg/Library/BaseXApicX2ApicLib/BaseXApicX2ApicLib.inf DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc index dcce4f947f..c6a03afb1e 100644 --- a/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc +++ b/OvmfPkg/RiscVVirt/RiscVVirt.dsc.inc @@ -111,7 +111,7 @@ # # CryptoPkg libraries needed by multiple firmware features # - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf !if $(NETWORK_TLS_ENABLE) == TRUE OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf !else diff --git a/README.md b/README.md index 9720e0e94b..09298631c6 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Available stable branches:
Ext4Pkg, FatPkg: Various improvements based on [Sydr](https://github.com/ispras/oss-sydr-fuzz) fuzzing results
Introduced CpuArchLib to move the CPU Architectural initialization to DxeCore (https://bugzilla.tianocore.org/show_bug.cgi?id=3223)
CI checks not only compilation results of various packages but also boot results of Windows 10 / Linux kernels for OVMF, ArmVirtQemu
+Introduced new image protection policy, which forbids loading of unaligned images
## PE loader designed with formal methods diff --git a/STATUS.md b/STATUS.md index 77589f54ca..c55c07dd37 100644 --- a/STATUS.md +++ b/STATUS.md @@ -61,7 +61,7 @@ | $${\color{lightblue}RedfishPkg/}$$ | | RedfishPkg.dsc | IA32 X64 ARM AARCH64 RISCV64 | DEBUG RELEASE NOOPT | ❓ | ❌ | | $${\color{lightblue}SecurityPkg/}$$ | -| SecurityPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | +| SecurityPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | GCC CLANGDWARF CLANGPDB VS2019 XCODE5 | ❌ | | Test/SecurityPkgHostTest.dsc | IA32 X64 | NOOPT | ❓ | ❌ | | $${\color{lightblue}ShellPkg/}$$ | | ShellPkg.dsc | IA32 X64 EBC ARM AARCH64 RISCV64 LOONGARCH64 | DEBUG RELEASE NOOPT | ❓ | ❌ | diff --git a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf index 5e91968576..11e65bc739 100644 --- a/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf +++ b/SecurityPkg/DeviceSecurity/SpdmLib/SpdmCryptLib.inf @@ -43,3 +43,8 @@ BaseCryptLib RngLib MemLibWrapper + +[BuildOptions] + CLANGPDB:*_*_*_CC_FLAGS = -Wno-non-literal-null-conversion + GCC:*_*_*_CC_FLAGS = -Wno-non-literal-null-conversion + XCODE:*_*_*_CC_FLAGS = -Wno-non-literal-null-conversion diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c index 86cf9b225c..3852025ec4 100644 --- a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmAuthentication.c @@ -136,9 +136,9 @@ ExtendCertificate ( EventLog = NULL; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (BaseHashAlgo); - Status = SpdmGetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &BaseHashAlgo, &DataSize); + Status = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataBaseHashAlgo, &Parameter, &BaseHashAlgo, &DataSize); ASSERT_EFI_ERROR (Status); DeviceContextSize = GetDeviceMeasurementContextSize (SpdmDeviceContext); @@ -520,9 +520,9 @@ DoDeviceCertificate ( SpdmContext = SpdmDeviceContext->SpdmContext; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (CapabilityFlags); - SpdmReturn = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); + SpdmReturn = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR; return EFI_DEVICE_ERROR; @@ -641,9 +641,9 @@ DoDeviceAuthentication ( SpdmContext = SpdmDeviceContext->SpdmContext; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (CapabilityFlags); - SpdmReturn = SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); + SpdmReturn = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { SecurityState->AuthenticationState = EDKII_DEVICE_SECURITY_STATE_ERROR_DEVICE_ERROR; return EFI_DEVICE_ERROR; diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c index d61aa01698..962e906e4e 100644 --- a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmConnectionInit.c @@ -338,8 +338,8 @@ CreateSpdmDeviceContext ( DataSize = DbList->SignatureSize - sizeof (EFI_GUID); ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationLocal; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataPeerPublicRootCert, &Parameter, Data, DataSize); + Parameter.location = (libspdm_data_location_t)SpdmDataLocationLocal; + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataPeerPublicRootCert, &Parameter, Data, DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { if (SpdmReturn == LIBSPDM_STATUS_BUFFER_FULL) { Status = RecordConnectionFailureStatus ( @@ -366,22 +366,22 @@ CreateSpdmDeviceContext ( Data8 = 0; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationLocal; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityCTExponent, &Parameter, &Data8, sizeof (Data8)); + Parameter.location = (libspdm_data_location_t)SpdmDataLocationLocal; + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityCTExponent, &Parameter, &Data8, sizeof (Data8)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; } Data32 = 0; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &Data32, sizeof (Data32)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &Data32, sizeof (Data32)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; } Data8 = SPDM_MEASUREMENT_SPECIFICATION_DMTF; - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataMeasurementSpec, &Parameter, &Data8, sizeof (Data8)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataMeasurementSpec, &Parameter, &Data8, sizeof (Data8)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; @@ -398,7 +398,7 @@ CreateSpdmDeviceContext ( SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; } - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseAsymAlgo, &Parameter, &Data32, sizeof (Data32)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataBaseAsymAlgo, &Parameter, &Data32, sizeof (Data32)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; @@ -412,7 +412,7 @@ CreateSpdmDeviceContext ( SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512; } - SpdmReturn = SpdmSetData (SpdmContext, SpdmDataBaseHashAlgo, &Parameter, &Data32, sizeof (Data32)); + SpdmReturn = SpdmSetData (SpdmContext, (libspdm_data_type_t)SpdmDataBaseHashAlgo, &Parameter, &Data32, sizeof (Data32)); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { ASSERT (FALSE); goto Error; @@ -433,9 +433,9 @@ CreateSpdmDeviceContext ( } ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (Data16); - SpdmReturn = SpdmGetData (SpdmContext, SpdmDataSpdmVersion, &Parameter, &Data16, &DataSize); + SpdmReturn = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataSpdmVersion, &Parameter, &Data16, &DataSize); if (LIBSPDM_STATUS_IS_ERROR (SpdmReturn)) { DEBUG ((DEBUG_ERROR, "SpdmGetData - %p\n", SpdmReturn)); goto Error; diff --git a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c index f94ec1e7bf..3eb33292bd 100644 --- a/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c +++ b/SecurityPkg/DeviceSecurity/SpdmSecurityLib/SpdmMeasurement.c @@ -209,9 +209,9 @@ ExtendMeasurement ( EventLog = NULL; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (MeasurementHashAlgo); - Status = SpdmGetData (SpdmContext, SpdmDataMeasurementHashAlgo, &Parameter, &MeasurementHashAlgo, &DataSize); + Status = SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataMeasurementHashAlgo, &Parameter, &MeasurementHashAlgo, &DataSize); ASSERT_EFI_ERROR (Status); if (MeasurementRecord != NULL) { @@ -531,9 +531,9 @@ DoDeviceMeasurement ( SpdmContext = SpdmDeviceContext->SpdmContext; ZeroMem (&Parameter, sizeof (Parameter)); - Parameter.location = SpdmDataLocationConnection; + Parameter.location = (libspdm_data_location_t)SpdmDataLocationConnection; DataSize = sizeof (CapabilityFlags); - SpdmGetData (SpdmContext, SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); + SpdmGetData (SpdmContext, (libspdm_data_type_t)SpdmDataCapabilityFlags, &Parameter, &CapabilityFlags, &DataSize); if ((CapabilityFlags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == 0) { AuthState = TCG_DEVICE_SECURITY_EVENT_DATA_DEVICE_AUTH_STATE_FAIL_NO_SIG; diff --git a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c index 91101ccd1f..6c82dac66b 100644 --- a/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c +++ b/SecurityPkg/Library/HashLibTpm2/HashLibTpm2.c @@ -59,10 +59,10 @@ Tpm2GetAlgoFromHashMask ( @retval EFI_SUCCESS Hash sequence start and HandleHandle returned. @retval EFI_OUT_OF_RESOURCES No enough resource to start hash. **/ -BOOLEAN +EFI_STATUS EFIAPI HashStart ( - OUT VOID **HashHandle + OUT HASH_HANDLE *HashHandle ) { TPMI_DH_OBJECT SequenceHandle; @@ -72,12 +72,13 @@ HashStart ( AlgoId = Tpm2GetAlgoFromHashMask (); Status = Tpm2HashSequenceStart (AlgoId, &SequenceHandle); - if (!EFI_ERROR (Status)) { - *HashHandle = (VOID *)(UINTN)SequenceHandle; - return TRUE; + if (EFI_ERROR (Status)) { + return Status; } - return FALSE; + *HashHandle = (HASH_HANDLE)SequenceHandle; + + return EFI_SUCCESS; } /** @@ -89,11 +90,11 @@ HashStart ( @retval EFI_SUCCESS Hash sequence updated. **/ -BOOLEAN +EFI_STATUS EFIAPI HashUpdate ( - IN VOID *HashHandle, - IN CONST VOID *DataToHash, + IN HASH_HANDLE HashHandle, + IN VOID *DataToHash, IN UINTN DataToHashLen ) { @@ -108,9 +109,9 @@ HashUpdate ( CopyMem (HashBuffer.buffer, Buffer, sizeof (HashBuffer.buffer)); Buffer += sizeof (HashBuffer.buffer); - Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)(UINTN)HashHandle, &HashBuffer); + Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer); if (EFI_ERROR (Status)) { - return FALSE; + return Status; } } @@ -119,12 +120,12 @@ HashUpdate ( // HashBuffer.size = (UINT16)HashLen; CopyMem (HashBuffer.buffer, Buffer, (UINTN)HashLen); - Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)(UINTN)HashHandle, &HashBuffer); + Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer); if (EFI_ERROR (Status)) { - return FALSE; + return Status; } - return TRUE; + return EFI_SUCCESS; } /** @@ -141,7 +142,7 @@ HashUpdate ( EFI_STATUS EFIAPI HashCompleteAndExtend ( - IN VOID *HashHandle, + IN HASH_HANDLE HashHandle, IN TPMI_DH_PCR PcrIndex, IN VOID *DataToHash, IN UINTN DataToHashLen, @@ -163,7 +164,7 @@ HashCompleteAndExtend ( CopyMem (HashBuffer.buffer, Buffer, sizeof (HashBuffer.buffer)); Buffer += sizeof (HashBuffer.buffer); - Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)(UINTN)HashHandle, &HashBuffer); + Status = Tpm2SequenceUpdate ((TPMI_DH_OBJECT)HashHandle, &HashBuffer); if (EFI_ERROR (Status)) { return EFI_DEVICE_ERROR; } @@ -181,13 +182,13 @@ HashCompleteAndExtend ( if (AlgoId == TPM_ALG_NULL) { Status = Tpm2EventSequenceComplete ( PcrIndex, - (TPMI_DH_OBJECT)(UINTN)HashHandle, + (TPMI_DH_OBJECT)HashHandle, &HashBuffer, DigestList ); } else { Status = Tpm2SequenceComplete ( - (TPMI_DH_OBJECT)(UINTN)HashHandle, + (TPMI_DH_OBJECT)HashHandle, &HashBuffer, &Result ); diff --git a/SecurityPkg/SecurityPkg.dsc b/SecurityPkg/SecurityPkg.dsc index bd27cc95f3..b8822ebfb7 100644 --- a/SecurityPkg/SecurityPkg.dsc +++ b/SecurityPkg/SecurityPkg.dsc @@ -122,7 +122,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf !endif @@ -140,7 +140,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -161,7 +161,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf !endif @@ -173,7 +173,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -192,7 +192,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf !endif diff --git a/SignedCapsulePkg/SignedCapsulePkg.dsc b/SignedCapsulePkg/SignedCapsulePkg.dsc index b363ffb6bb..5db6e45c52 100644 --- a/SignedCapsulePkg/SignedCapsulePkg.dsc +++ b/SignedCapsulePkg/SignedCapsulePkg.dsc @@ -125,7 +125,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf !endif @@ -140,7 +140,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -154,7 +154,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf !endif @@ -177,7 +177,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/SmmCryptLib.inf !endif @@ -189,7 +189,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif @@ -201,7 +201,7 @@ !ifdef CONTINUOUS_INTEGRATION BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf !else - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf !endif diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index c42ba9fb0a..c2b5d5a47b 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -68,7 +68,7 @@ UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf CpuArchLib|UefiCpuPkg/Library/CpuArchLib/CpuArchLib.inf [LibraryClasses.common.SEC] @@ -131,7 +131,7 @@ UefiCpuPkg/MicrocodeMeasurementDxe/MicrocodeMeasurementDxe.inf [Components.IA32] - CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + MdePkg/Library/IntrinsicLib/IntrinsicLib.inf [Components.IA32, Components.X64] UefiCpuPkg/CpuFeatures/CpuFeaturesPei.inf { diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 999e3ab802..a2a00fb7e4 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -214,7 +214,7 @@ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf !endif - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + IntrinsicLib|MdePkg/Library/IntrinsicLib/IntrinsicLib.inf OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf HobLib|UefiPayloadPkg/Library/DxeHobLib/DxeHobLib.inf diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook b/UnitTestFrameworkPkg/Library/SubhookLib/subhook deleted file mode 160000 index 83d4e1ebef..0000000000 --- a/UnitTestFrameworkPkg/Library/SubhookLib/subhook +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83d4e1ebef3588fae48b69a7352cc21801cb70bc diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/.editorconfig b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/.editorconfig new file mode 100644 index 0000000000..8b9ca59445 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/.editorconfig @@ -0,0 +1,10 @@ +# EditorConfig is awesome: http://EditorConfig.org + +root = true + +[*] +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/.travis.yml b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/.travis.yml new file mode 100644 index 0000000000..59fa62da00 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/.travis.yml @@ -0,0 +1,30 @@ +language: c + +os: + - linux + - osx + - freebsd +env: + global: + - CTEST_OUTPUT_ON_FAILURE=ON + matrix: + - ARCH=x86 + - ARCH=x86_64 +addons: + apt: + packages: + - gcc + - g++ + - gcc-multilib + - g++-multilib + - cmake + - yasm +before_install: + - if [ $TRAVIS_OS_NAME == osx ]; then brew install yasm; fi + - if [ $TRAVIS_OS_NAME == freebsd ]; then sudo pkg install -y yasm; fi + +before_script: + - cmake . -DSUBHOOK_FORCE_32BIT=`([ $ARCH = x86 ] && echo 'ON') || echo 'OFF'` +script: + - make + - make test diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/CMakeLists.txt b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/CMakeLists.txt new file mode 100644 index 0000000000..2afd850707 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/CMakeLists.txt @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 3.10) + +project(subhook VERSION 0.8.2 LANGUAGES C) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) + +include(GNUInstallDirs) + +macro(subhook_add_option_var name type default_value description) + set(${name}_DEFAULT ${default_value}) + if(DEFINED ${name}) + set(${name}_DEFAULT ${${name}}) + endif() + set(${name} ${${name}_DEFAULT} CACHE ${type} ${description}) +endmacro() + +subhook_add_option_var(SUBHOOK_STATIC BOOL OFF "Build as a static library") +subhook_add_option_var(SUBHOOK_INSTALL + BOOL ON "Enable installation and packaging of targets/files with CPack") +subhook_add_option_var(SUBHOOK_TESTS BOOL ON "Enable tests") +subhook_add_option_var(SUBHOOK_FORCE_32BIT + BOOL OFF "Configure for compiling 32-bit binaries (on 64-bit systems)") + +set(SUBHOOK_HEADERS subhook.h) +set(SUBHOOK_SOURCES subhook.c subhook_private.h subhook_x86.c) +if(WIN32) + list(APPEND SUBHOOK_SOURCES subhook_windows.c) +elseif(UNIX) + list(APPEND SUBHOOK_SOURCES subhook_unix.c) +endif() + +if(SUBHOOK_STATIC) + add_library(subhook STATIC ${SUBHOOK_HEADERS} ${SUBHOOK_SOURCES}) + target_compile_definitions(subhook PUBLIC SUBHOOK_STATIC) +else() + add_library(subhook SHARED ${SUBHOOK_HEADERS} ${SUBHOOK_SOURCES}) +endif() + +add_library(subhook::subhook ALIAS subhook) + +target_compile_definitions(subhook PUBLIC + SUBHOOK_IMPLEMENTATION + SUBHOOK_SEPARATE_SOURCE_FILES +) +target_include_directories(subhook PUBLIC + $ + $ +) + +if(CMAKE_COMPILER_ID MATCHES GNU OR CMAKE_C_COMPILER_ID MATCHES Clang) + target_compile_options(subhook PRIVATE "-Wall -Wextra") +endif() + +if(SUBHOOK_FORCE_32BIT) + if(APPLE) + set_target_properties(subhook PROPERTIES OSX_ARCHITECTURES i386) + endif() + if(UNIX) + target_compile_options(subhook PRIVATE "-m32") + target_link_options(subhook PRIVATE "-m32") + endif() +endif() + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +if(SUBHOOK_INSTALL) + include(CMakePackageConfigHelpers) + + install(TARGETS subhook EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + install(FILES ${SUBHOOK_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + + set(config_file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake) + set(version_file ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake) + set(config_install_destination lib/cmake/${PROJECT_NAME}) + + configure_package_config_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in + ${config_file} + INSTALL_DESTINATION ${config_install_destination} + ) + + write_basic_package_version_file( + ${version_file} + COMPATIBILITY SameMajorVersion + ) + + install(FILES ${config_file} ${version_file} DESTINATION ${config_install_destination}) + install( + EXPORT ${PROJECT_NAME}Targets + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${config_install_destination} + ) +endif() + +set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) +set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) + +include(CPack) +include(CTest) + +if(BUILD_TESTING AND SUBHOOK_TESTS) + enable_testing() + add_subdirectory(tests) +endif() diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/LICENSE.txt b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/LICENSE.txt new file mode 100644 index 0000000000..67e03821c6 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/LICENSE.txt @@ -0,0 +1,23 @@ +Copyright (c) 2012-2018 Zeex +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/README.md b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/README.md new file mode 100644 index 0000000000..01c905a0c3 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/README.md @@ -0,0 +1,165 @@ +[![Build Status][build_status]][build] +[![Build Status - Windows][build_status_win]][build_win] + +SubHook is a super-simple hooking library for C and C++ that works on Windows, +Linux and macOS. It supports x86 only (32-bit and 64-bit). + +Installation +------------ + +Easy method: + +1. Copy the source and header files to your project and include + [`subhook.c`](subhook.c) in your build. +2. On Windows only: Define `SUBHOOK_STATIC` before including `subhook.h`. + +With CMake: + +1. Copy the subhook repo to your project tree. +2. Call `add_subdirectory(path/to/subhook)` in your CMakeLists.txt. +3. Optional: configure how the library is built by setting these varaible prior + to `add_subdirectory(...)`: + + * `SUBHOOK_STATIC` - Build as static library (`OFF` by default) + * `SUBHOOK_INSTALL` - Enable installation and packaging of targets/files + with CPack (`OFF` by default) + * `SUBHOOK_TESTS` - Enable tests (`ON` by default) + * `SUBHOOK_FORCE_32BIT` - Configure for compiling 32-bit binaries on 64-bit + systems (default is `OFF`) + +Use of CMake is not mandatory, the library can be built without it (no extra +build configuration is required). + +Examples +-------- + +In the following examples `foo` is some function or a function pointer that +takes a single argument of type `int` and uses the same calling convention +as `my_foo` (depends on compiler). + +### Basic usage + +```c +#include +#include + +subhook_t foo_hook; + +void my_foo(int x) { + /* Remove the hook so that you can call the original function. */ + subhook_remove(foo_hook); + + printf("foo(%d) called\n", x); + foo(x); + + /* Install the hook back to intercept further calls. */ + subhook_install(foo_hook); +} + +int main() { + /* Create a hook that will redirect all foo() calls to to my_foo(). */ + foo_hook = subhook_new((void *)foo, (void *)my_foo, 0); + + /* Install it. */ + subhook_install(foo_hook); + + foo(123); + + /* Remove the hook and free memory when you're done. */ + subhook_remove(foo_hook); + subhook_free(foo_hook); +} +``` + +### Trampolines + +Using trampolines allows you to jump to the original code without removing +and re-installing hooks every time your function gets called. + +```c +typedef void (*foo_func)(int x); + +void my_foo(int x) { + printf("foo(%d) called\n", x); + + /* Call foo() via trampoline. */ + ((foo_func)subhook_get_trampoline(foo_hook))(x); +} + +int main() { + /* Same code as in the previous example. */ +} +``` + +Please note that subhook has a very simple length disassmebler engine (LDE) +that works only with most common prologue instructions like push, mov, call, +etc. When it encounters an unknown instruction subhook_get_trampoline() will +return NULL. You can delegate instruction decoding to a custom disassembler +of your choice via `subhook_set_disasm_handler()`. + +### C++ + +```c++ +#include +#include + +subhook::Hook foo_hook; +subhook::Hook foo_hook_tr; + +typedef void (*foo_func)(int x); + +void my_foo(int x) { + // ScopedHookRemove removes the specified hook and automatically re-installs + // it when the object goes out of scope (thanks to C++ destructors). + subhook::ScopedHookRemove remove(&foo_hook); + + std::cout << "foo(" << x << ") called" << std::endl; + foo(x + 1); +} + +void my_foo_tr(int x) { + std::cout << "foo(" << x << ") called" << std::endl; + + // Call the original function via trampoline. + ((foo_func)foo_hook_tr.GetTrampoline())(x + 1); +} + +int main() { + foo_hook.Install((void *)foo, (void *)my_foo); + foo_hook_tr.Install((void *)foo, (void *)my_foo_tr); +} +``` + +Known issues +------------ + +* `subhook_get_trampoline()` may return NULL because only a small subset of + x86 instructions is supported by the disassembler in this library (just + common prologue instructions). As a workaround you can plug in a more + advanced instruction length decoder using `subhook_set_disasm_handler()`. + +* If a target function (the function you are hooking) is less than N bytes + in length, for example if it's a short 2-byte jump to a nearby location + (sometimes compilers generate code like this), then you will not be able + to hook it. + + N is 5 by default: 1 byte for jmp opcode + 4 bytes for offset. But if you + enable the use of 64-bit offsets in 64-bit mode N becomes 14 (see the + definition of `subhook_jmp64`). + +* Some systems protect executable code form being modified at runtime, which + will not allow you to install hooks, or don't allow to mark heap-allocated + memory as executable, which prevents the use of trampolines. + + For example, on Fedora you can have such problems because of SELinux (though + you can disable it or exclude your files). + +License +------- + +Licensed under the 2-clause BSD license. + +[build]: https://travis-ci.org/Zeex/subhook +[build_status]: https://travis-ci.org/Zeex/subhook.svg?branch=master +[build_win]: https://ci.appveyor.com/project/Zeex/subhook/branch/master +[build_status_win]: https://ci.appveyor.com/api/projects/status/q5sp0p8ahuqfh8e4/branch/master?svg=true diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/appveyor.yml b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/appveyor.yml new file mode 100644 index 0000000000..c159d831b3 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/appveyor.yml @@ -0,0 +1,20 @@ +version: '{build}' + +platform: + - x86 + - x64 +configuration: + - Release +environment: + CTEST_OUTPUT_ON_FAILURE: ON + +install: + - choco install -y yasm +before_build: + - if %PLATFORM% == x86 set BUILD_ARCH=Win32 + - if %PLATFORM% == x64 set BUILD_ARCH=x64 + - cmake . -A %BUILD_ARCH% +build_script: + - cmake --build . --config %CONFIGURATION% +test_script: + - ctest --build-config %CONFIGURATION% diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/cmake/Config.cmake.in b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/cmake/Config.cmake.in new file mode 100644 index 0000000000..f83ace570c --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/cmake/Config.cmake.in @@ -0,0 +1,3 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/cmake/FindYasm.cmake b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/cmake/FindYasm.cmake new file mode 100644 index 0000000000..2fcf410b04 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/cmake/FindYasm.cmake @@ -0,0 +1,9 @@ +include(FindPackageHandleStandardArgs) + +find_file(YASM_EXECUTABLE NAMES yasm yasm.exe) +mark_as_advanced(YASM_EXECUTABLE) + +find_package_handle_standard_args(Yasm + FOUND_VAR YASM_FOUND + REQUIRED_VARS YASM_EXECUTABLE +) diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook.c b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook.c new file mode 100644 index 0000000000..8ea7d51d2a --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012-2018 Zeex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include "subhook.h" +#include "subhook_private.h" + +subhook_disasm_handler_t subhook_disasm_handler = NULL; + +SUBHOOK_EXPORT void *SUBHOOK_API subhook_get_src(subhook_t hook) { + if (hook == NULL) { + return NULL; + } + return hook->src; +} + +SUBHOOK_EXPORT void *SUBHOOK_API subhook_get_dst(subhook_t hook) { + if (hook == NULL) { + return NULL; + } + return hook->dst; +} + +SUBHOOK_EXPORT void *SUBHOOK_API subhook_get_trampoline(subhook_t hook) { + if (hook == NULL) { + return NULL; + } + return hook->trampoline; +} + +SUBHOOK_EXPORT int SUBHOOK_API subhook_is_installed(subhook_t hook) { + if (hook == NULL) { + return false; + } + return hook->installed; +} + +SUBHOOK_EXPORT void SUBHOOK_API subhook_set_disasm_handler( + subhook_disasm_handler_t handler) { + subhook_disasm_handler = handler; +} + +#ifndef SUBHOOK_SEPARATE_SOURCE_FILES + +#if defined SUBHOOK_WINDOWS + #include "subhook_windows.c" +#elif defined SUBHOOK_UNIX + #include "subhook_unix.c" +#endif + +#if defined SUBHOOK_X86 || defined SUBHOOK_X86_64 + #include "subhook_x86.c" +#endif + +#endif diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook.h b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook.h new file mode 100644 index 0000000000..5633f39b46 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2012-2018 Zeex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SUBHOOK_H +#define SUBHOOK_H + +#include + +#if defined _M_IX86 || defined __i386__ + #define SUBHOOK_X86 + #define SUBHOOK_BITS 32 +#elif defined _M_AMD64 || __amd64__ + #define SUBHOOK_X86_64 + #define SUBHOOK_BITS 64 +#else + #error Unsupported architecture +#endif + +#if defined _WIN32 || defined __CYGWIN__ + #define SUBHOOK_WINDOWS +#elif defined __linux__ \ + || defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ + #define SUBHOOK_UNIX + #elif defined __APPLE__ + #define SUBHOOK_APPLE + #define SUBHOOK_UNIX +#else + #error Unsupported operating system +#endif + +#if !defined SUBHOOK_EXTERN + #if defined __cplusplus + #define SUBHOOK_EXTERN extern "C" + #else + #define SUBHOOK_EXTERN extern + #endif +#endif + +#if defined SUBHOOK_STATIC + #define SUBHOOK_API + #define SUBHOOK_EXPORT SUBHOOK_EXTERN +#endif + +#if !defined SUBHOOK_API + #if defined SUBHOOK_X86 + #if defined SUBHOOK_WINDOWS + #define SUBHOOK_API __cdecl + #elif defined SUBHOOK_UNIX + #define SUBHOOK_API __attribute__((cdecl)) + #endif + #else + #define SUBHOOK_API + #endif +#endif + +#if !defined SUBHOOK_EXPORT + #if defined SUBHOOK_WINDOWS + #if defined SUBHOOK_IMPLEMENTATION + #define SUBHOOK_EXPORT SUBHOOK_EXTERN __declspec(dllexport) + #else + #define SUBHOOK_EXPORT SUBHOOK_EXTERN __declspec(dllimport) + #endif + #elif defined SUBHOOK_UNIX + #if defined SUBHOOK_IMPLEMENTATION + #define SUBHOOK_EXPORT SUBHOOK_EXTERN __attribute__((visibility("default"))) + #else + #define SUBHOOK_EXPORT SUBHOOK_EXTERN + #endif + #endif +#endif + +typedef enum subhook_flags { + /* Use the 64-bit jump method on x86-64 (requires more space). */ + SUBHOOK_64BIT_OFFSET = 1 +} subhook_flags_t; + +struct subhook_struct; +typedef struct subhook_struct *subhook_t; + +typedef int (SUBHOOK_API *subhook_disasm_handler_t)( + void *src, + int *reloc_op_offset); + +SUBHOOK_EXPORT subhook_t SUBHOOK_API subhook_new( + void *src, + void *dst, + subhook_flags_t flags); +SUBHOOK_EXPORT void SUBHOOK_API subhook_free(subhook_t hook); + +SUBHOOK_EXPORT void *SUBHOOK_API subhook_get_src(subhook_t hook); +SUBHOOK_EXPORT void *SUBHOOK_API subhook_get_dst(subhook_t hook); +SUBHOOK_EXPORT void *SUBHOOK_API subhook_get_trampoline(subhook_t hook); + +SUBHOOK_EXPORT int SUBHOOK_API subhook_install(subhook_t hook); +SUBHOOK_EXPORT int SUBHOOK_API subhook_is_installed(subhook_t hook); +SUBHOOK_EXPORT int SUBHOOK_API subhook_remove(subhook_t hook); + +/* + * Reads hook destination address from code. + * + * This function may be useful when you don't know the address or want to + * check whether src is already hooked. + */ +SUBHOOK_EXPORT void *SUBHOOK_API subhook_read_dst(void *src); + +/* + * Returns the length of the first instruction in src. You can replace it with + * a custom function via subhook_set_disasm_handler. + */ +SUBHOOK_EXPORT int SUBHOOK_API subhook_disasm(void *src, int *reloc_op_offset); + +/* + * Sets a custom disassmbler function to use in place of the default one + * (subhook_disasm). + * + * The default function can recognize only a small subset of x86 instructions + * commonly used in prologues. If it fails in your situation, you might want + * to use a more advanced disassembler library. + */ +SUBHOOK_EXPORT void SUBHOOK_API subhook_set_disasm_handler( + subhook_disasm_handler_t handler); + +#ifdef __cplusplus + +namespace subhook { + +enum HookFlags { + HookNoFlags = 0, + HookFlag64BitOffset = SUBHOOK_64BIT_OFFSET +}; + +inline HookFlags operator|(HookFlags o1, HookFlags o2) { + return static_cast( + static_cast(o1) | static_cast(o2)); +} + +inline HookFlags operator&(HookFlags o1, HookFlags o2) { + return static_cast( + static_cast(o1) & static_cast(o2)); +} + +inline void *ReadHookDst(void *src) { + return subhook_read_dst(src); +} + +inline void SetDisasmHandler(subhook_disasm_handler_t handler) { + subhook_set_disasm_handler(handler); +} + +class Hook { + public: + Hook() : hook_(NULL) {} + Hook(void *src, void *dst, HookFlags flags = HookNoFlags) + : hook_(subhook_new(src, dst, (subhook_flags_t)flags)) + { + } + + ~Hook() { + subhook_remove(hook_); + subhook_free(hook_); + } + + void *GetSrc() const { return subhook_get_src(hook_); } + void *GetDst() const { return subhook_get_dst(hook_); } + void *GetTrampoline() const { return subhook_get_trampoline(hook_); } + + bool Install() { + return subhook_install(hook_) == 0; + } + + bool Install(void *src, + void *dst, + HookFlags flags = HookNoFlags) { + if (hook_ != NULL) { + subhook_remove(hook_); + subhook_free(hook_); + } + hook_ = subhook_new(src, dst, (subhook_flags_t)flags); + if (hook_ == NULL) { + return false; + } + return Install(); + } + + bool Remove() { + return subhook_remove(hook_) == 0; + } + + bool IsInstalled() const { + return !!subhook_is_installed(hook_); + } + + private: + Hook(const Hook &); + void operator=(const Hook &); + + private: + subhook_t hook_; +}; + +class ScopedHookRemove { + public: + ScopedHookRemove(Hook *hook) + : hook_(hook), + removed_(hook_->Remove()) + { + } + + ~ScopedHookRemove() { + if (removed_) { + hook_->Install(); + } + } + + private: + ScopedHookRemove(const ScopedHookRemove &); + void operator=(const ScopedHookRemove &); + + private: + Hook *hook_; + bool removed_; +}; + +class ScopedHookInstall { + public: + ScopedHookInstall(Hook *hook) + : hook_(hook), + installed_(hook_->Install()) + { + } + + ScopedHookInstall(Hook *hook, + void *src, + void *dst, + HookFlags flags = HookNoFlags) + : hook_(hook), + installed_(hook_->Install(src, dst, flags)) + { + } + + ~ScopedHookInstall() { + if (installed_) { + hook_->Remove(); + } + } + + private: + ScopedHookInstall(const ScopedHookInstall &); + void operator=(const ScopedHookInstall &); + + private: + Hook *hook_; + bool installed_; +}; + +} // namespace subhook + +#endif /* __cplusplus */ + +#endif /* SUBHOOK_H */ diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_private.h b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_private.h new file mode 100644 index 0000000000..4b345af69e --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_private.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012-2018 Zeex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef SUBHOOK_PRIVATE_H +#define SUBHOOK_PRIVATE_H + +#include + +#ifndef true + #define true 1 +#endif +#ifndef false + #define false 0 +#endif + +struct subhook_struct { + int installed; + void *src; + void *dst; + subhook_flags_t flags; + void *code; + void *trampoline; + size_t jmp_size; + size_t trampoline_size; + size_t trampoline_len; +}; + +int subhook_unprotect(void *address, size_t size); +void *subhook_alloc_code(size_t size); +int subhook_free_code(void *address, size_t size); + +#endif /* SUBHOOK_PRIVATE_H */ diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_unix.c b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_unix.c new file mode 100644 index 0000000000..697974d181 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_unix.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2012-2018 Zeex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "subhook.h" +#ifdef SUBHOOK_APPLE +#include +#endif + + +#define SUBHOOK_CODE_PROTECT_FLAGS (PROT_READ | PROT_WRITE | PROT_EXEC) + +int subhook_unprotect(void *address, size_t size) { + long pagesize; + + pagesize = sysconf(_SC_PAGESIZE); + void *aligned_address = (void *)((long)address & ~(pagesize - 1)); + + // Fix up the length - since we rounded the start address off, if a jump is right at the + // end of a page we could need to unprotect both. + void *end = address + size; + size_t new_size = end - aligned_address; + + int error = mprotect(aligned_address, new_size, SUBHOOK_CODE_PROTECT_FLAGS); +#ifdef SUBHOOK_APPLE + if (-1 == error) + { + /* If mprotect fails, try to use VM_PROT_COPY with vm_protect. */ + kern_return_t kret = vm_protect(mach_task_self(), (unsigned long)aligned_address, new_size, 0, SUBHOOK_CODE_PROTECT_FLAGS | VM_PROT_COPY); + if (kret != KERN_SUCCESS) + { + error = -1; + } + error = 0; + } +#endif + return error; +} + +void *subhook_alloc_code(size_t size) { + void *address; + + address = mmap(NULL, + size, + SUBHOOK_CODE_PROTECT_FLAGS, + #if defined MAP_32BIT && !defined __APPLE__ + MAP_32BIT | + #endif + MAP_PRIVATE | MAP_ANONYMOUS, + -1, + 0); + return address == MAP_FAILED ? NULL : address; +} + +int subhook_free_code(void *address, size_t size) { + if (address == NULL) { + return 0; + } + return munmap(address, size); +} diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_windows.c b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_windows.c new file mode 100644 index 0000000000..321207e168 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_windows.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2012-2018 Zeex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#define SUBHOOK_CODE_PROTECT_FLAGS PAGE_EXECUTE_READWRITE + +int subhook_unprotect(void *address, size_t size) { + DWORD old_flags; + BOOL result = VirtualProtect(address, + size, + SUBHOOK_CODE_PROTECT_FLAGS, + &old_flags); + return !result; +} + +void *subhook_alloc_code(size_t size) { + return VirtualAlloc(NULL, + size, + MEM_COMMIT | MEM_RESERVE, + SUBHOOK_CODE_PROTECT_FLAGS); +} + +int subhook_free_code(void *address, size_t size) { + (void)size; + + if (address == NULL) { + return 0; + } + return !VirtualFree(address, 0, MEM_RELEASE); +} diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_x86.c b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_x86.c new file mode 100644 index 0000000000..0941be4bfe --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/subhook_x86.c @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2012-2018 Zeex + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include "subhook.h" +#include "subhook_private.h" + +#ifdef SUBHOOK_WINDOWS + #define INT32_MAX 0x7fffffff + #define INT32_MIN (-INT32_MAX - 1) + typedef unsigned __int8 uint8_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + #ifdef SUBHOOK_X86_64 + typedef __int64 intptr_t; + typedef unsigned __int64 uintptr_t; + #else + typedef __int32 intptr_t; + typedef unsigned __int32 uintptr_t; + #endif +#else + #include +#endif + +#define ABS(x) ((x) >= 0 ? (x) : -(x)) +#define MAX_INSN_LEN 15 /* maximum length of x86 instruction */ + +#define JMP_OPCODE 0xE9 +#define PUSH_OPCODE 0x68 +#define MOV_OPCODE 0xC7 +#define RET_OPCODE 0xC3 + +#define JMP64_MOV_MODRM 0x44 /* write to address + 1 byte displacement */ +#define JMP64_MOV_SIB 0x24 /* write to [rsp] */ +#define JMP64_MOV_OFFSET 0x04 + +#define CHECK_INT32_OVERFLOW(x) \ + ((int64_t)(x) < INT32_MIN || ((int64_t)(x)) > INT32_MAX) + +#pragma pack(push, 1) + +struct subhook_jmp32 { + uint8_t opcode; + int32_t offset; +}; + +/* Since AMD64 doesn't support 64-bit direct jumps, we'll push the address + * onto the stack, then call RET. + */ +struct subhook_jmp64 { + uint8_t push_opcode; + uint32_t push_addr; /* lower 32-bits of the address to jump to */ + uint8_t mov_opcode; + uint8_t mov_modrm; + uint8_t mov_sib; + uint8_t mov_offset; + uint32_t mov_addr; /* upper 32-bits of the address to jump to */ + uint8_t ret_opcode; +}; + +#pragma pack(pop) + +extern subhook_disasm_handler_t subhook_disasm_handler; + +SUBHOOK_EXPORT int SUBHOOK_API subhook_disasm(void *src, int *reloc_op_offset) { + enum flags { + MODRM = 1, + PLUS_R = 1 << 1, + REG_OPCODE = 1 << 2, + IMM8 = 1 << 3, + IMM16 = 1 << 4, + IMM32 = 1 << 5, + RELOC = 1 << 6 + }; + + static uint8_t prefixes[] = { + 0xF0, 0xF2, 0xF3, + 0x2E, 0x36, 0x3E, 0x26, 0x64, 0x65, + 0x66, /* operand size override */ + 0x67 /* address size override */ + }; + + struct opcode_info { + uint8_t opcode; + uint8_t reg_opcode; + unsigned int flags; + }; + + /* + * See the Intel Developer Manual volumes 2a and 2b for more information + * about instruction format and encoding: + * + * https://www-ssl.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html + */ + static struct opcode_info opcodes[] = { + /* ADD AL, imm8 */ {0x04, 0, IMM8}, + /* ADD EAX, imm32 */ {0x05, 0, IMM32}, + /* ADD r/m8, imm8 */ {0x80, 0, MODRM | REG_OPCODE | IMM8}, + /* ADD r/m32, imm32 */ {0x81, 0, MODRM | REG_OPCODE | IMM32}, + /* ADD r/m32, imm8 */ {0x83, 0, MODRM | REG_OPCODE | IMM8}, + /* ADD r/m8, r8 */ {0x00, 0, MODRM}, + /* ADD r/m32, r32 */ {0x01, 0, MODRM}, + /* ADD r8, r/m8 */ {0x02, 0, MODRM}, + /* ADD r32, r/m32 */ {0x03, 0, MODRM}, + /* AND AL, imm8 */ {0x24, 0, IMM8}, + /* AND EAX, imm32 */ {0x25, 0, IMM32}, + /* AND r/m8, imm8 */ {0x80, 4, MODRM | REG_OPCODE | IMM8}, + /* AND r/m32, imm32 */ {0x81, 4, MODRM | REG_OPCODE | IMM32}, + /* AND r/m32, imm8 */ {0x83, 4, MODRM | REG_OPCODE | IMM8}, + /* AND r/m8, r8 */ {0x20, 0, MODRM}, + /* AND r/m32, r32 */ {0x21, 0, MODRM}, + /* AND r8, r/m8 */ {0x22, 0, MODRM}, + /* AND r32, r/m32 */ {0x23, 0, MODRM}, + /* CALL rel32 */ {0xE8, 0, IMM32 | RELOC}, + /* CALL r/m32 */ {0xFF, 2, MODRM | REG_OPCODE}, + /* CMP r/m32, imm8 */ {0x83, 7, MODRM | REG_OPCODE | IMM8}, + /* CMP r/m32, r32 */ {0x39, 0, MODRM}, + /* CMP imm16/32 */ {0x3D, 0, IMM32}, + /* DEC r/m32 */ {0xFF, 1, MODRM | REG_OPCODE}, + /* DEC r32 */ {0x48, 0, PLUS_R}, + /* ENTER imm16, imm8 */ {0xC8, 0, IMM16 | IMM8}, + /* FLD m32fp */ {0xD9, 0, MODRM | REG_OPCODE}, + /* FLD m64fp */ {0xDD, 0, MODRM | REG_OPCODE}, + /* FLD m80fp */ {0xDB, 5, MODRM | REG_OPCODE}, + /* INT 3 */ {0xCC, 0, 0}, + /* JMP rel32 */ {0xE9, 0, IMM32 | RELOC}, + /* JMP r/m32 */ {0xFF, 4, MODRM | REG_OPCODE}, + /* LEA r32,m */ {0x8D, 0, MODRM}, + /* LEAVE */ {0xC9, 0, 0}, + /* MOV r/m8,r8 */ {0x88, 0, MODRM}, + /* MOV r/m32,r32 */ {0x89, 0, MODRM}, + /* MOV r8,r/m8 */ {0x8A, 0, MODRM}, + /* MOV r32,r/m32 */ {0x8B, 0, MODRM}, + /* MOV r/m16,Sreg */ {0x8C, 0, MODRM}, + /* MOV Sreg,r/m16 */ {0x8E, 0, MODRM}, + /* MOV AL,moffs8 */ {0xA0, 0, IMM8}, + /* MOV EAX,moffs32 */ {0xA1, 0, IMM32}, + /* MOV moffs8,AL */ {0xA2, 0, IMM8}, + /* MOV moffs32,EAX */ {0xA3, 0, IMM32}, + /* MOV r8, imm8 */ {0xB0, 0, PLUS_R | IMM8}, + /* MOV r32, imm32 */ {0xB8, 0, PLUS_R | IMM32}, + /* MOV r/m8, imm8 */ {0xC6, 0, MODRM | REG_OPCODE | IMM8}, + /* MOV r/m32, imm32 */ {0xC7, 0, MODRM | REG_OPCODE | IMM32}, + /* NOP */ {0x90, 0, 0}, + /* OR AL, imm8 */ {0x0C, 0, IMM8}, + /* OR EAX, imm32 */ {0x0D, 0, IMM32}, + /* OR r/m8, imm8 */ {0x80, 1, MODRM | REG_OPCODE | IMM8}, + /* OR r/m32, imm32 */ {0x81, 1, MODRM | REG_OPCODE | IMM32}, + /* OR r/m32, imm8 */ {0x83, 1, MODRM | REG_OPCODE | IMM8}, + /* OR r/m8, r8 */ {0x08, 0, MODRM}, + /* OR r/m32, r32 */ {0x09, 0, MODRM}, + /* OR r8, r/m8 */ {0x0A, 0, MODRM}, + /* OR r32, r/m32 */ {0x0B, 0, MODRM}, + /* POP r/m32 */ {0x8F, 0, MODRM | REG_OPCODE}, + /* POP r32 */ {0x58, 0, PLUS_R}, + /* PUSH r/m32 */ {0xFF, 6, MODRM | REG_OPCODE}, + /* PUSH r32 */ {0x50, 0, PLUS_R}, + /* PUSH imm8 */ {0x6A, 0, IMM8}, + /* PUSH imm32 */ {0x68, 0, IMM32}, + /* RET */ {0xC3, 0, 0}, + /* RET imm16 */ {0xC2, 0, IMM16}, + /* SUB AL, imm8 */ {0x2C, 0, IMM8}, + /* SUB EAX, imm32 */ {0x2D, 0, IMM32}, + /* SUB r/m8, imm8 */ {0x80, 5, MODRM | REG_OPCODE | IMM8}, + /* SUB r/m32, imm32 */ {0x81, 5, MODRM | REG_OPCODE | IMM32}, + /* SUB r/m32, imm8 */ {0x83, 5, MODRM | REG_OPCODE | IMM8}, + /* SUB r/m8, r8 */ {0x28, 0, MODRM}, + /* SUB r/m32, r32 */ {0x29, 0, MODRM}, + /* SUB r8, r/m8 */ {0x2A, 0, MODRM}, + /* SUB r32, r/m32 */ {0x2B, 0, MODRM}, + /* TEST AL, imm8 */ {0xA8, 0, IMM8}, + /* TEST EAX, imm32 */ {0xA9, 0, IMM32}, + /* TEST r/m8, imm8 */ {0xF6, 0, MODRM | REG_OPCODE | IMM8}, + /* TEST r/m32, imm32 */ {0xF7, 0, MODRM | REG_OPCODE | IMM32}, + /* TEST r/m8, r8 */ {0x84, 0, MODRM}, + /* TEST r/m32, r32 */ {0x85, 0, MODRM}, + /* XOR AL, imm8 */ {0x34, 0, IMM8}, + /* XOR EAX, imm32 */ {0x35, 0, IMM32}, + /* XOR r/m8, imm8 */ {0x80, 6, MODRM | REG_OPCODE | IMM8}, + /* XOR r/m32, imm32 */ {0x81, 6, MODRM | REG_OPCODE | IMM32}, + /* XOR r/m32, imm8 */ {0x83, 6, MODRM | REG_OPCODE | IMM8}, + /* XOR r/m8, r8 */ {0x30, 0, MODRM}, + /* XOR r/m32, r32 */ {0x31, 0, MODRM}, + /* XOR r8, r/m8 */ {0x32, 0, MODRM}, + /* XOR r32, r/m32 */ {0x33, 0, MODRM} + }; + + uint8_t *code = src; + size_t i; + int len = 0; + int operand_size = 4; + uint8_t opcode = 0; + int found_opcode = false; + + for (i = 0; i < sizeof(prefixes) / sizeof(*prefixes); i++) { + if (code[len] == prefixes[i]) { + len++; + if (prefixes[i] == 0x66) { + operand_size = 2; + } + } + } + +#ifdef SUBHOOK_X86_64 + if ((code[len] & 0xF0) == 0x40) { + /* This is a REX prefix (40H - 4FH). REX prefixes are valid only in + * 64-bit mode. + */ + uint8_t rex = code[len++]; + + if (rex & 8) { + /* REX.W changes size of immediate operand to 64 bits. */ + operand_size = 8; + } + } +#endif + + for (i = 0; i < sizeof(opcodes) / sizeof(*opcodes); i++) { + if (code[len] == opcodes[i].opcode) { + if (opcodes[i].flags & REG_OPCODE) { + found_opcode = ((code[len + 1] >> 3) & 7) == opcodes[i].reg_opcode; + } else { + found_opcode = true; + } + } + + if ((opcodes[i].flags & PLUS_R) + && (code[len] & 0xF8) == opcodes[i].opcode) { + found_opcode = true; + } + + if (found_opcode) { + opcode = code[len++]; + break; + } + } + + if (!found_opcode) { + return 0; + } + + if (reloc_op_offset != NULL && opcodes[i].flags & RELOC) { + /* Either a call or a jump instruction that uses an absolute or relative + * 32-bit address. + * + * Note: We don't support short (8-bit) offsets at the moment, so the + * caller can assume the operand will be always 4 bytes. + */ + *reloc_op_offset = len; + } + + if (opcodes[i].flags & MODRM) { + uint8_t modrm = code[len++]; /* +1 for Mod/RM byte */ + uint8_t mod = modrm >> 6; + uint8_t rm = modrm & 0x07; + + if (mod != 3 && rm == 4) { + uint8_t sib = code[len++]; /* +1 for SIB byte */ + uint8_t base = sib & 0x07; + + if (base == 5) { + /* The SIB is followed by a disp32 with no base if the MOD is 00B. + * Otherwise, disp8 or disp32 + [EBP]. + */ + if (mod == 1) { + len += 1; /* for disp8 */ + } else { + len += 4; /* for disp32 */ + } + } + } + +#ifdef SUBHOOK_X86_64 + if (reloc_op_offset != NULL && mod == 0 && rm == 5) { + /* RIP-relative addressing: target is at [RIP + disp32]. */ + *reloc_op_offset = (int32_t)len; + } +#endif + + if (mod == 1) { + len += 1; /* for disp8 */ + } + if (mod == 2 || (mod == 0 && rm == 5)) { + len += 4; /* for disp32 */ + } + } + + if (opcodes[i].flags & IMM8) { + len += 1; + } + if (opcodes[i].flags & IMM16) { + len += 2; + } + if (opcodes[i].flags & IMM32) { + len += operand_size; + } + + return len; +} + +static size_t subhook_get_jmp_size(subhook_flags_t flags) { +#ifdef SUBHOOK_X86_64 + if ((flags & SUBHOOK_64BIT_OFFSET) != 0) { + return sizeof(struct subhook_jmp64); + } +#else + (void)flags; +#endif + return sizeof(struct subhook_jmp32); +} + +static int subhook_make_jmp32(void *src, void *dst) { + struct subhook_jmp32 *jmp = (struct subhook_jmp32 *)src; + intptr_t src_addr = (intptr_t)src; + intptr_t dst_addr = (intptr_t)dst; +#ifdef SUBHOOK_X86_64 + int64_t distance = ABS(src_addr - dst_addr); +#endif + +#ifdef SUBHOOK_X86_64 + if (CHECK_INT32_OVERFLOW(distance)) { + return -EOVERFLOW; + } +#endif + + jmp->opcode = JMP_OPCODE; + jmp->offset = (int32_t)(dst_addr - (src_addr + sizeof(*jmp))); + + return 0; +} + +#ifdef SUBHOOK_X86_64 + +static int subhook_make_jmp64(void *src, void *dst) { + struct subhook_jmp64 *jmp = (struct subhook_jmp64 *)src; + + jmp->push_opcode = PUSH_OPCODE; + jmp->push_addr = (uint32_t)(uintptr_t)dst; /* truncate */ + jmp->mov_opcode = MOV_OPCODE; + jmp->mov_modrm = JMP64_MOV_MODRM; + jmp->mov_sib = JMP64_MOV_SIB; + jmp->mov_offset = JMP64_MOV_OFFSET; + jmp->mov_addr = (uint32_t)(((uintptr_t)dst) >> 32); + jmp->ret_opcode = RET_OPCODE; + + return 0; +} + +#endif + +static int subhook_make_jmp(void *src, + void *dst, + subhook_flags_t flags) { +#ifdef SUBHOOK_X86_64 + if ((flags & SUBHOOK_64BIT_OFFSET) != 0) { + return subhook_make_jmp64(src, dst); + } +#else + (void)flags; +#endif + return subhook_make_jmp32(src, dst); +} + +static int subhook_make_trampoline(void *trampoline, + void *src, + size_t jmp_size, + size_t *trampoline_len, + subhook_flags_t flags) { + size_t orig_size = 0; + size_t insn_len; + intptr_t trampoline_addr = (intptr_t)trampoline; + intptr_t src_addr = (intptr_t)src; + subhook_disasm_handler_t disasm_handler = + subhook_disasm_handler != NULL ? subhook_disasm_handler : subhook_disasm; + + assert(trampoline_len != NULL); + + /* Determine how many bytes of original code needs to be copied over + * to the trampoline. + */ + while (orig_size < jmp_size) { + int reloc_op_offset = 0; + + insn_len = + disasm_handler((void *)(src_addr + orig_size), &reloc_op_offset); + + if (insn_len == 0) { + return -EINVAL; + } + + /* Copy this instruction to the trampoline. + */ + memcpy((void *)(trampoline_addr + orig_size), + (void *)(src_addr + orig_size), + insn_len); + + /* If the operand is a relative address, such as found in calls or jumps, + * it needs to be relocated because the original code and the trampoline + * reside at different locations in memory. + */ + if (reloc_op_offset > 0) { + /* Calculate how far our trampoline is from the source and change the + * address accordingly. + */ + intptr_t offset = trampoline_addr - src_addr; +#ifdef SUBHOOK_X86_64 + if (CHECK_INT32_OVERFLOW(offset)) { + /* + * Oops! It looks like the two locations are too far away from each + * other! This is not going to work... + */ + *trampoline_len = 0; + return -EOVERFLOW; + } +#endif + int32_t *op = (int32_t *)(trampoline_addr + orig_size + reloc_op_offset); + *op -= (int32_t)offset; + } + + orig_size += insn_len; + } + + *trampoline_len = orig_size + jmp_size; + + /* Insert the final jump. It goes back to the original code at + * src + orig_size. + */ + return subhook_make_jmp((void *)(trampoline_addr + orig_size), + (void *)(src_addr + orig_size), + flags); +} + +SUBHOOK_EXPORT subhook_t SUBHOOK_API subhook_new(void *src, + void *dst, + subhook_flags_t flags) { + subhook_t hook; + int error; + + hook = calloc(1, sizeof(*hook)); + if (hook == NULL) { + return NULL; + } + + hook->src = src; + hook->dst = dst; + hook->flags = flags; + hook->jmp_size = subhook_get_jmp_size(hook->flags); + hook->trampoline_size = hook->jmp_size * 2 + MAX_INSN_LEN; + + hook->code = malloc(hook->jmp_size); + if (hook->code == NULL) { + goto error_exit; + } + + memcpy(hook->code, hook->src, hook->jmp_size); + + error = subhook_unprotect(hook->src, hook->jmp_size); + if (error != 0) { + goto error_exit; + } + + hook->trampoline = subhook_alloc_code(hook->trampoline_size); + if (hook->trampoline != NULL) { + error = subhook_make_trampoline(hook->trampoline, + hook->src, + hook->jmp_size, + &hook->trampoline_len, + hook->flags); + if (error != 0) { + subhook_free_code(hook->trampoline, hook->trampoline_size); + hook->trampoline = NULL; + hook->trampoline_size = 0; + hook->trampoline_len = 0; + } + } + + return hook; + +error_exit: + subhook_free_code(hook->trampoline, hook->trampoline_size); + free(hook->code); + free(hook); + + return NULL; +} + +SUBHOOK_EXPORT void SUBHOOK_API subhook_free(subhook_t hook) { + if (hook == NULL) { + return; + } + + subhook_free_code(hook->trampoline, hook->trampoline_size); + free(hook->code); + free(hook); +} + +SUBHOOK_EXPORT int SUBHOOK_API subhook_install(subhook_t hook) { + int error; + + if (hook == NULL) { + return -EINVAL; + } + if (hook->installed) { + return -EINVAL; + } + + error = subhook_make_jmp(hook->src, hook->dst, hook->flags); + if (error >= 0) { + hook->installed = true; + return 0; + } + + return error; +} + +SUBHOOK_EXPORT int SUBHOOK_API subhook_remove(subhook_t hook) { + if (hook == NULL) { + return -EINVAL; + } + if (!hook->installed) { + return -EINVAL; + } + + memcpy(hook->src, hook->code, hook->jmp_size); + hook->installed = 0; + + return 0; +} + +SUBHOOK_EXPORT void *SUBHOOK_API subhook_read_dst(void *src) { + struct subhook_jmp32 *maybe_jmp32 = (struct subhook_jmp32 *)src; +#ifdef SUBHOOK_X86_64 + struct subhook_jmp64 *maybe_jmp64 = (struct subhook_jmp64 *)src; +#endif + + if (maybe_jmp32->opcode == JMP_OPCODE) { + return (void *)( + maybe_jmp32->offset + (uintptr_t)src + sizeof(*maybe_jmp32)); + } + +#ifdef SUBHOOK_X86_64 + if (maybe_jmp64->push_opcode == PUSH_OPCODE + && maybe_jmp64->mov_opcode == MOV_OPCODE + && maybe_jmp64->mov_modrm == JMP64_MOV_MODRM + && maybe_jmp64->mov_sib == JMP64_MOV_SIB + && maybe_jmp64->mov_offset == JMP64_MOV_OFFSET + && maybe_jmp64->ret_opcode == RET_OPCODE) { + return (void *)( + maybe_jmp64->push_addr & ((uintptr_t)maybe_jmp64->mov_addr << 32)); + } +#endif + + return NULL; +} diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/CMakeLists.txt b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/CMakeLists.txt new file mode 100644 index 0000000000..41cbb24901 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/CMakeLists.txt @@ -0,0 +1,103 @@ +find_package(Yasm REQUIRED) + +if (CMAKE_SIZEOF_VOID_P EQUAL 4 OR SUBHOOK_FORCE_32BIT) + set(BITS 32) +else() + set(BITS 64) +endif() + +set(asm_file foo_${BITS}.asm) +if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT SUBHOOK_FORCE_32BIT) + if(WIN32) + set(asm_file foo_64_win.asm) + elseif(UNIX) + set(asm_file foo_64_unix.asm) + set(asm_obj_file ${asm_file}.o) + endif() +endif() +if(NOT asm_obj_file) + set(asm_obj_file ${asm_file}.obj) +endif() + +if(WIN32) + set(asm_format "win${BITS}") +elseif(APPLE) + set(asm_format "macho${BITS}") +else() + set(asm_format "elf${BITS}") +endif() + +set(options "-f" "${asm_format}") +if(APPLE OR (WIN32 AND (CMAKE_SIZEOF_VOID_P EQUAL 4 OR SUBHOOK_FORCE_32BIT))) + list(APPEND options "--prefix=_") +endif() +if(CMAKE_SYSTEM_NAME MATCHES "Linux") + list(APPEND options "-DUSE_PLT") +endif() + +add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${asm_obj_file}" + COMMAND "${YASM_EXECUTABLE}" ${options} "-o" + "${CMAKE_CURRENT_BINARY_DIR}/${asm_obj_file}" + "${CMAKE_CURRENT_SOURCE_DIR}/${asm_file}" + MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/${asm_file}" +) + +add_executable(subhook_test_exe + test.c + "${CMAKE_CURRENT_BINARY_DIR}/${asm_obj_file}" +) +set_target_properties(subhook_test_exe PROPERTIES OUTPUT_NAME test) + +enable_language(CXX) +add_executable(subhook_cxx_test_exe + test.cpp + "${CMAKE_CURRENT_BINARY_DIR}/${asm_obj_file}" +) +set_target_properties(subhook_cxx_test_exe PROPERTIES OUTPUT_NAME test++) + +foreach(target subhook_test_exe subhook_cxx_test_exe) + if(SUBHOOK_FORCE_32BIT) + if(APPLE) + set_target_properties(${target} PROPERTIES OSX_ARCHITECTURES i386) + endif() + if(UNIX) + set_property(TARGET ${target} APPEND_STRING PROPERTY + COMPILE_FLAGS " -m32") + set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " -m32") + endif() + endif() + + target_link_libraries(${target} subhook) + + if(MSVC) + set_property(TARGET ${target} + APPEND_STRING PROPERTY LINK_FLAGS " /INCREMENTAL:NO") + endif() + + if(APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT SUBHOOK_FORCE_32BIT) + set_property(TARGET ${target} APPEND_STRING PROPERTY + LINK_FLAGS " -Wl,-no_pie") + endif() + + add_test(NAME ${target}_test COMMAND $) + + set(expected_output +"Testing initial install +foo_hooked\\(\\) called +foo\\(\\) called +Testing re-install +foo_hooked\\(\\) called +foo\\(\\) called +Testing trampoline +foo_hooked_tr\\(\\) called +foo\\(\\) called +") + set_tests_properties(${target}_test PROPERTIES + PASS_REGULAR_EXPRESSION "${expected_output}") + + if(WIN32 AND NOT SUBHOOK_STATIC) + set_tests_properties(${target}_test PROPERTIES + ENVIRONMENT PATH=$) + endif() +endforeach() diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo.cpp b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo.cpp new file mode 100644 index 0000000000..c3e7def921 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo.cpp @@ -0,0 +1,5 @@ +#include + +extern "C" void foo() { + puts("foo() called"); +} diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_32.asm b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_32.asm new file mode 100644 index 0000000000..f1de5b31d3 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_32.asm @@ -0,0 +1,31 @@ +extern puts +global foo + +section .rodata + +message: + db 'foo() called', 0 + +section .text + +;; Long nop macros for nasm/yasm borrowed from nasm-utils: +;; https://github.com/travisdowns/nasm-utils +%define nop1 nop ; just a nop, included for completeness +%define nop2 db 0x66, 0x90 ; 66 NOP +%define nop3 db 0x0F, 0x1F, 0x00 ; NOP DWORD ptr [EAX] +%define nop4 db 0x0F, 0x1F, 0x40, 0x00 ; NOP DWORD ptr [EAX + 00H] +%define nop5 db 0x0F, 0x1F, 0x44, 0x00, 0x00 ; NOP DWORD ptr [EAX + EAX*1 + 00H] +%define nop6 db 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 ; 66 NOP DWORD ptr [EAX + EAX*1 + 00H] +%define nop7 db 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 ; NOP DWORD ptr [EAX + 00000000H] +%define nop8 db 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 ; NOP DWORD ptr [EAX + EAX*1 + 00000000H] +%define nop9 db 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 ; 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] + +foo: + push ebp + mov ebp, esp + sub esp, 4 ; align the stack to a 16-byte boundary + push message + call puts + mov esp, ebp + pop ebp + ret diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_64_unix.asm b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_64_unix.asm new file mode 100644 index 0000000000..e91767a469 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_64_unix.asm @@ -0,0 +1,24 @@ +bits 64 + +extern puts +global foo + +section .data + +message: + db 'foo() called', 0 + +section .text + +foo: + nop + push rbp + mov rbp, rsp + lea rdi, [rel message] + %ifdef USE_PLT + call puts wrt ..plt + %else + call puts + %endif + pop rbp + ret diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_64_win.asm b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_64_win.asm new file mode 100644 index 0000000000..e628aa2d43 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_64_win.asm @@ -0,0 +1,22 @@ +bits 64 + +extern puts +global foo + +section .data + +message: + db 'foo() called', 0 + +section .text + +foo: + nop + push rbp + mov rbp, rsp + sub rsp, 32 + mov rcx, qword message + call puts + add rsp, 32 + pop rbp + ret diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_main.c b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_main.c new file mode 100644 index 0000000000..a26e671f1a --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_main.c @@ -0,0 +1,6 @@ +extern void foo(void); + +int main() { + foo(); + return 0; +} diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_main.cpp b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_main.cpp new file mode 100644 index 0000000000..b49a3ccae1 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/foo_main.cpp @@ -0,0 +1,6 @@ +extern "C" void foo(void); + +int main() { + foo(); + return 0; +} diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/test.c b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/test.c new file mode 100644 index 0000000000..d8b39fda69 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/test.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include + +typedef void (*foo_func_t)(void); + +#ifdef SUBHOOK_X86 + #if defined SUBHOOK_WINDOWS + #define FOO_CALL __cdecl + #elif defined SUBHOOK_UNIX + #define FOO_CALL __attribute__((cdecl)) + #endif +#endif +#ifndef FOO_CALL + #define FOO_CALL +#endif + +extern void FOO_CALL foo(void); +foo_func_t foo_tr = NULL; + +void foo_hooked(void) { + puts("foo_hooked() called"); +} + +void foo_hooked_tr(void) { + puts("foo_hooked_tr() called"); + foo_tr(); +} + +int main() { + puts("Testing initial install"); + + subhook_t foo_hook = subhook_new((void *)foo, + (void *)foo_hooked, + SUBHOOK_64BIT_OFFSET); + if (foo_hook == NULL || subhook_install(foo_hook) < 0) { + puts("Install failed"); + return EXIT_FAILURE; + } + foo(); + if (subhook_remove(foo_hook) < 0) { + puts("Remove failed"); + return EXIT_FAILURE; + } + foo(); + + puts("Testing re-install"); + + if (subhook_install(foo_hook) < 0) { + puts("Install failed"); + return EXIT_FAILURE; + } + foo(); + if (subhook_remove(foo_hook) < 0) { + puts("Remove failed"); + return EXIT_FAILURE; + } + foo(); + + subhook_free(foo_hook); + + puts("Testing trampoline"); + + subhook_t foo_hook_tr = subhook_new((void *)foo, + (void *)foo_hooked_tr, + SUBHOOK_64BIT_OFFSET); + if (subhook_install(foo_hook_tr) < 0) { + puts("Install failed"); + return EXIT_FAILURE; + } + foo_tr = (foo_func_t)subhook_get_trampoline(foo_hook_tr); + if (foo_tr == NULL) { + puts("Failed to build trampoline"); + return EXIT_FAILURE; + } + foo(); + + subhook_free(foo_hook_tr); + + return EXIT_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/test.cpp b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/test.cpp new file mode 100644 index 0000000000..7ba167ad99 --- /dev/null +++ b/UnitTestFrameworkPkg/Library/SubhookLib/subhook/tests/test.cpp @@ -0,0 +1,77 @@ +#include +#include +#include + +typedef void (*foo_func_t)(); + +#ifdef SUBHOOK_X86 + #if defined SUBHOOK_WINDOWS + #define FOO_CALL __cdecl + #elif defined SUBHOOK_UNIX + #define FOO_CALL __attribute__((cdecl)) + #endif +#endif +#ifndef FOO_CALL + #define FOO_CALL +#endif + +extern "C" void FOO_CALL foo(); +foo_func_t foo_tr = 0; + +void foo_hooked() { + std::cout << "foo_hooked() called" << std::endl;; +} + +void foo_hooked_tr() { + std::cout << "foo_hooked_tr() called" << std::endl; + foo_tr(); +} + +int main() { + std::cout << "Testing initial install" << std::endl; + + subhook::Hook foo_hook((void *)foo, + (void *)foo_hooked, + subhook::HookFlag64BitOffset); + if (!foo_hook.Install()) { + std::cout << "Install failed" << std::endl; + return EXIT_FAILURE; + } + foo(); + if (!foo_hook.Remove()) { + std::cout << "Remove failed" << std::endl; + return EXIT_FAILURE; + } + foo(); + + std::cout << "Testing re-install" << std::endl; + + if (!foo_hook.Install()) { + std::cout << "Install failed" << std::endl; + return EXIT_FAILURE; + } + foo(); + if (!foo_hook.Remove()) { + std::cout << "Remove failed" << std::endl; + return EXIT_FAILURE; + } + foo(); + + std::cout << "Testing trampoline" << std::endl; + + subhook::Hook foo_hook_tr((void *)foo, + (void *)foo_hooked_tr, + subhook::HookFlag64BitOffset); + if (!foo_hook_tr.Install()) { + std::cout << "Install failed" << std::endl; + return EXIT_FAILURE; + } + foo_tr = (foo_func_t)foo_hook_tr.GetTrampoline(); + if (foo_tr == 0) { + std::cout << "Failed to build trampoline" << std::endl; + return EXIT_FAILURE; + } + foo(); + + return EXIT_SUCCESS; +}