[UEFI] SetVariable()

2026. 2. 14. 17:37·CS/Graduation project

SetVariable

UEFI 런타임 서비스인 SetVariable은 변수의 값을 설정하는 함수이다.

 

 

 

프로토타입

typedef
EFI_STATUS
SetVariable (
 IN CHAR16 *VariableName,
 IN EFI_GUID *VendorGuid,
 IN UINT32 Attributes,
 IN UINTN DataSize,
 IN VOID *Data
 );
  • VariableName: 벤더 변수의 이름(Null로 끝나는 문자열)으로, 각 VendorGuid마다 유일해야 하며, 빈 문자열이면 EFI_INVALID_PARAMETER를 반환한다.
  • VendorGuid: 벤더를 식별하는 고유 ID (GUID)
  • Attributes: 변수에 설정할 속성 비트마스크
  • DataSize: 데이터 버퍼의 크기(바이트)로 크기가 0이면 해당 변수를 삭제한다.
  • Data: 변수에 저장할 내용

 

 

 

변수 속성

 

변수를 생성할 때 속성을 지정해야 하고 아래 플래그들의 조합으로 구성된다

  • EFI_VARIABLE_NON_VOLATILE (NV): 재부팅 후에도 변수가 유지
  • EFI_VARIABLE_BOOTSERVICE_ACCESS (BS): UEFI 부팅 단계에서 접근 가능
  • EFI_VARIABLE_RUNTIME_ACCESS (RT): OS 단계(ExitBootServices 호출 이후)에서도 접근 가능

모든 조합이 가능한 것은 아니고, 주로 사용되는 유효한 조합은 아래와 같다.

  • NV | BS (비휘발성 + 부트 서비스)
  • BS | RT (부트 서비스 + 런타임)
  • NV | BS | RT (비휘발성 + 부트 서비스 + 런타임)

 

 

 


1. 애플리케이션 구현

 

 

1.1 SetVariableExample.c

#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiLib.h>

VOID Usage()
{
  Print(L"Delete variable\n");
  Print(L"   SetVariableExample <variable name>\n");
  Print(L"\n");
  Print(L"Set variable\n");
  Print(L"   SetVariableExample <variable name> <attributes> <value>\n");
  Print(L"\n");
  Print(L"<attributes> can be <n|b|r>\n");
  Print(L"n - NON_VOLATILE\n");
  Print(L"b - BOOTSERVICE_ACCESS\n");
  Print(L"r - RUNTIME_ACCESS\n");
}

INTN EFIAPI ShellAppMain(IN UINTN Argc, IN CHAR16 **Argv)
{
  EFI_STATUS Status;

  if (Argc==2) {
  
    CHAR16* VariableName = Argv[1];
    Status = gRT->SetVariable (
                VariableName,
                &gEfiCallerIdGuid,
                0,
                0,
                NULL
                );
    if (EFI_ERROR(Status)) {
      Print(L"%r\n", Status);
    } else {
      Print(L"Variable %s was successfully deleted\n", VariableName);
    }
    return Status;
  } else if (Argc==4) {

    CHAR16* VariableName = Argv[1];
    CHAR16* AttributesStr = Argv[2];
    CHAR16* Value = Argv[3];
    UINT32  Attributes = 0;
    
  
    for (UINTN i=0; i<StrLen(AttributesStr); i++) {
      switch(AttributesStr[i]) {
        case L'n':
          Attributes |= EFI_VARIABLE_NON_VOLATILE;
          break;
        case L'b':
          Attributes |= EFI_VARIABLE_BOOTSERVICE_ACCESS;
          break;
        case L'r':
          Attributes |= EFI_VARIABLE_RUNTIME_ACCESS;
          break;
        default:
          Print(L"Error! Unknown attribute!");
          return EFI_INVALID_PARAMETER;
      }
    }
    Status = gRT->SetVariable (
                VariableName,
                &gEfiCallerIdGuid,
                Attributes,
                StrSize(Value),
                Value
                );
    if (EFI_ERROR(Status)) {
      Print(L"%r\n", Status);
    } else {
      Print(L"Variable %s was successfully changed\n", VariableName);
    }
    return Status;
  } else {
    Usage();
  }

  return EFI_SUCCESS;
}

SetVariable을 활용하여 사용자 정의 변수를 생성, 수정 또는 삭제하게 하는 UEFI 쉘 애플리케이션 코드이다. 인자를 통해 변수 정보를 입력받고, 입력된 인자의 개수에 따라 변수의 상태를 조작한다.

 

변수 이름만 입력할 경우에는 데이터 크기를 0으로 설정하여 해당 변수를 시스템에서 즉시 제거하며, 변수 이름과 속성 문자열 및 저장할 값을 모두 입력할 경우에는 입력된 문자를 비트 연산으로 조합하여 UEFI 표준 플래그를 생성한다. 이때 저장할 데이터의 크기는 StrSize 함수를 통해 계산 후 gRT->SetVariable로 전달되며, 이를 통해 새로운 변수를 생성하거나 기존의 내용을 업데이트한다.

 

마지막으로 지정되지 않은 속성이 입력되거나 인자 형식이 올바르지 않은 경우 Usage()가 출력된다.

 

 

 

1.2. SetVariableExample.inf

[Defines]
  INF_VERSION                    = 1.25
  BASE_NAME                      = SetVariableExample
  FILE_GUID                      = bb2a829f-7943-4691-a03a-f1f48519d7e6
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 1.0
  ENTRY_POINT                    = ShellCEntryLib

[Sources]
  SetVariableExample.c

[Packages]
  MdePkg/MdePkg.dec

[LibraryClasses]
  UefiLib
  ShellCEntryLib

빌드 정보 파일은 위와 같이 설정했다.

 

이후 SetVariableExample 폴더를 만들고 앞서 만든 소스 파일과 inf 파일을 옮겼다. 그리고 빌드 시스템이 새로운 애플리케이션을 인식할 수 있도록 OvmfPkg/OvmfPkgX64.dsc 파일의 [Components] 섹션에 해당 경로를 추가하여 컴파일 대상에 포함시켰다.

 

 

 

1.3. 빌드 및 부팅

build -p OvmfPkg/OvmfPkgX64.dsc -a X64 -t GCC5
// -b RELEASE를 추가하면 RELEASE로 빌드됨

// 이후 생성된 efi파일을 USB 드라이버 용 폴더인 UEFI DISK에 복사 후 qemu 실행

qemu-system-x86_64 \
  -drive if=pflash,format=raw,readonly,file=Build/OvmfX64/RELEASE_GCC5/FV/OVMF_CODE.fd \
  -drive if=pflash,format=raw,file=Build/OvmfX64/RELEASE_GCC5/FV/OVMF_VARS.fd \
  -drive format=raw,file=fat:rw:~/UEFI_disk \
  -net none \
  -nographic

비휘발성(NV) 변수 테스트를 위해 QEMU 실행 시 NVRAM(pflash) 설정을 적용한다. 또한 시스템 재부팅 후에도 데이터가 영구적으로 보존될 수 있도록 변수 서비스의 실제 저장소 역할을 하는 OVMF_VARS.fd를 쓰기 가능한 플래시 드라이브로 추가한다. (앞서 만든 efi 파일은 UEFI_disk 폴더 내에 들어있다.)

 

 

 


2. 실습

 

 

2.1. 변수 확인

dmpstore -guid bb2a829f-7943-4691-a03a-f1f48519d7e6

UEFI 부팅 후 변수 확인을 위해 쉘 내장 명령어인 dmpstore를 통해 앞서 만든 SetVariableExample의 GUID에 해당하는 변수만 필터링해서 확인한다

처음에는 아무것도 없는 것을 확인할 수 있다.

 

 

 

 

2.2. 변수 생성

MyVar라는 이름의 속성 b(BS), 값은 Hello인 변수를 생성한다. 이후 2.1과 동일한 명령어를 확인해보면 변수가 정상적으로 생성된 것을 볼 수 있다.

 

 

 

 

2.3. 변수값 변경

동일한 변수에 새로운 값인 “Hello World”를 덮어쓰면, 값이 덮여 쓴 것을 확인할 수 있다.

 

 

 

 

2.4. 변수 삭제

이름만 전달할 시 DataSize를 0으로 전달하게 구현했으므로, 변수 이름만 입력할 시 값이 삭제되는 것을 확인할 수 있다.

 

dmpstore -d -guid bb2a829f-7943-4691-a03a-f1f48519d7e6 MyPersistentVar

쉘의 dmpstore -d 명령어를 통해서도 변수를 삭제할 수 있다.

 

 

 

 

2.5. 비휘발성, 휘발성 변수 검증

 

두 개의 변수를 서로 다른 속성으로 만든다.

MyPersistentVar는 NV + BS로 비휘발성이며 재부팅 후 유지된다. 반면 MyVar는 BS로 메모리 전용이며 재부팅 시 사라진다.  reset 명령어로 QEMU를 재시작한 후 다시 확인해보자

 

비휘발성인 MyPersistentVar  만 남아있는 것을 확인할 수 있다.

'CS > Graduation project' 카테고리의 다른 글

[UEFI] 기드라 스크립트 검증과 오탐 분석  (0) 2026.02.19
CVE-2021-39297 분석 및 실습  (0) 2026.02.14
[UEFI] 리눅스(WSL) 환경에서 EDK2 빌드 및 실행  (0) 2026.02.14
[UEFI] EDK2를 활용한 Stack Buffer Overflow 실습  (0) 2026.02.02
SMM 권한 상승과 Secure Boot 우회 (CVE-2025-7026, 3052)  (0) 2026.01.26
'CS/Graduation project' 카테고리의 다른 글
  • [UEFI] 기드라 스크립트 검증과 오탐 분석
  • CVE-2021-39297 분석 및 실습
  • [UEFI] 리눅스(WSL) 환경에서 EDK2 빌드 및 실행
  • [UEFI] EDK2를 활용한 Stack Buffer Overflow 실습
tteokbokki-master
tteokbokki-master
공부하며 알아가는 걸 조금씩 정리하고 있어요
  • tteokbokki-master
    용로그
    tteokbokki-master
  • 전체
    오늘
    어제
    • 분류 전체보기
      • CS
        • 컴파일러개론
        • Graduation project
      • 프로그래밍 언어
        • HTML & CSS
        • JavaScript
        • React 기초
        • 파이썬 기초
        • TanStack-Query
        • C언어 기초
        • git
        • 리눅스
        • 코딩테스트 공부
      • 개발 지식
      • 언어학
        • 의미론
      • 회고 및 기록
      • 프로젝트
        • TodoList 만들기
        • 학수고대 프로젝트
        • 2025 동계 모각코 (안조용희)
      • 기타
        • [JS-0기] 한입 FE 챌린지
        • 서평
  • 인기 글

  • 글쓰기 / 관리
  • hELLO· Designed By정상우.v4.10.3
tteokbokki-master
[UEFI] SetVariable()
상단으로

티스토리툴바