💻
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
  • MULTI_LINE
  • IFR
  • Note
  1. UEFI 개발
  2. VFR

66. VFR 추가 입력 요소 Part 2: string

Previous65. VFR 추가 입력 요소 Part 1: numberNext67. VFR 추가 입력 요소 Part 3: date & time

Last updated 2 years ago

이번 장에서는 다른 데이터 입력 VFR 요소를 살펴보겠다. - string

해당 요소는 CHAR16 문자열을 저장하기 위해 사용된다. 이전과 동일하게 minsize/maxsize 요소는 문자열에 필수로 사용되며 아래는 VFR 코드에 추가해야 하는 최소한의 코드이다.

string
  varid = FormData.StringValue,
  prompt = STRING_TOKEN(STRING_PROMPT),
  help = STRING_TOKEN(STRING_HELP),
  minsize = 5,
  maxsize = 10,
endstring;

당연히 Strings.uni 파일에도 새로운 토큰을 추가해야 한다.

#string STRING_PROMPT          #language en-US  "String prompt"
#string STRING_HELP            #language en-US  "String help"

UEFI_VARIABLE_STRUCTURE의 경우 크기가 최소 maxsize인 UINT16 요소의 배열을 추가해야 한다.

typedef struct {
  UINT8 CheckboxValue;
  UINT16 NumericValue;
  UINT16 StringValue[10];
} UEFI_VARIABLE_STRUCTURE;

배열의 크기가 maxsize보다 작은 경우 EDKII 빌드 시스템에서 오류를 반환한다.

ERROR 12288: String MaxSize can't be larger than the max number of elements in string array.

이전과 동일하게 업데이트된 드라이버를 로드하기 전에 이전 UEFI 변수를 삭제해야 한다.

Shell> dmpstore -guid 531bc507-9191-4fa2-9446-b844e35dd12a -d
Delete variable '531BC507-9191-4FA2-9446-B844E35DD12A:FormData': Success
Shell> load fs0:HIIFormDataElements.efi

실행을 하면 아래와 같은 화면을 볼 수 있다.

minsize를 5로 정의했기 때문에 5미만의 문자열 입력이 불가능하다.

또한 maxsize는 10으로 정의했기 때문에 10이상의 문자열을 입력 불가능하다. 이외에도 HII는 기호를 입력하는 것에도 제한을 한다.

이 모든 것을 고려해서 작성하면 성공적으로 데이터가 저장되는 것을 볼 수 있다.

이후 UEFI 변수를 확인하면 값이 저장된 것을 확인 가능하다.

Shell> dmpstore -guid 531bc507-9191-4fa2-9446-b844e35dd12a
Variable NV+BS '531BC507-9191-4FA2-9446-B844E35DD12A:FormData' DataSize = 0x17
  00000000: 00 00 00 55 00 45 00 46-00 49 00 2D 00 4C 00 65  *...U.E.F.I.-.L.e*
  00000010: 00 73 00 73 00 6F 00                             *.s.s.o.*

위의 값에서 보다시피 문자열에는 \0 종료 기호가 포함되어 있지 않다. 따라서 단순하게 배열 크기를 VFR maxsize 필드의 값보다 하나 크게 선언하는 것이 나을 수 있다 (예: CHAR16 StringValue[11]).

이렇게 하면 UEFI 변수에서 문자열 필드를 더 쉽게 파싱할 수 있다.

Shell> dmpstore -guid 531bc507-9191-4fa2-9446-b844e35dd12a
Variable NV+BS '531BC507-9191-4FA2-9446-B844E35DD12A:FormData' DataSize = 0x19
  00000000: 00 00 00 55 00 45 00 46-00 49 00 2D 00 4C 00 65  *...U.E.F.I.-.L.e*
  00000010: 00 73 00 73 00 6F 00 00-00                       *.s.s.o...*

MULTI_LINE

VFR 사양은 string 요소에 대한 MULTI_LINE 플래그를 정의한다.

string
  varid = FormData.StringValue,
  prompt = STRING_TOKEN(STRING_PROMPT),
  help = STRING_TOKEN(STRING_HELP),
  flags = MULTI_LINE,
  minsize = 5,
  maxsize = 10,
endstring;

이 플래그는 여러 줄의 텍스트가 허용될 수 있는 양식 브라우저에 대한 힌트로 작동해야 한다. 그러나 현재 OVMF 양식 브라우저는 해당 플래그를 사용하지 않는다.

IFR

Build/UefiLessonsPkg/RELEASE_GCC5/X64/UefiLessonsPkg/HIIFormDataElements/HIIFormDataElements/DEBUG/Form.lst에 존재하는 IFR 코드를 확인하자.

    string
>00000082: 1C 90 09 00 0A 00 03 00 01 00 03 00 00 05 0A 00
      varid = FormData.StringValue,
      prompt = STRING_TOKEN(0x0009),
      help = STRING_TOKEN(0x000A),
      minsize = 5,
      maxsize = 10,
    endstring;
>00000092: 29 02

해당 데이터는 EFI_IFR_STRING 구조체를 인코딩 한 것이다.

Summary:
Defines the string question.

Prototype:
#define EFI_IFR_STRING_OP 0x1C

typedef struct _EFI_IFR_STRING {
 EFI_IFR_OP_HEADER Header;
 EFI_IFR_QUESTION_HEADER Question;
 UINT8 MinSize;
 UINT8 MaxSize;
 UINT8 Flags;
} EFI_IFR_STRING;

Members:
Header 		The sequence that defines the type of opcode as well as the length of the opcode being defined.
		Header.OpCode = EFI_IFR_STRING_OP.
Question 	The standard question header.
MinSize 	The minimum number of characters that can be accepted for this opcode.
MaxSize 	The maximum number of characters that can be accepted for this opcode.
Flags 		Flags which control the string editing behavior.

Description:
This creates a string question. The minimum length is MinSize and the maximum length is MaxSize

데이터를 파싱할 수 있지만 실제로 새롭게 얻을 수 있는 것은 없다.

Note

해당 글을 쓰는 시점에서 EDKII 빌드 시스템을 속이고 크기가 10이지만 유형이 UINT8인 StringValue 배열을 선언할 수 있다. 해당 코드는 컴파일되지만 모든 것이 잘 될 수 있다고 기대해서는 안된다. 바로 지금 이렇게 속인 것으로 인하여 HII 시스템은 양식을 저장할 수 있게 되고 아무 에러도 나타나지 않는 것이다. 그러나 실제 값 데이터는 여전히 폼 데이터와 동일하지 않기 때문에 HII는 폼 데이터를 무한정으로 저장하도록 할 수 있다.

🖥️
https://edk2-docs.gitbook.io/edk-ii-vfr-specification/2_vfr_description_in_bnf/211_vfr_form_definition#2.11.6.7.1-vfr-string-statement-definition