Last active
June 23, 2025 03:49
-
-
Save deeglaze/efb75ab98cd834e16ffcc7a8d034f124 to your computer and use it in GitHub Desktop.
Read firmware.igvm (Gemini 2.5 flash)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <efi.h> | |
#include <efiprot.h> | |
#include <efidef.h> | |
#include <efilib.h> // For LibLocateProtocol, Print, etc. | |
// Define the target GUID for the partition | |
// C12A7328-F81F-11D2-BA4B-00A0C93EC93B | |
#define TARGET_PARTITION_GUID \ | |
{0xC12A7328, 0xF81F, 0x11D2, {0xBA, 0x4B,0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B}} | |
// Macro to compare GUIDs | |
#define CompareGuid(g1, g2) \ | |
(g1->Data1 == g2->Data1 && \ | |
g1->Data2 == g2->Data2 && \ | |
g1->Data3 == g2->Data3 && \ | |
g1->Data4[0] == g2->Data4[0] && \ | |
g1->Data4[1] == g2->Data4[1] && \ | |
g1->Data4[2] == g2->Data4[2] && \ | |
g1->Data4[3] == g2->Data4[3] && \ | |
g1->Data4[4] == g2->Data4[4] && \ | |
g1->Data4[5] == g2->Data4[5] && \ | |
g1->Data4[6] == g2->Data4[6] && \ | |
g1->Data4[7] == g2->Data4[7]) | |
EFI_STATUS | |
EFIAPI | |
UefiMain( | |
IN EFI_HANDLE ImageHandle, | |
IN EFI_SYSTEM_TABLE* SystemTable | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN NoHandles; | |
EFI_HANDLE* Buffer = NULL; | |
UINTN Index; | |
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFs = NULL; | |
EFI_FILE_PROTOCOL* Root = NULL; | |
EFI_FILE_PROTOCOL* FileHandle = NULL; | |
EFI_GUID PartitionInfoProtocolGuid = EFI_PARTITION_INFO_PROTOCOL_GUID; | |
EFI_PARTITION_INFO_PROTOCOL* PartitionInfo = NULL; | |
EFI_GUID TargetGuid = TARGET_PARTITION_GUID; | |
UINT8* FileData = NULL; | |
UINTN FileSize = 0; | |
EFI_FILE_INFO* FileInfo = NULL; | |
UINTN FileInfoSize = 0; | |
CHAR16 Filename[] = L"\\FIRMWARE.IGVM"; // Note the backslash for root directory | |
// Initialize Lib (from EfiLib.h) | |
InitializeLib(ImageHandle, SystemTable); | |
ST->ConOut->OutputString(ST->ConOut, L"UEFI Application: Reading FIRMWARE.IGVM\r\n"); | |
// 1. Locate all handles that support the EFI_SIMPLE_FILE_SYSTEM_PROTOCOL | |
Status = gBS->LocateHandleBuffer( | |
ByProtocol, | |
&gEfiSimpleFileSystemProtocolGuid, | |
NULL, | |
&NoHandles, | |
&Buffer | |
); | |
if (EFI_ERROR(Status)) { | |
Print(L"Failed to locate EFI_SIMPLE_FILE_SYSTEM_PROTOCOL handles: %r\r\n", Status); | |
goto Exit; | |
} | |
Print(L"Found %d handles with EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.\r\n", NoHandles); | |
// 2. Iterate through handles to find the partition with the target GUID | |
EFI_HANDLE TargetPartitionHandle = NULL; | |
for (Index = 0; Index < NoHandles; Index++) { | |
Status = gBS->HandleProtocol( | |
Buffer[Index], | |
&PartitionInfoProtocolGuid, | |
(VOID**)&PartitionInfo | |
); | |
if (!EFI_ERROR(Status)) { | |
// Check if it's a GPT partition | |
if (PartitionInfo->Info.Gpt.Header->PartitionType == PARTITION_TYPE_GPT) { | |
// Compare partition GUID | |
if (CompareGuid(&PartitionInfo->Info.Gpt.PartitionTypeGUID, &TargetGuid)) { | |
Print(L"Found target GPT partition at handle %p.\r\n", Buffer[Index]); | |
TargetPartitionHandle = Buffer[Index]; | |
// Release the protocol we just opened on this handle | |
gBS->CloseProtocol(Buffer[Index], &PartitionInfoProtocolGuid, ImageHandle, NULL); | |
break; // Found it, no need to continue searching | |
} | |
} | |
// Close the protocol if it was opened but not the target | |
gBS->CloseProtocol(Buffer[Index], &PartitionInfoProtocolGuid, ImageHandle, NULL); | |
} | |
} | |
if (TargetPartitionHandle == NULL) { | |
Print(L"Error: EFI system partition not found.\r\n"); | |
Status = EFI_NOT_FOUND; | |
goto Exit; | |
} | |
// 3. Open the Simple File System Protocol on the target partition handle | |
Status = gBS->HandleProtocol( | |
TargetPartitionHandle, | |
&gEfiSimpleFileSystemProtocolGuid, | |
(VOID**)&SimpleFs | |
); | |
if (EFI_ERROR(Status)) { | |
Print(L"Failed to open EFI_SIMPLE_FILE_SYSTEM_PROTOCOL on target handle: %r\r\n", Status); | |
goto Exit; | |
} | |
// 4. Open the root directory | |
Status = SimpleFs->OpenVolume(SimpleFs, &Root); | |
if (EFI_ERROR(Status)) { | |
Print(L"Failed to open root volume: %r\r\n", Status); | |
goto Exit; | |
} | |
// 5. Open the FIRMWARE.IGVM file | |
Print(L"Attempting to open file: %s\r\n", Filename); | |
Status = Root->Open(Root, &FileHandle, Filename, EFI_FILE_MODE_READ, 0); | |
if (EFI_ERROR(Status)) { | |
Print(L"Error: Failed to open %s: %r\r\n", Filename, Status); | |
goto Exit; | |
} | |
Print(L"Successfully opened %s.\r\n", Filename); | |
// 6. Get file size | |
FileInfoSize = 0; | |
Status = FileHandle->GetInfo(FileHandle, &gEfiFileInfoGuid, &FileInfoSize, NULL); | |
if (Status == EFI_BUFFER_TOO_SMALL) { | |
Status = gBS->AllocatePool(EfiBootServicesData, FileInfoSize, (VOID**)&FileInfo); | |
if (EFI_ERROR(Status)) { | |
Print(L"Failed to allocate pool for FileInfo: %r\r\n", Status); | |
goto Exit; | |
} | |
Status = FileHandle->GetInfo(FileHandle, &gEfiFileInfoGuid, &FileInfoSize, FileInfo); | |
if (EFI_ERROR(Status)) { | |
Print(L"Failed to get file info: %r\r\n", Status); | |
goto Exit; | |
} | |
FileSize = FileInfo->FileSize; | |
Print(L"File size of %s: %Lu bytes\r\n", Filename, FileSize); | |
} else { | |
Print(L"Failed to get file info size: %r\r\n", Status); | |
goto Exit; | |
} | |
if (FileSize == 0) { | |
Print(L"Warning: %s has zero size. Nothing to read.\r\n", Filename); | |
goto Exit; | |
} | |
// 7. Allocate buffer and read file contents | |
Status = gBS->AllocatePool(EfiBootServicesData, FileSize, (VOID**)&FileData); | |
if (EFI_ERROR(Status)) { | |
Print(L"Failed to allocate pool for file data: %r\r\n", Status); | |
goto Exit; | |
} | |
Status = FileHandle->Read(FileHandle, &FileSize, FileData); | |
if (EFI_ERROR(Status)) { | |
Print(L"Failed to read file %s: %r\r\n", Filename, Status); | |
gBS->FreePool(FileData); // Free buffer on read error | |
FileData = NULL; | |
goto Exit; | |
} | |
Print(L"Successfully read %Lu bytes from %s.\r\n", FileSize, Filename); | |
// 8. Display/Process - print first 64 bytes for demonstration | |
Print(L"\r\nFirst 64 bytes of %s:\r\n", Filename); | |
for (UINTN i = 0; i < FileSize && i < 64; i++) { | |
Print(L"%02x ", FileData[i]); | |
if ((i + 1) % 16 == 0) { | |
Print(L"\r\n"); | |
} | |
} | |
Print(L"\r\n"); | |
// In a real scenario, you would now process FileData. | |
Exit: | |
// 9. Clean up | |
if (FileHandle != NULL) { | |
FileHandle->Close(FileHandle); | |
} | |
if (Root != NULL) { | |
Root->Close(Root); // Closing the root directory handle | |
} | |
if (FileData != NULL) { | |
gBS->FreePool(FileData); | |
} | |
if (FileInfo != NULL) { | |
gBS->FreePool(FileInfo); | |
} | |
if (Buffer != NULL) { | |
gBS->FreePool(Buffer); | |
} | |
// Give some time to see the output before exiting | |
gBS->Stall(5 * 1000 * 1000); // 5 seconds | |
return Status; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment