일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- swing
- Multimedia
- ctf-d
- Frida
- K-shield Jr 10기
- 안티디버깅
- 리버싱핵심원리
- 모바일프로그래밍
- Mobile
- 써니나타스
- John the ripper
- ZIP
- SW에듀서포터즈
- Reversing
- upx
- CodeEngn
- K-sheild Jr
- Autoware
- crack
- 케쉴주
- Interceptor
- shadow
- tar
- 파일해시생성
- Android
- disk
- 디스크
- 침해사고대응
- 포렌식
- Today
- Total
물먹는산세베리아
PE 파일 구조 : PE 헤더 본문
PE 파일은 DOS header ~ Section header까지는 PE 헤더, 그 아래의 Sections들은 PE 바디로 구성되어 있다.
먼저, PE 헤더에 대해 살펴보자.
참고로, 파일은 일반적인 PE 파일의 기본 구조를 갖고 있는 윈도우의 notepad.exe 파일을 사용했다.
1. DOS Header
PEViewer에서 notepad.exe 열어봄
PE 헤더의 맨 앞에는 IMAGE_DOS_HEADER 구조체가 있다.
IMAGE_DOS_HEADER
typedef struct _IMAGE_DOS_HEADER // DOS .EXE header
{
WORD e_magic; // Magic number
WORD e_cblp; // Byte on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Checksum
WORD e_ip; // Initital IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
* microsoft docs winnt.h 에서 구조체 찾아봤는데 안나옴..
크기는 64바이트이며, 0x0000003F까지 해당 구조체에 속한다. 이 중 주목할 만한 건 e_magic과 e_lfanew이다.
- e_magic: PE 파일 구조, DOS signature (4D 5A, 워드로 읽으면 0x5A4D)
- e_lfanew: NT header 오프셋 표시 (000000F8), 파일에 따라 가변적인 값을 갖는다. IMAGE_NT_HEADER 시작주소 *리틀엔디언 표기법
* windows/notepad.exe는 000000F8, windodws/system32/notepad.exe는 00001000 이던데 그래서 그런가..? 또 다른 곳에서는 000000e0이다.
2. DOS Stub
DOS Header 밑에 존재 하나 옵션이기 때문에 크기도 일정하지 않고, 없다고 해도 실행에 문제 되지 않는다.
notepad.exe 파일은 MS-DOS 호환 모드를 갖고 있기 때문에 DOS 환경에서 실행 할 경우 DOS EXE 코드가 동작하면서 "This is program cannot be run in DOS Mode" 문장을 출력한다. 즉, 하나의 실행 파일로 DOS, Windows 모두 사용 가능한 파일을 만들 수 있다는 뜻이다.
3. NT Header
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
3.1. Signature
첫번째 멤버 Signature은 '00004550' 값은 갖는다. IMAGE_NT_SIGNATURE PE
좀 전의 IMAGE_DOCS_HEADER에서 e_Ifanew의 값이 IMAGE_NT_HEADER 시작주소라고 했었는데 '000000F8'로 값이 같음을 확인할 수 있다.
3.2. File Header
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
주요 멤버를 살펴보자면
① Machine
- Machine 넘버는 CPU 별로 고유한 값을 갖는다.
- 0x8664는 AMD64(K8)
② NumberOfSections
- PE 파일은 코드, 데이터, 리소스 등이 각각의 섹션에 나뉘어 저장됨
- 이때 섹션의 개수
- 반드시 0보다 커야 함
- 정의된 섹션 개수와 실제 섹션이 다르면 실행 에러 발생
- 0x0007
③ TimeDateStamp
- 0xF57E80D4 → 4,118,708,436 →130년 220일 5시간 40분 36초 → 1970년 1월 1일 0시에 더 하면 엥 말이 안된다.
④ SizeOfOptionalHeader
- IMAGE_NT_HEADERS 구조체의 마지막 멤버는 IMAGE_OPTIONAL HEADER32구조체
- IMAGE_OPTIONAL_HEADER32 구조체의 크기를 나타냄
- PE32+ 형태의 파일인 경우 IMAGE_OPTIONAL_HEADER64 구조체 사용
- 0xF0은 64bit
- 0xE0(32bit), 0x00(obj)
⑤ Characteristics
- 실행 가능한 파일인지, DLL파일인지 등 파일의 속성 정보가 OR 형식으로 조합됨
- 0x0002 IMAGE_FILE_EXECUTABLE_IMAGE(파일 실행 가능 여부)
- 0x0020 IMAGE_FILE_LARGE_ADDRESS_AWARE(2GB 이상의 메모리 사용이 가능한지)
3.3. Optional Header
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD Magic;
BYTE MajorLinkerVersion;
BYTE MinorLinkerVersion;
DWORD SizeOfCode;
DWORD SizeOfInitializedData;
DWORD SizeOfUninitializedData;
DWORD AddressOfEntryPoint;
DWORD BaseOfCode;
DWORD BaseOfData;
DWORD ImageBase;
DWORD SectionAlignment;
DWORD FileAlignment;
WORD MajorOperatingSystemVersion;
WORD MinorOperatingSystemVersion;
WORD MajorImageVersion;
WORD MinorImageVersion;
WORD MajorSubsystemVersion;
WORD MinorSubsystemVersion;
DWORD Win32VersionValue;
DWORD SizeOfImage;
DWORD SizeOfHeaders;
DWORD CheckSum;
WORD Subsystem;
WORD DllCharacteristics;
DWORD SizeOfStackReserve;
DWORD SizeOfStackCommit;
DWORD SizeOfHeapReserve;
DWORD SizeOfHeapCommit;
DWORD LoaderFlags;
DWORD NumberOfRvaAndSizes;
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
주요 멤버들만 몇개 뽑아보자면
Magic | 0x10B(IMAGE_OPTIONAL_HEADER32), 0x20B(IMAGE_OPTIONAL_HEADER64) |
AddressOfEntryPoint | 프로그램에서 최초로 실행되는 코드의 시작 주소인 RVA 값을 갖고 있음 |
ImageBase | PE 파일이 로딩되는 시작 주소 |
SectionAligment | 메모리에서 섹션의 최소단위를 나타냄 |
FileAligment | 파일에서 섹션의 최소단위를 나타냄 |
SizeOfImage | PE 파일이 메모리에 로딩됐을 때 가상 메모리에서 PE Image가 차지하는 크기 |
SIzeOfHeader | PE 헤더의 전체 크기, 파일의 시작에서 SizeOfHeader 오프셋만큼 떨어진 곳에 첫번째 섹션 위치 |
Subsystem | 1: Driver file 2: GUI 파일(창 기반 ex.notepad.exe) 3: CUI 파일(콘솔 기반 ex.cmd.exe) |
NumberOfRvaAndSizes | DataDirectory 배열의 개수 (IMAGE_OPTIONAL_HEADER32 구조체의 마지막 멤버) |
DataDirectory | IMAGE_DATA_DIRECTORY 구조체의 배열, 배열 각 항목마다 정의된 값을 가짐 |
4. Section Header
각 섹션의 속성을 정의한 것
프로그램의 안전성을 위해 code, data, resource가 각각 다른 특성, 접근 권한을 가져야 한다.
종류 | 엑세스 권한 |
code | 실행, 읽기 |
data | 비실행, 읽기, 쓰기 |
resource | 비실행, 읽기 |
4.1. IMAGE_SECTION_HEADER
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;
항목 | 의미 |
VirtualSize | 메모리에서 섹션이 차지하는 크기 |
VirtualAddress | 메모리에서 섹션의 시작 주소(RVA) |
SizeOfRawData | 파일에서 섹션이 차지하는 크기 |
PointerToRawData | 파일에서 섹션의 시작 위치 |
Characteristics | 섹션의 속성(bit OR) |
여기서 VirtualAddress와 PointerToRawData는 각각 IMAGE_OPTIONAL_HEADER32에 정의된 SEctionAlignment, FileAlignmnet에 맞에 결정된다. 또, 파일에서의 섹션 크기와 메모리에서 로딩된 섹션 크기는 다르다. (일반적으로 VirtualSize != SizeOfRawData)
참고
https://777bareman777.github.io/2019/09/17/UnderstandPE/
리버싱 핵심원리, 이승원 저
https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-image_optional_header32
'Waregame & CTF > Reversing' 카테고리의 다른 글
[dreamkack.io] rev-basic-4 (0) | 2021.10.02 |
---|---|
32bit IAT, EAT 로딩 과정 (0) | 2021.10.02 |
어셈블리 명령어 모음 (0) | 2021.09.26 |
64bit 레지스터 / 32bit, 64bit 함수호출규약 (0) | 2021.09.11 |
[dreamhack.io]rev-basic-1 (0) | 2021.09.11 |