From f323be45e2d8d505df5af001288bd3b5aebadfa6 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Fri, 3 Apr 2020 18:58:54 +0300 Subject: [PATCH] MmapDump: Initial version of MMAP dumping utility --- Application/MmapDump/MmapDump.c | 101 ++++++++++++++++ Application/MmapDump/MmapDump.inf | 52 ++++++++ Include/Library/OcMemoryLib.h | 34 ++++-- Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c | 2 +- Library/OcMemoryLib/MemoryMap.c | 111 ++++++++++++------ OpenCorePkg.dsc | 1 + macbuild.tool | 1 + 7 files changed, 258 insertions(+), 44 deletions(-) create mode 100644 Application/MmapDump/MmapDump.c create mode 100644 Application/MmapDump/MmapDump.inf diff --git a/Application/MmapDump/MmapDump.c b/Application/MmapDump/MmapDump.c new file mode 100644 index 00000000..9191967f --- /dev/null +++ b/Application/MmapDump/MmapDump.c @@ -0,0 +1,101 @@ +/** @file + Dump memory map and memory attributes. + +Copyright (c) 2020, vit9696. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + OC_FIRMWARE_RUNTIME_PROTOCOL *FwRuntime; + EFI_PHYSICAL_ADDRESS Address; + UINTN Pages; + UINTN MemoryMapSize; + UINTN OriginalSize; + UINTN DescriptorSize; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + + Address = 0; + Status = gBS->LocateProtocol (&gOcFirmwareRuntimeProtocolGuid, NULL, (VOID **) &FwRuntime); + if (!EFI_ERROR (Status) && FwRuntime->Revision == OC_FIRMWARE_RUNTIME_REVISION) { + Status = FwRuntime->GetExecArea (&Address, &Pages); + DEBUG (( + DEBUG_WARN, + "MMDD: OpenRuntime r%u resides at %X - %r\n", + (UINT32) FwRuntime->Revision, + (UINT32) Address, + Status + )); + } else if (FwRuntime->Revision != OC_FIRMWARE_RUNTIME_REVISION) { + DEBUG (( + DEBUG_WARN, + "MMDD: OpenRuntime has unexpected revision r%u instead of r%u\n", + (UINT32) FwRuntime->Revision, + (UINT32) OC_FIRMWARE_RUNTIME_REVISION + )); + } else { + DEBUG (( + DEBUG_WARN, + "MMDD: OpenRuntime is missing - %r\n", + Status + )); + } + + DEBUG (( + DEBUG_WARN, + "MMDD: Note, that DEBUG version of the tool prints more\n" + )); + + OcPrintMemoryAttributesTable (); + + MemoryMap = OcGetCurrentMemoryMap ( + &MemoryMapSize, + &DescriptorSize, + NULL, + NULL, + &OriginalSize, + TRUE + ); + + if (MemoryMap != NULL) { + DEBUG ((DEBUG_INFO, "MMDD: Dumping the original memory map\n")); + OcPrintMemoryMap (MemoryMapSize, MemoryMap, DescriptorSize); + DEBUG ((DEBUG_INFO, "MMDD: Dumping patched memory map\n")); + OcUpdateAttributes (Address, EfiRuntimeServicesCode, EFI_MEMORY_RO, EFI_MEMORY_XP); + Status = OcSplitMemoryMapByAttributes (OriginalSize, &MemoryMapSize, MemoryMap, DescriptorSize); + if (!EFI_ERROR (Status)) { + OcPrintMemoryMap (MemoryMapSize, MemoryMap, DescriptorSize); + } else { + DEBUG ((DEBUG_INFO, "MMDD: Cannot patch memory map - %r\n", Status)); + } + } else { + DEBUG ((DEBUG_INFO, "MMDD: Unable to obtain memory map\n")); + } + + gBS->Stall (SECONDS_TO_MICROSECONDS (3)); + + return EFI_SUCCESS; +} diff --git a/Application/MmapDump/MmapDump.inf b/Application/MmapDump/MmapDump.inf new file mode 100644 index 00000000..13e5ca0e --- /dev/null +++ b/Application/MmapDump/MmapDump.inf @@ -0,0 +1,52 @@ +## @file +# Dump memory map and memory attributes. +# +# Copyright (c) 2018, vit9696. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MmapDump + FILE_GUID = 932C885D-D6CA-408E-B482-90A582212F30 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = UefiMain + +# +# This flag specifies whether HII resource section is generated into PE image. +# + UEFI_HII_RESOURCE_SECTION = TRUE + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + MmapDump.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + OpenCorePkg/OpenCorePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[Protocols] + gOcFirmwareRuntimeProtocolGuid ## CONSUMES + +[LibraryClasses] + OcConsoleControlEntryModeGenericLib + OcMemoryLib + UefiApplicationEntryPoint + UefiLib + PcdLib + IoLib diff --git a/Include/Library/OcMemoryLib.h b/Include/Library/OcMemoryLib.h index 551eb799..dbf87b68 100644 --- a/Include/Library/OcMemoryLib.h +++ b/Include/Library/OcMemoryLib.h @@ -73,21 +73,25 @@ LegacyRegionUnlock ( ); /** - Get current memory map allocated on pool. + Get current memory map allocated on pool with reserved entries. - @param[out] MemoryMapSize Resulting memory map size in bytes. - @param[out] DescriptorSize Resulting memory map descriptor size in bytes. - @param[out] MapKey Memory map key, optional. - @param[out] DescriptorVersion Memory map descriptor version, optional. + @param[out] MemoryMapSize Resulting memory map size in bytes. + @param[out] DescriptorSize Resulting memory map descriptor size in bytes. + @param[out] MapKey Memory map key, optional. + @param[out] DescriptorVersion Memory map descriptor version, optional. + @param[out] OriginalMemoryMapSize Actual pool allocation memory, optional. + @param[out] IncludeSplitSpace Allocate memory to permit splitting memory map. @retval current memory map or NULL. **/ EFI_MEMORY_DESCRIPTOR * -GetCurrentMemoryMap ( +OcGetCurrentMemoryMap ( OUT UINTN *MemoryMapSize, OUT UINTN *DescriptorSize, - OUT UINTN *MapKey OPTIONAL, - OUT UINT32 *DescriptorVersion OPTIONAL + OUT UINTN *MapKey OPTIONAL, + OUT UINT32 *DescriptorVersion OPTIONAL, + OUT UINTN *OriginalMemoryMapSize OPTIONAL, + IN BOOLEAN IncludeSplitSpace ); /** @@ -220,6 +224,20 @@ OcPrintMemoryAttributesTable ( VOID ); +/** + Print memory map. + + @param[in] MemoryMapSize Memory map size in bytes. + @param[in] MemoryMap Memory map to print. + @param[in] DescriptorSize Memory map descriptor size in bytes. +**/ +VOID +OcPrintMemoryMap ( + IN UINTN MemoryMapSize, + IN EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN DescriptorSize + ); + /** Refresh memory descriptor containing the specified address. diff --git a/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c b/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c index 9cdbb733..8ef3cb3e 100644 --- a/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c +++ b/Library/OcAppleRamDiskLib/OcAppleRamDiskLib.c @@ -246,7 +246,7 @@ InternalAppleRamDiskAllocate ( UINTN RemainingSize; APPLE_RAM_DISK_EXTENT_TABLE *ExtentTable; - MemoryMap = GetCurrentMemoryMap (&MemoryMapSize, &DescriptorSize, NULL, NULL); + MemoryMap = OcGetCurrentMemoryMap (&MemoryMapSize, &DescriptorSize, NULL, NULL, NULL, FALSE); if (MemoryMap == NULL) { return NULL; } diff --git a/Library/OcMemoryLib/MemoryMap.c b/Library/OcMemoryLib/MemoryMap.c index 847d82d6..67026e71 100644 --- a/Library/OcMemoryLib/MemoryMap.c +++ b/Library/OcMemoryLib/MemoryMap.c @@ -24,16 +24,20 @@ #include EFI_MEMORY_DESCRIPTOR * -GetCurrentMemoryMap ( +OcGetCurrentMemoryMap ( OUT UINTN *MemoryMapSize, OUT UINTN *DescriptorSize, - OUT UINTN *MapKey OPTIONAL, - OUT UINT32 *DescriptorVersion OPTIONAL + OUT UINTN *MapKey OPTIONAL, + OUT UINT32 *DescriptorVersion OPTIONAL, + OUT UINTN *OriginalMemoryMapSize OPTIONAL, + IN BOOLEAN IncludeSplitSpace ) { EFI_MEMORY_DESCRIPTOR *MemoryMap; EFI_STATUS Status; UINTN MapKeyValue; + UINTN OriginalSize; + UINTN ExtraSize; UINT32 DescriptorVersionValue; BOOLEAN Result; @@ -50,13 +54,19 @@ GetCurrentMemoryMap ( return NULL; } + if (IncludeSplitSpace) { + ExtraSize = OcCountSplitDescritptors () * *DescriptorSize; + } else { + ExtraSize = 0; + } + // // Apple uses 1024 as constant, however it will grow by at least // DescriptorSize. // Result = OcOverflowAddUN ( *MemoryMapSize, - MAX (*DescriptorSize, 1024), + MAX (*DescriptorSize + ExtraSize, 1024 + ExtraSize), MemoryMapSize ); @@ -64,7 +74,8 @@ GetCurrentMemoryMap ( return NULL; } - MemoryMap = AllocatePool (*MemoryMapSize); + OriginalSize = *MemoryMapSize; + MemoryMap = AllocatePool (OriginalSize); if (MemoryMap == NULL) { return NULL; } @@ -90,6 +101,10 @@ GetCurrentMemoryMap ( *DescriptorVersion = DescriptorVersionValue; } + if (OriginalMemoryMapSize != NULL) { + *OriginalMemoryMapSize = OriginalSize; + } + return MemoryMap; } @@ -398,7 +413,7 @@ CountFreePages ( *LowerMemory = 0; } - MemoryMap = GetCurrentMemoryMap (&MemoryMapSize, &DescriptorSize, NULL, NULL); + MemoryMap = OcGetCurrentMemoryMap (&MemoryMapSize, &DescriptorSize, NULL, NULL, NULL, FALSE); if (MemoryMap == NULL) { return 0; } @@ -443,38 +458,64 @@ OcPrintMemoryAttributesTable ( { UINTN Index; CONST EFI_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; - CONST EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; + EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; - for (Index = 0; Index < gST->NumberOfTableEntries; ++Index) { - if (CompareGuid (&gST->ConfigurationTable[Index].VendorGuid, &gEfiMemoryAttributesTableGuid)) { - MemoryAttributesTable = (CONST EFI_MEMORY_ATTRIBUTES_TABLE *) gST->ConfigurationTable[Index].VendorTable; - - DEBUG ((DEBUG_INFO, "OCMM: MemoryAttributesTable:\n")); - DEBUG ((DEBUG_INFO, "OCMM: Version - 0x%08x\n", MemoryAttributesTable->Version)); - DEBUG ((DEBUG_INFO, "OCMM: NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); - DEBUG ((DEBUG_INFO, "OCMM: DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); - - MemoryAttributesEntry = (CONST EFI_MEMORY_DESCRIPTOR *) (MemoryAttributesTable + 1); - - for (Index = 0; Index < MemoryAttributesTable->NumberOfEntries; ++Index) { - DEBUG ((DEBUG_INFO, "OCMM: Entry (0x%x)\n", MemoryAttributesEntry)); - DEBUG ((DEBUG_INFO, "OCMM: Type - 0x%x\n", MemoryAttributesEntry->Type)); - DEBUG ((DEBUG_INFO, "OCMM: PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); - DEBUG ((DEBUG_INFO, "OCMM: VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart)); - DEBUG ((DEBUG_INFO, "OCMM: NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages)); - DEBUG ((DEBUG_INFO, "OCMM: Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute)); - - MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR ( - MemoryAttributesEntry, - MemoryAttributesTable->DescriptorSize - ); - } - - return; - } + MemoryAttributesTable = OcGetMemoryAttributes (&MemoryAttributesEntry); + if (MemoryAttributesTable == NULL) { + DEBUG ((DEBUG_INFO, "OCMM: MemoryAttributesTable is not present!\n")); + return; } - DEBUG ((DEBUG_INFO, "OCMM: MemoryAttributesTable is not present!\n")); + DEBUG ((DEBUG_INFO, "OCMM: MemoryAttributesTable:\n")); + DEBUG ((DEBUG_INFO, "OCMM: Version - 0x%08x\n", MemoryAttributesTable->Version)); + DEBUG ((DEBUG_INFO, "OCMM: NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); + DEBUG ((DEBUG_INFO, "OCMM: DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); + + for (Index = 0; Index < MemoryAttributesTable->NumberOfEntries; ++Index) { + DEBUG ((DEBUG_INFO, "OCMM: Entry (0x%x)\n", MemoryAttributesEntry)); + DEBUG ((DEBUG_INFO, "OCMM: Type - 0x%x\n", MemoryAttributesEntry->Type)); + DEBUG ((DEBUG_INFO, "OCMM: PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); + DEBUG ((DEBUG_INFO, "OCMM: VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart)); + DEBUG ((DEBUG_INFO, "OCMM: NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages)); + DEBUG ((DEBUG_INFO, "OCMM: Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute)); + + MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR ( + MemoryAttributesEntry, + MemoryAttributesTable->DescriptorSize + ); + } +} + +VOID +OcPrintMemoryMap ( + IN UINTN MemoryMapSize, + IN EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN DescriptorSize + ) +{ + UINTN Index; + UINT32 NumberOfEntries; + + NumberOfEntries = (UINT32) (MemoryMapSize / DescriptorSize); + + DEBUG ((DEBUG_INFO, "OCMM: MemoryMap:\n")); + DEBUG ((DEBUG_INFO, "OCMM: Size - 0x%08x\n", MemoryMapSize)); + DEBUG ((DEBUG_INFO, "OCMM: NumberOfEntries - 0x%08x\n", NumberOfEntries)); + DEBUG ((DEBUG_INFO, "OCMM: DescriptorSize - 0x%08x\n", DescriptorSize)); + + for (Index = 0; Index < NumberOfEntries; ++Index) { + DEBUG ((DEBUG_INFO, "OCMM: Entry (0x%x)\n", MemoryMap)); + DEBUG ((DEBUG_INFO, "OCMM: Type - 0x%x\n", MemoryMap->Type)); + DEBUG ((DEBUG_INFO, "OCMM: PhysicalStart - 0x%016lx\n", MemoryMap->PhysicalStart)); + DEBUG ((DEBUG_INFO, "OCMM: VirtualStart - 0x%016lx\n", MemoryMap->VirtualStart)); + DEBUG ((DEBUG_INFO, "OCMM: NumberOfPages - 0x%016lx\n", MemoryMap->NumberOfPages)); + DEBUG ((DEBUG_INFO, "OCMM: Attribute - 0x%016lx\n", MemoryMap->Attribute)); + + MemoryMap = NEXT_MEMORY_DESCRIPTOR ( + MemoryMap, + DescriptorSize + ); + } } EFI_STATUS diff --git a/OpenCorePkg.dsc b/OpenCorePkg.dsc index 4746353a..cf2e0ac2 100755 --- a/OpenCorePkg.dsc +++ b/OpenCorePkg.dsc @@ -145,6 +145,7 @@ OpenCorePkg/Application/GopStop/GopStop.inf OpenCorePkg/Application/HdaCodecDump/HdaCodecDump.inf OpenCorePkg/Application/KeyTester/KeyTester.inf + OpenCorePkg/Application/MmapDump/MmapDump.inf OpenCorePkg/Application/OpenControl/OpenControl.inf OpenCorePkg/Application/PavpProvision/PavpProvision.inf OpenCorePkg/Application/VerifyMsrE2/VerifyMsrE2.inf diff --git a/macbuild.tool b/macbuild.tool index 5526cfc4..83631659 100755 --- a/macbuild.tool +++ b/macbuild.tool @@ -31,6 +31,7 @@ package() { cp HdaCodecDump.efi tmp/EFI/OC/Tools/ || exit 1 cp HiiDatabase.efi tmp/EFI/OC/Drivers/ || exit 1 cp KeyTester.efi tmp/EFI/OC/Tools/ || exit 1 + cp MmapDump.efi tmp/EFI/OC/Tools/ || exit 1 cp NvmExpressDxe.efi tmp/EFI/OC/Drivers/ || exit 1 cp OpenCanopy.efi tmp/EFI/OC/Drivers/ || exit 1 cp OpenControl.efi tmp/EFI/OC/Tools/ || exit 1