💻
UEFI 프로젝트
  • 🧑‍🏫프로젝트 개요
  • 📖UEFI 개념
    • 1. BIOS의 과거
    • 2. UEFI 개념
    • 3. BIOS vs UEFI
    • 4. UEFI 부팅 단계
  • 🖥️UEFI 개발
    • UEFI 개발 시작하기
      • 0. EDK II 빌드 환경 구성
      • 1. 간단한 EFI application 만들기
      • 2. 간단한 Pkg 만들기
      • 3. Hello World 출력하기
      • 4. 라이브러리와 Hello World
      • 5. Conf를 통한 Build 단순화
    • 핸들 및 프로토콜
      • 6. 핸들/프로토콜 데이터 베이스 구조 - Part 1
      • 7. 핸들/프로토콜 데이터 베이스 구조 - Part 2
      • 8. HandleProtocol API 함수 & ImageHandle 프로토콜을 통한 정보
      • 9. ProtocolsPerHandle API를 통한 ImageHandle 프로토콜 가져오기
      • 10. EFI_STATUS 타입 과 EFI_ERROR 매크로
    • 메모리 맵
      • 11. EFI 메모리 맵 정보 얻기
      • 12. EFI 메모리 맵을 리눅스 커널 스타일로 바꾸기
    • 명령줄 인수를 받는 간단한 앱 만들기
      • 13.ShellAppMain Entry point
      • 14.gRT->GetNextVariableName API를 사용하여 모든 변수 이름 및 GUID 가져오기
    • 부팅 옵션
      • 15. gRT->GetVariable API를 사용하여 부팅 변수 가져오기 및 구문 분석
      • 16. OVMF 이미지 내에 부팅 옵션 추가
      • 17. 부팅 옵션에 WaitForEvent 함수 추가
      • 18. ReadKeyStroke 함수로 사용자 입력 처리
      • 19. bcfg 명령어를 사용한 부팅 옵션 수정
    • PCD
      • 20. PCD 소개
      • 21. PCD 변수에 대한 Overriding
      • 22. Feature Flag PCD와 BOOLEAN FixedAtBuild PCD의 비교
      • 23. PatchableInModule PCD 및 GenPatchPcdTable/PatchPcdValue 유틸리티를 통해 PCD를 변경하는 방법
      • 24. Dynamic/DynamiEx PCDs
      • 25. PCD 더 알아보기
    • 테이블
      • 26. EFI_CONFIGURATION_TABLE에서 참조되는 테이블
      • 27. dmem/EFI_SMBIOS_PROTOCOL/smbiosview를 통해서 SMBIOS 정보 가져오기
      • 28. EFI_SHELL_PROTOCOL을 통하여 ACPI 테이블을 파일에 저장하기
      • 29. EFI_ACPI_SDT_PROTOCOL 및 ShellLib를 사용하여 ACPI BGRT 테이블에서 BMP 이미지 저장하기
    • PCI
      • 30. PCI 루트 브리지 찾은 후 시스템의 모든 PCI 기능 가져오기
      • 31. ShellLib/PrintLib 함수를 사용해 PCI Vendor/Device 정보 가져오기
      • 32. EFI_PCI_IO_PROTOCOL을 사용해 PCI Option ROM 이미지 표시
      • 33. EfiRom 유틸리티를 사용한 PCI Option ROM 이미지 파싱 및 생성
    • 드라이버 및 라이브러리
      • 34. 간단한 UEFI 드라이버 생성
      • 35. 애플리케이션에서 사용할 간단한 라이브러리 생성
      • 36. Library의 constructor와 destructor, NULL Library
      • 37. Shell에 acpiview 명령을 추가하는 방법 조사
      • 38. 사용자 지정 프로토콜을 만들고 사용하기
      • 39. RegisterKeyNotify / UnrigisterKeyNotify 함수를 사용해 단축키 기능을 추가하는 드라이버 만들기
      • 40. Key #### NVRAM 변수
    • 디버그
      • 41. DEBUG 출력문 내부 구조와 DEBUG 문 제어를 위한 PCD 분석, 그리고 OVMF 부트 로그 가져오기
      • 42. GDB를 이용한 Driver/Application 및 OVMF Debug
    • HII
      • 43. HII 데이터베이스 개념 및 출력
      • 44. HII 데이터베이스 내부
      • 45. EFI_HII_DATABASE_PROTOCOL의 NewPackageList를 사용하여 문자열 패키지가 포함된 문자열 목록 게시
      • 46. EFI_HII_DATABASE_PROTOCOL의 NewPackageList를 사용하여 문자열 패키지가 포함된 HII 패키지 목록 게시
      • 47. EFI_HII_DATABASE_PROTOCOL의 NewPackageList를 사용하여 문자열 패키지가 포함된 HII 패키지 목록 게시
      • 48. UNI 파일 및 HiiLib를 사용하여 HII String 패키지 게시 및 작업하기
      • 49.MODULE_UNI_FILE/PACKAGE_UNI_FILE/[UserExtensions.TianoCore."ExtraFiles"]의 도움으로 UNI 파일 선언하기
      • 50.UEFI_HII_RESOURCE_SECTION을 사용하여 문자열 패키지와 함께 HII 패키지 목록 게시하기
      • 51. UEFI APP에 메뉴얼 추가하기(shell의 -?와 help 옵션)
      • 52. Russian 글꼴 추가 - Part 1.
      • 53. Russian 글꼴 추가 - Part 2.
      • 54. EFI_HII_STRING_PROTOCOL의 NewString 및 SetString 함수를 사용하여 다른 언어에 대한 문자열 패키지를 동적으로 추가
      • 55. PlatformLangCodes EFI 변수 수정 및 다른 언어를 동적 추가하기
      • 56. 코드에서 FILE_GUID 및 BASE_NAME을 가져오기
    • VFR
      • 57. VFR을 사용해 간단한 폼 생성 및 EFI_FORM_BROWSER2_PROTOCOL.SendForm()를 통해 화면에 폼 표시하기
      • 58. VFR 요소 : subtitle 및 text
      • 59. 간단한 폼 애플리케이션을 UEFI 드라이버 Form으로 변환하기
      • 60. gRT->SetVariable() 함수를 사용한 UEFI 변수 생성, 변경 및 삭제
      • 61.dmpstore 명령을 사용하여 변수를 파일에 저장/로드하기
      • 62. UEFI Device path의 구조
      • 63. checkbox를 가진 HII 폼 만들기
      • 64. checkbox를 가진 HII폼 만들기
      • 65. VFR 추가 입력 요소 Part 1: number
      • 66. VFR 추가 입력 요소 Part 2: string
      • 67. VFR 추가 입력 요소 Part 3: date & time
      • 68. VFR 추가 입력 요소 Part 3: oneof & orderedlist
      • 69. VFR의 조건부 키워드
      • 70. VFR의 상수 및 연산자가 내장된 기본 조건문
      • 71. 기본 VFR 내장 문자열용 함수
      • 72. label 키워드를 이용하여 HII 양식에 동적 요소 추가하기
      • 73. VFR question 기본값 설정
  • 🔐UEFI 보안
    • 1. 개요
    • 2. 공격 벡터
    • 3. mitigation
    • 4. 정적 분석 방법
    • 5. 동적 분석 방법
Powered by GitBook
On this page
  1. UEFI 개발
  2. VFR

61.dmpstore 명령을 사용하여 변수를 파일에 저장/로드하기

dmpstore 변수 덤프에서 CRC32 체크섬을 재계산하는 애플리케이션 작성하기

UEFI Shell에는 UEFI 변수의 내용을 확인하는 데 도움이 되는 dmpstore 명령이 있다.

이 dmpstore 명령의 도움말을 보면 이 명령이 제공하는 유용한 기능을 하나 더 볼 수 있다. 이 명령을 사용하면 UEFI 변수를 파일에 저장하고 해당 파일에서 다시 로드할 수 있다.

FS0:\> dmpstore -?
...
DMPSTORE [-all | ([variable] [-guid guid])] [-s file]
DMPSTORE [-all | ([variable] [-guid guid])] [-l file]
...
  -s       - Saves variables to a file.
  -l       - Loads and sets variables from a file.
...

이 메커니즘을 사용하여 기존 UEFI 변수의 내용을 수정해보자. 이것은 디버그에 유용한 기능이 될 수 있다.

이전 레슨에서는 UEFI 부팅 변수의 내용을 기반으로 부팅 소스를 표시하는 ShowBootVariables.efi 애플리케이션을 만들었었다.

FS0:\> ShowBootVariables.efi
Boot0000
UiApp
Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(462CAA21-7614-4503-836E-8AB6F4662331)

Boot0001
UEFI QEMU DVD-ROM QM00003
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)

Boot0002*
EFI Internal Shell
Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1)

Boot0003
UEFI QEMU HARDDISK QM00001
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)

이 애플리케이션에서 구문 분석된 변수 중 하나는 BootOrder 변수였다.

잊어버린 경우에는 아래의 개념을 보자.

BootOrder 변수는 Boot####옵션의 정렬된 목록을 구성하는 UINT16의 배열을 포함한다. 배열의 첫 번째 요소는 첫 번째 논리적 부팅 옵션의 값이고 두 번째 요소는 두 번째 논리적 부팅 옵션의 값 등이다. BootOrder 순서 목록은 펌웨어의 부팅 관리자를 기본 부팅 순서로 지정한다.

BootOrder 변수의 내용을 출력해보자.

FS0:\> dmpstore BootOrder
Variable NV+RT+BS 'EFIGlobalVariable:BootOrder' DataSize = 0x08
  00000000: 00 00 01 00 02 00 03 00-                         *........*

현재 순서는 다음과 같다.

Boot0000
Boot0001
Boot0002
Boot0003

모든 것이 ShowBootVariables 애플리케이션이 보여주는 것과 같다.

dmpstore 명령을 사용하여 BootOrder 변수의 내용을 파일로 덤프할 수 있다.

FS0:\> dmpstore BootOrder -s BootOrder.bin
Save variable to file: BootOrder.bin.
Variable NV+RT+BS '8BE4DF61-93CA-11D2-AA0D-00E098032B8C:BootOrder' DataSize = 0x08

UEFI Shell에는 자체적으로 hexedit 명령이 포함되어 있기 때문에 이를 통해 생성된 파일의 내용을 볼 수 있다.

hexedit은 16진수 편집기이며 Ctrl+E 명령으로 도움말 메시지를 볼 수 있다.

Ctrl-W로 도움말을 종료할 수 있다.

dmpstore 명령은 파일에서 다음 구조체로 각 변수를 나타낸다.

{
  UINT32 NameSize;           // Size of the variable name in bytes
  UINT32 DataSize;           // Size of the variable data in bytes
  CHAR16 Name[NameSize/2];   // Variable name in CHAR16
  EFI_GUID Guid;             // Variable GUID
  UINT32 Attributes;         // Variable attributes
  UINT8 Data[DataSize];      // Variable data
  UINT32 Crc;                // CRC32 checksum for the record
}

다음은 구조체 각각의 필드에 대한 강조 표시가 된 파일이다.

부팅 순서를 다음으로 변경하여 파일 내용을 수정해 보자.

Boot0001
Boot0000
Boot0002
Boot0003

종료하려면 Ctrl+Q를 입력하고 우리의 수정 사항을 저장하기 위해 y를 입력하자.

만약 변경된 설정을 로드하려고 하면 오류가 발생한다.

FS0:\> dmpstore -l BootOrder.bin
Load and set variables from file: BootOrder.bin.
dmpstore: Incorrect file format.
dmpstore: No matching variables found. Guid 8BE4DF61-93CA-11D2-AA0D-00E098032B8C

이는 레코드의 UINT32 Crc 필드가 현재 레코드 내용에 대해 더 이상 유효하지 않기 때문에 발생한다.

dmpstore 덤프에서 CRC 필드를 업데이트하기 위해 UpdateDmpstoreDump 애플리케이션을 만들어 보자.

다시 한 번 명령 Shell 인수를 파싱할 것이므로 Shell 애플리케이션을 만드는게 좋다. 우리는 파일을 읽고 쓸 것이므로 LibraryClasses에 ShellLib를 포함해준다.

UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.inf
[Defines]
  INF_VERSION                    = 1.25
  BASE_NAME                      = UpdateDmpstoreDump
  FILE_GUID                      = d14fe21b-7dbf-40ff-96cb-5d6f5b63cda6
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = ShellCEntryLib

[Sources]
  UpdateDmpstoreDump.c

[Packages]
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec

[LibraryClasses]
  UefiLib
  ShellCEntryLib
  ShellLib

UefiLessonsPkg/UpdateDmpstoreDump/UpdateDmpstoreDump.c에서 명령 인수에서 덤프 파일 이름을 읽고 읽기 및 쓰기 속성으로 파일을 여는 것부터 시작한다.

#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/ShellLib.h>
#include <Library/MemoryAllocationLib.h>

VOID Usage()
{
  Print(L"Recalculate CRCs for dmpstore command dump\n");
  Print(L"\n");
  Print(L"  UpdateDmpstoreDump <filename>\n");
}

INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv)
{
  if (Argc!=2) {
    Usage();
    return EFI_INVALID_PARAMETER;
  }

  SHELL_FILE_HANDLE FileHandle;

  CHAR16* Filename = Argv[1];
  EFI_STATUS Status = ShellOpenFileByName(
    Filename,
    &FileHandle,
    EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ,
    0
  );
  if (EFI_ERROR(Status)) {
    Print(L"Error! Can't open file %s\n", Filename);
    return Status;
  }

  ...

  Status = ShellCloseFile(&FileHandle);
  if (EFI_ERROR(Status)) {
    Print(L"Can't close file: %r\n", Status);
  }

  return EFI_SUCCESS;
}

덤프 파일은 자체적으로 많은 레코드를 가질 수 있으며 레코드의 크기는 일정하지 않지만 레코드 필드에 따라 다르다. 따라서 모든 레코드 CRC를 수정하는 유일한 방법은 파일이 끝날 때까지 파일 레코드를 단계별로 실행하는 것이다.

  UINT64 FileSize;
  Status = ShellGetFileSize(FileHandle, &FileSize);
  if (EFI_ERROR(Status)) {
    Status = ShellCloseFile(&FileHandle);
    return SHELL_DEVICE_ERROR;
  }

  UINT64 FilePos = 0;
  while (FilePos < FileSize) {
    ...
  }
UINTN ToReadSize;
UINT32 NameSize;
ToReadSize = sizeof(NameSize);
Status = ShellReadFile(FileHandle, &ToReadSize, &NameSize);
if (EFI_ERROR(Status) || (ToReadSize != sizeof(NameSize))) {
  Status = SHELL_VOLUME_CORRUPTED;
  break;
}
FilePos += ToReadSize;

UINT32 DataSize;
ToReadSize = sizeof(DataSize);
Status = ShellReadFile(FileHandle, &ToReadSize, &DataSize);
if (EFI_ERROR(Status) || (ToReadSize != sizeof(DataSize))) {
  Status = SHELL_VOLUME_CORRUPTED;
  break;
}
FilePos += ToReadSize;

UINTN RemainingSize = NameSize +
                      sizeof(EFI_GUID) +
                      sizeof(UINT32) +
                      DataSize;
UINT8* Buffer = AllocatePool(sizeof(NameSize) + sizeof(DataSize) + RemainingSize);
if (Buffer == NULL) {
  Status = SHELL_OUT_OF_RESOURCES;
  break;
}

*(UINT32*)Buffer = NameSize;
*((UINT32*)Buffer + 1) = DataSize;

ToReadSize = RemainingSize;
Status = ShellReadFile(FileHandle, &ToReadSize, (UINT32*)Buffer + 2);
if (EFI_ERROR(Status) || (ToReadSize != RemainingSize)) {
  Status = SHELL_VOLUME_CORRUPTED;
  FreePool (Buffer);
  break;
}
FilePos += ToReadSize;


UINT32 Crc32;
gBS->CalculateCrc32 (
   Buffer,
   sizeof(NameSize) + sizeof(DataSize) + RemainingSize,
   &Crc32
);

...

FreePool(Buffer);

여기서 CRC32 체크섬을 계산하기 위해 EFI_BOOT_SERVICES.CalculateCrc32() 함수를 사용한다.

EFI_BOOT_SERVICES.CalculateCrc32()

Summary:
Computes and returns a 32-bit CRC for a data buffer.

Prototype:
typedef
EFI_STATUS
(EFIAPI *EFI_CALCULATE_CRC32)
 IN VOID *Data,
 IN UINTN DataSize,
 OUT UINT32 *Crc32
 );

Parameters:
Data 		A pointer to the buffer on which the 32-bit CRC is to be computed.
DataSize 	The number of bytes in the buffer Data.
Crc32 		The 32-bit CRC that was computed for the data buffer specified by Data and DataSize.

Description:
This function computes the 32-bit CRC for the data buffer specified by Data and DataSize. If the 32-bit CRC is computed, then it is returned in Crc32 and EFI_SUCCESS is returned.

CRC32 체크섬이 있으면 ShellWriteFile 함수를 사용하여 파일 내용을 업데이트할 수 있다.

UINTN ToWriteSize = sizeof(Crc32);
Status = ShellWriteFile(
  FileHandle,
  &ToWriteSize,
  &Crc32
);
if (EFI_ERROR(Status) || (ToWriteSize != sizeof(Crc32))) {
  Print(L"Error! Not all data was written\n");
  FreePool(Buffer);
  break;
}
FilePos += ToWriteSize;

애플리케이션을 빌드하고 dmpstore 덤프에 사용해보자.

FS0:\> UpdateDmpstoreDump.efi BootOrder.bin

파일 내용을 다시 보면 CRC 필드가 변경되었음을 알 수 있다.

이제 dmpstore -l은 오류 없이 완료되는 것을 확인할 수 있다.

FS0:\> dmpstore -l BootOrder.bin
Load and set variables from file: BootOrder.bin.
Variable NV+RT+BS '8BE4DF61-93CA-11D2-AA0D-00E098032B8C:BootOrder' DataSize = 0x08

또한 변수 내용이 수정된 것을 볼 수 있다.

FS0:\> dmpstore BootOrder
Variable NV+RT+BS 'EFIGlobalVariable:BootOrder' DataSize = 0x08
  00000000: 01 00 00 00 02 00 03 00-                         *........*

ShowBootVariables.efi 애플리케이션을 사용하여 변경 사항을 확인할 수도 있다.

FS0:\> ShowBootVariables.efi
Boot0001
UEFI QEMU DVD-ROM QM00003
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)

Boot0000
UiApp
Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(462CAA21-7614-4503-836E-8AB6F4662331)

Boot0002*
EFI Internal Shell
Fv(7CB8BDC9-F8EB-4F34-AAEA-3EE4AF6516A1)/FvFile(7C04A583-9E3E-4F1C-AD65-E05268D0B4D1)

Boot0003
UEFI QEMU HARDDISK QM00001
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)

덤프 파일에 여러 변수가 있는 경우 프로그램이 작동하는지 확인할 수도 있다.

이전 레슨에 따라 일부 영구 변수가 있는 경우에 대비하여 dmpstore -d -guid 명령을 사용하여 GUID 아래의 모든 변수를 삭제해준다.

FS0:\> dmpstore -d -guid bb2a829f-7943-4691-a03a-f1f48519d7e6
dmpstore: No matching variables found. Guid 7C04A583-9E3E-4F1C-AD65-E05268D0B4D1

새 변수를 생성하고 파일에 저장한다.

FS0:\> SetVariableExample.efi HelloVar nb "Hello World"
Variable HelloVar was successfully changed
FS0:\> SetVariableExample.efi ByeVar nbr "Bye World"
Variable ByeVar was successfully changed
FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 -s MyVar.bin
Save variable to file: MyVar.bin.
Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x16
Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x1A

hexedit를 사용하여 덤프 파일의 두 레코드에서 World 문자열을 수정해준다. 여기에서는 각 문자 코드에 1을 더했다.

전:

00000000 0E 00 00 00 14 00 00 00  42 00 79 00 65 00 56 00  ........B.y.e.V.
00000010 61 00 72 00 00 00 9F 82  2A BB 43 79 91 46 A0 3A  a.r...??*?Cy?F?:
00000020 F1 F4 85 19 D7 E6 07 00  00 00 42 00 79 00 65 00  ???.??....B.y.e.
00000030 20 00 57 00 6F 00 72 00  6C 00 64 00 00 00 EC 24   .W.o.r.l.d...?$
00000040 78 CD 12 00 00 00 18 00  00 00 48 00 65 00 6C 00  x?........H.e.l.
00000050 6C 00 6F 00 56 00 61 00  72 00 00 00 9F 82 2A BB  l.o.V.a.r...??*?
00000060 43 79 91 46 A0 3A F1 F4  85 19 D7 E6 03 00 00 00  Cy?F?:???.??....
00000070 48 00 65 00 6C 00 6C 00  6F 00 20 00 57 00 6F 00  H.e.l.l.o. .W.o.
00000080 72 00 6C 00 64 00 00 00  97 82 10 13              r.l.d...??..

후:

00000000 0E 00 00 00 14 00 00 00  42 00 79 00 65 00 56 00  ........B.y.e.V.
00000010 61 00 72 00 00 00 9F 82  2A BB 43 79 91 46 A0 3A  a.r...??*?Cy?F?:
00000020 F1 F4 85 19 D7 E6 07 00  00 00 42 00 79 00 65 00  ???.??....B.y.e.
00000030 20 00 58 00 70 00 73 00  6D 00 65 00 00 00 EC 24   .X.p.s.m.e...?$
00000040 78 CD 12 00 00 00 18 00  00 00 48 00 65 00 6C 00  x?........H.e.l.
00000050 6C 00 6F 00 56 00 61 00  72 00 00 00 9F 82 2A BB  l.o.V.a.r...??*?
00000060 43 79 91 46 A0 3A F1 F4  85 19 D7 E6 03 00 00 00  Cy?F?:???.??....
00000070 48 00 65 00 6C 00 6C 00  6F 00 20 00 58 00 70 00  H.e.l.l.o. .X.p.
00000080 73 00 6D 00 65 00 00 00  97 82 10 13              s.m.e...??..

우리의 프로그램을 사용해서 체크섬을 업데이트해준다.

FS0:\> UpdateDmpstoreDump.efi MyVar.bin

이제 새 덤프가 실제로 두 변수 콘텐츠 내용을 모두 변경했는지 확인할 수 있다.

FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6
Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x14
  00000000: 42 00 79 00 65 00 20 00-57 00 6F 00 72 00 6C 00  *B.y.e. .W.o.r.l.*
  00000010: 64 00 00 00                                      *d...*
Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x18
  00000000: 48 00 65 00 6C 00 6C 00-6F 00 20 00 57 00 6F 00  *H.e.l.l.o. .W.o.*
  00000010: 72 00 6C 00 64 00 00 00-                         *r.l.d...*

FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 -l MyVar.bin
Load and set variables from file: MyVar.bin.
Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x14
Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x18

FS0:\> dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6
Variable NV+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:HelloVar' DataSize = 0x18
  00000000: 48 00 65 00 6C 00 6C 00-6F 00 20 00 58 00 70 00  *H.e.l.l.o. .X.p.*
  00000010: 73 00 6D 00 65 00 00 00-                         *s.m.e...*
Variable NV+RT+BS 'BB2A829F-7943-4691-A03A-F1F48519D7E6:ByeVar' DataSize = 0x14
  00000000: 42 00 79 00 65 00 20 00-58 00 70 00 73 00 6D 00  *B.y.e. .X.p.s.m.*
  00000010: 65 00 00 00                                      *e...*

여기서는 해당이 안되지만 데이터의 크기를 변경하면 UINT32 DataSize 필드도 변경해줘야 된다는 것을 명심해야 한다.

Previous60. gRT->SetVariable() 함수를 사용한 UEFI 변수 생성, 변경 및 삭제Next62. UEFI Device path의 구조

Last updated 2 years ago

다음은 레코드 데이터를 읽고 CRC32를 계산하는 코드이다. dmpstore 명령에 LoadVariablesFromFileFunction이 있는 것과 매우 유사하다. ()

🖥️
https://github.com/tianocore/edk2/blob/master/ShellPkg/Library/UefiShellDebug1CommandsLib/DmpStore.c