PE 형식
이 사양은 Windows 운영 체제 제품군에 있는 실행 파일(이미지) 파일 및 개체 파일의 구조를 설명합니다. 이러한 파일은 각각 PE(이식 가능한 실행 파일) 및 COFF(공용 개체 파일 형식) 파일이라고 합니다.
참고
이 문서는 Windows용 도구 및 애플리케이션 개발을 지원하기 위해 제공되지만 모든 측면에서 완전한 사양이 될 수는 없습니다. Microsoft는 사전 통지 없이 이 문서를 변경할 권리를 보유합니다.
Microsoft PE(이식 가능한 실행 파일) 및 COFF(공용 개체 파일 형식) 사양의 이 수정 버전은 이 사양의 이전 수정 버전을 모두 대체합니다.
일반 개념
이 문서에서는 Microsoft Windows 운영 체제 제품군에 있는 실행 파일(이미지) 파일 및 개체 파일의 구조를 지정합니다. 이러한 파일은 각각 PE(이식 가능한 실행 파일) 및 COFF(공용 개체 파일 형식) 파일이라고 합니다. "이식 가능한 실행 파일"이라는 이름은 형식이 아키텍처에 따라 달라지지 않는다는 사실을 나타냅니다.
다음 표에서는 이 사양 전체에 나타나는 특정 개념을 설명합니다.
속성 | 설명 |
---|---|
특성 인증서 |
확인 가능한 명령문을 이미지와 연결하는 데 사용되는 인증서입니다. 다양한 확인 가능한 명령문이 파일과 연결될 수 있습니다. 가장 유용한 명령문 중 하나는 예상되는 이미지의 메시지 다이제스트를 나타내는 소프트웨어 제조업체의 명령문입니다. 메시지 다이제스트는 위조하기가 매우 어렵다는 점을 제외하면 체크섬과 비슷합니다. 따라서 원본 파일과 동일한 메시지 다이제스트를 포함하도록 파일을 수정하는 것은 매우 어렵습니다. 이 명령문은 공개 또는 프라이빗 키 암호화 체계를 사용하여 제조업체에서 만든 것으로 확인할 수 있습니다. 이 문서에서는 이미지 파일에 삽입할 수 있도록 허용하는 것 이외의 특성 인증서에 대한 세부 정보를 설명합니다. |
날짜/시간 스탬프 |
PE 또는 COFF 파일의 여러 위치에서 다른 용도로 사용되는 스탬프입니다. 대부분의 경우 각 스탬프의 형식은 C 런타임 라이브러리의 시간 함수에서 사용하는 형식과 동일합니다. 예외는 디버그 형식에서 IMAGE_DEBUG_TYPE_REPRO에 대한 설명을 참조하세요. 스탬프 값이 0 또는 0xFFFFFFFF인 경우 실제 또는 의미 있는 날짜/시간 스탬프를 나타내지 않습니다. |
파일 포인터 |
링커(개체 파일의 경우) 또는 로더(이미지 파일의 경우)에서 처리하기 전의 파일 자체 내 항목에 대한 위치입니다. 즉, 디스크에 저장된 파일 내의 위치입니다. |
링커 |
Microsoft Visual Studio를 통해 제공되는 링커에 대한 참조입니다. |
개체 파일 |
링커에 대한 입력으로 제공되는 파일입니다. 링커는 이미지 파일을 생성하며, 이에 따라 로더에서 이 파일을 입력으로 사용합니다. "개체 파일"이라는 용어가 반드시 개체 지향 프로그래밍에 대한 연결을 의미하지는 않습니다. |
예약됨, 0이어야 함 |
필드 값이 생성기에 대해 0이어야 하고 소비자가 이 필드를 무시해야 함을 나타내는 필드에 대한 설명입니다. |
RVA(상대 가상 주소) |
이미지 파일에서 이 주소는 메모리에 로드된 후의 항목의 주소에서 이미지 파일의 베이스 주소를 뺀 값입니다. 항목의 RVA는 거의 항상 디스크의 파일 내 위치(파일 포인터)와 다릅니다. 개체 파일에서 RVA는 메모리 위치가 할당되지 않으므로 의미가 적습니다. 이 경우 RVA는 나중에 재배치가 연결 중에 적용되는 섹션 내의 주소(이 표의 뒷부분에서 설명함)입니다. 간단히 하기 위해 컴파일러에서 각 섹션의 첫 번째 RVA를 0으로 설정해야 합니다. |
섹션 |
PE 또는 COFF 파일 내의 코드 또는 데이터의 기본 단위입니다. 예를 들어 개체 파일의 모든 코드는 단일 섹션 내에서 결합되거나(컴파일러 동작에 따라) 각 함수에서 자체 섹션을 차지할 수 있습니다. 섹션이 많을수록 파일 오버헤드가 더 커지지만 링커는 코드에서 더 선택적으로 연결할 수 있습니다. 섹션은 Intel 8086 아키텍처의 세그먼트와 비슷합니다. 섹션의 모든 원시 데이터는 연속적으로 로드해야 합니다. 또한 이미지 파일에는 특수 용도의 .tls 또는 .reloc와 같은 여러 섹션이 포함될 수 있습니다. |
VA(가상 주소) |
이미지 파일의 베이스 주소를 빼지 않는다는 점을 제외하면 RVA와 동일합니다. Windows에서 실제 메모리와 관계없이 각 프로세스에 대해 고유한 VA 공간을 만들므로 이 주소를 VA라고 합니다. 거의 모든 용도에서 VA는 주소로만 간주해야 합니다. 로더에서 이미지를 기본 설정 위치에 로드하지 않을 수 있으므로 VA는 RVA만큼 예측 가능하지 않습니다. |
개요
다음 목록에서는 이미지 헤더의 베이스가 맨 위에 있는 Microsoft PE 실행 파일 형식에 대해 설명합니다. MS-DOS 2.0 호환 EXE 헤더에서 PE 헤더 바로 앞의 unused 섹션까지의 섹션은 MS-DOS 2.0 섹션이며 MS-DOS 호환성 용도로만 사용됩니다.
MS-DOS 2.0 호환 EXE 헤더
unused
OEM 식별자
OEM 정보
PE 헤더로 오프셋
MS-DOS 2.0 스텁 프로그램 및 재배치 테이블
unused
PE 헤더(8바이트 경계에 맞춤)
섹션 헤더
이미지 페이지:
가져오기 정보
내보내기 정보
베이스 재배치
리소스 정보
다음 목록에서는 Microsoft COFF 개체 모듈 형식에 대해 설명합니다.
Microsoft COFF 헤더
섹션 헤더
원시 데이터:
코드
데이터
디버그 정보
재배치
파일 헤더
PE 파일 헤더는 Microsoft MS-DOS 스텁, PE 서명, COFF 파일 헤더 및 선택적 헤더로 구성됩니다. COFF 개체 파일 헤더는 COFF 파일 헤더와 선택적 헤더로 구성됩니다. 두 경우 모두에서 섹션 헤더는 파일 헤더 바로 뒤에 있습니다.
MS-DOS 스텁(이미지만 해당)
MS-DOS 스텁은 MS-DOS에서 실행되는 유효한 애플리케이션입니다. EXE 이미지의 앞에 배치됩니다. 링커는 이미지가 MS-DOS에서 실행될 때 "이 프로그램은 DOS 모드에서 실행할 수 없습니다."라는 메시지를 출력하는 기본 스텁을 여기에 배치합니다. 사용자는 /STUB 링커 옵션을 사용하여 다른 스텁을 지정할 수 있습니다.
0x3c 위치의 스텁에는 PE 서명에 대한 파일 오프셋이 있습니다. 이 정보를 사용하면 MS-DOS 스텁이 있더라도 Windows에서 이미지 파일을 제대로 실행할 수 있습니다. 이 파일 오프셋은 연결하는 동안 위치 0x3c에 배치됩니다.
서명(이미지만 해당)
MS-DOS 스텁 이후 0x3c 오프셋에 지정된 파일 오프셋에는 파일을 PE 형식 이미지 파일로 식별하는 4바이트 서명이 있습니다. 이 서명은 "PE\0\0"("P" 및 "E" 문자 뒤에 두 개의 null 바이트가 있음)입니다.
COFF 파일 헤더(개체 및 이미지)
개체 파일의 시작 또는 이미지 파일의 서명 바로 뒤에는 다음 형식의 표준 COFF 파일 헤더가 있습니다. Windows 로더는 섹션 수를 96개로 제한합니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
2 |
컴퓨터 |
대상 컴퓨터의 종류를 식별하는 번호입니다. 자세한 내용은 컴퓨터 종류를 참조하세요. |
2 |
2 |
NumberOfSections |
섹션 수입니다. 헤더 바로 다음에 오는 섹션 테이블의 크기를 나타냅니다. |
4 |
4 |
TimeDateStamp |
파일을 만든 시간을 나타내는 1970년 1월 1일 00:00(time_t C 런타임 값) 이후 초 수의 하위 32비트입니다. |
8 |
4 |
PointerToSymbolTable |
COFF 기호 테이블의 파일 오프셋이거나 COFF 기호 테이블이 없는 경우 0입니다. COFF 디버깅 정보가 더 이상 사용되지 않으므로 이미지의 경우 이 값은 0이어야 합니다. |
12 |
4 |
NumberOfSymbols |
기호 테이블의 항목 수입니다. 이 데이터를 사용하여 기호 테이블 바로 뒤에 오는 문자열 테이블을 찾을 수 있습니다. COFF 디버깅 정보가 더 이상 사용되지 않으므로 이미지의 경우 이 값은 0이어야 합니다. |
16 |
2 |
SizeOfOptionalHeader |
실행 파일에는 필요하지만 개체 파일에는 필요하지 않은 선택적 헤더의 크기입니다. 개체 파일의 경우 이 값이 0이어야 합니다. 헤더 형식에 대한 설명은 선택적 헤더(이미지만 해당)를 참조하세요. |
18 |
2 |
특징 |
파일의 특성을 나타내는 플래그입니다. 특정 플래그 값은 특성을 참조하세요. |
컴퓨터 종류
Machine 필드에는 CPU 종류를 지정하는 다음 값 중 하나가 있습니다. 이미지 파일은 지정된 컴퓨터 또는 지정된 컴퓨터를 에뮬레이트하는 시스템에서만 실행할 수 있습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_FILE_MACHINE_UNKNOWN |
0x0 |
이 필드의 콘텐츠는 모든 컴퓨터 종류에 적용할 수 있는 것으로 간주됩니다. |
IMAGE_FILE_MACHINE_ALPHA |
0x184 |
알파 AXP, 32비트 주소 공간 |
IMAGE_FILE_MACHINE_ALPHA64 |
0x284 |
알파 64, 64비트 주소 공간 |
IMAGE_FILE_MACHINE_AM33 |
0x1d3 |
Matsushita AM33 |
IMAGE_FILE_MACHINE_AMD64 |
0x8664 |
x64 |
IMAGE_FILE_MACHINE_ARM |
0x1c0 |
ARM little endian |
IMAGE_FILE_MACHINE_ARM64 |
0xaa64 |
ARM64 little endian |
IMAGE_FILE_MACHINE_ARMNT |
0x1c4 |
ARM Thumb-2 little endian |
IMAGE_FILE_MACHINE_AXP64 |
0x284 |
AXP 64(알파 64와 동일) |
IMAGE_FILE_MACHINE_EBC |
0xebc |
EFI 바이트 코드 |
IMAGE_FILE_MACHINE_I386 |
0x14c |
Intel 386 이상 프로세서 및 호환 프로세서 |
IMAGE_FILE_MACHINE_IA64 |
0x200 |
Intel Itanium 프로세서 제품군 |
IMAGE_FILE_MACHINE_LOONGARCH32 |
0x6232 |
LoongArch 32비트 프로세서 제품군 |
IMAGE_FILE_MACHINE_LOONGARCH64 |
0x6264 |
LoongArch 64비트 프로세서 제품군 |
IMAGE_FILE_MACHINE_M32R |
0x9041 |
Mitsubishi M32R little endian |
IMAGE_FILE_MACHINE_MIPS16 |
0x266 |
MIPS16 |
IMAGE_FILE_MACHINE_MIPSFPU |
0x366 |
FPU를 통한 MIPS |
IMAGE_FILE_MACHINE_MIPSFPU16 |
0x466 |
FPU를 통한 MIPS16 |
IMAGE_FILE_MACHINE_POWERPC |
0x1f0 |
Power PC little endian |
IMAGE_FILE_MACHINE_POWERPCFP |
0x1f1 |
Power PC(부동 소수점 지원 포함) |
IMAGE_FILE_MACHINE_R4000 |
0x166 |
MIPS little endian |
IMAGE_FILE_MACHINE_RISCV32 |
0x5032 |
RISC-V 32비트 주소 공간 |
IMAGE_FILE_MACHINE_RISCV64 |
0x5064 |
RISC-V 64비트 주소 공간 |
IMAGE_FILE_MACHINE_RISCV128 |
0x5128 |
RISC-V 128비트 주소 공간 |
IMAGE_FILE_MACHINE_SH3 |
0x1a2 |
Hitachi SH3 |
IMAGE_FILE_MACHINE_SH3DSP |
0x1a3 |
Hitachi SH3 DSP |
IMAGE_FILE_MACHINE_SH4 |
0x1a6 |
Hitachi SH4 |
IMAGE_FILE_MACHINE_SH5 |
0x1a8 |
Hitachi SH5 |
IMAGE_FILE_MACHINE_THUMB |
0x1c2 |
Thumb |
IMAGE_FILE_MACHINE_WCEMIPSV2 |
0x169 |
MIPS little-endian WCE v2 |
특징
Characteristics 필드에는 개체 또는 이미지 파일의 특성을 나타내는 플래그가 포함됩니다. 현재 정의되는 플래그는 다음과 같습니다.
플래그 | 값 | 설명 |
---|---|---|
IMAGE_FILE_RELOCS_STRIPPED |
0x0001 |
이미지만 해당, Windows CE 및 Microsoft Windows NT 이상. 베이스 재배치가 파일에 포함되지 않으므로 기본 설정 베이스 주소에 로드해야 함을 나타냅니다. 베이스 주소를 사용할 수 없는 경우 로더에서 오류를 보고합니다. 링커의 기본 동작은 실행 파일(EXE)에서 베이스 재배치를 제거하는 것입니다. |
IMAGE_FILE_EXECUTABLE_IMAGE |
0x0002 |
이미지만 해당. 이는 이미지 파일이 유효하고 실행할 수 있음을 나타냅니다. 이 플래그가 설정되지 않으면 링커 오류를 나타냅니다. |
IMAGE_FILE_LINE_NUMS_STRIPPED |
0x0004 |
COFF 줄 번호가 제거되었습니다. 이 플래그는 더 이상 사용되지 않으며 0이어야 합니다. |
IMAGE_FILE_LOCAL_SYMS_STRIPPED |
0x0008 |
로컬 기호에 대한 COFF 기호 테이블 항목이 제거되었습니다. 이 플래그는 더 이상 사용되지 않으며 0이어야 합니다. |
IMAGE_FILE_AGGRESSIVE_WS_TRIM |
0x0010 |
사용되지 않습니다. 작업 집합을 적극적으로 자릅니다. 이 플래그는 Windows 2000 이상에서 더 이상 사용되지 않으며 0이어야 합니다. |
IMAGE_FILE_LARGE_ADDRESS_ AWARE |
0x0020 |
애플리케이션에서 2GB가 넘는 주소를 처리할 수 있습니다. |
0x0040 |
이 플래그는 나중에 사용하도록 예약되어 있습니다. |
|
IMAGE_FILE_BYTES_REVERSED_LO |
0x0080 |
메모리에서 LSB(최하위 비트)가 MSB(최상위 비트) 앞에 오는 little endian 방식입니다. 이 플래그는 더 이상 사용되지 않으며 0이어야 합니다. |
IMAGE_FILE_32BIT_MACHINE |
0x0100 |
컴퓨터가 32비트 단어 아키텍처를 기반으로 합니다. |
IMAGE_FILE_DEBUG_STRIPPED |
0x0200 |
이미지 파일에서 디버깅 정보가 제거됩니다. |
IMAGE_FILE_REMOVABLE_RUN_ FROM_SWAP |
0x0400 |
이미지가 이동식 미디어에 있는 경우 이미지를 완전히 로드하고 스왑 파일에 복사합니다. |
IMAGE_FILE_NET_RUN_FROM_SWAP |
0x0800 |
이미지가 네트워크 미디어에 있는 경우 이미지를 완전히 로드하고 스왑 파일에 복사합니다. |
IMAGE_FILE_SYSTEM |
0x1000 |
이미지 파일이 사용자 프로그램이 아닌 시스템 파일입니다. |
IMAGE_FILE_DLL |
0x2000 |
이미지 파일이 DLL(동적 연결 라이브러리)입니다. 이러한 파일은 직접 실행할 수 없지만 거의 모든 용도에서 실행 파일로 간주됩니다. |
IMAGE_FILE_UP_SYSTEM_ONLY |
0x4000 |
파일을 단일 프로세서 컴퓨터에서만 실행해야 합니다. |
IMAGE_FILE_BYTES_REVERSED_HI |
0x8000 |
메모리에서 MSB가 LSB 앞에 오는 big endian 방식입니다. 이 플래그는 더 이상 사용되지 않으며 0이어야 합니다. |
선택적 헤더(이미지만 해당)
모든 이미지 파일에는 정보를 로더에 제공하는 선택적 헤더가 있습니다. 이 헤더는 일부 파일(특히 개체 파일)에 없다는 점에서 선택 사항입니다. 이미지 파일의 경우 이 헤더가 필요합니다. 개체 파일에는 선택적 헤더가 있을 수 있지만, 일반적으로 이 헤더에는 개체 파일의 크기를 늘리는 기능만 있습니다.
선택적 헤더의 크기는 고정되지 않습니다. COFF 헤더의 SizeOfOptionalHeader 필드는 특정 데이터 디렉터리의 파일에 대한 프로브가 SizeOfOptionalHeader를 초과하지 않는지 확인하는 데 사용해야 합니다. 자세한 내용은 COFF 파일 헤더(개체 및 이미지)를 참조하세요.
선택적 헤더의 NumberOfRvaAndSizes 필드도 특정 데이터 디렉터리 항목에 대한 프로브가 선택적 헤더를 초과하지 않도록 하는 데 사용해야 합니다. 또한 형식 호환성을 위해 선택적 헤더 매직 넘버의 유효성을 검사해야 합니다.
선택적 헤더 매직 넘버는 이미지가 PE32 또는 PE32+ 실행 파일인지 여부를 결정합니다.
매직 넘버 | PE 형식 |
---|---|
0x10b |
PE32 |
0x20b |
PE32+ |
PE32+ 이미지는 이미지 크기를 2GB로 제한하면서 64비트 주소 공간을 허용합니다. 다른 PE32+ 수정 사항은 해당 섹션에서 처리합니다.
선택적 헤더 자체에는 다음 세 가지 주요 부분이 있습니다.
오프셋(PE32/PE32+) | 크기(PE32/PE32+) | 헤더 부분 | 설명 |
---|---|---|---|
0 |
28/24 |
표준 필드 |
UNIX를 포함하여 COFF의 모든 구현에 대해 정의된 필드입니다. |
28/24 |
68/88 |
Windows 관련 필드 |
Windows의 특정 기능(예: 하위 시스템)을 지원하는 추가 필드입니다. |
96/112 |
변수 |
데이터 디렉터리 |
이미지 파일에 있고 운영 체제에서 사용되는 특수 테이블(예: 가져오기 테이블 및 내보내기 테이블)에 대한 주소/크기 쌍입니다. |
선택적 헤더 표준 필드(이미지만 해당)
선택적 헤더의 처음 8개 필드는 COFF의 모든 구현에 대해 정의된 표준 필드입니다. 이러한 필드에는 실행 파일을 로드하고 실행하는 데 유용한 일반 정보가 포함됩니다. PE32+ 형식에서는 변경되지 않습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
2 |
매직 |
이미지 파일의 상태를 식별하는 부호 없는 정수입니다. 가장 일반적인 숫자는 0x10B이며 일반 실행 파일로 식별합니다. 0x107은 ROM 이미지로 식별하고, 0x20B는 PE32+ 실행 파일로 식별합니다. |
2 |
1 |
MajorLinkerVersion |
링커 주 버전 번호입니다. |
3 |
1 |
MinorLinkerVersion |
링커 부 버전 번호입니다. |
4 |
4 |
SizeOfCode |
코드(텍스트) 섹션의 크기 또는 모든 코드 섹션의 합계(여러 섹션이 있는 경우)입니다. |
8 |
4 |
SizeOfInitializedData |
초기화된 데이터 섹션의 크기 또는 이러한 모든 섹션의 합계(여러 데이터 섹션이 있는 경우)입니다. |
12 |
4 |
SizeOfUninitializedData |
초기화되지 않은 데이터 섹션(BSS)의 크기 또는 이러한 모든 섹션의 합계(여러 BSS 섹션이 있는 경우)입니다. |
16 |
4 |
AddressOfEntryPoint |
실행 파일이 메모리에 로드될 때 이미지 베이스를 기준으로 하는 진입점의 주소입니다. 프로그램 이미지의 경우 시작 주소입니다. 디바이스 드라이버의 경우 초기화 함수의 주소입니다. DLL에 대한 진입점은 선택 사항입니다. 진입점이 없는 경우 이 필드는 0이어야 합니다. |
20 |
4 |
BaseOfCode |
메모리에 로드될 때 코드 시작 섹션의 이미지 베이스를 기준으로 하는 주소입니다. |
PE32에는 다음 추가 필드(PE32+에는 없음)가 BaseOfCode 뒤에 있습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
24 |
4 |
BaseOfData |
메모리에 로드될 때 데이터 시작 섹션의 이미지 베이스를 기준으로 하는 주소입니다. |
선택적 헤더 Windows 관련 필드(이미지만 해당)
다음 21개 필드는 COFF 선택적 헤더 형식의 확장입니다. 여기에는 Windows의 링커 및 로더에 필요한 추가 정보가 포함됩니다.
오프셋(PE32/ PE32+) | 사이즈(PE32/PE32+) | 필드 | 설명 |
---|---|---|---|
28/24 |
4/8 |
ImageBase |
메모리에 로드될 때 이미지의 첫 번째 바이트에 대한 기본 설정 주소입니다. 64K의 배수여야 합니다. DLL에 대한 기본값은 0x10000000입니다. Windows CE EXE에 대한 기본값은 0x00010000입니다. Windows NT, Windows 2000, Windows XP, Windows 95, Windows 98 및 Windows Me에 대한 기본값은 0x00400000입니다. |
32/32 |
4 |
SectionAlignment |
메모리에 로드되는 섹션의 맞춤(바이트)입니다. FileAlignment보다 크거나 같아야 합니다. 기본값은 아키텍처의 페이지 크기입니다. |
36/36 |
4 |
FileAlignment |
이미지 파일의 섹션 원시 데이터를 정렬하는 데 사용되는 맞춤 요소(바이트)입니다. 값은 512에서 64K까지의 2제곱이어야 합니다. 기본값은 512입니다. SectionAlignment가 아키텍처의 페이지 크기보다 작은 경우 FileAlignment는 SectionAlignment와 일치해야 합니다. |
40/40 |
2 |
MajorOperatingSystemVersion |
필수 운영 체제의 주 버전 번호입니다. |
42/42 |
2 |
MinorOperatingSystemVersion |
필수 운영 체제의 부 버전 번호입니다. |
44/44 |
2 |
MajorImageVersion |
브라우저의 주 버전 번호입니다. |
46/46 |
2 |
MinorImageVersion |
브라우저의 부 버전 번호입니다. |
48/48 |
2 |
MajorSubsystemVersion |
하위 시스템의 주 버전 번호입니다. |
50/50 |
2 |
MinorSubsystemVersion |
하위 시스템의 부 버전 번호입니다. |
52/52 |
4 |
Win32VersionValue |
예약됨, 0이어야 합니다. |
56/56 |
4 |
SizeOfImage |
이미지가 메모리에 로드될 때 모든 헤더를 포함한 이미지의 크기(바이트)입니다. SectionAlignment의 배수여야 합니다. |
60/60 |
4 |
SizeOfHeaders |
FileAlignment의 배수로 반올림된 MS-DOS 스텁, PE 헤더 및 섹션 헤더의 결합된 크기입니다. |
64/64 |
4 |
CheckSum |
이미지 파일 체크섬입니다. 체크섬을 계산하는 알고리즘은 IMAGHELP.DLL에 통합됩니다. 로드 시 유효성 검사를 위해 모든 드라이버, 부팅 시 로드되는 모든 DLL 및 중요한 Windows 프로세스에 로드되는 모든 DLL을 확인합니다. |
68/68 |
2 |
하위 시스템 |
이 이미지를 실행하는 데 필요한 하위 시스템입니다. 자세한 내용은 Windows 하위 시스템을 참조하세요. |
70/70 |
2 |
DllCharacteristics |
자세한 내용은 이 사양의 뒷부분에 있는 DLL 특성을 참조하세요. |
72/72 |
4/8 |
SizeOfStackReserve |
예약할 스택의 크기입니다. SizeOfStackCommit만 커밋됩니다. 나머지는 예약 크기에 도달할 때까지 한 번에 한 페이지씩 사용할 수 있습니다. |
76/80 |
4/8 |
SizeOfStackCommit |
커밋할 스택의 크기입니다. |
80/88 |
4/8 |
SizeOfHeapReserve |
예약할 로컬 힙 공간의 크기입니다. SizeOfHeapCommit만 커밋됩니다. 나머지는 예약 크기에 도달할 때까지 한 번에 한 페이지씩 사용할 수 있습니다. |
84/96 |
4/8 |
SizeOfHeapCommit |
커밋할 로컬 힙 공간의 크기입니다. |
88/104 |
4 |
LoaderFlags |
예약됨, 0이어야 합니다. |
92/108 |
4 |
NumberOfRvaAndSizes |
선택적 헤더의 나머지 부분에 있는 데이터 디렉터리 항목의 수입니다. 각 항목은 위치와 크기를 설명합니다. |
Windows 하위 시스템
이미지를 실행하는 데 필요한 Windows 하위 시스템(있는 경우)을 결정하는 선택적 헤더의 하위 시스템 필드에 대해 정의되는 값은 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_SUBSYSTEM_UNKNOWN |
0 |
알 수 없는 하위 시스템 |
IMAGE_SUBSYSTEM_NATIVE |
1 |
디바이스 드라이버 및 네이티브 Windows 프로세스 |
IMAGE_SUBSYSTEM_WINDOWS_GUI |
2 |
Windows GUI(그래픽 사용자 인터페이스) 하위 시스템 |
IMAGE_SUBSYSTEM_WINDOWS_CUI |
3 |
Windows 문자 하위 시스템 |
IMAGE_SUBSYSTEM_OS2_CUI |
5 |
OS/2 문자 하위 시스템 |
IMAGE_SUBSYSTEM_POSIX_CUI |
7 |
Posix 문자 하위 시스템 |
IMAGE_SUBSYSTEM_NATIVE_WINDOWS |
8 |
네이티브 Win9x 드라이버 |
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI |
9 |
Windows CE |
IMAGE_SUBSYSTEM_EFI_APPLICATION |
10 |
EFI(Extensible Firmware Interface) 애플리케이션 |
IMAGE_SUBSYSTEM_EFI_BOOT_ SERVICE_DRIVER |
11 |
부팅 서비스가 포함된 EFI 드라이버 |
IMAGE_SUBSYSTEM_EFI_RUNTIME_ DRIVER |
12 |
런타임 서비스가 포함된 EFI 드라이버 |
IMAGE_SUBSYSTEM_EFI_ROM |
13 |
EFI ROM 이미지 |
IMAGE_SUBSYSTEM_XBOX |
14 |
XBOX |
IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION |
16 |
Windows 부팅 애플리케이션. |
DLL 특성
선택적 헤더의 DllCharacteristics 필드에 대해 정의되는 값은 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
0x0001 |
예약됨, 0이어야 합니다. |
|
0x0002 |
예약됨, 0이어야 합니다. |
|
0x0004 |
예약됨, 0이어야 합니다. |
|
0x0008 |
예약됨, 0이어야 합니다. |
|
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
0x0020 |
이미지에서 높은 엔트로피 64비트 가상 주소 공간을 처리할 수 있습니다. |
IMAGE_DLLCHARACTERISTICS_ DYNAMIC_BASE |
0x0040 |
로드 시 DLL을 재배치할 수 있습니다. |
IMAGE_DLLCHARACTERISTICS_ FORCE_INTEGRITY |
0x0080 |
코드 무결성 검사를 적용합니다. |
IMAGE_DLLCHARACTERISTICS_ NX_COMPAT |
0x0100 |
이미지를 NX와 호환합니다. |
IMAGE_DLLCHARACTERISTICS_ NO_ISOLATION |
0x0200 |
격리를 인식하지만 이미지를 격리하지 않습니다. |
IMAGE_DLLCHARACTERISTICS_ NO_SEH |
0x0400 |
SE(구조적 예외) 처리를 사용하지 않습니다. 이 이미지에서 SE 처리기를 호출할 수 없습니다. |
IMAGE_DLLCHARACTERISTICS_ NO_BIND |
0x0800 |
이미지를 바인딩하지 않습니다. |
IMAGE_DLLCHARACTERISTICS_APPCONTAINER |
0x1000 |
AppContainer에서 이미지를 실행해야 합니다. |
IMAGE_DLLCHARACTERISTICS_ WDM_DRIVER |
0x2000 |
WDM 드라이버입니다. |
IMAGE_DLLCHARACTERISTICS_GUARD_CF |
0x4000 |
이미지에서 제어 흐름 보호를 지원합니다. |
IMAGE_DLLCHARACTERISTICS_ TERMINAL_SERVER_AWARE |
0x8000 |
터미널 서버를 인식합니다. |
선택적 헤더 데이터 디렉터리(이미지만 해당)
각 데이터 디렉터리는 Windows에서 사용하는 테이블 또는 문자열의 주소와 크기를 제공합니다. 시스템에서 런타임에 사용할 수 있도록 이러한 데이터 디렉터리 항목은 모두 메모리에 로드됩니다. 데이터 디렉터리는 다음 선언이 있는 8바이트 필드입니다.
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
첫 번째 필드인 VirtualAddress는 실제로 테이블의 RVA입니다. RVA는 테이블이 로드될 때 이미지의 베이스 주소를 기준으로 하는 테이블의 주소입니다. 두 번째 필드는 크기를 바이트 단위로 제공합니다. 선택적 헤더의 마지막 부분을 구성하는 데이터 디렉터리는 다음 표에 나열되어 있습니다.
디렉터리 수는 고정되지 않습니다. 특정 디렉터리를 찾기 전에 선택적 헤더에서 NumberOfRvaAndSizes 필드를 확인합니다.
또한 이 테이블의 RVA에서 섹션의 시작을 가리키거나 특정 이름이 특정 테이블이 포함된 섹션에 있다고 가정하지 마세요.
오프셋(PE/PE32+) | 크기 | 필드 | 설명 |
---|---|---|---|
96/112 |
8 |
Export Table |
내보내기 테이블 주소 및 크기입니다. 자세한 내용은 .edata 섹션(이미지만 해당)을 참조하세요. |
104/120 |
8 |
Import Table |
가져오기 테이블 주소 및 크기입니다. 자세한 내용은 .idata 섹션을 참조하세요. |
112/128 |
8 |
리소스 테이블 |
리소스 테이블 주소 및 크기입니다. 자세한 내용은 .rsrc 섹션을 참조하세요. |
120/136 |
8 |
예외 테이블 |
예외 테이블 주소 및 크기입니다. 자세한 내용은 .pdata 섹션을 참조하세요. |
128/144 |
8 |
인증서 테이블 |
특성 인증서 테이블 주소 및 크기입니다. 자세한 내용은 특성 인증서 테이블(이미지만 해당)을 참조하세요. |
136/152 |
8 |
베이스 재배치 테이블 |
베이스 재배치 테이블 주소 및 크기입니다. 자세한 내용은 .reloc 섹션(이미지만 해당)을 참조하세요. |
144/160 |
8 |
디버그 |
디버그 데이터 시작 주소 및 크기입니다. 자세한 내용은 .debug 섹션을 참조하세요. |
152/168 |
8 |
아키텍처 |
예약됨, 0이어야 함 |
160/176 |
8 |
Global Ptr |
전역 포인터 레지스터에 저장할 값의 RVA입니다. 이 구조체의 size 멤버는 0으로 설정해야 합니다. |
168/184 |
8 |
TLS 테이블 |
TLS(스레드 로컬 스토리지) 테이블 주소 및 크기입니다. 자세한 내용은 .tls 섹션을 참조하세요. |
176/192 |
8 |
로드 구성 테이블 |
로드 구성 테이블 주소 및 크기입니다. 자세한 내용은 로드 구성 구조체(이미지만 해당)를 참조하세요. |
184/200 |
8 |
바인딩된 가져오기 |
바인딩된 가져오기 테이블 주소 및 크기입니다. |
192/208 |
8 |
IAT |
가져오기 주소 테이블 주소 및 크기입니다. 자세한 내용은 가져오기 주소 테이블을 참조하세요. |
200/216 |
8 |
지연 가져오기 설명자 |
지연 가져오기 설명자 주소 및 크기입니다. 자세한 내용은 지연 로드 가져오기 테이블(이미지만 해당)을 참조하세요. |
208/224 |
8 |
CLR Runtime Header |
CLR 런타임 헤더 주소 및 크기입니다. 자세한 내용은 .cormeta 섹션(개체만 해당)을 참조하세요. |
216/232 |
8 |
예약됨, 0이어야 함 |
Certificate Table 항목은 특성 인증서 테이블을 가리킵니다. 이러한 인증서는 이미지의 일부로 메모리에 로드되지 않습니다. 따라서 일반적으로 RVA인 이 항목의 첫 번째 필드는 대신 파일 포인터입니다.
섹션 테이블(섹션 헤더)
섹션 테이블의 각 행은 사실상 섹션 헤더입니다. 이 테이블은 선택적 헤더(있는 경우) 바로 뒤에 옵니다. 파일 헤더에는 섹션 테이블에 대한 직접 포인터가 포함되지 않으므로 이 위치 지정이 필요합니다. 대신 섹션 테이블의 위치는 헤더 뒤 첫 번째 바이트의 위치를 계산하여 결정됩니다. 파일 헤더에 지정된 선택적 헤더의 크기를 사용해야 합니다.
섹션 테이블의 항목 수는 파일 헤더의 NumberOfSections 필드에서 지정됩니다. 섹션 테이블의 항목은 1부터 시작하여 번호가 매겨집니다. 코드 및 데이터 메모리 섹션 항목은 링커에서 선택한 순서대로 있습니다.
이미지 파일에서 섹션에 대한 VA는 오름차순으로 인접하도록 링커에서 할당해야 하며 선택적 헤더의 SectionAlignment 값의 배수여야 합니다.
각 섹션 헤더(섹션 테이블 항목)의 형식은 항목당 총 40바이트입니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
8 |
입력 |
UTF-8로 인코딩된 null 패딩 8바이트 문자열입니다. 문자열의 길이가 정확히 8자이면 종료 null이 없습니다. 더 긴 이름의 경우 이 필드에는 슬래시(/) 뒤에 문자열 테이블에 대한 오프셋인 10진수의 ASCII 표현이 포함됩니다. 실행 파일 이미지는 문자열 테이블을 사용하지 않으며 8자보다 긴 섹션 이름을 지원하지 않습니다. 개체 파일의 긴 이름은 실행 파일로 내보내는 경우 잘립니다. |
8 |
4 |
VirtualSize |
메모리에 로드될 때 섹션의 전체 크기입니다. 이 값이 SizeOfRawData보다 큰 경우 섹션이 0으로 채워집니다. 이 필드는 실행 파일 이미지에만 유효하며, 개체 파일의 경우 0으로 설정해야 합니다. |
12 |
4 |
VirtualAddress |
실행 파일 이미지의 경우 섹션이 메모리에 로드될 때 이미지 베이스를 기준으로 하는 섹션의 첫 번째 바이트 주소입니다. 개체 파일의 경우 이 필드는 재배치가 적용되기 전의 첫 번째 바이트에 대한 주소입니다. 간단히 하기 위해 컴파일러에서 이 값을 0으로 설정해야 합니다. 그렇지 않으면 재배치 중에 오프셋에서 빼는 임의의 값입니다. |
16 |
4 |
SizeOfRawData |
섹션의 크기(개체 파일의 경우) 또는 디스크에서 초기화된 데이터의 크기(이미지 파일의 경우)입니다. 실행 파일 이미지의 경우 선택적 헤더에 있는 FileAlignment의 배수여야 합니다. 이 값이 VirtualSize보다 작은 경우 섹션의 나머지 부분은 0으로 채워집니다. SizeOfRawData 필드는 반올림되지만 VirtualSize 필드는 반올림되지 않으므로 SizeOfRawData도 VirtualSize보다 클 수 있습니다. 초기화되지 않은 데이터만 섹션에 포함되는 경우 이 필드는 0이어야 합니다. |
20 |
4 |
PointerToRawData |
COFF 파일 내에 있는 섹션의 첫 번째 페이지를 가리키는 파일 포인터입니다. 실행 파일 이미지의 경우 선택적 헤더에 있는 FileAlignment의 배수여야 합니다. 개체 파일의 경우 최상의 성능을 위해 값을 4바이트 경계에 맞춰야 합니다. 초기화되지 않은 데이터만 섹션에 포함되는 경우 이 필드는 0이어야 합니다. |
24 |
4 |
PointerToRelocations |
섹션에 대한 재배치 항목의 시작을 가리키는 파일 포인터입니다. 실행 파일 이미지의 경우 또는 재배치가 없는 경우 0으로 설정됩니다. |
28 |
4 |
PointerToLinenumbers |
섹션에 대한 줄 번호 항목의 시작을 가리키는 파일 포인터입니다. COFF 줄 번호가 없는 경우 0으로 설정됩니다. COFF 디버깅 정보가 더 이상 사용되지 않으므로 이미지의 경우 이 값은 0이어야 합니다. |
32 |
2 |
NumberOfRelocations |
섹션에 대한 재배치 항목의 수입니다. 실행 파일 이미지의 경우 0으로 설정됩니다. |
34 |
2 |
NumberOfLinenumbers |
섹션에 대한 줄 번호 항목의 수입니다. COFF 디버깅 정보가 더 이상 사용되지 않으므로 이미지의 경우 이 값은 0이어야 합니다. |
36 |
4 |
특징 |
섹션의 특성을 설명하는 플래그입니다. 자세한 내용은 섹션 플래그를 참조하세요. |
섹션 플래그
섹션 헤더의 Characteristics 필드에 있는 섹션 플래그는 섹션의 특성을 나타냅니다.
플래그 | 값 | 설명 |
---|---|---|
0x00000000 |
향후 사용을 위해 예약되어 있습니다. |
|
0x00000001 |
향후 사용을 위해 예약되어 있습니다. |
|
0x00000002 |
향후 사용을 위해 예약되어 있습니다. |
|
0x00000004 |
향후 사용을 위해 예약되어 있습니다. |
|
IMAGE_SCN_TYPE_NO_PAD |
0x00000008 |
섹션을 다음 경계까지 채우지 않습니다. 이 플래그는 더 이상 사용되지 않으며 IMAGE_SCN_ALIGN_1BYTES로 대체됩니다. 개체 파일에만 유효합니다. |
0x00000010 |
향후 사용을 위해 예약되어 있습니다. |
|
IMAGE_SCN_CNT_CODE |
0x00000020 |
실행 코드가 섹션에 포함됩니다. |
IMAGE_SCN_CNT_INITIALIZED_DATA |
0x00000040 |
초기화된 데이터가 섹션에 포함됩니다. |
IMAGE_SCN_CNT_UNINITIALIZED_ DATA |
0x00000080 |
초기화되지 않은 데이터가 섹션에 포함됩니다. |
IMAGE_SCN_LNK_OTHER |
0x00000100 |
향후 사용을 위해 예약되어 있습니다. |
IMAGE_SCN_LNK_INFO |
0x00000200 |
주석 또는 기타 정보가 섹션에 포함됩니다. .drectve 섹션에는 이 형식이 있습니다. 개체 파일에만 유효합니다. |
0x00000400 |
향후 사용을 위해 예약되어 있습니다. |
|
IMAGE_SCN_LNK_REMOVE |
0x00000800 |
섹션이 이미지의 일부가 되지 않습니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_LNK_COMDAT |
0x00000100 |
COMDAT 데이터가 섹션에 포함됩니다. 자세한 내용은 COMDAT 섹션(개체만 해당)을 참조하세요. 개체 파일에만 유효합니다. |
IMAGE_SCN_GPREL |
0x00008000 |
GP(전역 포인터)를 통해 참조되는 데이터가 섹션에 포함됩니다. |
IMAGE_SCN_MEM_PURGEABLE |
0x00020000 |
향후 사용을 위해 예약되어 있습니다. |
IMAGE_SCN_MEM_16BIT |
0x00020000 |
향후 사용을 위해 예약되어 있습니다. |
IMAGE_SCN_MEM_LOCKED |
0x00040000 |
향후 사용을 위해 예약되어 있습니다. |
IMAGE_SCN_MEM_PRELOAD |
0x00080000 |
향후 사용을 위해 예약되어 있습니다. |
IMAGE_SCN_ALIGN_1BYTES |
0x00100000 |
데이터를 1바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_2BYTES |
0x00200000 |
데이터를 2바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_4BYTES |
0x00300000 |
데이터를 4바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_8BYTES |
0x00400000 |
데이터를 8바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_16BYTES |
0x00500000 |
데이터를 16바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_32BYTES |
0x00600000 |
데이터를 32바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_64BYTES |
0x00700000 |
데이터를 64바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_128BYTES |
0x00800000 |
데이터를 128바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_256BYTES |
0x00900000 |
데이터를 256바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_512BYTES |
0x00A00000 |
데이터를 512바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_1024BYTES |
0x00B00000 |
데이터를 1,024바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_2048BYTES |
0x00C00000 |
데이터를 2,048바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_4096BYTES |
0x00D00000 |
데이터를 4,096바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_ALIGN_8192BYTES |
0x00E00000 |
데이터를 8,192바이트 경계에 맞춥니다. 개체 파일에만 유효합니다. |
IMAGE_SCN_LNK_NRELOC_OVFL |
0x01000000 |
확장 재배치가 섹션에 포함됩니다. |
IMAGE_SCN_MEM_DISCARDABLE |
0x02000000 |
필요에 따라 섹션을 삭제할 수 있습니다. |
IMAGE_SCN_MEM_NOT_CACHED |
0x04000000 |
섹션을 캐시할 수 없습니다. |
IMAGE_SCN_MEM_NOT_PAGED |
0x08000000 |
섹션을 페이징할 수 없습니다. |
IMAGE_SCN_MEM_SHARED |
0x10000000 |
메모리에서 섹션을 공유할 수 있습니다. |
IMAGE_SCN_MEM_EXECUTE |
0x20000000 |
섹션을 코드로 실행할 수 있습니다. |
IMAGE_SCN_MEM_READ |
0x40000000 |
섹션을 읽을 수 있습니다. |
IMAGE_SCN_MEM_WRITE |
0x80000000 |
섹션에 쓸 수 있습니다. |
IMAGE_SCN_LNK_NRELOC_OVFL은 섹션에 대한 재배치 횟수가 섹션 헤더에 예약된 16비트를 초과함을 나타냅니다. 비트가 설정되고 섹션 헤더의 NumberOfRelocations 필드가 0xffff인 경우 실제 재배치 횟수는 첫 번째 재배치의 32비트 VirtualAddress 필드에 저장됩니다. IMAGE_SCN_LNK_NRELOC_OVFL이 설정되고 섹션의 0xffff 재배치 미만인 경우 오류입니다.
그룹화된 섹션(개체만 해당)
'$' 문자(달러 기호)에는 개체 파일의 섹션 이름에서 특별한 해석이 있습니다.
객체 섹션의 콘텐츠를 포함할 이미지 섹션을 결정할 때 링커는 "$"와 그 뒤에 오는 모든 문자를 삭제합니다. 따라서 .text$X라는 개체 섹션은 실제로 이미지의 .text 섹션에 기여합니다.
그러나 "$" 뒤에 오는 문자에 따라 이미지 섹션에 대한 기여 순서가 결정됩니다. 개체 섹션 이름이 동일한 모든 기여는 이미지에서 연속적으로 할당되며, 기여 블록은 개체 섹션 이름별로 어휘 순서로 정렬됩니다. 따라서 섹션 이름이 .text$X인 개체 파일의 모든 항목은 .text$W 기여 후와 .text$Y 기여 전에 모두 끝납니다.
이미지 파일의 섹션 이름에는 "$" 문자가 포함되지 않습니다.
파일의 기타 콘텐츠
- 섹션 데이터
- COFF 재배치(개체만 해당)
- COFF 줄 번호(사용되지 않음)
- COFF 기호 테이블
- 보조 기호 레코드
- COFF 문자열 테이블
- 특성 인증서 테이블(이미지만 해당)
- 지연 로드 가져오기 테이블(이미지만 해당)
선택적 헤더를 포함하여 지금까지 설명한 데이터 구조체는 모두 파일 시작(또는 파일이 MS-DOS 스텁을 포함하는 이미지인 경우 PE 헤더)으로부터의 고정된 오프셋에 있습니다.
COFF 개체 또는 이미지 파일의 나머지 부분에는 반드시 특정 파일 오프셋에 없는 데이터 블록이 포함됩니다. 대신, 위치는 선택적 헤더 또는 섹션 헤더의 포인터로 정의됩니다.
단, SectionAlignment 값이 아키텍처의 페이지 크기(Intel x86 및 MIPS의 경우 4K, Itanium의 경우 8K)보다 작은 이미지는 예외입니다. SectionAlignment에 대한 설명은 선택적 헤더(이미지만 해당)를 참조하세요. 이 경우 섹션 5.1 "섹션 데이터"에서 설명한 대로 섹션 데이터의 파일 오프셋에 대한 제약 조건이 있습니다. 또 다른 예외는 로더에서 이러한 제약 조건을 메모리에 매핑하지 않으므로 특성 인증서 및 디버그 정보를 디버그 섹션 바로 앞에 있는 특성 인증서 테이블과 함께 이미지 파일의 맨 끝에 배치해야 한다는 것입니다. 그러나 특성 인증서 및 디버그 정보에 대한 규칙은 개체 파일에 적용되지 않습니다.
섹션 데이터
섹션의 초기화된 데이터는 간단한 바이트 블록으로 구성됩니다. 그러나 0이 모두 포함된 섹션의 경우 섹션 데이터를 포함할 필요가 없습니다.
각 섹션의 데이터는 섹션 헤더의 PointerToRawData 필드에서 지정한 파일 오프셋에 있습니다. 파일에서 이 데이터의 크기는 SizeOfRawData 필드로 표시됩니다. SizeOfRawData가 VirtualSize보다 작은 경우 나머지 부분은 0으로 채워집니다.
이미지 파일에서 섹션 데이터는 선택적 헤더의 FileAlignment 필드에서 지정한 대로 경계에 맞춰야 합니다. 섹션 데이터는 해당 섹션의 RVA 값 순서대로 표시해야 합니다(섹션 테이블의 개별 섹션 헤더도 마찬가지임).
선택적 헤더의 SectionAlignment 값이 아키텍처의 페이지 크기보다 작은 경우 이미지 파일에 대한 추가 제한이 있습니다. 이러한 파일의 경우 섹션 데이터의 물리적 오프셋이 RVA와 동일하도록 이미지가 로드될 때 파일의 섹션 데이터 위치가 메모리에서의 위치와 일치해야 합니다.
COFF 재배치(개체만 해당)
개체 파일에는 이미지 파일에 배치하여 메모리에 로드할 때 섹션 데이터를 수정하는 방법을 지정하는 COFF 재배치가 포함됩니다.
플랫 주소 공간의 주소가 참조된 모든 기호에 이미 할당되어 있으므로 이미지 파일에는 COFF 재배치가 포함되지 않습니다. IMAGE_FILE_RELOCS_STRIPPED 특성이 이미지에 있는 경우를 제외하고는 재배치 정보가 .reloc 섹션의 베이스 재배치 형식으로 이미지에 포함됩니다. 자세한 내용은 .reloc 섹션(이미지만 해당)을 참조하세요.
개체 파일의 각 섹션에 대한 고정 길이 레코드 배열에는 섹션의 COFF 재배치가 있습니다. 배열의 위치와 길이는 섹션 헤더에 지정됩니다. 배열의 각 요소에 대한 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
VirtualAddress |
재배치가 적용되는 항목의 주소입니다. 섹션 시작으로부터의 오프셋과 섹션의 RVA/오프셋 필드 값을 더한 값입니다. 섹션 테이블(섹션 헤더)을 참조하세요. 예를 들어 섹션의 첫 번째 바이트의 주소가 0x10인 경우 세 번째 바이트의 주소는 0x12입니다. |
4 |
4 |
SymbolTableIndex |
0부터 시작하는 기호 테이블에 대한 인덱스입니다. 이 기호는 재배치에 사용할 주소를 제공합니다. 섹션 스토리지 클래스가 지정된 기호에 있는 경우 기호의 주소는 동일한 이름의 첫 번째 섹션이 있는 주소입니다. |
8 |
2 |
입력 |
수행해야 하는 재배치의 종류를 나타내는 값입니다. 유효한 재배치 형식은 컴퓨터 종류에 따라 달라집니다. 형식 표시기를 참조하세요. |
IMAGE_SYM_CLASS_SECTION 스토리지 클래스가 SymbolTableIndex 필드에서 참조하는 기호에 있는 경우 기호의 주소는 섹션의 시작입니다. 개체 파일이 보관(라이브러리)의 일부인 경우를 제외하고 이 섹션은 일반적으로 동일한 파일에 있습니다. 이 경우 섹션은 현재 개체 파일과 동일한 보관 멤버 이름이 있는 보관의 다른 개체 파일에서 찾을 수 있습니다. (보관 멤버 이름과의 관계는 가져오기 테이블, 즉 .idata 섹션의 연결에 사용됩니다.)
형식 표시기
재배치 레코드의 Type 필드는 수행해야 하는 재배치의 종류를 나타냅니다. 컴퓨터 종류마다 다른 재배치 형식이 정의됩니다.
x64 프로세서
x64 및 호환 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_AMD64_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_AMD64_ADDR64 |
0x0001 |
재배치 대상의 64비트 VA입니다. |
IMAGE_REL_AMD64_ADDR32 |
0x0002 |
재배치 대상의 32비트 VA입니다. |
IMAGE_REL_AMD64_ADDR32NB |
0x0003 |
이미지 베이스가 없는 32비트 주소(RVA)입니다. |
IMAGE_REL_AMD64_REL32 |
0x0004 |
재배치 뒤에 있는 바이트의 32비트 상대 주소입니다. |
IMAGE_REL_AMD64_REL32_1 |
0x0005 |
재배치에서의 바이트 거리 1을 기준으로 하는 32비트 주소입니다. |
IMAGE_REL_AMD64_REL32_2 |
0x0006 |
재배치에서의 바이트 거리 2를 기준으로 하는 32비트 주소입니다. |
IMAGE_REL_AMD64_REL32_3 |
0x0007 |
재배치에서의 바이트 거리 3을 기준으로 하는 32비트 주소입니다. |
IMAGE_REL_AMD64_REL32_4 |
0x0008 |
재배치에서의 바이트 거리 4를 기준으로 하는 32비트 주소입니다. |
IMAGE_REL_AMD64_REL32_5 |
0x0009 |
재배치에서의 바이트 거리 5를 기준으로 하는 32비트 주소입니다. |
IMAGE_REL_AMD64_SECTION |
0x000A |
대상이 포함된 섹션의 16비트 섹션 인덱스입니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_AMD64_SECREL |
0x000B |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_AMD64_SECREL7 |
0x000C |
대상이 포함된 섹션의 베이스로부터의 부호 없는 7비트 오프셋입니다. |
IMAGE_REL_AMD64_TOKEN |
0x000D |
CLR 토큰입니다. |
IMAGE_REL_AMD64_SREL32 |
0x000E |
개체로 내보내는 부호 있는 32비트 범위 종속 값입니다. |
IMAGE_REL_AMD64_PAIR |
0x000F |
모든 범위 종속 값 바로 뒤에 있어야 하는 쌍입니다. |
IMAGE_REL_AMD64_SSPAN32 |
0x0010 |
링크 타임에 적용되는 부호 있는 32비트 범위 종속 값입니다. |
ARM 프로세서
ARM 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_ARM_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_ARM_ADDR32 |
0x0001 |
대상의 32비트 VA입니다. |
IMAGE_REL_ARM_ADDR32NB |
0x0002 |
대상의 32비트 RVA입니다. |
IMAGE_REL_ARM_BRANCH24 |
0x0003 |
대상에 대한 24비트 상대 변위입니다. |
IMAGE_REL_ARM_BRANCH11 |
0x0004 |
서브루틴 호출에 대한 참조입니다. 참조는 11비트 오프셋이 있는 두 개의 16비트 명령으로 구성됩니다. |
IMAGE_REL_ARM_REL32 |
0x000A |
재배치 뒤에 있는 바이트의 32비트 상대 주소입니다. |
IMAGE_REL_ARM_SECTION |
0x000E |
대상이 포함된 섹션의 16비트 섹션 인덱스입니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_ARM_SECREL |
0x000F |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_ARM_MOV32 |
0x0010 |
대상의 32비트 VA입니다. 이 재배치는 하위 16비트에 대한 MOVW 명령과 상위 16비트에 대한 MOVT를 사용하여 적용됩니다. |
IMAGE_REL_THUMB_MOV32 |
0x0011 |
대상의 32비트 VA입니다. 이 재배치는 하위 16비트에 대한 MOVW 명령과 상위 16비트에 대한 MOVT를 사용하여 적용됩니다. |
IMAGE_REL_THUMB_BRANCH20 |
0x0012 |
명령은 2바이트 맞춤 대상에 대한 21비트 상대 변위로 수정됩니다. 변위의 최하위 비트는 항상 0이며 저장되지 않습니다. 이 재배치는 Thumb-2 32비트 조건부 B 명령에 해당합니다. |
사용 안 함 |
0x0013 |
|
IMAGE_REL_THUMB_BRANCH24 |
0x0014 |
명령은 2바이트 맞춤 대상에 대한 25비트 상대 변위로 수정됩니다. 변위의 최하위 비트는 0이며 저장되지 않습니다. 이 재배치는 Thumb-2 B 명령에 해당합니다. |
IMAGE_REL_THUMB_BLX23 |
0x0015 |
명령은 4바이트 맞춤 대상에 대한 25비트 상대 변위로 수정됩니다. 변위의 하위 2비트는 0이며 저장되지 않습니다. 이 재배치는 Thumb-2 BLX 명령에 해당합니다. |
IMAGE_REL_ARM_PAIR |
0x0016 |
재배치는 ARM_REFHI 또는 THUMB_REFHI 바로 뒤에 있는 경우에만 유효합니다. SymbolTableIndex에는 기호 테이블에 대한 인덱스가 아닌 변위가 포함됩니다. |
ARM64 프로세서
ARM64 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_ARM64_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_ARM64_ADDR32 |
0x0001 |
대상의 32비트 VA입니다. |
IMAGE_REL_ARM64_ADDR32NB |
0x0002 |
대상의 32비트 RVA입니다. |
IMAGE_REL_ARM64_BRANCH26 |
0x0003 |
B 및 BL 명령에 대한 대상의 26비트 상대 변위입니다. |
IMAGE_REL_ARM64_PAGEBASE_REL21 |
0x0004 |
ADRP 명령에 대한 대상의 페이지 베이스입니다. |
IMAGE_REL_ARM64_REL21 |
0x0005 |
ADR 명령에 대한 대상의 12비트 상대 변위입니다. |
IMAGE_REL_ARM64_PAGEOFFSET_12A |
0x0006 |
0 이동이 있는 ADD/ADDS 명령에 대한 대상의 12비트 페이지 오프셋(immediate)입니다. |
IMAGE_REL_ARM64_PAGEOFFSET_12L |
0x0007 |
LDR 명령에 대한 대상의 12비트 페이지 오프셋(인덱싱되고 부호 없는 immediate)입니다. |
IMAGE_REL_ARM64_SECREL |
0x0008 |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_ARM64_SECREL_LOW12A |
0x0009 |
0 이동이 있는 ADD/ADDS 명령에 대한 대상의 0:11비트 섹션 오프셋(immediate)입니다. |
IMAGE_REL_ARM64_SECREL_HIGH12A |
0x000A |
0 이동이 있는 ADD/ADDS 명령에 대한 대상의 12:23비트 섹션 오프셋(immediate)입니다. |
IMAGE_REL_ARM64_SECREL_LOW12L |
0x000B |
LDR 명령에 대한 대상의 0:11비트 섹션 오프셋(인덱싱되고 부호 없는 immediate)입니다. |
IMAGE_REL_ARM64_TOKEN |
0x000C |
CLR 토큰입니다. |
IMAGE_REL_ARM64_SECTION |
0x000D |
대상이 포함된 섹션의 16비트 섹션 인덱스입니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_ARM64_ADDR64 |
0x000E |
재배치 대상의 64비트 VA입니다. |
IMAGE_REL_ARM64_BRANCH19 |
0x000F |
조건부 B 명령에 대한 재배치 대상의 19비트 오프셋입니다. |
IMAGE_REL_ARM64_BRANCH14 |
0x0010 |
TBZ 및 TBNZ 명령에 대한 재배치 대상의 14비트 오프셋입니다. |
IMAGE_REL_ARM64_REL32 |
0x0011 |
재배치 뒤에 있는 바이트의 32비트 상대 주소입니다. |
Hitachi SuperH 프로세서
SH3 및 SH4 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다. SH5 관련 재배치는 SHM(SH Media)으로 표시됩니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_SH3_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_SH3_DIRECT16 |
0x0001 |
대상 기호의 VA가 포함된 16비트 위치에 대한 참조입니다. |
IMAGE_REL_SH3_DIRECT32 |
0x0002 |
대상 기호의 32비트 VA입니다. |
IMAGE_REL_SH3_DIRECT8 |
0x0003 |
대상 기호의 VA가 포함된 8비트 위치에 대한 참조입니다. |
IMAGE_REL_SH3_DIRECT8_WORD |
0x0004 |
대상 기호의 유효 16비트 VA가 포함된 8비트 명령에 대한 참조입니다. |
IMAGE_REL_SH3_DIRECT8_LONG |
0x0005 |
대상 기호의 유효 32비트 VA가 포함된 8비트 명령에 대한 참조입니다. |
IMAGE_REL_SH3_DIRECT4 |
0x0006 |
하위 4비트에 대상 기호의 VA가 포함된 8비트 위치에 대한 참조입니다. |
IMAGE_REL_SH3_DIRECT4_WORD |
0x0007 |
하위 4비트에 대상 기호의 유효 16비트 VA가 포함된 8비트 명령에 대한 참조입니다. |
IMAGE_REL_SH3_DIRECT4_LONG |
0x0008 |
하위 4비트에 대상 기호의 유효 32비트 VA가 포함된 8비트 명령에 대한 참조입니다. |
IMAGE_REL_SH3_PCREL8_WORD |
0x0009 |
대상 기호의 유효 16비트 상대 오프셋이 포함된 8비트 명령에 대한 참조입니다. |
IMAGE_REL_SH3_PCREL8_LONG |
0x000A |
대상 기호의 유효 32비트 상대 오프셋이 포함된 8비트 명령에 대한 참조입니다. |
IMAGE_REL_SH3_PCREL12_WORD |
0x000B |
하위 12비트에 대상 기호의 유효 16비트 상대 오프셋이 포함된 16비트 명령에 대한 참조입니다. |
IMAGE_REL_SH3_STARTOF_SECTION |
0x000C |
대상 기호가 포함된 섹션의 VA인 32비트 위치에 대한 참조입니다. |
IMAGE_REL_SH3_SIZEOF_SECTION |
0x000D |
대상 기호가 포함된 섹션의 크기인 32비트 위치에 대한 참조입니다. |
IMAGE_REL_SH3_SECTION |
0x000E |
대상이 포함된 섹션의 16비트 섹션 인덱스입니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_SH3_SECREL |
0x000F |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_SH3_DIRECT32_NB |
0x0010 |
대상 기호의 32비트 RVA입니다. |
IMAGE_REL_SH3_GPREL4_LONG |
0x0011 |
GP를 기준으로 합니다. |
IMAGE_REL_SH3_TOKEN |
0x0012 |
CLR 토큰입니다. |
IMAGE_REL_SHM_PCRELPT |
0x0013 |
긴 단어(longword)의 현재 명령으로부터의 오프셋입니다. NOMODE 비트가 설정되지 않은 경우 32비트에서 하위 비트의 역을 삽입하여 PTA 또는 PTB를 선택합니다. |
IMAGE_REL_SHM_REFLO |
0x0014 |
32비트 주소의 하위 16입니다. |
IMAGE_REL_SHM_REFHALF |
0x0015 |
32비트 주소의 상위 16비트입니다. |
IMAGE_REL_SHM_RELLO |
0x0016 |
상대 주소의 하위 16비트입니다. |
IMAGE_REL_SHM_RELHALF |
0x0017 |
상대 주소의 상위 16비트입니다. |
IMAGE_REL_SHM_PAIR |
0x0018 |
재배치는 REFHALF, RELHALF 또는 RELLO 재배치 바로 뒤에 있는 경우에만 유효합니다. 재배치의 SymbolTableIndex 필드에는 기호 테이블에 대한 인덱스가 아닌 변위가 포함됩니다. |
IMAGE_REL_SHM_NOMODE |
0x8000 |
재배치에서 섹션 모드를 무시합니다. |
IBM PowerPC 프로세서
PowerPC 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_PPC_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_PPC_ADDR64 |
0x0001 |
대상의 64비트 VA입니다. |
IMAGE_REL_PPC_ADDR32 |
0x0002 |
대상의 32비트 VA입니다. |
IMAGE_REL_PPC_ADDR24 |
0x0003 |
대상 VA의 하위 24비트입니다. 대상 기호가 절댓값이고 원래 값으로 부호 확장할 수 있는 경우에만 유효합니다. |
IMAGE_REL_PPC_ADDR16 |
0x0004 |
대상 VA의 하위 16비트입니다. |
IMAGE_REL_PPC_ADDR14 |
0x0005 |
대상 VA의 하위 14비트입니다. 대상 기호가 절댓값이고 원래 값으로 부호 확장할 수 있는 경우에만 유효합니다. |
IMAGE_REL_PPC_REL24 |
0x0006 |
기호 위치에 대한 24비트 PC 기준 상대 오프셋입니다. |
IMAGE_REL_PPC_REL14 |
0x0007 |
기호 위치에 대한 14비트 PC 기준 상대 오프셋입니다. |
IMAGE_REL_PPC_ADDR32NB |
0x000A |
대상의 32비트 RVA입니다. |
IMAGE_REL_PPC_SECREL |
0x000B |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_PPC_SECTION |
0x000C |
대상이 포함된 섹션의 16비트 섹션 인덱스입니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_PPC_SECREL16 |
0x000F |
해당 섹션의 시작으로부터의 대상의 16비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_PPC_REFHI |
0x0010 |
대상의 32비트 VA 중 상위 16비트입니다. 전체 주소를 로드하는 두 명령 시퀀스의 첫 번째 명령에 사용됩니다. 이 재배치 바로 뒤에는 재배치되는 위치에서 가져온 상위 16비트에 추가하는 부호 있는 16비트 변위가 SymbolTableIndex에 포함된 PAIR 재배치가 있어야 합니다. |
IMAGE_REL_PPC_REFLO |
0x0011 |
대상 VA의 하위 16비트입니다. |
IMAGE_REL_PPC_PAIR |
0x0012 |
REFHI 또는 SECRELHI 재배치 바로 뒤에 있는 경우에만 유효한 재배치입니다. SymbolTableIndex에는 기호 테이블에 대한 인덱스가 아닌 변위가 포함됩니다. |
IMAGE_REL_PPC_SECRELLO |
0x0013 |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋 중 하위 16비트입니다. |
IMAGE_REL_PPC_GPREL |
0x0015 |
GP 레지스터를 기준으로 하는 대상의 부호 있는 16비트 변위입니다. |
IMAGE_REL_PPC_TOKEN |
0x0016 |
CLR 토큰입니다. |
Intel 386 프로세서
Intel 386 및 호환 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_I386_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_I386_DIR16 |
0x0001 |
지원되지 않습니다. |
IMAGE_REL_I386_REL16 |
0x0002 |
지원되지 않습니다. |
IMAGE_REL_I386_DIR32 |
0x0006 |
대상의 32비트 VA입니다. |
IMAGE_REL_I386_DIR32NB |
0x0007 |
대상의 32비트 RVA입니다. |
IMAGE_REL_I386_SEG12 |
0x0009 |
지원되지 않습니다. |
IMAGE_REL_I386_SECTION |
0x000A |
대상이 포함된 섹션의 16비트 섹션 인덱스입니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_I386_SECREL |
0x000B |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_I386_TOKEN |
0x000C |
CLR 토큰입니다. |
IMAGE_REL_I386_SECREL7 |
0x000D |
대상이 포함된 섹션의 베이스로부터의 7비트 오프셋입니다. |
IMAGE_REL_I386_REL32 |
0x0014 |
대상에 대한 32비트 상대 변위입니다. x86 상대 분기 및 호출 명령을 지원합니다. |
Intel IPF(Itanium 프로세서 제품군)
Intel Itanium 프로세서 제품군 및 호환 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다. 명령에 대한 재배치는 번들의 오프셋 및 슬롯 번호를 재배치 오프셋에 사용합니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_IA64_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_IA64_IMM14 |
0x0001 |
명령 재배치 뒤에는 값이 IMM14 번들의 지정된 슬롯에 삽입되기 전에 해당 값이 대상 주소에 추가되는 ADDEND 재배치가 있을 수 있습니다. 재배치 대상은 절댓값이거나 이미지가 고정되어 있어야 합니다. |
IMAGE_REL_IA64_IMM22 |
0x0002 |
명령 재배치 뒤에는 값이 IMM22 번들의 지정된 슬롯에 삽입되기 전에 해당 값이 대상 주소에 추가되는 ADDEND 재배치가 있을 수 있습니다. 재배치 대상은 절댓값이거나 이미지가 고정되어 있어야 합니다. |
IMAGE_REL_IA64_IMM64 |
0x0003 |
이 재배치의 슬롯 번호는 1이어야 합니다. 재배치 뒤에는 값이 IMM64 번들의 세 슬롯 모두에 저장되기 전에 해당 값이 대상 주소에 추가되는 ADDEND 재배치가 있을 수 있습니다. |
IMAGE_REL_IA64_DIR32 |
0x0004 |
대상의 32비트 VA입니다. /LARGEADDRESSAWARE:NO 이미지에 대해서만 지원됩니다. |
IMAGE_REL_IA64_DIR64 |
0x0005 |
대상의 64비트 VA입니다. |
IMAGE_REL_IA64_PCREL21B |
0x0006 |
명령은 16비트 맞춤 대상에 대한 25비트 상대 변위로 수정됩니다. 변위의 하위 4비트는 0이며 저장되지 않습니다. |
IMAGE_REL_IA64_PCREL21M |
0x0007 |
명령은 16비트 맞춤 대상에 대한 25비트 상대 변위로 수정됩니다. 0인 변위의 하위 4비트는 저장되지 않습니다. |
IMAGE_REL_IA64_PCREL21F |
0x0008 |
이 재배치 오프셋의 LSB는 슬롯 번호를 포함해야 하며, 나머지는 번들 주소입니다. 번들은 16비트 맞춤 대상에 대한 25비트 상대 변위로 수정됩니다. 변위의 하위 4비트는 0이며 저장되지 않습니다. |
IMAGE_REL_IA64_GPREL22 |
0x0009 |
명령 재배치 뒤에는 값이 대상 주소에 추가된 ADDEND 재배치 및 계산되고 GPREL22 번들에 적용되는 22비트 GP 기준 상대 오프셋이 차례로 있을 수 있습니다. |
IMAGE_REL_IA64_LTOFF22 |
0x000A |
명령은 대상 기호의 리터럴 테이블 항목에 대한 22비트 GP 기준 상대 오프셋으로 수정됩니다. 링커는 이 재배치 및 그 뒤에 있을 수 있는 ADDEND 재배치에 따라 이 리터럴 테이블 항목을 만듭니다. |
IMAGE_REL_IA64_SECTION |
0x000B |
대상이 섹션의 16비트 섹션 인덱스에 포함됩니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_IA64_SECREL22 |
0x000C |
명령은 해당 섹션의 시작으로부터의 대상의 22비트 오프셋으로 수정됩니다. 이 재배치 뒤에는 섹션 시작으로부터의 대상의 부호 없는 32비트 오프셋이 Value 필드에 포함된 ADDEND 재배치가 있을 수 있습니다. |
IMAGE_REL_IA64_SECREL64I |
0x000D |
이 재배치의 슬롯 번호는 1이어야 합니다. 명령은 해당 섹션의 시작으로부터의 대상의 64비트 오프셋으로 수정됩니다. 이 재배치 뒤에는 섹션 시작으로부터의 대상의 부호 없는 32비트 오프셋이 Value 필드에 포함된 ADDEND 재배치가 있을 수 있습니다. |
IMAGE_REL_IA64_SECREL32 |
0x000E |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋으로 수정할 데이터의 주소입니다. |
IMAGE_REL_IA64_DIR32NB |
0x0010 |
대상의 32비트 RVA입니다. |
IMAGE_REL_IA64_SREL14 |
0x0011 |
재배치 가능한 두 대상 간의 차이가 포함된 부호 있는 14비트 immediate에 적용됩니다. 컴파일러에서 이 값을 이미 내보냈음을 나타내는 링커의 선언적 필드입니다. |
IMAGE_REL_IA64_SREL22 |
0x0012 |
재배치 가능한 두 대상 간의 차이가 포함된 부호 있는 22비트 immediate에 적용됩니다. 컴파일러에서 이 값을 이미 내보냈음을 나타내는 링커의 선언적 필드입니다. |
IMAGE_REL_IA64_SREL32 |
0x0013 |
재배치 가능한 두 값 간의 차이가 포함된 부호 있는 32비트 immediate에 적용됩니다. 컴파일러에서 이 값을 이미 내보냈음을 나타내는 링커의 선언적 필드입니다. |
IMAGE_REL_IA64_UREL32 |
0x0014 |
재배치 가능한 두 값 간의 차이가 포함된 부호 없는 32비트 immediate에 적용됩니다. 컴파일러에서 이 값을 이미 내보냈음을 나타내는 링커의 선언적 필드입니다. |
IMAGE_REL_IA64_PCREL60X |
0x0015 |
항상 MLX 번들의 BRL 명령으로 유지되는 60비트 PC 기준 상대 수정입니다. |
IMAGE_REL_IA64_PCREL60B |
0x0016 |
60비트 PC 기준 상대 수정입니다. 대상 변위가 부호 있는 25비트 필드에 맞는 경우 전체 번들을 슬롯 1의 NOP.B와 슬롯 2의 25비트(4개의 최하위 비트가 모두 0이고 삭제됨) BR 명령이 있는 MBB 번들로 변환합니다. |
IMAGE_REL_IA64_PCREL60F |
0x0017 |
60비트 PC 기준 상대 수정입니다. 대상 변위가 부호 있는 25비트 필드에 맞는 경우 전체 번들을 슬롯 1의 NOP.F와 슬롯 2의 25비트(4개의 최하위 비트가 모두 0이고 삭제됨) BR 명령이 있는 MFB 번들로 변환합니다. |
IMAGE_REL_IA64_PCREL60I |
0x0018 |
60비트 PC 기준 상대 수정입니다. 대상 변위가 부호 있는 25비트 필드에 맞는 경우 전체 번들을 슬롯 1의 NOP.I와 슬롯 2의 25비트(4개의 최하위 비트가 모두 0이고 삭제됨) BR 명령이 있는 MIB 번들로 변환합니다. |
IMAGE_REL_IA64_PCREL60M |
0x0019 |
60비트 PC 기준 상대 수정입니다. 대상 변위가 부호 있는 25비트 필드에 맞는 경우 전체 번들을 슬롯 1의 NOP.M과 슬롯 2의 25비트(4개의 최하위 비트가 모두 0이고 삭제됨) BR 명령이 있는 MMB 번들로 변환합니다. |
IMAGE_REL_IA64_IMMGPREL64 |
0x001a |
64비트 GP 기준 상대 수정입니다. |
IMAGE_REL_IA64_TOKEN |
0x001b |
CLR 토큰입니다. |
IMAGE_REL_IA64_GPREL32 |
0x001c |
32비트 GP 기준 상대 수정입니다. |
IMAGE_REL_IA64_ADDEND |
0x001F |
재배치는 IMM14, IMM22, IMM64, GPREL22, LTOFF22, LTOFF64, SECREL22, SECREL64I 또는 SECREL32 재배치 중 하나 바로 뒤에 있는 경우에만 유효합니다. 해당 값에는 데이터가 아닌 번들 내의 지침에 적용할 추가 콘텐츠가 포함됩니다. |
MIPS 프로세서
MIPS 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_MIPS_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_MIPS_REFHALF |
0x0001 |
대상의 32비트 VA 중 상위 16비트입니다. |
IMAGE_REL_MIPS_REFWORD |
0x0002 |
대상의 32비트 VA입니다. |
IMAGE_REL_MIPS_JMPADDR |
0x0003 |
대상 VA의 하위 26비트입니다. MIPS J 및 JAL 명령을 지원합니다. |
IMAGE_REL_MIPS_REFHI |
0x0004 |
대상의 32비트 VA 중 상위 16비트입니다. 전체 주소를 로드하는 두 명령 시퀀스의 첫 번째 명령에 사용됩니다. 이 재배치 바로 뒤에는 재배치되는 위치에서 가져온 상위 16비트에 추가하는 부호 있는 16비트 변위가 SymbolTableIndex에 포함된 PAIR 재배치가 있어야 합니다. |
IMAGE_REL_MIPS_REFLO |
0x0005 |
대상 VA의 하위 16비트입니다. |
IMAGE_REL_MIPS_GPREL |
0x0006 |
GP 레지스터를 기준으로 하는 대상의 부호 있는 16비트 변위입니다. |
IMAGE_REL_MIPS_LITERAL |
0x0007 |
IMAGE_REL_MIPS_GPREL과 동일합니다. |
IMAGE_REL_MIPS_SECTION |
0x000A |
대상이 섹션의 16비트 섹션 인덱스에 포함됩니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_MIPS_SECREL |
0x000B |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_MIPS_SECRELLO |
0x000C |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋 중 하위 16비트입니다. |
IMAGE_REL_MIPS_SECRELHI |
0x000D |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋 중 상위 16비트입니다. IMAGE_REL_MIPS_PAIR 재배치는 이 재배치 바로 뒤에 있어야 합니다. PAIR 재배치의 SymbolTableIndex에는 재배치되는 위치에서 가져온 상위 16비트에 추가하는 부호 있는 16비트 변위가 포함됩니다. |
IMAGE_REL_MIPS_JMPADDR16 |
0x0010 |
대상 VA의 하위 26비트입니다. MIPS16 JAL 명령을 지원합니다. |
IMAGE_REL_MIPS_REFWORDNB |
0x0022 |
대상의 32비트 RVA입니다. |
IMAGE_REL_MIPS_PAIR |
0x0025 |
재배치는 REFHI 또는 SECRELHI 재배치 바로 뒤에 있는 경우에만 유효합니다. SymbolTableIndex에는 기호 테이블에 대한 인덱스가 아닌 변위가 포함됩니다. |
Mitsubishi M32R
Mitsubishi M32R 프로세서에 대해 정의되는 재배치 형식 표시기는 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_M32R_ABSOLUTE |
0x0000 |
재배치가 무시됩니다. |
IMAGE_REL_M32R_ADDR32 |
0x0001 |
대상의 32비트 VA입니다. |
IMAGE_REL_M32R_ADDR32NB |
0x0002 |
대상의 32비트 RVA입니다. |
IMAGE_REL_M32R_ADDR24 |
0x0003 |
대상의 24비트 VA입니다. |
IMAGE_REL_M32R_GPREL16 |
0x0004 |
GP 레지스터로부터의 대상의 16비트 오프셋입니다. |
IMAGE_REL_M32R_PCREL24 |
0x0005 |
PC(프로그램 카운터)로부터의 대상의 24비트 오프셋이며, 왼쪽으로 2비트 이동하고 부호 확장합니다. |
IMAGE_REL_M32R_PCREL16 |
0x0006 |
PC로부터의 대상의 16비트 오프셋이며, 왼쪽으로 2비트 이동하고 부호 확장합니다. |
IMAGE_REL_M32R_PCREL8 |
0x0007 |
PC로부터의 대상의 8비트 오프셋이며, 왼쪽으로 2비트 이동하고 부호 확장합니다. |
IMAGE_REL_M32R_REFHALF |
0x0008 |
대상 VA의 16MSB입니다. |
IMAGE_REL_M32R_REFHI |
0x0009 |
LSB 부호 확장에 맞게 조정된 대상 VA의 16MSB입니다. 전체 32비트 주소를 로드하는 두 명령 시퀀스의 첫 번째 명령에 사용됩니다. 이 재배치 바로 뒤에는 재배치되는 위치에서 가져온 상위 16비트에 추가하는 부호 있는 16비트 변위가 SymbolTableIndex에 포함된 PAIR 재배치가 있어야 합니다. |
IMAGE_REL_M32R_REFLO |
0x000A |
대상 VA의 16LSB입니다. |
IMAGE_REL_M32R_PAIR |
0x000B |
재배치는 REFHI 재배치 뒤에 있어야 합니다. SymbolTableIndex에는 기호 테이블에 대한 인덱스가 아닌 변위가 포함됩니다. |
IMAGE_REL_M32R_SECTION |
0x000C |
대상이 포함된 섹션의 16비트 섹션 인덱스입니다. 디버깅 정보를 지원하는 데 사용됩니다. |
IMAGE_REL_M32R_SECREL |
0x000D |
해당 섹션의 시작으로부터의 대상의 32비트 오프셋입니다. 디버깅 정보 및 정적 스레드 로컬 스토리지를 지원하는 데 사용됩니다. |
IMAGE_REL_M32R_TOKEN |
0x000E |
CLR 토큰입니다. |
COFF 줄 번호(사용되지 않음)
COFF 줄 번호는 더 이상 생성되지 않으며 나중에도 사용되지 않습니다.
COFF 줄 번호는 소스 파일의 코드와 줄 번호 간의 관계를 나타냅니다. COFF 줄 번호에 대한 Microsoft 형식은 표준 COFF와 비슷하지만 단일 섹션이 여러 소스 파일의 줄 번호와 관련될 수 있도록 확장되었습니다.
COFF 줄 번호는 고정 길이 레코드의 배열로 구성됩니다. 배열의 위치(파일 오프셋) 및 크기는 섹션 헤더에 지정됩니다. 각 줄 번호 레코드의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
형식(*) |
SymbolTableIndex 및 VirtualAddress라는 두 필드의 공용 구조체입니다. SymbolTableIndex 또는 RVA를 사용할지 여부는 Linenumber 값에 따라 달라집니다. |
4 |
2 |
Linenumber |
0이 아닌 경우 이 필드는 1부터 시작하는 줄 번호를 지정합니다. 0인 경우 Type 필드는 함수의 기호 테이블 인덱스로 해석됩니다. |
Type 필드는 SymbolTableIndex 및 VirtualAddress라는 두 개의 4바이트 필드로 구성된 공용 구조체입니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
SymbolTableIndex |
Linenumber가 0인 경우 사용됩니다. 함수의 기호 테이블 항목에 대한 인덱스입니다. 이 형식은 줄 번호 레코드 그룹에서 참조하는 함수를 나타내는 데 사용됩니다. |
0 |
4 |
VirtualAddress |
Linenumber가 0이 아닌 경우 사용됩니다. 표시된 소스 줄에 해당하는 실행 코드의 RVA입니다. 개체 파일에서 섹션 내의 VA가 포함됩니다. |
줄 번호 레코드는 Linenumber 필드를 0으로 설정하고 기호 테이블의 함수 정의를 가리키거나 개체 코드에서 양의 정수(줄 번호)와 해당 주소를 지정하여 표준 줄 번호 항목으로 작동할 수 있습니다.
줄 번호 항목 그룹은 항상 첫 번째 형식인 함수 기호의 인덱스로 시작합니다. 섹션의 첫 번째 줄 번호 레코드인 경우 섹션의 COMDAT 플래그가 설정되면 함수의 COMDAT 기호 이름이기도 합니다. COMDAT 섹션(개체만 해당)을 참조하세요. 기호 테이블에 있는 함수의 보조 레코드에는 이 동일한 줄 번호 레코드를 가리키는 Linenumber 필드에 대한 포인터가 있습니다.
함수를 식별하는 레코드 뒤에는 실제 줄 번호 정보를 제공하는 여러 줄 번호 항목(즉, Linenumber가 0보다 큰 항목)이 옵니다. 이러한 항목은 함수의 시작을 기준으로 1부터 시작하며 첫 번째 줄을 제외한 함수의 모든 소스 줄을 나타냅니다.
예를 들어 다음 예제의 첫 번째 줄 번호 레코드는 ReverseSign 함수(ReverseSign의 SymbolTableIndex 및 Linenumber가 0으로 설정됨)를 지정합니다. 그런 다음, Linenumber 값이 1, 2, 3인 레코드가 뒤따르며 이는 다음과 같이 소스 줄에 해당합니다.
// some code precedes ReverseSign function
int ReverseSign(int i)
1: {
2: return -1 * i;
3: }
COFF 기호 테이블
이 섹션의 기호 테이블은 기존 COFF 형식에서 상속됩니다. Microsoft Visual C++ 디버그 정보와는 다릅니다. 파일에는 COFF 기호 테이블과 Visual C++ 디버그 정보가 모두 포함될 수 있으며 이러한 두 항목은 별도로 유지됩니다. 일부 Microsoft 도구는 COMDAT 정보를 링커에 전달하는 것과 같이 제한적이지만 중요한 용도로 기호 테이블을 사용합니다. 기호 테이블에는 섹션 이름과 파일 이름 외에도 코드 및 데이터 기호가 나열됩니다.
기호 테이블의 위치는 COFF 헤더에 표시됩니다.
기호 테이블은 각각 18바이트 길이의 레코드 배열입니다. 각 레코드는 표준 또는 보조 기호 테이블 레코드입니다. 표준 레코드는 기호 또는 이름을 정의하며, 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
8 |
입력(*) |
세 가지 구조체의 공용 구조체로 표현되는 기호의 이름입니다. 이름이 8바이트 이하인 경우 8바이트 배열이 사용됩니다. 자세한 내용은 기호 이름 표현을 참조하세요. |
8 |
4 |
값 |
기호와 관련된 값입니다. 이 필드의 해석은 SectionNumber 및 StorageClass에 따라 달라집니다. 일반적인 의미는 재배치 가능한 주소입니다. |
12 |
2 |
SectionNumber |
1부터 시작하는 섹션 테이블에 대한 인덱스를 사용하여 섹션을 식별하는 부호 있는 정수입니다. 일부 값에는 섹션 5.4.2 "섹션 번호 값"에서 정의한 대로 특별한 의미가 있습니다. |
14 |
2 |
입력 |
형식을 나타내는 숫자입니다. Microsoft 도구는 이 필드를 0x20(함수) 또는 0x0(함수 아님)으로 설정합니다. 자세한 내용은 형식 표현을 참조하세요. |
16 |
1 |
StorageClass |
스토리지 클래스를 나타내는 열거형 값입니다. 자세한 내용은 스토리지 클래스를 참조하세요. |
17 |
1 |
NumberOfAuxSymbols |
이 레코드 뒤에 있는 보조 기호 테이블 항목의 수입니다. |
0개 이상의 보조 기호 테이블 레코드는 각 표준 기호 테이블 레코드 바로 뒤에 있습니다. 그러나 일반적으로 표준 기호 테이블 레코드 뒤에는 하나 이하의 보조 기호 테이블 레코드가 있습니다(파일 이름이 긴 .file 레코드 제외). 각 보조 레코드는 표준 기호 테이블 레코드(18바이트)와 크기가 동일하지만, 새 기호를 정의하는 대신 보조 레코드에서 정의된 마지막 기호에 대한 추가 정보를 제공합니다. 사용할 여러 형식 중에서 선택할 수 있는 형식은 StorageClass 필드에 따라 달라집니다. 현재 보조 기호 테이블 레코드에 대해 정의된 형식은 섹션 5.5 "보조 기호 레코드"에 나와 있습니다.
COFF 기호 테이블을 읽는 도구는 해석할 수 없는 보조 기호 레코드를 무시해야 합니다. 이렇게 하면 기존 도구를 중단하지 않고 기호 테이블 형식을 확장하여 새 보조 레코드를 추가할 수 있습니다.
기호 이름 표현
길이가 8바이트를 넘지 않거나 기호 테이블의 ShortName 필드에서 오프셋을 문자열 테이블에 제공하는 경우 ShortName 필드는 이름 자체를 포함하는 8바이트로 구성됩니다. 이름 자체 또는 오프셋이 제공되는지 여부를 확인하려면 처음 4바이트가 0과 같은지 테스트합니다.
규칙에 따라 이름은 0으로 끝나는 UTF-8로 인코딩된 문자열로 처리됩니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
8 |
ShortName |
8바이트 배열입니다. 이름이 8바이트 미만인 경우 이 배열의 오른쪽이 null로 채워집니다. |
0 |
4 |
0 |
이름이 8바이트를 초과하는 경우 모두 0으로 설정되는 필드입니다. |
4 |
4 |
오프셋 |
문자열 테이블에 대한 오프셋입니다. |
섹션 번호 값
일반적으로 기호 테이블 항목의 Section Value 필드는 1부터 시작하는 섹션 테이블에 대한 인덱스입니다. 그러나 이 필드는 부호 있는 정수이며 음수 값을 사용할 수 있습니다. 1 미만의 다음 값에는 특별한 의미가 있습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_SYM_UNDEFINED |
0 |
기호 레코드에 섹션이 아직 할당되어 있지 않습니다. 0 값은 외부 기호에 대한 참조가 다른 곳에 정의되어 있음을 나타냅니다. 0이 아닌 값은 값으로 지정된 크기의 공통 기호입니다. |
IMAGE_SYM_ABSOLUTE |
-1 |
기호에는 주소가 아닌 절댓값(재배치 불가능)이 있습니다. |
IMAGE_SYM_DEBUG |
2- |
기호는 일반 형식 또는 디버깅 정보를 제공하지만 섹션에 해당하지 않습니다. Microsoft 도구는 .file 레코드(FILE 스토리지 클래스)와 함께 이 설정을 사용합니다. |
형식 표현
기호 테이블 항목의 Type 필드에는 각 바이트에서 형식 정보를 나타내는 2바이트가 포함됩니다. LSB는 단순(기본) 데이터 형식을 나타내고, MSB는 복합 형식(있는 경우)을 나타냅니다.
MSB | LSB |
---|---|
복합 형식: 없음, 포인터, 함수, 배열. |
기본 형식: 정수, 부동 소수점 등 |
Microsoft 도구는 일반적으로 이 필드를 사용하지 않고 LSB를 0으로 설정하지만, 다음 값은 기본 형식에 대해 정의됩니다. 대신 Visual C++ 디버그 정보를 사용하여 형식을 나타냅니다. 그러나 완전히 설명하기 위해 가능한 COFF 값이 여기에 나와 있습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_SYM_TYPE_NULL |
0 |
형식 정보 또는 알 수 없는 기본 형식이 없습니다. Microsoft 도구는 이 설정을 사용합니다. |
IMAGE_SYM_TYPE_VOID |
1 |
유효한 형식이 없습니다. void 포인터 및 함수와 함께 사용됩니다. |
IMAGE_SYM_TYPE_CHAR |
2 |
문자(부호 있는 바이트) |
IMAGE_SYM_TYPE_SHORT |
3 |
부호 있는 2바이트 정수 |
IMAGE_SYM_TYPE_INT |
4 |
자연 정수 형식(Windows에서는 일반적으로 4바이트) |
IMAGE_SYM_TYPE_LONG |
5 |
부호 있는 4바이트 정수 |
IMAGE_SYM_TYPE_FLOAT |
6 |
4바이트 부동 소수점 숫자 |
IMAGE_SYM_TYPE_DOUBLE |
7 |
8바이트 부동 소수점 숫자 |
IMAGE_SYM_TYPE_STRUCT |
8 |
구조체 |
IMAGE_SYM_TYPE_UNION |
9 |
공용 구조체 |
IMAGE_SYM_TYPE_ENUM |
10 |
열거형 |
IMAGE_SYM_TYPE_MOE |
11 |
열거형 멤버(특정 값) |
IMAGE_SYM_TYPE_BYTE |
12 |
바이트, 부호 없는 1바이트 정수 |
IMAGE_SYM_TYPE_WORD |
13 |
단어, 부호 없는 2바이트 정수 |
IMAGE_SYM_TYPE_UINT |
14 |
일반 크기의 부호 없는 정수(일반적으로 4바이트) |
IMAGE_SYM_TYPE_DWORD |
15 |
부호 없는 4바이트 정수 |
최상위 바이트는 기호가 LSB에 지정된 기본 형식의 포인터, 함수 반환 또는 배열인지 여부를 지정합니다. Microsoft 도구는 이 필드를 사용하여 기호가 함수인지 여부만 나타내므로 Type 필드에 대한 유일한 두 개의 결과 값은 0x0 및 0x20입니다. 그러나 다른 도구는 이 필드를 사용하여 더 많은 정보를 전달할 수 있습니다.
함수 특성을 올바르게 지정해야 합니다. 증분 링크가 올바르게 작동하려면 이 정보가 필요합니다. 일부 아키텍처의 경우 정보가 다른 용도로 필요할 수 있습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_SYM_DTYPE_NULL |
0 |
파생 형식이 없습니다. 기호는 간단한 스칼라 변수입니다. |
IMAGE_SYM_DTYPE_POINTER |
1 |
기호는 기본 형식에 대한 포인터입니다. |
IMAGE_SYM_DTYPE_FUNCTION |
2 |
기호는 기본 형식을 반환하는 함수입니다. |
IMAGE_SYM_DTYPE_ARRAY |
3 |
기호는 기본 형식의 배열입니다. |
스토리지 클래스
기호 테이블의 StorageClass 필드는 기호가 나타내는 정의의 종류를 나타냅니다. 다음 표에서는 가능한 값을 보여 줍니다. StorageClass 필드는 부호 없는 1바이트 정수입니다. 따라서 -1 특수 값은 동등한 부호 없는 0xFF를 의미하는 것으로 사용해야 합니다.
기존의 COFF 형식은 많은 스토리지 클래스 값을 사용하지만, Microsoft 도구는 Visual C++ 디버그 형식을 대부분의 기호화된 정보에 사용하며 일반적으로 EXTERNAL(2), STATIC(3), FUNCTION(101) 및 FILE(103)의 4가지 스토리지 클래스 값만 사용합니다. 아래의 두 번째 열 제목을 제외하고 "값"은 기호 레코드의 Value 필드를 의미하는 것으로 사용해야 합니다(해석은 스토리지 클래스로 검색한 수에 따라 다름).
상수 | 값 | Value 필드의 설명/해석 |
---|---|---|
IMAGE_SYM_CLASS_END_OF_FUNCTION |
-1 (0xFF) |
디버깅을 위해 함수의 끝을 나타내는 특수 기호입니다. |
IMAGE_SYM_CLASS_NULL |
0 |
할당된 스토리지 클래스가 없습니다. |
IMAGE_SYM_CLASS_AUTOMATIC |
1 |
자동(스택) 변수입니다. Value 필드는 스택 프레임 오프셋을 지정합니다. |
IMAGE_SYM_CLASS_EXTERNAL |
2 |
Microsoft 도구에서 외부 기호에 사용하는 값입니다. 섹션 번호가 IMAGE_SYM_UNDEFINED(0)인 경우 Value 필드는 크기를 나타냅니다. 섹션 번호가 0이 아닌 경우 Value 필드는 섹션 내의 오프셋을 지정합니다. |
IMAGE_SYM_CLASS_STATIC |
3 |
섹션 내 기호의 오프셋입니다. Value 필드가 0인 경우 기호는 섹션 이름을 나타냅니다. |
IMAGE_SYM_CLASS_REGISTER |
4 |
레지스터 변수. Value 필드는 레지스터 번호를 지정합니다. |
IMAGE_SYM_CLASS_EXTERNAL_DEF |
5 |
외부에서 정의된 기호입니다. |
IMAGE_SYM_CLASS_LABEL |
6 |
모듈 내에 정의된 코드 레이블입니다. Value 필드는 섹션 내 기호의 오프셋을 지정합니다. |
IMAGE_SYM_CLASS_UNDEFINED_LABEL |
7 |
정의되지 않은 코드 레이블에 대한 참조입니다. |
IMAGE_SYM_CLASS_MEMBER_OF_STRUCT |
8 |
구조체 멤버입니다. Value 필드는 n번째 멤버를 지정합니다. |
IMAGE_SYM_CLASS_ARGUMENT |
9 |
함수의 형식 인수(매개 변수)입니다. Value 필드는 n번째 인수를 지정합니다. |
IMAGE_SYM_CLASS_STRUCT_TAG |
10 |
구조체 태그 이름 항목입니다. |
IMAGE_SYM_CLASS_MEMBER_OF_UNION |
11 |
공용 구조체 멤버입니다. Value 필드는 n번째 멤버를 지정합니다. |
IMAGE_SYM_CLASS_UNION_TAG |
12 |
공용 구조체 태그 이름 항목입니다. |
IMAGE_SYM_CLASS_TYPE_DEFINITION |
13 |
Typedef 항목입니다. |
IMAGE_SYM_CLASS_UNDEFINED_STATIC |
14 |
정적 데이터 선언입니다. |
IMAGE_SYM_CLASS_ENUM_TAG |
15 |
열거형 형식 태그 이름 항목입니다. |
IMAGE_SYM_CLASS_MEMBER_OF_ENUM |
16 |
열거형의 멤버입니다. Value 필드는 n번째 멤버를 지정합니다. |
IMAGE_SYM_CLASS_REGISTER_PARAM |
17 |
레지스터 매개 변수입니다. |
IMAGE_SYM_CLASS_BIT_FIELD |
18 |
비트 필드 참조입니다. Value 필드는 비트 필드의 n번째 비트를 지정합니다. |
IMAGE_SYM_CLASS_BLOCK |
100 |
.bb(블록 시작) 또는 .eb(블록 끝) 레코드입니다. Value 필드는 코드 위치의 재배치 가능한 주소입니다. |
IMAGE_SYM_CLASS_FUNCTION |
101 |
Microsoft 도구에서 함수의 범위를 정의하는 기호 레코드(.bf(함수 시작), .ef(함수 끝) 및 .lf(함수의 줄))에 사용하는 값입니다. .lf 레코드의 경우 Value 필드는 함수의 소스 줄 수를 지정합니다. .ef 레코드의 경우 Value 필드는 함수 코드의 크기를 지정합니다. |
IMAGE_SYM_CLASS_END_OF_STRUCT |
102 |
구조체 끝 항목입니다. |
IMAGE_SYM_CLASS_FILE |
103 |
Microsoft 도구와 기존 COFF 형식에서 소스 파일 기호 레코드에 사용하는 값입니다. 기호 뒤에는 파일 이름을 지정하는 보조 레코드가 있습니다. |
IMAGE_SYM_CLASS_SECTION |
104 |
섹션의 정의입니다(Microsoft 도구는 STATIC 스토리지 클래스를 대신 사용함). |
IMAGE_SYM_CLASS_WEAK_EXTERNAL |
105 |
약한 외부입니다. 자세한 내용은 보조 형식 3: 약한 외부를 참조하세요. |
IMAGE_SYM_CLASS_CLR_TOKEN |
107 |
CLR 토큰 기호입니다. 이름은 토큰의 16진수 값으로 구성된 ASCII 문자열입니다. 자세한 내용은 CLR 토큰 정의(개체만 해당)를 참조하세요. |
보조 기호 레코드
보조 기호 테이블 레코드는 항상 일부 표준 기호 테이블 레코드를 따르고 적용합니다. 보조 레코드는 도구에서 인식할 수 있는 모든 형식을 포함할 수 있지만, 기호 테이블이 일반 크기의 배열로 유지되도록 18바이트를 할당해야 합니다. 현재 Microsoft 도구는 함수 정의, 함수 시작 및 끝 기호(.bf 및 .ef), 약한 외부, 파일 이름 및 섹션 정의와 같은 종류의 레코드에 대한 보조 형식을 인식합니다.
기존의 COFF 디자인에는 배열 및 구조체에 대한 보조 레코드 형식도 포함됩니다. Microsoft 도구는 이러한 형식을 사용하지 않는 대신, 디버그 섹션에서 기호 정보를 Visual C++ 디버그 형식으로 배치합니다.
보조 형식 1: 함수 정의
EXTERNAL(2)의 스토리지 클래스, 함수임을 나타내는 Type 값(0x20) 및 0보다 큰 섹션 번호가 모두 있는 경우 기호 테이블 레코드는 함수 정의의 시작을 표시합니다. 섹션 번호가 UNDEFINED(0)인 기호 테이블 레코드는 함수를 정의하지 않으며 보조 레코드가 없습니다. 함수 정의 기호 레코드 뒤에는 아래에서 설명하는 형식의 보조 레코드가 있습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
TagIndex |
해당 .bf(함수 시작) 기호 레코드의 기호 테이블 인덱스입니다. |
4 |
4 |
TotalSize |
함수 자체에 대한 실행 코드의 크기입니다. 함수가 자체 섹션에 있는 경우 섹션 헤더의 SizeOfRawData는 맞춤 고려 사항에 따라 이 필드보다 크거나 같습니다. |
8 |
4 |
PointerToLinenumber |
함수에 대한 첫 번째 COFF 줄 번호 항목의 파일 오프셋이거나 없는 경우 0입니다. 자세한 내용은 COFF 줄 번호(사용되지 않음)를 참조하세요. |
12 |
4 |
PointerToNextFunction |
다음 함수에 대한 레코드의 기호 테이블 인덱스입니다. 함수가 기호 테이블의 마지막 항목인 경우 이 필드는 0으로 설정됩니다. |
16 |
2 |
사용 안 함 |
보조 형식 2: .bf 및 .ef 기호
기호 테이블의 각 함수 정의에 대한 다음 세 가지 항목은 시작, 끝 및 줄 수를 설명합니다. 이러한 각 기호에는 FUNCTION(101) 스토리지 클래스가 있습니다.
.bf(함수 시작)라는 기호 레코드. Value 필드가 사용되지 않습니다.
.lf(함수의 줄 수)라는 기호 레코드. Value 필드는 함수의 줄 수를 제공합니다.
.ef(함수 끝)라는 기호 레코드. Value 필드에는 함수 정의 기호 레코드의 Total Size 필드와 동일한 숫자가 있습니다.
.bf 및 .ef 기호 레코드(.lf 레코드는 아님) 뒤에는 다음 형식의 보조 레코드가 있습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
사용 안 함 |
|
4 |
2 |
Linenumber |
.bf 또는 .ef 레코드에 해당하는 소스 파일 내의 실제 서수 줄 번호(1, 2, 3 등)입니다. |
6 |
6 |
사용 안 함 |
|
12 |
4 |
PointerToNextFunction(.bf만 해당) |
다음 .bf 기호 레코드의 기호 테이블 인덱스입니다. 함수가 기호 테이블의 마지막 항목인 경우 이 필드는 0으로 설정됩니다. .ef 레코드에는 사용되지 않습니다. |
16 |
2 |
사용 안 함 |
보조 형식 3: 약한 외부
"약한 외부"는 링크 타임에 유연성을 허용하는 개체 파일에 대한 메커니즘입니다. 모듈은 확인되지 않은 외부 기호(sym1)를 포함할 수 있지만, sym1이 링크 타임에 없는 경우 다른 외부 기호(sym2)가 참조를 확인하는 데 대신 사용됨을 나타내는 보조 레코드를 포함할 수도 있습니다.
sym1의 정의가 연결되면 기호에 대한 외부 참조가 정상적으로 확인됩니다. sym1의 정의가 연결되지 않으면 sym1에 대한 약한 외부의 모든 참조에서 sym2를 대신 참조합니다. 외부 기호 sym2는 항상 연결되어야 합니다. 일반적으로 sym1에 대한 약한 참조를 포함하는 모듈에서 정의됩니다.
약한 외부는 EXTERNAL 스토리지 클래스, UNDEF 섹션 번호 및 0 값이 있는 기호 테이블 레코드로 표시됩니다. 약한 외부 기호 레코드 뒤에는 다음 형식의 보조 레코드가 있습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
TagIndex |
sym1이 없는 경우 연결할 기호인 sym2의 기호 테이블 인덱스입니다. |
4 |
4 |
특징 |
IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 값은 sym1에 대한 라이브러리 검색을 수행하지 않아야 함을 나타냅니다. IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 값은 sym1에 대한 라이브러리 검색을 수행해야 함을 나타냅니다. IMAGE_WEAK_EXTERN_SEARCH_ALIAS 값은 sym1이 sym2의 별칭임을 나타냅니다. |
8 |
10 |
사용 안 함 |
Characteristics 필드는 WINNT.H에 정의되지 않습니다. 대신 Total Size 필드가 사용됩니다.
보조 형식 4: 파일
이 형식은 FILE(103) 스토리지 클래스가 있는 기호 테이블 레코드를 따릅니다. 기호 이름 자체는 .file이어야 하며, 그 뒤에 있는 보조 레코드는 소스 코드 파일의 이름을 지정합니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
18 |
파일 이름 |
소스 파일의 이름을 지정하는 ANSI 문자열입니다. 최대 길이보다 작은 경우 null로 채워집니다. |
보조 형식 5: 섹션 정의
이 형식은 섹션을 정의하는 기호 테이블 레코드를 따릅니다. 이러한 레코드에는 섹션 이름(예: .text 또는 .drectve)인 기호 이름과 STATIC(3) 스토리지 클래스가 있습니다. 보조 레코드는 참조하는 섹션에 대한 정보를 제공합니다. 따라서 섹션 헤더의 일부 정보를 복제합니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
길이 |
섹션 데이터의 크기이며 섹션 헤더의 SizeOfRawData와 동일합니다. |
4 |
2 |
NumberOfRelocations |
섹션에 대한 재배치 항목의 수입니다. |
6 |
2 |
NumberOfLinenumbers |
섹션에 대한 줄 번호 항목의 수입니다. |
8 |
4 |
CheckSum |
공동 데이터에 대한 체크섬입니다. IMAGE_SCN_LNK_COMDAT 플래그가 섹션 헤더에 설정되면 적용할 수 있습니다. 자세한 내용은 COMDAT 섹션(개체만 해당)을 참조하세요. |
12 |
2 |
숫자 |
1부터 시작하는 연결된 섹션의 섹션 테이블에 대한 인덱스입니다. COMDAT 선택 설정이 5인 경우 사용됩니다. |
14 |
1 |
선택 영역(S) |
COMDAT 선택 번호입니다. 섹션이 COMDAT 섹션인 경우 적용할 수 있습니다. |
15 |
3 |
사용 안 함 |
COMDAT 섹션(개체만 해당)
섹션이 COMDAT 섹션이면 섹션 정의 보조 형식의 Selection 필드를 적용할 수 있습니다. COMDAT 섹션은 둘 이상의 개체 파일에서 정의할 수 있는 섹션입니다. (IMAGE_SCN_LNK_COMDAT 플래그는 섹션 헤더의 Section Flags 필드에 설정됩니다.) Selection 필드는 링커에서 COMDAT 섹션의 여러 정의를 확인하는 방법을 결정합니다.
COMDAT 섹션의 섹션 값이 있는 첫 번째 기호는 섹션 기호여야 합니다. 이 기호에는 섹션 이름, 0과 같은 Value 필드, 해당 COMDAT 섹션의 섹션 번호, IMAGE_SYM_TYPE_NULL과 같은 Type 필드, IMAGE_SYM_CLASS_STATIC과 같은 Class 필드 및 하나의 보조 레코드가 있습니다. 두 번째 기호는 "COMDAT 기호"라고 하며 Selection 필드와 함께 링커에서 사용됩니다.
Selection 필드의 값은 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_COMDAT_SELECT_NODUPLICATES |
1 |
이 기호가 이미 정의되어 있으면 링커에서 "여러 번 정의된 기호" 오류가 발생합니다. |
IMAGE_COMDAT_SELECT_ANY |
2 |
동일한 COMDAT 기호를 정의하는 모든 섹션을 연결할 수 있으며, 나머지는 제거됩니다. |
IMAGE_COMDAT_SELECT_SAME_SIZE |
3 |
링커에서 이 기호에 대한 정의 중에서 임의의 섹션을 선택합니다. 모든 정의가 동일한 크기가 아닌 경우 "여러 번 정의된 기호" 오류가 발생합니다. |
IMAGE_COMDAT_SELECT_EXACT_MATCH |
4 |
링커에서 이 기호에 대한 정의 중에서 임의의 섹션을 선택합니다. 모든 정의가 정확히 일치하지 않으면 "여러 번 정의된 기호" 오류가 발생합니다. |
IMAGE_COMDAT_SELECT_ASSOCIATIVE |
5 |
특정 다른 COMDAT 섹션이 연결되면 이 섹션이 연결됩니다. 이 다른 섹션은 섹션 정의에 대한 보조 기호 레코드의 Number 필드로 표시됩니다. 이 설정은 여러 섹션(예: 하나의 코드 및 다른 섹션의 데이터)에 구성 요소가 있지만 모두 집합으로 연결하거나 삭제해야 하는 정의에 유용합니다. 이 섹션과 연결되는 다른 섹션은 COMDAT 섹션이어야 합니다. 이 섹션은 다른 연결 COMDAT 섹션일 수 있습니다. 연결 COMDAT 섹션의 섹션 연결 체인은 루프를 형성할 수 없습니다. 섹션 연결 체인은 결국 IMAGE_COMDAT_SELECT_ASSOCIATIVE가 설정되지 않은 COMDAT 섹션으로 이동해야 합니다. |
IMAGE_COMDAT_SELECT_LARGEST |
6 |
링커에서 이 기호에 대한 모든 정의 중에서 가장 큰 정의를 선택합니다. 여러 정의에 이 크기가 있는 경우 이러한 항목 중에서 임의로 선택합니다. |
CLR 토큰 정의(개체만 해당)
이 보조 기호는 일반적으로 IMAGE_SYM_CLASS_CLR_TOKEN을 따릅니다. 토큰을 COFF 기호 테이블의 네임스페이스와 연결하는 데 사용됩니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
1 |
bAuxType |
IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF(1)여야 합니다. |
1 |
1 |
bReserved |
예약됨, 0이어야 합니다. |
2 |
4 |
SymbolTableIndex |
이 CLR 토큰 정의에서 참조하는 COFF 기호의 기호 인덱스입니다. |
6 |
12 |
예약됨, 0이어야 합니다. |
COFF 문자열 테이블
COFF 기호 테이블 바로 뒤에는 COFF 문자열 테이블이 있습니다. 이 테이블의 위치는 COFF 헤더의 기호 테이블 주소를 가져와서 기호의 크기로 곱한 기호의 수를 더하여 찾습니다.
COFF 문자열 테이블의 시작에는 나머지 문자열 테이블의 전체 크기(바이트 단위)를 포함하는 4바이트가 있습니다. 이 크기에는 크기 필드 자체가 포함되므로 문자열이 없는 경우 이 위치의 값은 4가 됩니다.
크기 뒤에는 COFF 기호 테이블의 기호로 가리키는 null 종료 문자열이 있습니다.
특성 인증서 테이블(이미지만 해당)
특성 인증서 테이블을 추가하여 특성 인증서를 이미지와 연결할 수 있습니다. 특성 인증서 테이블은 일단의 인접한 쿼드워드 맞춤 특성 인증서 항목으로 구성됩니다. 이 맞춤을 위해 파일의 원래 끝과 특성 인증서 테이블의 시작 사이에 0 패딩이 삽입됩니다. 각 특성 인증서 항목에 포함되는 필드는 다음 과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
dwLength |
특성 인증서 항목의 길이를 지정합니다. |
4 |
2 |
wRevision |
인증서 버전 번호를 포함합니다. 자세한 내용은 다음 텍스트를 참조하세요. |
6 |
2 |
wCertificateType |
bCertificate의 콘텐츠 형식을 지정합니다. 자세한 내용은 다음 텍스트를 참조하세요. |
8 |
참조할 문서 |
bCertificate |
Authenticode 서명과 같은 인증서를 포함합니다. 자세한 내용은 다음 텍스트를 참조하세요. |
선택적 헤더 데이터 디렉터리에 있는 Certificate Table 항목의 가상 주소 값은 첫 번째 특성 인증서 항목에 대한 파일 오프셋입니다. 현재 특성 인증서 항목의 시작에서 해당 항목의 dwLength 바이트를 8바이트 배수로 반올림하여 후속 항목에 액세스합니다. 이 작업은 반올림된 dwLength 값의 합계가 선택적 헤더 데이터 디렉터리에 있는 인증서 테이블 항목의 Size 값과 같을 때까지 계속됩니다. 반올림된 dwLength 값의 합계가 Size 값과 같지 않으면 특성 인증서 테이블 또는 크기 필드가 손상된 것입니다.
예를 들어 선택적 헤더 데이터 디렉터리의 Certificate Table 항목에 다음이 포함된 경우가 있습니다.
virtual address = 0x5000
size = 0x1000
첫 번째 인증서는 디스크의 파일 시작으로부터의 0x5000 오프셋에서 시작합니다. 모든 특성 인증서 항목을 진행하려면 다음을 수행합니다.
- 첫 번째 특성 인증서의 dwLength 값을 시작 오프셋에 추가합니다.
- 1단계의 값을 가장 가까운 8바이트 배수로 반올림하여 두 번째 특성 인증서 항목의 오프셋을 찾습니다.
- 2단계의 오프셋 값을 두 번째 특성 인증서 항목의 dwLength 값에 추가하고 가장 가까운 8바이트 배수로 반올림하여 세 번째 특성 인증서 항목의 오프셋을 결정합니다.
- 계산된 오프셋이 0x6000(0x5000 시작 + 0x1000 전체 크기)이 될 때까지(전체 테이블을 액세스했음을 나타냄) 각 연속 인증서에 대해 3단계를 반복합니다.
또는 루프에서 Win32 ImageEnumerateCertificates 함수를 호출하여 인증서 항목을 열거할 수 있습니다. 함수의 참조 페이지에 대한 링크는 참조를 참조하세요.
올바른 dwLength 값, 고유한 wRevision 값 및 고유한 wCertificateType 값이 항목에 있는 동안에는 특성 인증서 테이블 항목에서 모든 인증서 형식을 포함할 수 있습니다. 가장 일반적인 형식의 인증서 테이블 항목은 Wintrust.h에서 문서화되고 이 섹션의 나머지 부분에서 설명하는 WIN_CERTIFICATE 구조체입니다.
WIN_CERTIFICATE wRevision 멤버에 대한 옵션에는 다음이 포함되지만 이에 국한되지는 않습니다.
값 | 속성 | 메모 |
---|---|---|
0x0100 |
WIN_CERT_REVISION_1_0 |
버전 1이며 Win_Certificate 구조체의 레거시 버전입니다. 레거시 Authenticode 서명을 확인하는 용도로만 지원됩니다. |
0x0200 |
WIN_CERT_REVISION_2_0 |
버전 2는 Win_Certificate 구조체의 현재 버전입니다. |
WIN_CERTIFICATE wCertificateType 멤버에 대한 옵션에는 다음 표의 항목이 포함되지만 이에 국한되지는 않습니다. 일부 값은 현재 지원되지 않습니다.
값 | 속성 | 메모 |
---|---|---|
0x0001 |
WIN_CERT_TYPE_X509 |
bCertificate에는 X.509 인증서가 포함됩니다. 지원되지 않음 |
0x0002 |
WIN_CERT_TYPE_PKCS_SIGNED_DATA |
bCertificate에는 PKCS#7 SignedData 구조체가 포함됩니다. |
0x0003 |
WIN_CERT_TYPE_RESERVED_1 |
예약됨 |
0x0004 |
WIN_CERT_TYPE_TS_STACK_SIGNED |
터미널 서버 프로토콜 스택 인증서 서명입니다. 지원되지 않음 |
WIN_CERTIFICATE 구조체의 bCertificate 멤버에는 wCertificateType에서 지정된 콘텐츠 형식이 있는 가변 길이 바이트 배열이 포함됩니다. Authenticode에서 지원하는 형식은 PKCS#7 SignedData 구조체인 WIN_CERT_TYPE_PKCS_SIGNED_DATA입니다. Authenticode 디지털 서명 형식에 대한 자세한 내용은 Windows Authenticode 휴대용 실행 파일 서명 형식을 참조하세요.
bCertificate 콘텐츠가 쿼드워드 경계에서 끝나지 않는 경우 특성 인증서 항목은 bCertificate의 끝에서 다음 쿼드워드 경계까지 0으로 채워집니다.
dwLength 값은 최종 WIN_CERTIFICATE 구조체의 길이이며 다음과 같이 계산됩니다.
dwLength = offsetof(WIN_CERTIFICATE, bCertificate) + (size of the variable-length binary array contained within bCertificate)
이 길이에는 각 WIN_CERTIFICATE 구조체가 쿼드워드에 맞춰져야 한다는 요구 사항을 충족하는 데 사용되는 패딩 크기가 포함되어야 합니다.
dwLength += (8 - (dwLength & 7)) & 7;
선택적 헤더 데이터 디렉터리(이미지만)의 Certificate Table 항목에 지정된 Certificate Table 크기에는 패딩이 포함됩니다.
ImageHlp API를 사용하여 PE 파일에서 인증서를 열거, 추가 및 제거하는 방법에 대한 자세한 내용은 ImageHlp 함수를 참조하세요.
인증서 데이터
이전 섹션에서 설명한 대로 특성 인증서 테이블의 인증서는 모든 인증서 형식을 포함할 수 있습니다. PE 파일의 무결성을 보장하는 인증서에는 PE 이미지 해시가 포함될 수 있습니다.
PE 이미지 해시(또는 파일 해시)는 해시 알고리즘에서 파일의 무결성과 관련된 메시지 다이제스트를 생성한다는 점에서 파일 체크섬과 비슷합니다. 그러나 체크섬은 간단한 알고리즘으로 생성되며, 주로 디스크의 메모리 블록이 잘못되었고 이 블록에 저장된 값이 손상되었는지 여부를 검색하는 데 사용됩니다. 파일 해시는 파일 손상도 검색한다는 점에서 체크섬과 비슷합니다. 그러나 대부분의 체크섬 알고리즘과 달리 원래 수정되지 않은 값에서 파일 해시를 변경하지 않고 파일을 수정하는 것은 매우 어렵습니다. 따라서 파일 해시는 바이러스, 해커 또는 트로이 목마 프로그램에서 도입된 것과 같이 파일에 대한 의도적이고 미묘한 수정을 검색하는 데 사용할 수 있습니다.
인증서에 포함되는 경우 이미지 다이제스트는 선택적 헤더 데이터 디렉터리의 Checksum 및 Certificate Table 항목과 같은 PE 이미지의 특정 필드를 제외해야 합니다. 이는 인증서를 추가하는 작업에서 이러한 필드를 변경하고 다른 해시 값을 계산하기 때문입니다.
Win32 ImageGetDigestStream 함수는 함수를 해시하는 대상 PE 파일의 데이터 스트림을 제공합니다. 인증서가 PE 파일에 추가되거나 제거될 때 이 데이터 스트림에서 일관성을 유지합니다. ImageGetDigestStream에 전달된 매개 변수에 따라 PE 이미지의 다른 데이터는 해시 계산에서 생략할 수 있습니다. 함수의 참조 페이지에 대한 링크는 참조를 참조하세요.
지연 로드 가져오기 테이블(이미지만 해당)
이러한 테이블은 애플리케이션에서 해당 DLL에 처음 호출할 때까지 DLL 로드를 지연시키는 균일한 메커니즘을 지원하기 위해 이미지에 추가되었습니다. 테이블의 레이아웃은 섹션 6.4 .idata 섹션에서 설명하는 기존 가져오기 테이블의 레이아웃과 일치합니다. 여기서는 몇 가지 세부 정보만 설명합니다.
지연 로드 Directory 테이블
지연 로드 Directory 테이블은 가져오기 Directory 테이블에 해당합니다. 선택적 헤더 데이터 디렉터리 목록(200 오프셋)의 지연 가져오기 설명자 항목을 통해 검색할 수 있습니다. 테이블은 다음과 같이 정렬됩니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
특성 |
0이어야 합니다. |
4 |
4 |
입력 |
로드할 DLL 이름의 RVA입니다. 이름은 이미지의 읽기 전용 데이터 섹션에 있습니다. |
8 |
4 |
모듈 핸들 |
지연 로드할 DLL의 모듈 핸들(이미지의 데이터 섹션에 있음)의 RVA입니다. 지연 로드를 관리하기 위해 제공되는 루틴의 저장에 사용됩니다. |
12 |
4 |
지연 가져오기 주소 테이블 |
지연 로드 가져오기 주소 테이블의 RVA입니다. 자세한 내용은 지연 IAT(가져오기 주소 테이블)를 참조하세요. |
16 |
4 |
지연 가져오기 이름 테이블 |
로드해야 할 수 있는 가져오기의 이름이 포함된 지연 로드 이름 테이블의 RVA입니다. 가져오기 이름 테이블의 레이아웃과 일치합니다. 자세한 내용은 힌트/이름 테이블을 참조하세요. |
20 |
4 |
바운드된 지연 가져오기 테이블 |
바인딩된 지연 로드 주소 테이블의 RVA(있는 경우)입니다. |
24 |
4 |
지연 언로드 가져오기 테이블 |
언로드 지연 로드 주소 테이블의 RVA(있는 경우)입니다. 지연 가져오기 주소 테이블의 정확한 복사본입니다. 호출자가 DLL을 언로드하는 경우 DLL에 대한 후속 호출에서 썽킹 메커니즘을 올바르게 계속 사용할 수 있도록 이 테이블을 지연 가져오기 주소 테이블에 다시 복사해야 합니다. |
28 |
4 |
타임스탬프 |
이 이미지가 바인딩된 DLL의 타임스탬프입니다. |
이 데이터 구조체에서 참조되는 테이블은 기존 가져오기의 경우와 마찬가지로 구성되고 정렬됩니다. 자세한 내용은 .idata 섹션을 참조하세요.
특성
아직 특성 플래그가 정의되지 않았습니다. 링커는 이미지에서 이 필드를 0으로 설정합니다. 이 필드는 새 필드의 현재 상태를 표시하여 레코드를 확장하는 데 사용하거나 지연 또는 언로드 도우미 함수에 대한 동작을 표시하는 데 사용할 수 있습니다.
속성
지연 로드할 DLL의 이름은 이미지의 읽기 전용 데이터 섹션에 있습니다. szName 필드를 통해 참조됩니다.
모듈 핸들
지연 로드할 DLL의 핸들은 이미지의 데이터 섹션에 있습니다. phmod 필드는 핸들을 가리킵니다. 제공된 지연 로드 도우미는 이 위치를 사용하여 로드된 DLL에 대한 핸들을 저장합니다.
지연 가져오기 주소 테이블
지연 IAT(가져오기 주소 테이블)는 pIAT 필드를 통해 지연 가져오기 설명자에서 참조됩니다. 지연 로드 도우미는 썽크가 더 이상 호출 루프에 있지 않도록 이러한 포인터를 실제 진입점으로 업데이트합니다. 함수 포인터는 pINT->u1.Function
식을 사용하여 액세스합니다.
지연 가져오기 이름 테이블
지연 INT(가져오기 이름 테이블)에는 로드가 필요할 수 있는 가져오기의 이름이 포함됩니다. 이러한 이름은 IAT의 함수 포인터와 동일한 방식으로 정렬됩니다. 표준 INT와 동일한 구조체로 구성되며 pINT->u1.AddressOfData->Name[0]
식을 사용하여 액세스합니다.
지연 바인딩된 가져오기 주소 테이블 및 타임스탬프
지연 BIAT(바인딩된 가져오기 주소 테이블)는 프로세스 후 바인딩 단계에서 지연 로드 Directory 테이블의 타임스탬프 필드와 함께 사용되는 IMAGE_THUNK_DATA 항목의 선택적 테이블입니다.
지연 언로드 가져오기 주소 테이블
지연 UIAT(언로드 가져오기 주소 테이블)는 언로드 코드에서 명시적 언로드 요청을 처리하는 데 사용하는 IMAGE_THUNK_DATA 항목의 선택적 테이블입니다. 지연 로드 썽크에 대한 코드를 참조한 원래 IAT의 정확한 복사본인 읽기 전용 섹션의 초기화된 데이터로 구성됩니다. 언로드 요청 시 라이브러리를 해제하고 *phmod를 지우고 IAT를 UIAT에 작성하여 모든 항목을 미리 로드 상태로 복원할 수 있습니다.
특수 섹션
- .debug 섹션
- .drectve 섹션(개체만 해당)
- .edata 섹션(이미지만 해당)
- .idata 섹션
- .pdata 섹션
- .reloc 섹션(이미지만 해당)
- .tls 섹션
- 로드 구성 구조체(이미지만 해당)
- .rsrc 섹션
- .cormeta 섹션(개체만 해당)
- .sxdata 섹션
일반적인 COFF 섹션에는 섹션 콘텐츠에 대한 특별한 지식 없이 링커와 Microsoft Win32 로더에서 처리하는 코드 또는 데이터가 포함됩니다. 콘텐츠는 연결되거나 실행되는 애플리케이션과만 관련이 있습니다.
그러나 일부 COFF 섹션에는 개체 파일 또는 이미지 파일에서 찾을 때 특별한 의미가 있습니다. 섹션 헤더에 특수 플래그가 설정되어 있거나, 이미지 선택적 헤더의 특수 위치가 해당 섹션을 가리키거나, 섹션 이름 자체에서 섹션의 특수 함수를 나타내므로 도구 및 로더에서 이러한 섹션을 인식합니다. (섹션 이름 자체에서 해당 섹션의 특수 함수를 나타내지 않더라도 규칙에 따라 섹션 이름을 지정하므로 이 사양의 작성자는 모든 경우에서 섹션 이름을 참조할 수 있습니다.)
예약된 섹션 및 해당 특성은 아래 표에서 설명하고 있으며, 실행 파일에 유지되는 섹션 형식 및 확장에 대한 메타데이터를 포함하는 섹션 형식에 대한 자세한 설명이 뒤에 나와 있습니다.
섹션 이름 | 콘텐츠 | 특징 |
---|---|---|
.bss |
초기화되지 않은 데이터(자유 형식) |
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.cormeta |
개체 파일에 관리 코드가 포함되어 있음을 나타내는 CLR 메타데이터 |
IMAGE_SCN_LNK_INFO |
.data |
초기화된 데이터(자유 형식) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.debug$F |
생성된 FPO 디버그 정보(개체만 해당, x86 아키텍처만, 이제 사용되지 않음) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.debug$P |
미리 컴파일된 디버그 형식(개체만 해당) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.debug$S |
디버그 기호(개체만 해당) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.debug$T |
디버그 형식(개체만 해당) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.drective |
링커 옵션 |
IMAGE_SCN_LNK_INFO |
.edata |
내보내기 테이블 |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.idata |
가져오기 테이블 |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.idlsym |
IDL 특성을 지원하기 위해 등록된 SEH(이미지만 해당)를 포함합니다. 자세한 내용은 이 항목의 끝에 있는 참조의 "IDL 특성"을 참조하세요. |
IMAGE_SCN_LNK_INFO |
.pdata |
예외 정보 |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.rdata |
초기화된 읽기 전용 데이터 |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.reloc |
이미지 재배치 |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE |
.rsrc |
리소스 디렉터리 |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
.sbss |
초기화되지 않은 GP 기준 상대 데이터(자유 형식) |
IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL IMAGE_SCN_GPREL 플래그는 IA64 아키텍처에 대해서만 설정해야 합니다. 이 플래그는 다른 아키텍처에 대해 유효하지 않습니다. IMAGE_SCN_GPREL 플래그는 개체 파일에만 해당합니다. 이 섹션 형식이 이미지 파일에 나타나면 IMAGE_SCN_GPREL 플래그를 설정하면 안 됩니다. |
.sdata |
GP 기준 상대 초기화된 데이터(자유 형식) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE _SCN_GPREL IMAGE_SCN_GPREL 플래그는 IA64 아키텍처에 대해서만 설정해야 합니다. 이 플래그는 다른 아키텍처에 대해 유효하지 않습니다. IMAGE_SCN_GPREL 플래그는 개체 파일에만 해당합니다. 이 섹션 형식이 이미지 파일에 나타나면 IMAGE_SCN_GPREL 플래그를 설정하면 안 됩니다. |
.srdata |
GP 기준 상대 읽기 전용 데이터(자유 형식) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE _SCN_GPREL IMAGE_SCN_GPREL 플래그는 IA64 아키텍처에 대해서만 설정해야 합니다. 이 플래그는 다른 아키텍처에 대해 유효하지 않습니다. IMAGE_SCN_GPREL 플래그는 개체 파일에만 해당합니다. 이 섹션 형식이 이미지 파일에 나타나면 IMAGE_SCN_GPREL 플래그를 설정하면 안 됩니다. |
.sxdata |
등록된 예외 처리기 데이터(자유 형식 및 x86/개체만 해당) |
IMAGE_SCN_LNK_INFO 해당 개체 파일의 코드에서 참조하는 각 예외 처리기의 기호 인덱스를 포함합니다. 기호는 UNDEF 기호 또는 해당 모듈에 정의된 기호에 대한 것일 수 있습니다. |
.text |
실행 코드(자유 형식) |
IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IIMAGE_SCN_MEM_READ |
.tls |
스레드 로컬 스토리지(개체만 해당) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.tls$ |
스레드 로컬 스토리지(개체만 해당) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.vsdata |
GP 기준 상대 초기화된 데이터(자유 형식, ARM, SH4 및 Thumb 아키텍처만 해당) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE |
.xdata |
예외 정보(자유 형식) |
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ |
여기에 나열된 섹션 중 일부는 "개체만 해당" 또는 "이미지만 해당"으로 표시되어 해당 특수 의미 체계가 각각 개체 파일 또는 이미지 파일과만 관련이 있음을 나타냅니다. "이미지만 해당"으로 표시된 섹션은 여전히 이미지 파일에 포함되는 방법으로 개체 파일에 나타날 수 있지만 이 섹션은 링커에 특별한 의미가 없으며 이미지 파일 로더에만 의미가 있습니다.
.debug 섹션
.debug 섹션은 컴파일러에서 생성된 디버그 정보를 포함하는 개체 파일과 생성된 모든 디버그 정보를 포함하는 이미지 파일에서 사용됩니다. 이 섹션에서는 개체 및 이미지 파일의 디버그 정보 패키징에 대해 설명합니다.
다음 섹션에서는 이미지의 어느 위치에나 있을 수 있는 디버그 디렉터리의 형식에 대해 설명합니다. 후속 섹션에서는 디버그 정보를 포함하는 개체 파일의 "groups"에 대해 설명합니다.
링커의 기본값은 디버그 정보가 이미지의 주소 공간에 매핑되지 않는다는 것입니다. 디버그 정보가 주소 공간에 매핑되는 경우에만 .debug 섹션이 존재합니다.
디버그 디렉터리(이미지만 해당)
이미지 파일에는 존재하는 디버그 정보의 형식과 위치를 나타내는 선택적 디버그 디렉터리가 포함됩니다. 이 디렉터리는 위치와 크기가 이미지 선택적 헤더에 표시되는 디버그 디렉터리 항목의 배열로 구성됩니다.
디버그 디렉터리는 삭제 가능한 .debug 섹션(있는 경우)에 있거나 이미지 파일의 다른 섹션에 포함되거나 섹션에 전혀 포함되지 않을 수 있습니다.
각 디버그 디렉터리 항목은 디버그 정보 블록의 위치와 크기를 식별합니다. 디버그 정보가 섹션 헤더에 포함되지 않는 경우(즉, 이미지 파일에 있고 런타임 주소 공간에 매핑되지 않은 경우) 지정된 RVA는 0일 수 있습니다. 매핑되는 경우 RVA는 해당 주소입니다.
디버그 디렉터리 항목의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
특징 |
예약됨, 0이어야 합니다. |
4 |
4 |
TimeDateStamp |
디버그 데이터를 만든 시간과 날짜입니다. |
8 |
2 |
MajorVersion |
디버그 데이터 형식의 주 버전 번호입니다. |
10 |
2 |
MinorVersion |
디버그 데이터 형식의 부 버전 번호입니다. |
12 |
4 |
입력 |
디버깅 정보의 형식입니다. 이 필드를 사용하면 여러 디버거를 지원할 수 있습니다. 자세한 내용은 디버그 형식을 참조하세요. |
16 |
4 |
SizeOfData |
디버그 데이터의 크기입니다(디버그 디렉터리 자체는 포함하지 않음). |
20 |
4 |
AddressOfRawData |
로드될 때 이미지 베이스를 기준으로 하는 디버그 데이터의 주소입니다. |
24 |
4 |
PointerToRawData |
디버그 데이터에 대한 파일 포인터입니다. |
디버그 형식
디버그 디렉터리 항목의 Type 필드에 대해 정의되는 값은 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_DEBUG_TYPE_UNKNOWN |
0 |
모든 도구에서 무시되는 알 수 없는 값입니다. |
IMAGE_DEBUG_TYPE_COFF |
1 |
COFF 디버그 정보(줄 번호, 기호 테이블, 문자열 테이블)입니다. 파일 헤더의 필드에서도 이 형식의 디버그 정보를 가리킵니다. |
IMAGE_DEBUG_TYPE_CODEVIEW |
2 |
Visual C++ 디버그 정보입니다. |
IMAGE_DEBUG_TYPE_FPO |
3 |
FPO(프레임 포인터 생략) 정보입니다. 이 정보는 프레임 포인터 이외의 용도로 EBP 레지스터를 사용하는 비표준 스택 프레임을 해석하는 방법을 디버거에 알려줍니다. |
IMAGE_DEBUG_TYPE_MISC |
4 |
DBG 파일의 위치입니다. |
IMAGE_DEBUG_TYPE_EXCEPTION |
5 |
.pdata 섹션의 복사본입니다. |
IMAGE_DEBUG_TYPE_FIXUP |
6 |
예약되었습니다. |
IMAGE_DEBUG_TYPE_OMAP_TO_SRC |
7 |
이미지의 RVA에서 소스 이미지의 RVA로의 매핑입니다. |
IMAGE_DEBUG_TYPE_OMAP_FROM_SRC |
8 |
소스 이미지의 RVA에서 이미지의 RVA로의 매핑입니다. |
IMAGE_DEBUG_TYPE_BORLAND |
9 |
Borland용으로 예약되어 있습니다. |
IMAGE_DEBUG_TYPE_RESERVED10 |
10 |
예약되었습니다. |
IMAGE_DEBUG_TYPE_CLSID |
11 |
예약되었습니다. |
IMAGE_DEBUG_TYPE_REPRO |
16 |
PE 결정성 또는 재현 가능성입니다. |
Undefined |
17 |
디버깅 정보는 PointerToRawData로 지정된 위치에 PE 파일에 임베드됩니다. |
Undefined |
19 |
PE/COFF 파일을 빌드하는 데 사용되는 심볼 파일의 콘텐츠에 대한 암호화 해시를 저장합니다. |
IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS | 20 | 확장 DLL 특성 비트입니다. |
Type 필드가 IMAGE_DEBUG_TYPE_FPO로 설정되는 경우 디버그 원시 데이터는 각 멤버에서 함수의 스택 프레임을 설명하는 배열입니다. 디버그 형식이 FPO인 경우에도 이미지 파일의 모든 함수에 대해 정의된 FPO 정보가 있어야 하는 것은 아닙니다. FPO 정보가 없는 함수에는 일반 스택 프레임이 있다고 가정합니다. FPO 정보의 형식은 다음과 같습니다.
#define FRAME_FPO 0
#define FRAME_TRAP 1
#define FRAME_TSS 2
typedef struct _FPO_DATA {
DWORD ulOffStart; // offset 1st byte of function code
DWORD cbProcSize; // # bytes in function
DWORD cdwLocals; // # bytes in locals/4
WORD cdwParams; // # bytes in params/4
WORD cbProlog : 8; // # bytes in prolog
WORD cbRegs : 3; // # regs saved
WORD fHasSEH : 1; // TRUE if SEH in func
WORD fUseBP : 1; // TRUE if EBP has been allocated
WORD reserved : 1; // reserved for future use
WORD cbFrame : 2; // frame type
} FPO_DATA;
IMAGE_DEBUG_TYPE_REPRO 형식의 항목이 있다는 것은 PE 파일이 결정성 또는 재현 가능성을 달성하는 방식으로 빌드되었음을 나타냅니다. 입력이 변경되지 않으면 PE가 생성되는 시점과 또는 위치에 관계없이 출력 PE 파일이 비트마다 동일하도록 보장됩니다. PE 파일의 다양한 날짜/시간 스탬프 필드는 PE 파일 콘텐츠를 입력으로 사용하는 계산된 해시 값의 일부 또는 모든 비트로 채워지므로 더 이상 PE 파일 또는 PE 내의 관련 특정 데이터가 생성된 실제 날짜 및 시간을 나타내지 않습니다. 이 디버그 항목의 원시 데이터는 비어 있거나 해시 값 길이를 나타내는 4바이트 값이 앞에 있는 계산된 해시 값을 포함할 수 있습니다.
Type 필드가 IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS로 설정되는 경우 디버그 원시 데이터에는 이미지의 선택적 헤더에 설정할 수 있는 것 외에도 확장 DLL 특성 비트가 포함됩니다. 선택적 헤더 Windows 관련 필드(이미지만 해당) 섹션의 DLL 특성을 참조하세요.
확장 DLL 특성
확장 DLL 특성 비트에 대해 정의되는 값은 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT | 0x0001 | 이미지는 제어 흐름 시행 기술(CET) 섀도 스택과 호환됩니다. |
IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT | 0x0040 | 모든 이미지 코드 섹션의 모든 분기 대상에는 x86 CET-Indirect Branch Tracking(IBT) 또는 ARM BTI(Arm Branch Target Identification) 지침과 같은 전방 에지 제어 흐름 무결성 보호 지침이 주석으로 추가됩니다. 이 비트는 Windows에서 사용되지 않습니다. |
.debug$F(개체만 해당)
이 섹션의 데이터는 Visual C++ 버전 7.0 이상에서 .debug$S 하위 섹션으로 내보내는 더 광범위한 데이터 세트로 대체되었습니다.
개체 파일은 하나 이상의 FPO_DATA 레코드(프레임 포인터 누락 정보)가 포함된 .debug$F 섹션을 포함할 수 있습니다. 디버그 형식의 "IMAGE_DEBUG_TYPE_FPO"를 참조하세요.
링커는 이러한 .debug$F 레코드를 인식합니다. 디버그 정보가 생성되는 경우 링커는 RVA 프로시저별로 FPO_DATA 레코드를 정렬하고 이에 대한 디버그 디렉터리 항목을 생성합니다.
컴파일러는 표준 프레임 형식이 있는 프로시저에 대한 FPO 레코드를 생성하지 않아야 합니다.
.debug$S(개체만 해당)
이 섹션에는 Visual C++ 디버그 정보(기호화된 정보)가 포함됩니다.
.debug$P(개체만 해당)
이 섹션에는 Visual C++ 디버그 정보(미리 컴파일된 정보)가 포함됩니다. 이러한 형식은 이 개체를 사용하여 생성된 미리 컴파일된 헤더를 통해 컴파일된 모든 개체 간에 공유되는 형식입니다.
.debug$T(개체만 해당)
이 섹션에는 Visual C++ 디버그 정보(형식 정보)가 포함됩니다.
Microsoft 디버그 정보에 대한 링커 지원
디버그 정보를 지원하기 위해 링커에서 다음을 수행합니다.
.debug$F, debug$S, .debug$P 및 .debug$T 섹션에서 모든 관련 디버그 데이터를 수집합니다.
링커에서 생성한 디버깅 정보와 함께 해당 데이터를 PDB 파일로 처리하고, 이를 참조하는 디버그 디렉터리 항목을 만듭니다.
.drectve 섹션(개체만 해당)
IMAGE_SCN_LNK_INFO 플래그가 섹션 헤더에 설정되어 있고 .drectve 섹션 이름이 있는 경우 섹션은 지시문 섹션입니다. 링커는 정보를 처리한 후 .drectve 섹션을 제거하므로 연결되는 이미지 파일에는 해당 섹션이 표시되지 않습니다.
.drectve 섹션은 ANSI 또는 UTF-8로 인코딩할 수 있는 텍스트 문자열로 구성됩니다. UTF-8 BOM(바이트 순서 표식, 0xEF, 0xBB 및 0xBF로 구성된 3바이트 접두사)가 없는 경우 지시문 문자열은 ANSI로 해석됩니다. 지시문 문자열은 공백으로 구분되는 일련의 링커 옵션입니다. 각 옵션에는 하이픈, 옵션 이름 및 해당 특성이 포함됩니다. 옵션에 공백이 포함되는 경우 해당 옵션을 따옴표로 묶어야 합니다. .drectve 섹션에는 재배치 또는 줄 번호가 없어야 합니다.
.edata 섹션(이미지만 해당)
.edata라는 내보내기 데이터 섹션에는 다른 이미지에서 동적 링크를 통해 액세스할 수 있는 기호에 대한 정보가 포함됩니다. 내보낸 기호는 일반적으로 DLL에서 찾을 수 있지만, DLL에서 기호를 가져올 수도 있습니다.
내보내기 섹션의 일반적인 구조체에 대한 개요는 아래에서 설명하고 있습니다. 설명하는 테이블은 일반적으로 표시된 순서대로 파일에서 연속됩니다(필수는 아님). 기호를 서수로 내보내려면 내보내기 Directory 테이블과 내보내기 주소 테이블만 필요합니다. (서수는 내보내기 주소 테이블 인덱스에서 직접 액세스하는 내보내기입니다.) 이름 포인터 테이블, 서수 테이블 및 내보내기 이름 테이블은 모두 내보내기 이름 사용을 지원하기 위해 존재합니다.
테이블 이름 | 설명 |
---|---|
내보내기 디렉토리 테이블 |
디버그 디렉터리와 달리 하나의 행만 있는 테이블입니다. 이 테이블은 다른 내보내기 테이블의 위치와 크기를 나타냅니다. |
내보내기 주소 테이블 |
내보낸 기호의 RVA 배열입니다. 실행 코드 및 데이터 섹션 내에서 내보낸 함수 및 데이터의 실제 주소입니다. 다른 이미지 파일은 이 테이블에 대한 인덱스(서수)를 사용하거나 퍼블릭 이름이 정의된 경우 필요에 따라 서수에 해당하는 퍼블릭 이름을 사용하여 기호를 가져올 수 있습니다. |
이름 포인터 테이블 |
오름차순으로 정렬된 퍼블릭 내보내기 이름에 대한 포인터 배열입니다. |
서수 테이블 |
이름 포인터 테이블의 멤버에 해당하는 서수의 배열입니다. 위치별로 대응합니다. 따라서 이름 포인터 테이블과 서수 테이블에는 동일한 수의 멤버가 있어야 합니다. 각 서수는 내보내기 주소 테이블에 대한 인덱스입니다. |
이름 내보내기 테이블 |
일련의 null로 끝나는 ASCII 문자열입니다. 이름 포인터 테이블의 멤버는 이 영역을 가리킵니다. 이러한 이름은 기호를 가져오고 내보내는 데 사용되는 퍼블릭 이름이며, 이미지 파일 내에서 사용되는 프러이빗 이름과 반드시 같을 필요는 없습니다. |
다른 이미지 파일이 이름으로 기호를 가져오면 Win32 로더는 이름 포인터 테이블에서 일치하는 문자열을 검색합니다. 일치하는 문자열이 검색되면 서수 테이블에서 해당 멤버(즉, 이름 포인터 테이블에서 찾은 문자열 포인터와 동일한 인덱스가 있는 서수 테이블의 멤버)를 조회하여 연결된 서수가 식별됩니다. 결과 서수는 원하는 기호의 실제 위치를 제공하는 내보내기 주소 테이블에 대한 인덱스입니다. 모든 내보내기 기호는 서수로 액세스할 수 있습니다.
다른 이미지 파일이 서수로 기호를 가져오는 경우 이름 포인터 테이블에서 일치하는 문자열을 검색할 필요가 없습니다. 따라서 서수를 직접 사용하는 것이 더 효율적입니다. 그러나 내보내기 이름은 기억하기 쉽고 사용자가 기호에 대한 테이블 인덱스를 알 필요가 없습니다.
내보내기 Directory 테이블
내보내기 기호 정보는 내보내기 기호 정보의 나머지 부분을 설명하는 내보내기 Directory 테이블로 시작합니다. 내보내기 Directory 테이블에는 이 이미지 내의 진입점에 대한 가져오기를 확인하는 데 사용되는 주소 정보가 포함됩니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
내보내기 플래그 |
예약됨, 0이어야 합니다. |
4 |
4 |
날짜/시간 스탬프 |
내보내기 데이터를 만든 시간과 날짜입니다. |
8 |
2 |
주 버전 |
주 버전 번호입니다. 주 및 부 버전 번호는 사용자가 설정할 수 있습니다. |
10 |
2 |
부 버전 |
부 버전 번호입니다. |
12 |
4 |
Name RVA |
DLL의 이름을 포함하는 ASCII 문자열의 주소입니다. 이 주소는 이미지 베이스를 기준으로 합니다. |
16 |
4 |
서수 베이스 |
이 이미지의 내보내기에 대한 시작 서수입니다. 이 필드는 내보내기 주소 테이블에 대한 시작 서수를 지정합니다. 일반적으로 1로 설정됩니다. |
20 |
4 |
Address Table Entries |
내보내기 주소 테이블의 항목 수입니다. |
24 |
4 |
이름 포인터 수 |
이름 포인터 테이블의 항목 수입니다. 서수 테이블의 항목 수이기도 합니다. |
28 |
4 |
Export Address Table RVA |
이미지 베이스를 기준으로 하는 내보내기 주소 테이블의 주소입니다. |
32 |
4 |
Name Pointer RVA |
이미지 베이스를 기준으로 하는 내보내기 이름 포인터 테이블의 주소입니다. 테이블 크기는 이름 포인터 수 필드에서 지정됩니다. |
36 |
4 |
Ordinal Table RVA |
이미지 베이스를 기준으로 하는 서수 테이블의 주소입니다. |
내보내기 주소 테이블
내보내기 주소 테이블에는 내보낸 진입점의 주소와 내보낸 데이터 및 절댓값이 포함됩니다. 서수는 내보내기 주소 테이블에 대한 인덱스로 사용됩니다.
내보내기 주소 테이블의 각 항목은 다음 표의 두 가지 형식 중 하나를 사용하는 필드입니다. 지정된 주소가 내보내기 섹션 내에 없는 경우(선택적 헤더에 표시된 주소 및 길이로 정의됨) 필드는 코드 또는 데이터의 실제 주소인 내보내기 RVA입니다. 그렇지 않은 경우 필드는 다른 DLL에서 기호 이름을 지정하는 전달자 RVA입니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
Export RVA |
이미지 베이스를 기준으로 하는 메모리에 로드될 때 내보낸 기호의 주소입니다. 예를 들어 내보낸 함수의 주소입니다. |
0 |
4 |
Forwarder RVA |
내보내기 섹션의 null로 끝나는 ASCII 문자열에 대한 포인터입니다. 이 문자열은 내보내기 테이블 데이터 디렉터리 항목에서 지정하는 범위 내에 있어야 합니다. 선택적 헤더 데이터 디렉터리(이미지만 해당)를 참조하세요. 이 문자열은 DLL 이름 및 내보내기 이름(예: "MYDLL.expfunc") 또는 DLL 이름 및 내보내기 서수(예: "MYDLL.#27")를 제공합니다. |
전달자 RVA는 다른 이미지에서 정의를 내보내 현재 이미지에서 내보내는 것처럼 표시됩니다. 이에 따라 기호를 동시에 가져오고 내보낼 수 있습니다.
예를 들어 Windows XP의 Kernel32.dll에서 "HeapAlloc"라는 내보내기는 "NTDLL.RtlAllocateHeap" 문자열로 전달됩니다. 이렇게 하면 애플리케이션에서 실제로 이에 대한 가져오기 참조를 포함하지 않고 Windows XP 특정 모듈인 Ntdll.dll을 사용할 수 있습니다. 애플리케이션의 가져오기 테이블은 Kernel32.dll만 참조합니다. 따라서 이 애플리케이션은 Windows XP에만 관련되지 않고 모든 Win32 시스템에서 실행할 수 있습니다.
내보내기 이름 포인터 테이블
내보내기 이름 포인터 테이블은 내보내기 이름 테이블에 대한 주소(RVA)의 배열입니다. 포인터는 각각 32비트이며 이미지 베이스를 기준으로 합니다. 포인터는 이진 검색을 허용하기 위해 어휘 순서로 정렬됩니다.
내보내기 이름에 대한 포인터가 내보내기 이름 포인터 테이블에 포함된 경우에만 해당 이름이 정의됩니다.
내보내기 서수 테이블
내보내기 서수 테이블은 내보내기 주소 테이블에 대한 16비트 비편향 인덱스의 배열입니다. 서수는 내보내기 Directory 테이블의 Ordinal Base 필드로 인해 편향됩니다. 즉, 내보내기 주소 테이블에 대한 실제 인덱스를 가져오려면 서수에서 서수 베이스를 빼야 합니다.
내보내기 이름 포인터 테이블과 내보내기 서수 테이블은 자연 필드 맞춤을 허용하도록 구분된 두 개의 병렬 배열을 형성합니다. 실제로 이러한 두 테이블은 하나의 테이블로 작동합니다. 이 경우 내보내기 이름 포인터 열은 퍼블릭(내보낸) 이름을 가리키고, 내보내기 서수 열은 해당 퍼블릭 이름에 해당하는 서수를 제공합니다. 내보내기 이름 포인터 테이블의 멤버와 내보내기 서수 테이블의 멤버는 각각의 배열에서 동일한 위치(인덱스)를 사용하여 연결됩니다.
따라서 내보내기 이름 포인터 테이블이 검색되고 위치 i에서 일치하는 문자열이 검색되면 기호의 RVA 및 편향된 서수를 찾는 알고리즘은 다음과 같습니다.
i = Search_ExportNamePointerTable (name);
ordinal = ExportOrdinalTable [i];
rva = ExportAddressTable [ordinal];
biased_ordinal = ordinal + OrdinalBase;
서수(편향된)로 기호를 검색하는 경우 기호의 RVA 및 이름을 찾는 알고리즘은 다음과 같습니다.
ordinal = biased_ordinal - OrdinalBase;
i = Search_ExportOrdinalTable (ordinal);
rva = ExportAddressTable [ordinal];
name = ExportNameTable [i];
내보내기 이름 테이블
내보내기 이름 테이블에는 내보내기 이름 포인터 테이블이 가리키는 실제 문자열 데이터가 포함됩니다. 이 테이블의 문자열은 다른 이미지가 기호를 가져오는 데 사용할 수 있는 퍼블릭 이름입니다. 이러한 퍼블릭 내보내기 이름은 기호가 자체 이미지 파일 및 소스 코드에 있는 프라이빗 기호 이름과 동일할 수 있지만 반드시 같지는 않습니다.
모든 내보낸 기호에는 내보낸 주소 테이블에 대한 인덱스일 뿐인 서수 값이 있습니다. 그러나 내보내기 이름을 사용하는 것은 선택 사항입니다. 내보낸 기호 중 일부 또는 전부에는 이름이 있을 수 있거나 전혀 없을 수 없습니다. 내보내기 이름이 있는 내보낸 기호의 경우 내보내기 이름 포인터 테이블과 내보내기 서수 테이블의 해당 항목이 함께 작동하여 각 이름을 서수와 연결합니다.
내보내기 이름 테이블의 구조체는 일련의 가변 길이 null 종료 ASCII 문자열입니다.
.idata 섹션
거의 모든 실행 파일(EXE)을 포함하여 기호를 가져오는 모든 이미지 파일에는 .idata 섹션이 있습니다. 가져오기 정보에 대한 일반적인 파일 레이아웃은 다음과 같습니다.
Directory 테이블
Null 디렉터리 항목
DLL1 가져오기 조회 테이블
Null
DLL2 가져오기 조회 테이블
Null
DLL3 가져오기 조회 테이블
Null
힌트 이름 테이블
가져오기 Directory 테이블
가져오기 정보는 가져오기 정보의 나머지 부분을 설명하는 가져오기 Directory 테이블로 시작합니다. 가져오기 Directory 테이블에는 DLL 이미지 내의 진입점에 대한 수정 참조를 확인하는 데 사용되는 주소 정보가 포함됩니다. 가져오기 Directory 테이블은 가져오기 디렉터리 항목의 배열로 구성되며 이미지에서 참조하는 각 DLL에 대한 항목이 하나씩 있습니다. 마지막 디렉터리 항목은 비어 있으며(null 값으로 채워짐) Directory 테이블의 끝을 나타냅니다.
각 가져오기 디렉터리 항목의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
Import Lookup Table RVA(Characteristics) |
가져오기 조회 테이블의 RVA입니다. 이 테이블에는 각 가져오기에 대한 이름 또는 서수가 포함됩니다. ("Characteristics"라는 이름은 Winnt.h에서 사용되지만 더 이상 이 필드를 설명하지 않습니다.) |
4 |
4 |
날짜/시간 스탬프 |
이미지가 바인딩될 때까지 0으로 설정되는 스탬프입니다. 이미지가 바인딩되면 이 필드가 DLL의 시간/데이터 스탬프로 설정됩니다. |
8 |
4 |
Forwarder Chain |
첫 번째 전달자 참조의 인덱스입니다. |
12 |
4 |
Name RVA |
DLL의 이름을 포함하는 ASCII 문자열의 주소입니다. 이 주소는 이미지 베이스를 기준으로 합니다. |
16 |
4 |
Import Address Table RVA(Thunk Table) |
가져오기 주소 테이블의 RVA입니다. 이미지가 바인딩될 때까지 이 테이블의 콘텐츠는 가져오기 조회 테이블의 콘텐츠와 동일합니다. |
가져오기 조회 테이블
가져오기 조회 테이블은 PE32의 경우 32비트 숫자 배열이고, PE32+의 경우 64비트 숫자 배열입니다. 각 항목은 다음 표에서 설명하는 비트 필드 형식을 사용합니다. 이 형식에서 31비트는 PE32의 최상위 비트이고, 63비트는 PE32+의 최상위 비트입니다. 이러한 항목의 컬렉션은 지정된 DLL의 모든 가져오기를 설명합니다. 마지막 항목은 테이블 끝을 나타내기 위해 0(NULL)으로 설정됩니다.
비트 | 크기 | 비트 필드 | 설명 |
---|---|---|---|
31/63 |
1 |
서수/이름 플래그 |
이 비트가 설정되면 서수로 가져옵니다. 그렇지 않으면 이름으로 가져옵니다. 비트는 PE32의 경우 0x80000000으로 마스킹되고, PE32+의 경우 0x8000000000000000으로 마스킹됩니다. |
15-0 |
16 |
서수 숫자 |
16비트 서수입니다. 이 필드는 Ordinal/Name Flag 비트 필드가 1(서수로 가져오기)인 경우에만 사용됩니다. 30~15 또는 62~15비트가 0이어야 합니다. |
30-0 |
31 |
Hint/Name Table RVA |
힌트/이름 테이블 항목의 31비트 RVA입니다. 이 필드는 Ordinal/Name Flag 비트 필드가 0(이름으로 가져오기)인 경우에만 사용됩니다. PE32+의 경우 62~31비트가 0이어야 합니다. |
Hint/Name Table
전체 가져오기 섹션에는 하나의 힌트/이름 테이블로 충분합니다. 각 힌트/이름 테이블 항목의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
2 |
힌트 |
내보내기 이름 포인터 테이블에 대한 인덱스입니다. 이 값을 사용하여 먼저 일치를 시도합니다. 실패하면 DLL의 내보내기 이름 포인터 테이블에서 이진 검색이 수행됩니다. |
2 |
변수 |
입력 |
가져올 이름을 포함하는 ASCII 문자열입니다. DLL의 퍼블릭 이름과 일치해야 하는 문자열입니다. 이 문자열은 대/소문자를 구분하며 null 바이트로 종료됩니다. |
* |
0 또는 1 |
패드 |
다음 항목을 짝수 경계에 맞추기 위해 필요한 경우 후행 null 바이트 뒤에 나타나는 후행 0 패드 바이트입니다. |
가져오기 주소 테이블
파일이 바인딩될 때까지 가져오기 주소 테이블의 구조체 및 콘텐츠는 가져오기 조회 테이블의 구조체 및 콘텐츠와 동일합니다. 바인딩하는 동안 가져오기 주소 테이블의 항목을 가져오는 기호의 32비트(PE32의 경우) 또는 64비트(PE32+의 경우) 주소로 덮어씁니다. 이러한 주소는 기술적으로 여전히 "가상 주소"라고 하지만 기호의 실제 메모리 주소입니다. 로더는 일반적으로 바인딩을 처리합니다.
.pdata 섹션
.pdata 섹션에는 예외 처리에 사용되는 함수 테이블 항목의 배열이 포함됩니다. 이 섹션은 이미지 데이터 디렉터리의 예외 테이블 항목에서 지정됩니다. 항목은 최종 이미지로 내보내기 전에 함수 주소(각 구조체의 첫 번째 필드)에 따라 정렬해야 합니다. 대상 플랫폼은 아래에서 설명하는 세 가지 함수 테이블 항목 형식 변형 중에서 사용되는 변형을 결정합니다.
32비트 MIPS 이미지의 경우 함수 테이블 항목의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
시작 주소 |
해당 함수의 VA입니다. |
4 |
4 |
끝 주소 |
함수 끝의 VA입니다. |
8 |
4 |
예외 처리기 |
실행할 예외 처리기에 대한 포인터입니다. |
12 |
4 |
처리기 데이터 |
처리기에 전달할 추가 정보에 대한 포인터입니다. |
16 |
4 |
Prolog 끝 주소 |
함수 프롤로그 끝의 VA입니다. |
ARM, PowerPC, SH3 및 SH4 Windows CE 플랫폼의 경우 함수 테이블 항목의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
시작 주소 |
해당 함수의 VA입니다. |
4 |
8비트 |
Prolog 길이 |
함수 프롤로그에 있는 명령의 수입니다. |
4 |
22비트 |
함수 길이 |
함수 명령의 수입니다. |
4 |
1비트 |
32-bit Flag |
설정되면 함수가 32비트 명령으로 구성됩니다. 그렇지 않으면 함수가 16비트 명령으로 구성됩니다. |
4 |
1비트 |
예외 플래그 |
설정되면 함수에 대한 예외 처리기가 있습니다. 그렇지 않으면 예외 처리기가 없습니다. |
x64 및 Itanium 플랫폼의 경우 함수 테이블 항목의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
시작 주소 |
해당 함수의 RVA입니다. |
4 |
4 |
끝 주소 |
함수 끝의 RVA입니다. |
8 |
4 |
정보 해제 |
해제 정보의 RVA입니다. |
.reloc 섹션(이미지만 해당)
베이스 재배치 테이블에는 이미지의 모든 베이스 재배치에 대한 항목이 포함됩니다. 선택적 헤더 데이터 디렉터리의 Base Relocation Table 필드는 베이스 재배치 테이블의 바이트 수를 지정합니다. 자세한 내용은 선택적 헤더 데이터 디렉터리(이미지만 해당)를 참조하세요. 베이스 재배치 테이블은 블록으로 나뉩니다. 각 블록은 4K 페이지의 베이스 재배치를 나타냅니다. 각 블록은 32비트 경계에서 시작해야 합니다.
PE 헤더에 지정된 이미지 베이스에서 로드 이미지를 로드할 수 있는 경우 로더는 링커에서 확인되는 베이스 재배치를 처리할 필요가 없습니다.
베이스 재배치 블록
각 베이스 재배치 블록에서 시작하는 구조체는 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
Page RVA |
이미지 베이스와 페이지 RVA가 각 오프셋에 추가되어 베이스 배치를 적용해야 하는 VA를 만듭니다. |
4 |
4 |
블록 크기 |
Page RVA 및 Block Size 필드와 뒤따르는 Type/Offse 필드를 포함한 베이스 재배치 블록의 총 바이트 수입니다. |
그런 다음, Block Size 필드 뒤에는 임의 개수의 Type 또는 Offset 필드 항목이 있습니다. 각 항목은 WORD(2바이트)이며 다음과 같은 구조체를 갖습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4비트 |
입력 |
WORD의 상위 4비트에 저장되며, 적용할 베이스 재배치의 형식을 나타내는 값입니다. 자세한 내용은 베이스 재배치 형식을 참조하세요. |
0 |
12비트 |
오프셋 |
블록의 Page RVA 필드에 지정된 시작 주소로부터의 오프셋인 WORD의 나머지 12비트에 저장됩니다. 이 오프셋은 베이스 재배치를 적용할 위치를 지정합니다. |
베이스 재배치를 적용하기 위해 기본 설정 베이스 주소와 이미지가 실제로 로드되는 베이스 주소 간의 차이가 계산됩니다. 기본 설정 베이스에서 이미지가 로드되는 경우 차이는 0이므로 베이스 재배치를 적용할 필요가 없습니다.
베이스 재배치 형식
상수 | 값 | 설명 |
---|---|---|
IMAGE_REL_BASED_ABSOLUTE |
0 |
베이스 재배치를 건너뜁니다. 이 형식은 블록을 채우는 데 사용할 수 있습니다. |
IMAGE_REL_BASED_HIGH |
1 |
베이스 재배치에서 차이의 상위 16비트를 오프셋의 16비트 필드에 추가합니다. 16비트 필드는 32비트 단어의 높은 값을 나타냅니다. |
IMAGE_REL_BASED_LOW |
2 |
베이스 재배치에서 차이의 하위 16비트를 오프셋의 16비트 필드에 추가합니다. 16비트 필드는 32비트 단어의 하위 절반을 나타냅니다. |
IMAGE_REL_BASED_HIGHLOW |
3 |
베이스 재배치에서 차이의 모든 32비트를 오프셋의 32비트 필드에 적용합니다. |
IMAGE_REL_BASED_HIGHADJ |
4 |
베이스 재배치에서 차이의 상위 16비트를 오프셋의 16비트 필드에 추가합니다. 16비트 필드는 32비트 단어의 높은 값을 나타냅니다. 32비트 값의 하위 16비트는 이 베이스 재배치 뒤에 있는 16비트 단어에 저장됩니다. 즉, 이 베이스 재배치에서 두 개의 슬롯을 차지합니다. |
IMAGE_REL_BASED_MIPS_JMPADDR |
5 |
재배치 해석은 컴퓨터 종류에 따라 달라집니다. 컴퓨터 종류가 MIPS인 경우 베이스 재배치가 MIPS 점프 명령에 적용됩니다. |
IMAGE_REL_BASED_ARM_MOV32 |
5 |
컴퓨터 종류가 ARM 또는 Thumb인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치에서 기호의 32비트 주소를 연속 MOVW/MOVT 명령 쌍에 적용합니다. |
IMAGE_REL_BASED_RISCV_HIGH20 |
5 |
컴퓨터 종류가 RISC-V인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치가 32비트 절대 주소의 상위 20비트에 적용됩니다. |
6 |
예약됨, 0이어야 합니다. |
|
IMAGE_REL_BASED_THUMB_MOV32 |
7 |
컴퓨터 종류가 Thumb인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치에서 기호의 32비트 주소를 연속 MOVW/MOVT 명령 쌍에 적용합니다. |
IMAGE_REL_BASED_RISCV_LOW12I |
7 |
컴퓨터 종류가 RISC-V인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치가 RISC-V I 형식의 명령 형식으로 구성된 32비트 절대 주소의 하위 12비트에 적용됩니다. |
IMAGE_REL_BASED_RISCV_LOW12S |
8 |
컴퓨터 종류가 RISC-V인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치가 RISC-V S 형식의 명령 형식으로 구성된 32비트 절대 주소의 하위 12비트에 적용됩니다. |
IMAGE_REL_BASED_LOONGARCH32_MARK_LA |
8 |
컴퓨터 종류가 LoongArch 32비트인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치가 2개의 연속 명령으로 구성된 32비트 절대 주소에 적용됩니다. |
IMAGE_REL_BASED_LOONGARCH64_MARK_LA |
8 |
컴퓨터 종류가 LoongArch 64비트인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치가 4개의 연속 명령으로 구성된 64비트 절대 주소에 적용됩니다. |
IMAGE_REL_BASED_MIPS_JMPADDR16 |
9 |
컴퓨터 종류가 MIPS인 경우에만 이 재배치에 의미가 있습니다. 베이스 재배치가 MIPS16 점프 명령에 적용됩니다. |
IMAGE_REL_BASED_DIR64 |
10 |
베이스 재배치에서 차이를 오프셋의 64비트 필드에 적용합니다. |
.tls 섹션
.tls 섹션은 정적 TLS(스레드 로컬 스토리지)에 대한 직접적인 PE 및 COFF 지원을 제공합니다. TLS는 데이터 개체가 자동(스택) 변수가 아니지만 코드를 실행하는 각 개별 스레드에 대해 로컬인 Windows에서 지원하는 특수 스토리지 클래스입니다. 따라서 각 스레드는 TLS를 사용하여 선언된 변수에 대해 서로 다른 값을 유지할 수 있습니다.
TlsAlloc, TlsFree, TlsSetValue 및 TlsGetValue API 호출을 사용하여 모든 양의 TLS 데이터를 지원할 수 있습니다. PE 또는 COFF 구현은 API를 사용하는 대체 접근 방식이며 고급 언어 프로그래머의 관점에서 더 간단하다는 장점이 있습니다. 이 구현을 사용하면 프로그램의 일반 정적 변수와 비슷하게 TLS 데이터를 정의하고 초기화할 수 있습니다. 예를 들어 Visual C++에서 정적 TLS 변수는 Windows API를 사용하지 않고 다음과 같이 정의할 수 있습니다.
__declspec (thread) int tlsFlag = 1;
이 프로그래밍 구문을 지원하기 위해 PE 및 COFF .tls 섹션은 초기화 데이터, 스레드별 초기화 및 종료에 대한 콜백 루틴 및 TLS 인덱스와 같은 정보를 지정합니다. 이에 대해 다음 논의에서 설명합니다.
참고 항목
Windows Vista 이전에는 정적으로 선언된 TLS 데이터 개체는 정적으로 로드된 이미지 파일에서만 사용할 수 있습니다. 이 사실로 인해 DLL 또는 DLL과 정적으로 연결된 모든 항목이 LoadLibrary API 함수를 사용하여 동적으로 로드되지 않는다는 것을 알고 있는 동안에는 DLL에서 정적 TLS 데이터를 사용할 수 있습니다. 그러나 Windows Vista부터는 정적 TLS를 사용한 DLL의 동적 로딩을 더 잘 지원하기 위해 Windows 로더가 개선되었습니다. 이 변경으로 이제 정적으로 선언된 TLS 데이터 객체가 있는 DLL을 LoadLibrary를 사용하여 동적으로 로드하는 경우에도 보다 안정적으로 사용할 수 있습니다. 로더는 로드 시점에 이러한 DLL에 대한 TLS 슬롯을 할당할 수 있으므로 이전 버전의 Windows에 존재하는 제한을 완화할 수 있습니다.
참고 항목
32비트 오프셋 및 인덱스 승수 4에 대한 참조는 32비트 아키텍처를 사용하는 시스템에 적용됩니다. 64비트 아키텍처를 기반으로 하는 시스템에서 필요에 따라 조정합니다.
실행 코드는 다음 단계를 통해 정적 TLS 데이터 개체에 액세스합니다.
링크 타임에 링커에서 TLS 디렉터리의 Address of Index 필드를 설정합니다. 이 필드는 프로그램에서 TLS 인덱스를 받을 것으로 예상되는 위치를 가리킵니다.
Microsoft 런타임 라이브러리는 TLS 디렉터리의 메모리 이미지를 정의하고 "__tls_used"(Intel x86 플랫폼) 또는 "_tls_used"(기타 플랫폼)라는 특수 이름을 지정하여 이 프로세스를 용이하게 합니다. 링커는 이 메모리 이미지를 찾고 여기에 있는 데이터를 사용하여 TLS 디렉터리를 만듭니다. TLS를 지원하고 Microsoft 링커를 사용하는 다른 컴파일러는 이와 동일한 기술을 사용해야 합니다.
스레드가 만들어지면 로더에서 TEB(스레드 환경 블록)의 주소를 FS 레지스터에 배치하여 스레드의 TLS 배열 주소를 전달합니다. TLS 배열에 대한 포인터는 TEB 시작으로부터의 0x2C 오프셋에 있습니다. 이는 Intel x86 관련 동작입니다.
로더에서 TLS 인덱스 값을 Address of Index 필드로 표시된 위치에 할당합니다.
실행 코드에서 TLS 인덱스와 TLS 배열의 위치도 검색합니다.
코드에서 TLS 인덱스와 TLS 배열 위치를 사용(인덱스와 4를 곱하여 배열에 대한 오프셋으로 사용)하여 지정된 프로그램 및 모듈에 대한 TLS 데이터 영역의 주소를 가져옵니다. 각 스레드에는 자체 TLS 데이터 영역이 있지만 이 영역은 개별 스레드에 데이터가 할당되는 방법을 인식할 필요가 없는 프로그램에 투명합니다.
개별 TLS 데이터 개체가 TLS 데이터 영역에 대한 일부 고정된 오프셋으로 액세스됩니다.
TLS 배열은 시스템에서 각 스레드에 대해 유지 관리하는 주소의 배열입니다. 이 배열의 각 주소는 프로그램 내에서 지정된 모듈(EXE 또는 DLL)에 대한 TLS 데이터의 위치를 제공합니다. TLS 인덱스는 사용할 배열의 멤버를 나타냅니다. 인덱스는 모듈을 식별하는 숫자(시스템에만 의미 있음)입니다.
TLS 디렉터리
TLS 디렉터리의 형식은 다음과 같습니다.
오프셋(PE32/ PE32+) | 사이즈(PE32/PE32+) | 필드 | 설명 |
---|---|---|---|
0 |
4/8 |
Raw Data Start VA |
TLS 템플릿의 시작 주소입니다. 템플릿은 TLS 데이터를 초기화하는 데 사용되는 데이터 블록입니다. 스레드가 만들어질 때마다 시스템에서 이 데이터를 모두 복사하므로 손상되지 않아야 합니다. 이 주소는 RVA가 아니며, 베이스 재배치가 .reloc 섹션에 있어야 하는 주소입니다. |
4/8 |
4/8 |
Raw Data End VA |
0 채우기를 제외한 TLS의 마지막 바이트 주소입니다. Raw Data Start VA 필드와 마찬가지로 RVA가 아니라 VA입니다. |
8/16 |
4/8 |
인덱스 주소 |
로더에서 할당하는 TLS 인덱스를 받을 위치입니다. 이 위치는 일반 데이터 섹션에 있으므로 프로그램에 액세스할 수 있는 기호 이름을 지정할 수 있습니다. |
12/24 |
4/8 |
콜백 주소 |
TLS 콜백 함수 배열에 대한 포인터입니다. 배열은 null로 종료되므로 콜백 함수가 지원되지 않는 경우 이 필드는 0으로 설정된 4바이트를 가리킵니다. 이러한 함수의 프로토타입에 대한 자세한 내용은 TLS 콜백 함수를 참조하세요. |
16/32 |
4 |
0 채우기 크기 |
Raw Data Start VA 및 Raw Data End VA 필드로 구분된 초기화된 데이터를 초과하는 템플릿의 크기(바이트)입니다. 전체 템플릿 크기는 이미지 파일에 있는 TLS 데이터의 전체 크기와 동일해야 합니다. 0 채우기는 0이 아닌 초기화된 데이터 뒤에 있는 데이터의 양입니다. |
20/36 |
4 |
특징 |
4비트[23:20]는 맞춤 정보를 설명합니다. 가능한 값은 IMAGE_SCN_ALIGN_*로 정의된 값이며, 개체 파일의 섹션 맞춤을 설명하는 데도 사용됩니다. 나머지 28비트는 나중에 사용하도록 예약되어 있습니다. |
TLS 콜백 함수
프로그램은 TLS 데이터 개체에 대한 추가 초기화 및 종료를 지원하기 위해 하나 이상의 TLS 콜백 함수를 제공할 수 있습니다. 이러한 콜백 함수의 일반적인 용도는 개체에 대한 생성자와 소멸자를 호출하는 것입니다.
일반적으로 둘 이상의 콜백 함수가 없지만 콜백은 원하는 경우 추가 콜백 함수를 추가할 수 있도록 배열로 구현됩니다. 둘 이상의 콜백 함수가 있는 경우 각 함수는 해당 주소가 배열에 나타나는 순서대로 호출됩니다. null 포인터는 배열을 종료합니다. 빈 목록(콜백이 지원되지 않음)을 갖는 것은 완벽하게 유효합니다. 이 경우 콜백 배열에는 정확히 하나의 멤버(null 포인터)가 있습니다.
콜백 함수의 프로토타입(PIMAGE_TLS_CALLBACK 형식의 포인터로 가리킴)에는 DLL 진입점 함수와 동일한 매개 변수가 있습니다.
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
);
Reserved 매개 변수는 0으로 설정해야 합니다. Reason 매개 변수에서 사용할 수 있는 값은 다음과 같습니다.
설정 | 값 | 설명 |
---|---|---|
DLL_PROCESS_ATTACH |
1 |
첫 번째 스레드를 포함하여 새 프로세스가 시작되었습니다. |
DLL_THREAD_ATTACH |
2 |
새 스레드가 만들어졌습니다. 첫 번째 스레드를 제외한 모든 스레드에 대해 이 알림을 보냅니다. |
DLL_THREAD_DETACH |
3 |
스레드가 종료됩니다. 첫 번째 스레드를 제외한 모든 스레드에 대해 이 알림을 보냅니다. |
DLL_PROCESS_DETACH |
0 |
원래 스레드를 포함하여 프로세스가 종료됩니다. |
로드 구성 구조체(이미지만 해당)
로드 구성 구조체(IMAGE_LOAD_CONFIG_DIRECTORY)는 이전에 파일 헤더 또는 이미지의 선택적 헤더에서 설명하기에는 너무 어렵거나 너무 큰 다양한 기능을 설명하기 위해 Windows NT 운영 체제 자체에서 매우 제한된 경우에만 사용되었습니다. 현재 버전의 Microsoft 링커 및 Windows XP 이상 버전의 Windows에서는 예약된 SEH 기술을 포함하는 32비트 x86 기반 시스템에 이 구조체의 새 버전을 사용합니다. 이렇게 하면 운영 체제에서 예외 디스패치 중에 사용하는 안전한 구조적 예외 처리기 목록이 제공됩니다. 처리기 주소가 이미지의 VA 범위에 있고 예약된 SEH 인식으로 표시되는 경우(즉, 앞에서 설명한 대로 선택적 헤더의 DllCharacteristics 필드에서 IMAGE_DLLCHARACTERISTICS_NO_SEH가 명확함) 처리기는 해당 이미지에 대해 알려진 안전한 처리기 목록에 있어야 합니다. 그렇지 않으면 운영 체제에서 애플리케이션을 종료합니다. 이는 과거에 운영 체제를 제어하는 데 사용된 "x86 예외 처리기 하이재킹" 익스플로잇을 방지하는 데 도움이 됩니다.
Microsoft 링커는 예약된 SEH 데이터를 포함하도록 기본 로드 구성 구조체를 자동으로 제공합니다. 사용자 코드에서 이미 로드 구성 구조체를 제공하는 경우 새로 예약된 SEH 필드를 포함해야 합니다. 그렇지 않으면 링커에서 예약된 SEH 데이터를 포함할 수 없으며 이미지가 예약된 SEH를 포함하는 것으로 표시되지 않습니다.
로드 구성 디렉터리
사전 예약된 SEH 로드 구성 구조체에 대한 데이터 디렉터리 항목은 운영 체제 로더에서 항상 특정 값일 것으로 예상하므로 로드 구성 구조의 특정 크기를 지정해야 합니다. 이와 관련하여 크기는 실제로 버전 확인일 뿐입니다. Windows XP 및 이전 버전의 Windows와의 호환성을 위해 크기는 x86 이미지의 경우 64여야 합니다.
로드 구성 레이아웃
로드 구성 구조체의 32비트 및 64비트 PE 파일에 대한 레이아웃은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
특징 |
파일의 특성을 나타내는 플래그이며 현재 사용되지 않습니다. |
4 |
4 |
TimeDateStamp |
날짜 및 시간 스탬프 값입니다. 값은 시스템 시계에 따라 1970년 1월 1일 자정(00:00:00)(협정 세계시) 이후 경과된 시간(초)으로 표시됩니다. 타임스탬프는 CRT(C 런타임) 시간 함수를 사용하여 출력할 수 있습니다. |
8 |
2 |
MajorVersion |
주 버전 번호입니다. |
10 |
2 |
MinorVersion |
부 버전 번호입니다. |
12 |
4 |
GlobalFlagsClear |
로더에서 프로세스를 시작할 때 이 프로세스에 대해 지울 전역 로더 플래그입니다. |
16 |
4 |
GlobalFlagsSet |
로더에서 프로세스를 시작할 때 이 프로세스에 대해 설정할 전역 로더 플래그입니다. |
20 |
4 |
CriticalSectionDefaultTimeout |
중단된 이 프로세스의 중요한 섹션에 사용할 기본 시간 제한 값입니다. |
24 |
4/8 |
DeCommitFreeBlockThreshold |
시스템에 반환되기 전에 해제해야 하는 메모리(바이트)입니다. |
28/32 |
4/8 |
DeCommitTotalFreeThreshold |
총 사용 가능한 메모리 양(바이트)입니다. |
32/40 |
4/8 |
LockPrefixTable |
[x86만 해당] 단일 프로세서 컴퓨터에서 NOP로 바꿀 수 있도록 LOCK 접두사가 사용되는 주소 목록의 VA입니다. |
36/48 |
4/8 |
MaximumAllocationSize |
최대 할당 크기(바이트)입니다. |
40/56 |
4/8 |
VirtualMemoryThreshold |
최대 가상 메모리 크기(바이트)입니다. |
44/64 |
4/8 |
ProcessAffinityMask |
이 필드를 0이 아닌 값으로 설정하는 것은 프로세스 시작 중에 이 값을 사용하여 SetProcessAffinityMask를 호출하는 것과 같습니다(.exe만 해당). |
48/72 |
4 |
ProcessHeapFlags |
HeapCreate 함수의 첫 번째 인수에 해당하는 힙 플래그를 처리합니다. 이러한 플래그는 프로세스를 시작하는 동안 만드는 프로세스 힙에 적용됩니다. |
52/76 |
2 |
CSDVersion |
서비스 팩 버전 식별자입니다. |
54/78 |
2 |
DependentLoadFlags |
운영 체제가 모듈의 정적으로 연결된 가져오기를 확인할 때 사용되는 기본 로드 플래그입니다. |
56/80 |
4/8 |
EditList |
시스템에서 사용하도록 예약되어 있습니다. |
60/88 |
4/8 |
SecurityCookie |
Visual C++ 또는 GS 구현에서 사용되는 쿠키에 대한 포인터입니다. |
64/96 |
4/8 |
SEHandlerTable |
[x86만 해당] 이미지에 있는 각각의 유효하고 고유한 SE 처리기의 정렬된 RVA 테이블에 대한 VA입니다. |
68/104 |
4/8 |
SEHandlerCount |
[x86만 해당] 테이블에 있는 고유한 처리기의 수입니다. |
72/112 |
4/8 |
GuardCFCheckFunctionPointer |
제어 흐름 보호 검사 함수 포인터가 저장되는 VA입니다. |
76/120 |
4/8 |
GuardCFDispatchFunctionPointer |
제어 흐름 보호 디스패치 함수 포인터가 저장되는 VA입니다. |
80/128 |
4/8 |
GuardCFFunctionTable |
이미지에 있는 각 제어 흐름 보호 함수의 정렬된 RVA 테이블에 대한 VA입니다. |
84/136 |
4/8 |
GuardCFFunctionCount |
위 테이블에 있는 고유한 RVA의 수입니다. |
88/144 |
4 |
GuardFlags |
제어 흐름 보호 관련 플래그입니다. |
92/148 |
12 |
CodeIntegrity |
코드 무결성 정보입니다. |
104/160 |
4/8 |
GuardAddressTakenIatEntryTable |
IAT 테이블을 가져온 제어 흐름 보호 주소가 저장되는 VA입니다. |
108/168 |
4/8 |
GuardAddressTakenIatEntryCount |
위 테이블에 있는 고유한 RVA의 수입니다. |
112/176 |
4/8 |
GuardLongJumpTargetTable |
제어 흐름 보호 점프 대상 테이블이 저장되는 VA입니다. |
116/184 |
4/8 |
GuardLongJumpTargetCount |
위 테이블에 있는 고유한 RVA의 수입니다. |
GuardFlags 필드에는 다음과 같은 플래그 및 하위 필드 중 하나 이상의 조합이 포함됩니다.
모듈에서 시스템 제공 지원을 사용하여 제어 흐름 무결성 검사를 수행합니다.
#define IMAGE_GUARD_CF_INSTRUMENTED 0x00000100
모듈에서 제어 흐름 및 쓰기 무결성 검사를 수행합니다.
#define IMAGE_GUARD_CFW_INSTRUMENTED 0x00000200
모듈에서 유효한 제어 흐름 대상 메타데이터를 포함합니다.
#define IMAGE_GUARD_CF_FUNCTION_TABLE_PRESENT 0x00000400
모듈에서 /GS 보안 쿠키를 사용하지 않습니다.
#define IMAGE_GUARD_SECURITY_COOKIE_UNUSED 0x00000800
모듈에서 읽기 전용 지연 로드 IAT를 지원합니다.
#define IMAGE_GUARD_PROTECT_DELAYLOAD_IAT 0x00001000
자유롭게 다시 보호할 수 있는 자체 .didat 섹션의 가져오기 테이블(다른 항목 없음)을 지연 로드합니다.
#define IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION 0x00002000
모듈에서 표시되지 않는 내보내기 정보를 포함합니다. 또한 IAT 테이블을 가져온 주소가 로드 구성에도 있음을 유추합니다.
#define IMAGE_GUARD_CF_EXPORT_SUPPRESSION_INFO_PRESENT 0x00004000
모듈에서 내보내기 표시 안 함을 사용하도록 설정합니다.
#define IMAGE_GUARD_CF_ENABLE_EXPORT_SUPPRESSION 0x00008000
모듈에서 longjmp 대상 정보를 포함합니다.
#define IMAGE_GUARD_CF_LONGJUMP_TABLE_PRESENT 0x00010000
제어 흐름 보호 함수 테이블 항목의 진행 속도(즉, 테이블 항목당 추가 바이트 수)를 포함하는 하위 필드에 대한 마스크입니다.
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_MASK 0xF0000000
또한 Windows SDK winnt.h 헤더는 제어 흐름 보호 함수 테이블 진행 속도를 오른쪽 맞춤하기 위해 GuardFlags 값을 오른쪽으로 이동하는 비트의 양에 대해 이 매크로를 정의합니다.
#define IMAGE_GUARD_CF_FUNCTION_TABLE_SIZE_SHIFT 28
.rsrc 섹션
리소스는 여러 수준의 이진 정렬 트리 구조체로 인덱싱됩니다. 일반 디자인은 2**31개 수준을 통합할 수 있습니다. 그러나 규칙에 따라 Windows는 다음 세 가지 수준을 사용합니다.
- 유형 이름 언어
일련의 리소스 Directory 테이블은 다음과 같은 방식으로 모든 수준과의 관계를 설정합니다. 각 Directory 테이블 뒤에는 해당 수준(Type, Name 또는 Language 수준)에 대한 이름 또는 식별자(ID)와 데이터 설명 또는 다른 Directory 테이블의 주소를 제공하는 일련의 디렉터리 항목이 있습니다. 주소에서 데이터 설명을 가리키는 경우 데이터는 트리의 리프입니다. 주소에서 다른 Directory 테이블을 가리키는 경우 해당 테이블은 다음 수준 아래의 디렉터리 항목을 나열합니다.
리프의 Type, Name 및 Language ID는 리프에 도달하기 위해 Directory 테이블을 통해 이동하는 경로에 따라 결정됩니다. 첫 번째 테이블은 Type ID를 결정하고, 두 번째 테이블(첫 번째 테이블의 디렉터리 항목에서 가리킴)은 Name ID를 결정하며, 세 번째 테이블은 Language ID를 결정합니다.
.rsrc 섹션의 일반 구조체는 다음과 같습니다.
데이터 | 설명 |
---|---|
리소스 디렉토리 테이블(및 리소스 디렉토리 항목) |
트리의 각 노드 그룹에 대해 하나씩 일련의 테이블입니다. 모든 최상위 수준(Type) 노드가 첫 번째 테이블에 나열됩니다. 이 테이블의 항목은 두 번째 수준 테이블을 가리킵니다. 두 번째 수준 트리마다 Type ID는 같지만 Name ID는 다릅니다. 세 번째 수준 트리에서는 Type 및 Name ID는 같지만 Language ID는 다릅니다. 각 개별 테이블 바로 뒤에는 디렉터리 항목이 있으며, 각 항목에는 이름 또는 숫자 식별자와 데이터 설명 또는 다음 하위 수준의 테이블에 대한 포인터가 있습니다. |
리소스 디렉토리 스트링 |
디렉터리 항목에서 가리키는 문자열 데이터 역할을 하는 2바이트 맞춤 유니코드 문자열입니다. |
리소스 데이터 설명 |
테이블에서 가리키는 레코드의 배열이며, 리소스 데이터의 실제 크기와 위치를 설명합니다. 이러한 레코드는 리소스 설명 트리의 리프입니다. |
리소스 데이터 |
리소스 섹션의 원시 데이터입니다. Resource Data Description 필드의 크기 및 위치 정보는 리소스 데이터의 개별 영역을 구분합니다. |
리소스 Directory 테이블
각 리소스 Directory 테이블의 형식은 다음과 같습니다. 테이블이 실제로 디렉터리 항목(섹션 6.9.2 "리소스 디렉터리 항목"에서 설명함)과 이 데이터 구조체로 구성되므로 이 구조체는 테이블의 제목으로 간주해야 합니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
특징 |
리소스 플래그입니다. 이 필드는 나중에 사용되도록 예약되어 있습니다. 현재 0으로 설정됩니다. |
4 |
4 |
날짜/시간 스탬프 |
리소스 컴파일러에서 리소스 데이터를 만든 시간입니다. |
8 |
2 |
주 버전 |
사용자가 설정한 주 버전 번호입니다. |
10 |
2 |
부 버전 |
사용자가 설정한 부 버전 번호입니다. |
12 |
2 |
이름 항목 수 |
문자열을 사용하여 Type, Name 또는 Language 항목을 식별하는 테이블 바로 뒤에 있는 디렉터리 항목의 수입니다(테이블 수준에 따라 다름). |
14 |
2 |
ID 항목 수 |
숫자 ID를 Type, Name 또는 Language 항목에 사용하는 Name 항목 바로 뒤에 있는 디렉터리 항목의 수입니다. |
리소스 디렉터리 항목
디렉터리 항목은 테이블의 행을 구성합니다. 각 리소스 디렉터리 항목의 형식은 다음과 같습니다. 항목이 Name 또는 ID 항목인지 여부는 리소스 Directory 테이블에서 표시되며, 이 항목 뒤에는 Name 및 ID 항목의 수가 표시됩니다(모든 Name 항목은 테이블의 모든 ID 항목보다 우선함). 테이블의 모든 항목은 오름차순으로 정렬됩니다. Name 항목은 대/소문자를 구분하는 문자열별로 정렬되고, ID 항목은 숫자 값별로 정렬됩니다. 오프셋은 IMAGE_DIRECTORY_ENTRY_RESOURCE DataDirectory의 주소를 기준으로 합니다. 자세한 내용은 PE 내 피어링: Win32 이식 가능한 실행 파일 형식 둘러보기를 참조하세요.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
이름 오프셋 |
테이블 수준에 따라 Type, Name 또는 Language ID 항목을 제공하는 문자열의 오프셋입니다. |
0 |
4 |
정수 ID |
Type, Name 또는 Language ID 항목을 식별하는 32비트 정수입니다. |
4 |
4 |
데이터 항목 오프셋 |
상위 0비트입니다. 리소스 데이터 항목(리프)의 주소입니다. |
4 |
4 |
하위 디렉토리 오프셋 |
상위 1비트입니다. 하위 31비트는 다른 리소스 Directory 테이블(다음 수준 아래)의 주소입니다. |
리소스 디렉터리 문자열
리소스 디렉터리 문자열 영역은 단어에 맞춘 유니코드 문자열로 구성됩니다. 이러한 문자열은 모두 마지막 리소스 디렉터리 항목 뒤와 첫 번째 리소스 데이터 항목 앞에 저장됩니다. 이렇게 하면 이러한 가변 길이 문자열이 고정 크기 디렉터리 항목의 맞춤에 미치는 영향을 최소화합니다. 각 리소스 디렉터리 문자열의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
2 |
길이 |
길이 필드 자체를 포함하지 않는 문자열의 크기입니다. |
2 |
변수 |
유니코드 문자열 |
단어에 맞춘 가변 길이 유니코드 문자열 데이터입니다. |
리소스 데이터 항목
각 리소스 데이터 항목은 리소스 데이터 영역에 있는 원시 데이터의 실제 단위를 설명합니다. 리소스 데이터 항목의 형식은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
Data RVA |
리소스 데이터 영역에 있는 리소스 데이터 단위의 주소입니다. |
4 |
4 |
크기 |
Data RVA 필드에서 가리키는 리소스 데이터의 크기(바이트)입니다. |
8 |
4 |
Codepage |
리소스 데이터 내의 코드 포인트 값을 디코딩하는 데 사용되는 코드 페이지입니다. 일반적으로 코드 페이지는 유니코드 코드 페이지입니다. |
12 |
4 |
예약됨, 0이어야 합니다. |
.cormeta 섹션(개체만 해당)
CLR 메타데이터는 이 섹션에 저장됩니다. 개체 파일에 관리 코드가 포함되어 있음을 나타내는 데 사용됩니다. 메타데이터의 형식은 문서화되지 않지만, 메타데이터를 처리하기 위해 CLR 인터페이스에 전달될 수 있습니다.
.sxdata 섹션
개체의 유효한 예외 처리기는 해당 개체의 .sxdata 섹션에 나열됩니다. 이 섹션은 IMAGE_SCN_LNK_INFO로 표시됩니다. 여기에는 인덱스당 4바이트를 사용하는 유효한 각 처리기의 COFF 기호 인덱스가 포함됩니다.
또한 컴파일러는 값 필드의 LSB가 1로 설정된 "@feat.00" 절대 기호를 내보내 COFF 개체를 등록된 SEH로 표시합니다. 등록된 SEH 처리기가 없는 COFF 개체에는 "@feat.00" 기호가 있지만 .sxdata 섹션은 없습니다.
보관(라이브러리) 파일 형식
COFF 보관 형식은 개체 파일 컬렉션을 저장하기 위한 표준 메커니즘을 제공합니다. 이러한 컬렉션은 일반적으로 프로그래밍 설명서에서 라이브러리라고 합니다.
보관의 처음 8바이트는 파일 서명으로 구성됩니다. 보관의 나머지 부분은 다음과 같이 일련의 보관 멤버로 구성됩니다.
첫 번째 및 두 번째 멤버는 "링커 멤버"입니다. 이러한 각 멤버에는 가져오기 이름 형식 섹션에서 설명한 대로 자체의 고유한 형식이 있습니다. 일반적으로 링커는 정보를 이러한 보관 멤버에 배치합니다. 링커 멤버에는 보관의 디렉터리가 포함됩니다.
세 번째 멤버는 "longnames" 멤버입니다. 이 선택적 멤버는 각 문자열이 다른 보관 멤버의 이름인 일련의 null로 끝나는 ASCII 문자열로 구성됩니다.
나머지 보관은 표준(개체 파일) 멤버로 구성됩니다. 이러한 각 멤버에는 하나의 개체 파일 전체의 콘텐츠가 포함됩니다.
보관 멤버 헤더는 각 멤버의 앞에 있습니다. 다음 목록에서는 보관의 일반 구조체를 보여 줍니다.
Signature :"!<arch>\n" |
---|
헤더 |
---|
첫 번째 링커 멤버 |
헤더 |
---|
두 번째 링커 멤버 |
헤더 |
---|
longnames 멤버 |
헤더 |
---|
OBJ 파일 1의 콘텐츠 (COFF 형식) |
헤더 |
---|
OBJ 파일 2의 콘텐츠 (COFF 형식) |
...
헤더 |
---|
OBJ 파일 N의 콘텐츠 (COFF 형식) |
보관 파일 서명
보관 파일 서명은 파일 유형을 식별합니다. 보관 파일을 입력으로 사용하는 모든 유틸리티(예: 링커)는 이 서명을 읽어 파일 유형을 확인할 수 있습니다. 서명은 다음 ASCII 문자로 구성되며, 아래의 각 문자는 줄 바꿈(\n) 문자를 제외하고 문자 그대로 표시됩니다.
!<arch>\n
Windows SDK winnt.h 헤더는 다음 매크로를 정의합니다.
#define IMAGE_ARCHIVE_START_SIZE 8
#define IMAGE_ARCHIVE_START "!<arch>\n"
#define IMAGE_ARCHIVE_END "`\n"
#define IMAGE_ARCHIVE_PAD "\n"
#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
#define IMAGE_ARCHIVE_HYBRIDMAP_MEMBER "/<HYBRIDMAP>/ "
보관 멤버 헤더
각 멤버(링커, longnames 또는 개체 파일 멤버) 앞에는 헤더가 있습니다. 보관 멤버 헤더의 형식은 다음과 같습니다. 여기서 각 필드는 왼쪽 맞춤되고 필드 끝까지 공백으로 채워지는 ASCII 텍스트 문자열입니다. 이러한 필드에는 종료 null 문자가 없습니다.
각 멤버 헤더는 이전 아카이브 멤버가 끝난 후 첫 번째 짝수 주소에서 시작하며, 다음 멤버가 짝수 주소에서 시작하도록 아카이브 멤버 뒤에 바이트 '\n'(IMAGE_ARCHIVE_PAD) 1개를 삽입할 수 있습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
16 |
입력 |
이름을 종료하기 위해 슬래시(/)가 추가된 보관 멤버의 이름입니다. 첫 번째 문자가 슬래시인 경우 이름은 다음 표에서 설명한 대로 특별하게 해석됩니다. |
16 |
12 |
날짜 |
보관 멤버를 만든 날짜 및 시간이며, 1970년 1월 1일 UCT 이후의 시간(초)에 대한 ASCII 10진수 표현입니다. |
28 |
6 |
사용자 ID |
사용자 ID에 대한 ASCII 10진수 표현입니다. Microsoft 도구는 모든 공백을 내보내므로 이 필드는 Windows 플랫폼에서 의미 있는 값을 포함하지 않습니다. |
34 |
6 |
그룹 ID |
그룹 ID에 대한 ASCII 10진수 표현입니다. Microsoft 도구는 모든 공백을 내보내므로 이 필드는 Windows 플랫폼에서 의미 있는 값을 포함하지 않습니다. |
40 |
8 |
모드 |
멤버의 파일 모드에 대한 ASCII 8진수 표현입니다. _wstat C 런타임 함수의 ST_MODE 값입니다. |
48 |
10 |
크기 |
헤더 크기를 포함하지 않은 보관 멤버의 전체 크기에 대한 ASCII 10진수 표현입니다. |
58 |
2 |
헤더 끝 |
C 문자열 "`\n"(IMAGE_ARCHIVE_END)의 2바이트(0x60 0x0A)입니다. |
Name 필드에는 다음 표에서 표시하는 형식 중 하나가 있습니다. 앞에서 설명한 대로 이러한 각 문자열은 왼쪽 맞춤되고 16바이트 필드 내에서 후행 공백으로 채워집니다.
Name 필드의 콘텐츠 | 설명 |
---|---|
이름/ |
보관 멤버의 이름입니다. |
/ |
보관 멤버는 두 링커 멤버 중 하나입니다. 두 링커 멤버는 모두 이 이름을 갖습니다. |
// |
보관 멤버는 일련의 null로 끝나는 ASCII 문자열로 구성된 longnames 멤버입니다. longnames 멤버는 세 번째 보관 멤버이며 선택 사항입니다. |
/n |
보관 멤버의 이름은 longnames 멤버 내의 n 오프셋에 있습니다. n 숫자는 오프셋의 10진수 표현입니다. 예를 들어 "/26"은 보관 멤버의 이름이 longnames 멤버 콘텐츠의 시작에서 26바이트 뒤에 있음을 나타냅니다. |
첫 번째 링커 멤버
첫 번째 링커 멤버의 이름은 "/"(IMAGE_ARCHIVE_LINKER_MEMBER)입니다. 첫 번째 링커 멤버는 이전 버전과의 호환성을 위해 포함됩니다. 현재 링커에서 사용하지 않지만 해당 형식이 정확해야 합니다. 이 링커 멤버는 두 번째 링커 멤버와 마찬가지로 기호 이름의 디렉터리를 제공합니다. 각 기호에 대해 정보는 기호가 포함된 보관 멤버를 찾을 수 있는 위치를 나타냅니다.
첫 번째 링커 멤버의 형식은 다음과 같습니다. 이 정보는 헤더 뒤에 나타납니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
심볼 수 |
인덱싱된 기호의 수를 포함하는 부호 없는 long입니다. 이 숫자는 big-endian 형식으로 저장됩니다. 각 개체 파일 멤버는 일반적으로 하나 이상의 외부 기호를 정의합니다. |
4 |
4 * n |
오프셋 |
보관 멤버 헤더에 대한 파일 오프셋의 배열입니다. 여기서 n은 Number of Symbols 필드와 같습니다. 배열의 각 숫자는 big-endian 형식으로 저장되는 부호 없는 long입니다. 이름이 문자열 테이블에 지정된 각 기호에 대해 오프셋 배열의 해당 요소는 기호가 포함된 보관 멤버의 위치를 제공합니다. |
* |
* |
문자열 테이블 |
디렉터리에 있는 모든 기호의 이름을 지정하는 일련의 null 종료 문자열입니다. 각 문자열은 이전 문자열의 null 문자 바로 뒤에서 시작합니다. 문자열 수는 Number of Symbols 필드의 값과 같아야 합니다. |
오프셋 배열의 요소는 오름차순으로 정렬되어야 합니다. 즉, 문자열 테이블의 기호가 보관 멤버의 순서에 따라 정렬되어야 합니다. 예를 들어 첫 번째 개체 파일 멤버의 모든 기호는 두 번째 개체 파일의 기호 앞에 나열되어야 합니다.
두 번째 링커 멤버
첫 번째 링커 멤버와 마찬가지로 두 번째 링커 멤버의 이름은 "/"(IMAGE_ARCHIVE_LINKER_MEMBER)입니다. 두 링커 멤버는 모두 기호 디렉터리와 이 디렉터리를 포함하는 보관 멤버를 제공하지만, 두 번째 링커 멤버는 모든 현재 링커에서 첫 번째 링커 멤버보다 우선적으로 사용됩니다. 두 번째 링커 멤버는 기호 이름을 어휘 순서로 포함하므로 이름별로 더 빠르게 검색할 수 있습니다.
두 번째 멤버의 형식은 다음과 같습니다. 이 정보는 헤더 뒤에 나타납니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
4 |
멤버 수 |
보관 멤버의 수를 포함하는 부호 없는 long입니다. |
4 |
4 * m |
오프셋 |
오름차순으로 정렬된 보관 멤버 헤더에 대한 파일 오프셋의 배열입니다. 각 오프셋은 부호 없는 long 입니다. m 숫자는 Number of Members 필드의 값과 같습니다. |
* |
4 |
심볼 수 |
인덱싱된 기호의 수를 포함하는 부호 없는 long입니다. 각 개체 파일 멤버는 일반적으로 하나 이상의 외부 기호를 정의합니다. |
* |
2 * n |
인덱스 |
기호 이름을 보관 멤버 오프셋에 매핑하고 1부터 시작하는 인덱스(부호 없는 short)의 배열입니다. n 숫자는 Number of Symbols 필드와 같습니다. 이름이 문자열 테이블에 지정된 각 기호에 대해 Indices 배열의 해당 요소는 인덱스를 Offsets 배열에 제공합니다. 그런 다음, Offsets 배열은 기호를 포함하는 보관 멤버의 위치를 제공합니다. |
* |
* |
문자열 테이블 |
디렉터리에 있는 모든 기호의 이름을 지정하는 일련의 null 종료 문자열입니다. 각 문자열은 이전 문자열의 null 바이트 바로 뒤에서 시작합니다. 문자열 수는 Number of Symbols 필드의 값과 같아야 합니다. 이 테이블은 모든 기호 이름을 어휘 오름차순으로 나열합니다. |
longnames 멤버
longnames 멤버의 이름은 "//"(IMAGE_ARCHIVE_LONGNAMES_MEMBER)입니다. longnames 멤버는 일련의 보관 멤버 이름 문자열입니다. Name 필드의 공간(16바이트)이 부족한 경우에만 이름이 여기에 나타납니다. longnames 멤버는 선택 사항입니다. 헤더만 있고 비어 있거나 헤더 없이 완전히 비어 있을 수도 있습니다.
문자열은 null로 종료됩니다. 각 문자열은 이전 문자열의 null 바이트 바로 뒤에서 시작합니다.
가져오기 라이브러리 형식
기존 가져오기 라이브러리, 즉 다른 이미지에서 사용하기 위해 한 이미지에서 내보내기를 설명하는 라이브러리는 일반적으로 섹션 7 보관(라이브러리) 파일 형식에서 설명하는 레이아웃을 따릅니다. 주요 차이점은 가져오기 라이브러리 멤버에는 실제 파일 대신 의사 개체 파일이 포함된다는 것입니다. 즉, 각 멤버에는 섹션 6.4 .idata 섹션에서 설명하는 가져오기 테이블을 빌드하는 데 필요한 섹션 기여가 포함됩니다. 링커는 내보내기 애플리케이션을 빌드하는 동안 이 보관을 생성합니다.
가져오기에 대한 섹션 기여는 작은 정보 세트에서 유추할 수 있습니다. 링커는 라이브러리를 만들 때 자세한 정보 전체를 각 멤버에 대한 가져오기 라이브러리에 생성하거나, 정식 정보만 라이브러리에 쓰고 나중에 이를 사용하는 애플리케이션에서 필요한 데이터를 즉시 생성하도록 할 수 있습니다.
긴 형식의 가져오기 라이브러리에서 단일 멤버에 포함되는 정보는 다음과 같습니다.
- 보관 멤버 헤더
- 파일 헤더
- 섹션 헤더
- 각 섹션 헤더에 해당하는 데이터
- COFF 기호 테이블
- 문자열
반면, 짧은 가져오기 라이브러리는 다음과 같이 작성됩니다.
- 보관 멤버 헤더
- 가져오기 헤더
- null 종료 가져오기 이름 문자열
- null 종료 DLL 이름 문자열
이는 사용하는 시점에서 멤버의 전체 콘텐츠를 정확하게 다시 구성하는 데 충분한 정보입니다.
가져오기 헤더
가져오기 헤더에 포함되는 필드와 오프셋은 다음과 같습니다.
Offset | 크기 | 필드 | 설명 |
---|---|---|---|
0 |
2 |
Sig1 |
IMAGE_FILE_MACHINE_UNKNOWN 이어야 합니다. 자세한 내용은 컴퓨터 종류를 참조하세요. |
2 |
2 |
Sig2 |
0xFFFF여야 합니다. |
4 |
2 |
버전 |
구조체 버전입니다. |
6 |
2 |
컴퓨터 |
대상 컴퓨터의 종류를 식별하는 번호입니다. 자세한 내용은 컴퓨터 종류를 참조하세요. |
8 |
4 |
날짜-시간 스탬프 |
파일을 만든 시간 및 날짜입니다. |
12 |
4 |
데이터 크기 |
헤더 뒤에 있는 문자열의 크기입니다. |
16 |
2 |
서수/힌트 |
Name Type 필드의 값에 따라 결정되는 가져오기에 대한 서수 또는 힌트입니다. |
18 |
2비트 |
입력 |
가져오기 형식입니다. 특정 값 및 설명은 가져오기 형식을 참조하세요. |
3비트 |
이름 형식 |
가져오기 이름 형식입니다. 자세한 내용은 가져오기 이름 형식을 참조하세요. |
|
11비트 |
예약됨 |
예약됨, 0이어야 합니다. |
이 구조체 뒤에는 가져온 기호의 이름과 해당 기호를 가져온 DLL을 설명하는 두 개의 null 종료 문자열이 있습니다.
가져오기 형식
가져오기 헤더의 Type 필드에 대해 정의되는 값은 다음과 같습니다.
상수 | 값 | 설명 |
---|---|---|
IMPORT_OBJECT_CODE |
0 |
실행 코드입니다. |
IMPORT_OBJECT_DATA |
1 |
데이터 |
IMPORT_OBJECT_CONST |
2 |
.def 파일에서 CONST로 지정됩니다. |
이러한 값은 해당 데이터에 액세스해야 하는 경우 라이브러리를 사용하는 도구에서 생성해야 하는 섹션 기여를 결정하는 데 사용됩니다.
가져오기 이름 형식
null로 끝나는 가져오기 기호 이름은 연결된 가져오기 헤더 바로 뒤에 있습니다. 가져오기 헤더의 Name Type 필드에 대해 정의되는 값은 다음과 같습니다. 이러한 값은 이름을 사용하여 가져오기를 나타내는 올바른 기호를 생성하는 방법을 나타냅니다.
상수 | 값 | 설명 |
---|---|---|
IMPORT_OBJECT_ORDINAL | 0 | 가져오기는 서수입니다. 이는 가져오기 헤더의 Ordinal/Hint 필드 값이 가져오기의 서수임을 나타냅니다. 이 상수가 지정되지 않으면 Ordinal/Hint 필드를 항상 가져오기의 힌트로 해석해야 합니다. |
IMPORT_OBJECT_NAME | 1 | 가져오기 이름은 퍼블릭 기호 이름과 동일합니다. |
IMPORT_OBJECT_NAME_NOPREFIX | 2 | 가져오기 이름은 퍼블릭 기호 이름이지만, 선행 ?, @ 또는 필요에 따라 _ 문자를 건너뜁니다. |
IMPORT_OBJECT_NAME_UNDECORATE | 3 | 가져오기 이름은 퍼블릭 기호 이름이지만, 선행 ?, @ 또는 필요에 따라 _ 문자를 건너뛰고 첫 번째 @ 문자에서 자릅니다. |
부록 A: Authenticode PE 이미지 해시 계산
이미지의 무결성을 확인하기 위해 여러 특성 인증서를 사용해야 합니다. 그러나 가장 일반적인 인증서는 Authenticode 서명입니다. Authenticode 서명을 사용하여 PE 이미지 파일의 관련 섹션이 파일의 원래 형식에서 어떤 방식으로도 변경되지 않았는지 확인할 수 있습니다. 이 작업을 수행하기 위해 Authenticode 서명에는 PE 이미지 해시라는 항목이 포함됩니다.
Authenticode PE 이미지 해시란?
Authenticode PE 이미지 해시 또는 간단히 하여 파일 해시는 파일의 무결성과 관련된 작은 값을 생성한다는 점에서 파일 체크섬과 비슷합니다. 체크섬은 간단한 알고리즘으로 생성되며 주로 메모리 오류를 검색하는 데 사용됩니다. 즉, 디스크의 메모리 블록이 잘못되었고 이 블록에 저장된 값이 손상되었는지 여부를 검색하는 데 사용됩니다. 파일 해시는 파일 손상도 검색한다는 점에서 체크섬과 비슷합니다. 그러나 대부분의 체크섬 알고리즘과 달리 원래(수정되지 않은) 형식과 동일한 파일 해시를 포함하도록 파일을 수정하는 것은 매우 어렵습니다. 즉, 체크섬은 손상으로 이어지는 간단한 메모리 오류를 검색하기 위한 것이지만, 파일 해시는 바이러스, 해커 또는 트로이 목마 프로그램에서 도입된 것과 같이 파일에 대한 의도적이거나 미묘한 수정을 검색하는 데 사용할 수 있습니다.
Authenticode 서명에서 파일 해시는 파일 서명자에게만 알려진 프라이빗 키를 사용하여 디지털 방식으로 서명됩니다. 소프트웨어 소비자는 파일의 해시 값을 계산하고 이 값을 Authenticode 디지털 서명에 포함된 서명된 해시 값과 비교하여 파일의 무결성을 확인할 수 있습니다. 파일 해시가 일치하지 않으면 PE 이미지 해시에 포함된 파일의 일부가 수정된 것입니다.
Authenticode PE 이미지 해시에 포함되는 항목은 무엇인가요?
모든 이미지 파일 데이터를 PE 이미지 해시 계산에 포함하는 것은 가능하거나 바람직하지 않습니다. 경우에 따라 바람직하지 않은 특성을 나타내거나(예: 공개적으로 릴리스된 파일에서 디버깅 정보를 제거할 수 없음) 포함할 수 없을 뿐입니다. 예를 들어 이미지 파일 내의 모든 정보를 Authenticode 서명에 포함한 다음, 이제 원래 있던 Authenticode 서명이 파일에 포함되어 있으므로 해당 PE 이미지 해시가 포함된 Authenticode 서명을 PE 이미지에 삽입하고 나중에 모든 이미지 파일 데이터를 계산에 다시 포함하여 동일한 PE 이미지 해시를 생성할 수는 없습니다.
Authenticode PE 이미지 해시 생성 프로세스
이 섹션에서는 PE 이미지 해시가 계산되는 방법과 Authenticode 서명을 무효화하지 않고 수정할 수 있는 PE 이미지의 특정 부분에 대해 설명합니다.
참고
특정 파일에 대한 PE 이미지 해시는 특성 인증서를 해시된 파일 내에 포함하지 않고 별도의 카탈로그 파일에 포함할 수 있습니다. 이는 실제로 Authenticode 서명이 포함되지 않은 PE 이미지를 수정하여 Authenticode 서명 카탈로그 파일의 PE 이미지 해시를 무효화할 수 있으므로 관련이 있습니다.
섹션 테이블에 지정된 PE 이미지 섹션의 모든 데이터는 다음 제외 범위를 제외하고 전체적으로 해시됩니다.
선택적 헤더의 Windows 관련 필드에 있는 파일 CheckSum 필드. 이 체크섬에는 전체 파일(파일의 특성 인증서 포함)이 포함됩니다. Authenticode 서명이 삽입되면 아마도 체크섬이 원래 값과 다를 것입니다.
특성 인증서와 관련된 정보. Authenticode 서명은 이미지의 전체 무결성에 영향을 주지 않고 이미지에 추가하거나 이미지에서 제거할 수 있으므로 Authenticode 서명과 관련된 PE 이미지의 영역은 PE 이미지 해시 계산에 포함되지 않습니다. PE 이미지를 다시 서명하거나 타임스탬프를 추가하는 사용자 시나리오가 있으므로 이는 문제가 되지 않습니다. Authenticode는 해시 계산에서 다음 정보를 제외합니다.
선택적 헤더 데이터 디렉터리의 Certificate Table 필드
바로 위에 나열된 Certificate Table 필드에서 가리키는 인증서 테이블 및 해당 인증서
PE 이미지 해시를 계산하기 위해 Authenticode는 섹션 테이블에 지정된 섹션을 주소 범위별로 정렬한 다음, 결과 바이트 시퀀스를 해시하여 제외 범위를 전달합니다.
마지막 섹션 끝 뒤의 정보. 마지막 섹션(가장 높은 오프셋으로 정의됨) 뒤의 영역은 해시되지 않습니다. 이 영역에는 일반적으로 디버그 정보가 포함됩니다. 디버그 정보는 일반적으로 디버거에 대한 권고로 간주할 수 있습니다. 실행 프로그램의 실제 무결성에는 영향을 주지 않습니다. 말 그대로 제품이 전달된 후 이미지에서 디버그 정보를 제거할 수 있으며, 프로그램의 기능에는 영향을 주지 않습니다. 실제로 디스크 저장 측정값으로 수행되는 경우도 있습니다. PE 이미지의 지정된 섹션에 포함된 디버그 정보는 Authenticode 서명을 무효화하지 않고는 제거할 수 없습니다.
Windows 플랫폼 SDK에서 제공하는 makecert 및 signtool 도구를 사용하여 Authenticode 서명을 만들고 확인하는 방법을 실험할 수 있습니다. 자세한 내용은 아래 참조를 참조하세요.
참조
Windows용 다운로드 및 도구(Windows SDK 포함)