Abstract
PE 포맷에서 Section이란 비슷한 데이터들을 모아놓은 공간을 의미한다. 주요 섹션으로는 실행 코드들이 저장되는 .text섹션과, 문자열 등이 저장되는 .data 섹션, 읽기만 가능한 데이터가 저장되는 .rdata 등이 있다. 각 섹션 헤더들은 섹션 데이터의 파일 내에서의 위치와 크기, 메모리에서의 위치와 크기를 명시하고 있으며, PE 로더는 이를 보고 각 섹션 데이터를 적절한 가상 메모리 영역에 로드한다.
Section Header
IMAGE_SECTION_HEADER structure
섹션은 비슷한 성질의 데이터들을 서로서로 모아놓은 것이다. 비유하자면 옷장에 반팔티, 반바지, 긴팔, 긴바지, 외투 등을 서로 다른 칸에 넣어둔 것과 비슷하다. 이렇게 되면 반바지만 모아놓은 칸은 반바지 섹션, 반팔티만 모아놓은 칸은 반팔티 섹션이 된다. 이 칸(섹션)들이 모여 옷장(PE 파일)을 이룬다. PE 파일도 마찬가지다. 어셈블리 코드만 모아놓은 코드 섹션, 문자열 등 상수 데이터를 모아놓은 데이터 섹션, 읽기만 가능한 읽기전용데이터 섹션 등 비슷한 속성의 데이터들을 모아놓은 것이 섹션이다.
이러한 섹션의 위치와 크기, 접근 권한 등을 정의해 놓은 것이 Section 헤더다.
//
// Section header format.
//
#define IMAGE_SIZEOF_SHORT_NAME 8
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
#define IMAGE_SIZEOF_SECTION_HEADER 40
주요 멤버는 다음과 같다.
Name
섹션의 이름이다. 8바이트 크기의 char 배열로, 사용 가능한 섹션 이름 길이는 8자다. 섹션 이름이 꼭 ".text"이어야만 어셈블리 코드가 담겨있다고 인식하는 것은 아니고, 사람이 보고 구분하거나 분석하기 쉽도록 하는 데에 의미가 있는 값이다. 어차피 프로그램 코드 시작은 Optional 헤더에 정의된 AddressOfEntryPoint 값에서부터 시작한다. Visual Studio에서 컴파일하면 어셈블리 코드는 .text 섹션에 저장되고 문자열 등은 .data 섹션에 저장된다. 아래 그림은 .data 섹션에 저장된 문자열 "C"와 "D"이다. 1E20h와 1E24h엔 "D"가, 1E28h와 1E2Ch엔 "C"가 저장되어 있다.
VirtualSize
PE 파일이 메모리에 로드될 때 해당 섹션이 메모리에서 차지하는 공간의 크기다. 이 값은 SectionAlignment의 배수가 아니어도 된다.
VirtualAddress
PE 파일이 메모리에 로드될 때 해당 섹션이 위치할 메모리 상의 주소다. 이 값은 반드시 Optional 헤더의 SectionAlignment 값의 배수여야 한다. RVA 형태이기 때문에 ImageBase 값을 더한 주소가 해당 섹션이 메모리에서 위치하는 공간의 주소가 된다. .text 섹션의 VirtualAddress 값인 1000h와 ImageBase 값인 400000h를 더한 401000h에 .text 섹션의 데이터가 로드된 것을 볼 수 있다.
SizeOfRawData
해당 섹션이 파일 내에서 차지하는 크기다.
PointerToRawData
해당 섹션이 위치한 파일 내 오프셋이다. 시작 지점은 파일 데이터의 시작으로부터의 오프셋이다. 즉 이 값이 800h면 파일 오프셋 800h에 해당 섹션 데이터가 존재한다는 의미다. 상대적인 위치가 아니다. 이 값은 반드시 Optional 헤더의 FileAlignment 값의 배수여야 한다.
Characteristics
섹션의 속성으로 읽기, 쓰기, 실행가능 여부를 포함해 다양한 정보가 OR 연산을 통해 표현된다. 어셈블리어 코드가 담긴 .text 섹션의 속성을 보면 읽을 수 있고, 실행할 수 있으며 code 데이터가 담겨있다는 정보를 나타내고 있다.
Characteristics에 포함되는 값들은 winnt.h에 정의되어 있다.
//
// Section characteristics.
//
// IMAGE_SCN_TYPE_REG 0x00000000 // Reserved.
// IMAGE_SCN_TYPE_DSECT 0x00000001 // Reserved.
// IMAGE_SCN_TYPE_NOLOAD 0x00000002 // Reserved.
// IMAGE_SCN_TYPE_GROUP 0x00000004 // Reserved.
#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
// IMAGE_SCN_TYPE_COPY 0x00000010 // Reserved.
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code.
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 // Section contains initialized data.
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 // Section contains uninitialized data.
#define IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
#define IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
// IMAGE_SCN_TYPE_OVER 0x00000400 // Reserved.
#define IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
#define IMAGE_SCN_LNK_COMDAT 0x00001000 // Section contents comdat.
// 0x00002000 // Reserved.
// IMAGE_SCN_MEM_PROTECTED - Obsolete 0x00004000
#define IMAGE_SCN_NO_DEFER_SPEC_EXC 0x00004000 // Reset speculative exceptions handling bits in the TLB entries for this section.
#define IMAGE_SCN_GPREL 0x00008000 // Section content can be accessed relative to GP
#define IMAGE_SCN_MEM_FARDATA 0x00008000
// IMAGE_SCN_MEM_SYSHEAP - Obsolete 0x00010000
#define IMAGE_SCN_MEM_PURGEABLE 0x00020000
#define IMAGE_SCN_MEM_16BIT 0x00020000
#define IMAGE_SCN_MEM_LOCKED 0x00040000
#define IMAGE_SCN_MEM_PRELOAD 0x00080000
#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 //
#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 //
#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 //
#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 //
#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 // Default alignment if no others are specified.
#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 //
#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 //
#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 //
#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 //
#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 //
#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 //
#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 //
#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 //
#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 //
// Unused 0x00F00000
#define IMAGE_SCN_ALIGN_MASK 0x00F00000
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 // Section contains extended relocations.
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 // Section can be discarded.
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 // Section is not cachable.
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 // Section is not pageable.
#define IMAGE_SCN_MEM_SHARED 0x10000000 // Section is shareable.
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable.
#define IMAGE_SCN_MEM_READ 0x40000000 // Section is readable.
#define IMAGE_SCN_MEM_WRITE 0x80000000 // Section is writeable.
'Malware Analysis > PE' 카테고리의 다른 글
#6 PE - .reloc 섹션 (0) | 2021.08.01 |
---|---|
#5 PE - IAT (0) | 2021.08.01 |
#3 PE - Optional Header (1) | 2021.08.01 |
#2 PE - File Header (0) | 2021.08.01 |
#1 PE - DOS Header (0) | 2021.07.31 |