Reverse engineering

PE 구조 - 2

LeeIkGyu 2022. 2. 12. 21:46

DOS Header

DOS 파일에 대한 하위 호환성을 고려하여 만들었다.

구조체 : IMAGE_DOS_HEADER

주요 멤버

주요 멤버 설명
e_maigc DOS signature(매직넘버)PE파일을 나타내는 첫 바이트, MZ(5A4D)로 고정되어 있으며 MZ이 아니면 로더는
해당 파일을
PE 인식하지 않는다.(참고로 MZDOS 실행 파일을 설계한 Mark Zbikowski)의 이니셜)
e_lfanew NT Header가 시작되는 위치의 옵셋을 뜻하며 e_lfanew값이 가리키는 위치에 NT Header구조체가 존재해야 한다.

 

DOS Stub

DOS환경에서 실행되는 코드를 가진 영역이며 일종의 옵션으로 DOS Stub이 없어도 파일 실행에 문제가 없다.

코드와 데이터의 혼합으로 이뤄졌으며 DOS환경에서 실행하면 “This program cannot be run is DOS mode”문자열을 출력하고 종료한다.

 

NT Header

구조체 : IMAGE_NT_HEADERS

DOS Header의 멤버 중 e_lfanew에 저장된 주소값이 이 부분을 가리킴

NT Header는 파일 실행에 필요한 정보가 저장

NT Header의 구조체에는 총 3개의 멤버로 구성되어있음

 

Signature of NT Header Member

제일 첫 멤버로 일반적으로 50450000h(“PE”00) 가진다.(변경불가)

 

File Header of NT Header Member

구조체 : IMAGE_FILE_HEADER

파일의 개략적인 속성을 나타냄

주요 멤버(해당 값들이 정확히 세팅되지 않으면 파일은 정상적으로 실행되지 않음)

주요 멤버 설명
Machine 파일의 실행 대상 플랫폼을 나타냄(winnt.h에 정의됨) I386(0x014C), IA64(0x200), AMD64(0x8664)
NumberOfSections 파일에 존재하는 섹션의 개수(파일에 따라 섹션의 개수가 달라지므로)이며 반드시 0보다 커야함(정의된 섹션 개수 > 실제 섹션 개수 : 실행 에러, 정의된 섹션 개수 < 실제 섹션 개수 : 정의된 개수만큼 인식)
SizeOfOptionalHeader 다음에 이어지는 Optional Header의 크기를 알려줌
Characteristics 파일의 속성을 나타내는 값으로 실행 파일인지 DLL파일인지 등의 정보들이 bit OR연산을 통해 최종 값으로 설정된다.(winnt.h파일에 정의됨), exe파일(0x0002), dll파일(0x2000)등으로 나타냄
TimeDateStamp 파일의 실행에 영향을 미치지 않는 값으로, 해당 파일의 빌드 시간을 나타냄

 

Optional Header of NT Header Member

구조체 : IMAGE_OPTIONAL_HEADER

파일 실행에 필요한 주요 정보들을 저장

주요 멤버

주요 멤버 설명
Magic IMAGE_OPTIONAL_HEADER32인지 64인지 구분(32인 경우 0x10B, 64인 경우 0x20B)
AddressOfEntryPoint 파일이 메모리에 매핑된 후 코드 시작 주소이며 ImageBase값에 이값을 더해 코드 시작 지점을 설정(Entry PointRVA 가짐)
ImageBase PE파일이 로딩되는 시작 주소이며 EXE, DLL파일은 user memory 영역에 위치하며 SYS파일은 kernelmemory 영역에 위치한다. 일반적으로 EXE파일은 0x4000000, DLL파일은 0x1000000의 값을 가진다.
SectionAlignment, FileAlignment 메모리/파일에서 섹션의 최소 단위를 나타내며 각 섹션은 반드시 Alignment의 배수 여야 한다.(섹션에서 크기가 남더라도 0으로 채워서 Alignment값을 맞춤)
SizeOfImage 메모리에 로딩될 때 가상 메모리에서 PE Image 차지하는 크기
SizeOfHeader PE Header의 전체 크기(FileAlignment의 배수여야 한다.)
Subsystem 동작환경을 정의한 것으로 sys 파일(0x1), GUI파일(0x2), CLI(0x3)의 값으로 세팅
NumberOfRvaAndSize DataDirectory배열의 개수로 일반적으로 16개의 디텍터리를 가지지만 해당 멤버로 디렉터리 수를 정할 수 있다.
DataDirectory IMAGE_DATA_DIRECTORY구조체의 배열로써 디렉토리별로 각각의 정보를 담음
IMAGE_DATA_DIRECTORY구조체의 주요 멤버 설명
Export Directory DLL등의 파일에서 외부에 함수를 공개하기 위한 정보들을 가짐
Import Directory 프로그램 실행을 위해 Import하는 DLL 이름과 사용할 함수 정보가 담긴 INT주소와 IAT주소 같은 정보가 담김
TLS Directory 스레드 지역 저장소 초기화 섹션에 대한 포인터
IAT Directory IAT의 시작번지를 가리킴

 

Section Header

Section의 헤더들이 존재하며 Section들은 메타데이터를 저장하고 메모리에 로드될 때 필요한 정보를 포함하고 있다.

주요 멤버

주요 멤버 설명
VirtualSize 메모리에서 섹션의 크기
VirtualAddress 메모리에서 섹션의 시작주소(RVA+ImageBase)
SizeOfRawData 파일에서 섹션의 크기
PointerToRawData 파일에서 섹션의 Offset
Characteristics 섹션의 속성, Bit OR연산