Malware Analysis/PE

#4 PE - Section Header

geunyeong 2021. 8. 1. 16:10

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"가 저장되어 있다.

 

.data 섹션에 위치한 "C", "D" 문자열 

 

VirtualSize

PE 파일이 메모리에 로드될 때 해당 섹션이 메모리에서 차지하는 공간의 크기다. 이 값은 SectionAlignment의 배수가 아니어도 된다. 

VirtualAddress

PE 파일이 메모리에 로드될 때 해당 섹션이 위치할 메모리 상의 주소다. 이 값은 반드시 Optional 헤더의 SectionAlignment 값의 배수여야 한다. RVA 형태이기 때문에 ImageBase 값을 더한 주소가 해당 섹션이 메모리에서 위치하는 공간의 주소가 된다. .text 섹션의 VirtualAddress 값인 1000h와 ImageBase 값인 400000h를 더한 401000h에 .text 섹션의 데이터가 로드된 것을 볼 수 있다.

 

메모리 상에서의 .text 섹션의 가상 메모리 주소 위치

 

SizeOfRawData

해당 섹션이 파일 내에서 차지하는 크기다.

PointerToRawData

해당 섹션이 위치한 파일 내 오프셋이다. 시작 지점은 파일 데이터의 시작으로부터의 오프셋이다. 즉 이 값이 800h면 파일 오프셋 800h에 해당 섹션 데이터가 존재한다는 의미다. 상대적인 위치가 아니다. 이 값은 반드시 Optional 헤더의 FileAlignment 값의 배수여야 한다. 

Characteristics

섹션의 속성으로 읽기, 쓰기, 실행가능 여부를 포함해 다양한 정보가 OR 연산을 통해 표현된다. 어셈블리어 코드가 담긴 .text 섹션의 속성을 보면 읽을 수 있고, 실행할 수 있으며 code 데이터가 담겨있다는 정보를 나타내고 있다.

 

SectionHeader.Characteristics 플래그

 

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