Study
리버싱 핵심원리_13_PE File(1) 본문
13. PE File
13.1 PE File이란?
- Windows 운영체제에서 사용되는 실행 파일 형식.
- 기본적으로 32비트 형태의 실행 파일을 의미하며 PE32라는 용어를 사용하기도 한다.
- 64비트 형태의 실행 파일은 PE+ 또는 PE32+라고 부르며 PE 파일의 확장 형태이다.
실행 계열 |
.scr |
- Screen Saver의 약자. 윈도우 화면 보호기 파일. 이 파일은 혼자서도 실행된다. |
.exe |
- Executable의 약자로 가장 기본적인 실행파일. | |
드라이버 계열 |
.sys |
- System의 약자로 시스템 운영에 꼭 필요한 파일이며, config,sys, msdows.sys처럼 부팅과 관련이 있거나 운영체제의 시스템에 관련된 내용이 들어 있다. |
.vxd |
- Virtual Device Driver(가상 디바이스 드라이버 파일)의 확장자로 하드웨어 또는 소프트웨어의 동작을 관리한다. | |
라이브러리 계열 |
.dll |
- 동적 링크 라이브러리(dynamic link lirary)의 약자로 독립된 개체들을 하나로 종합한 라이브러리 파일이다. |
.ocx |
- 프로그램에서 실행에 필요한 기능을 한데 모아 놓은 파일로 dll 파일과 비슷하다. | |
.drv |
- driver의 약자. PC에 설치된 수많은 하드웨어의 인식과 구동을 제어하는 디바이스 드라이버 파일로 데이터가 들어있는 파일이다. | |
오브젝트 계열 |
.obj |
- 컴파일되었지만 링크되지 않은 개체 파일 |
출처 - https://kin.naver.com/qna/detail.nhn?d1id=1&dirId=10603&docId=69718293
obj 파일을 제외한 드라이버, 라이브러리 계열 파일은 직접 실행은 아니더라도
다른 형태의 방법(디버거, 서비스, 기타)을 이용하여 실행이 가능한 파일이다.
13.2 PE File의 구조
- PE File의 구조
왼쪽 : 파일일 때의 모습
오른쪽 : 메모리상에서의 모습
파일은 그 모습 그대로 메모리에 올라가는 것이 아니라 각 섹션 헤더에 정의된 규칙에 따라 메모리에 올라가기 때문에 파일상에서의 모습과 다르다.
- PE File의 주소
파일에서는 Offset으로, 메모리에선 VA(Virtual Address) 또는 RVA(Relative Virtual Address)로 주소를 표현한다.
※ VA / RVA
RVA는 어느 기준 위치(ImageBase. 위 그림에선 1000000)에서부터의 상대주소를 말한다.
VA와 RVA의 관계는 다음과 같다.
RVA + ImageBase = VA
- PE File의 영역
Header 영역 |
- DOS header, NT header, 각 section header |
Body 영역 |
- 나머지 section 영역들 |
13.2.1 DOS Header
Microsoft는 DOS 파일에 대한 하위 호환성을 고려하여 PE 헤더의 제일 앞부분에 DOS EXE Header를 확장시킨
IMAGE_DOS_HEADER 구조체를 만들었다.
IMAGE_DOS_HEADER 구조체의 크기는 40(64byte)이다.
그 중 첫 번째 멤버인 e_magic과 마지막 멤버인 e_lfanew가 중요하다.
e_magic |
- DOS Header의 시작을 뜻하는 문자열 "MZ"(4D5A)를 저장한다. |
e_lfanew |
- IMAGE_NT_HEADER의 시작 주소를 저장한다. |
13.2.2 DOS Stub
DOS Stub의 존재 여부는 옵션이며 정해진 크기가 없다.
파일 Offset 40~4D 영역은 16비트 어셈블리 명령어이다. Notepad.exe 파일을 DOS 환경에서 실행하거나
DOS용 디버거를 이용하여 실행하면 위 코드를 실행시킬 수 있다.
이 특성을 이용하여 하나의 실행 파일에 DOS와 Windows에서 모두 실행 가능한 파일을 만들 수 있다.
(DOS 환경에서는 16비트 코드가, Windows 환경에서는 32비트 코드가 각각 실행된다)
13.2.3 NT Header
Signature |
NT header 구조체의 처음 멤버이고 헤더의 시작을 알리는 문자열("PE"00)을 저장한다. |
FileHeader, OptionalHeader |
파일의 개략적인 속성을 나타낸다. |
Machine |
- CPU 별로 고유한 값이다. Machine 넘버의 값들은 winnt.h파일에 정의되어 있다. |
NumberOfSections |
- 섹션의 개수를 나타내고 이 값은 반드시 0보다 커야 한다. |
SizeOfOptinalHeader |
- IMAGE_OPTIONAL_HEADER32 구조체의 크기를 정의한다. |
Characteristics |
- 파일이 실행이 가능한 형태인지 혹은 DLL 파일인지 등의 정보들이 bit OR 형식으로 조합된다. |
TimeDateStamp |
- 파일의 실행에 영향을 미치지 않는 값으로, 해당 파일의 빌드 시간을 나타낸다. |
Machine 넘버 |
#define IMAGE_FILE_MACHINE_UNKNOWN 0 big-endian |
Magic |
- IMAGE_OPTIONAL_HEADER32 구조체인 경우 10B - IMAGE_OPTIONAL_HEADER64 20B 값을 가진다. |
AddressOfEntryPoint |
- EP의 RVA값을 가지고 있다. |
ImageBase |
- 프로세스의 가상 메모리 주소는 0~FFFFFFFF 공간이다. 그중 PE 파일이 로딩되는 시작 주소를 나타낸다. |
SectionAlignment FileAlignment |
- 메모리에서 섹션의 최소 단위 / 파일에서 섹션의 최소 단위 |
SizeOfImage |
- PE 파일이 메모리에 로딩되었을 때 가상 메모리에서 PE Image가 차지하는 크기를 나타낸다. |
SizeOfHeader |
- PE 헤더의 전체 크기를 나타낸다. FileAlignment의 배수여야 한다. |
SubSystem |
- 이 값을 보고 시스템 드라이버 파일(*.sys)인지 일반 실행파일(*.exe, *.dll)인지 구분할 수 있다. |
NumberOfRvaAdnSize |
- IMAGE_OPTIONAL_HEADER32구조체의 마지막 멤버인 DataDirectory 배열의 개수를 나타낸다. - 구조체 정의에 이미 IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16이라고 명시되어 있지만, PE 로더는 이 값을 보고 배열의 크기를 인식한다. |
DataDirectory |
- IMAGE_DATA_DIRECTORY 구조체의 배열로, 배열의 각 항목마다 정의된 값을 가진다. |
13.2.4 Section Header
각 섹션의 속성(file/memory에서의 시작 위치, 크기, 액세스 권한 등)을 정의하는 헤더이다.
비슷한 성격을 가진 자료들을 섹션에 모아 구분, 각 섹션의 속성을 기술할 헤더가 필요해 만들어진 것이다.
code |
실행, 읽기 권한 |
data |
비실행, 읽기, 쓰기 권한 |
resource |
비실행, 읽기 권한 |
VirtualSize |
메모리에서 섹션이 차지하는 크기 |
VirtualAddress |
메모리에서 섹션의 시작 주소(RVA) |
SizeOfRawData |
파일에서 섹션이 차지하는 크기 |
PointerToRawData |
파일에서 섹션의 시작 위치 |
Characteristic |
섹션의 속성(bit OR) |
Name |
.text, .data 등의 이름이 지정되는 멤버 ※ PE 스펙에서는 섹션 Name에 대한 어떠한 명시적인 규칙이 없기 때문에 어떠한 값을 넣어도 되고 심지어 NULL로 채워도 상관이 없다. |
'Reversing > 리버싱 핵심원리' 카테고리의 다른 글
리버싱 핵심원리_17_실행 파일에서 .reloc 섹션 제거하기 (0) | 2019.02.10 |
---|---|
리버싱 핵심원리_16_Base Relocation Table (0) | 2019.02.10 |
리버싱 핵심원리_15_UPX 실행 압축된 notepad 디버깅 (0) | 2019.02.05 |
리버싱 핵심원리_13_PE File(2) (2) | 2019.01.31 |
리버싱 핵심원리_07_Stack Frame (0) | 2019.01.15 |