실행파일 (pe) 의 구조

25
실실실실 (PE) 실 실실

Upload: katima

Post on 23-Feb-2016

286 views

Category:

Documents


0 download

DESCRIPTION

실행파일 (PE) 의 구조. 정 의. PE(Portable Executable) 정의 : PE 구조로 된 PE 파일들은 플랫폼에 관계없이 Win32 운영 체제가 돌아가는 시스템이면 어디서든 실행 가능하다는 의미 EXE 와 DLL 등의 파일구조를 PE 파일 포맷이라고 명명함 COFF 라는 포맷을 계승한 파일 포맷. PE 파일의 전체구조. IMAGE_DOS_HEADER. DOS HEADER 는 항상 64byte 의 크기를 가지며 윈도우 내에서 IMAGE_DOS_HEADER 라는 구조체로 정의되어 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 실행파일 (PE) 의 구조

실행파일 (PE) 의 구조

Page 2: 실행파일 (PE) 의 구조

PE(Portable Executable) 정의 : PE 구조로 된 PE 파일들은 플랫폼에 관계없이 Win32 운영체제가 돌아가는 시스템이면 어디서든 실행 가능하다는의미

EXE 와 DLL 등의 파일구조를 PE 파일 포맷이라고 명명함COFF 라는 포맷을 계승한 파일 포맷

정 의

Page 3: 실행파일 (PE) 의 구조

IMAGE_DOS_HEADER IMAGE_DOS_HEADER64byte

DOS STUB CODE 의 Size 는 가변DOS STUB CODE

PE SignatureIMAGE_NT_HEADER

224byte or 96byteIMAGE_FILE_HEADER

IMAGE_OPTIONAL_HEADER

IMAGE_SECTION_HEADER Section 당 40byte

SECTION 1 Ex) .text

SECTION … Ex) .rdata

PE 파일의 전체구조

Page 4: 실행파일 (PE) 의 구조

DOS HEADER 는 항상 64byte 의 크기를 가지며 윈도우내에서 IMAGE_DOS_HEADER 라는 구조체로 정의되어 있다 (WinNT.h)

DOS HEADER 구조체의 처음 e_magic 값은 항상 MZ로 고정되며 , 마지막 e_lfanew 값은 PE 헤더의 시작위치를 가르키는 offset 값이다

DOS STUB CODE 는 없어도 되는 부분으로서 프로그램을 도스 모드에서 실행시켰을 때 실행되는 코드이며 , 일반적으로 “ This program must be run under Microsoft Windows” 라는 메시지를 출력하고 종료하는 코드가 삽입되어 있으며 사이즈는 가변이다 .

IMAGE_DOS_HEADER

Page 5: 실행파일 (PE) 의 구조

IMAGE_DOS_HEADER

IMAGE_DOS_HEADER

Page 6: 실행파일 (PE) 의 구조

RVA : PE 파일 내의 파일 offset 과는 무관하며 , PE 파일이 가상주소 공간에 로드되었을 때의 그 시작주소에 대한 상대주소를 나타냄 .메모리상에서의 PE 파일의 시작주소에 대한 offset

PE 파일에서의 절대주소 : Imagebase PE 파일에서의 상대주소 : 모든 RVA 값 RVA 를 통해서 파일상의 offset 구하기

RVA 값이 속한 섹션을 찾는다 .( 섹션테이블 ) 그 섹션의 RVA 값과 PointerToRawData 값의 차를 구한다 .

(converter) 찾고자 하는 RVA 값에서 converter 값을 뺀다 .

Page 7: 실행파일 (PE) 의 구조

Signature(4byte): PE(50 45 00 00) 의 값을 갖는다 .

IMAGE_FILE_HEADER(20byte) Machine : CPU 의 ID 를 나타낸다 . 0x14c(IA32) 또는

0x200(IA64) NumberOfSections : 섹션의 개수를 의미한다 . TimeDateStamp : 링커가 해당 파일을 만들어낸 시간을 의미한다 . SizeOfOptionalHeader : 파일헤더 뒤에오는

OPTIONAL_HEADER의 사이즈를 나타낸다 .( 데이터 디렉토리가 존재할 경우 224byte, 존재하지 않을경우 96byte) Characteristics : PE 파일의 속성을 의미한다 . 일반적으로 실행파일의 경우 0x10f 값을 가진다 .

IMAGE_NT_HEADERS

Page 8: 실행파일 (PE) 의 구조

IMAGE_OPTIONAL_HEADER Magic : IMAGE_OPTIONAL_HEADER 를 나타내는 시그너처로서

32bit PE 의 경우 0x010b, 64bit 의 경우 0x020b 값을 가진다 . AddressOfEntryPoint : 로더가 실행을 개시할 ( 최초로 실행될 코드 ) 주소 . 이 주소는 RVA 로서 보통 .text 섹션의 시작점이다 .

IMAGE_NT_HEADERS

디버거로 실행 (calc.exe)

Peview 로 calc.exe open

Page 9: 실행파일 (PE) 의 구조

ImageBase : 해당 PE 가 가상주소 공간에 로드될때의 그 시작주소 . 기본적으로 EXE 파일은 0x00400000, DLL 파일은 0x10000000

IMAGE_NT_HEADERS

DOS HEADERPE SignatureFILE_HEADER

OPTIONAL_HEADERSECTION HEADER

Section

….

DOS HEADER

PE Signature

FILE_HEADER

OPTIONAL_HEADER

SECTION HEADER

Section

….파일상태 메모리에 로드된 상태

ImageBase

Page 10: 실행파일 (PE) 의 구조

SectionAlignment : 메모리상에서 섹션의 각 섹션이 차지해야 하는 최소의 단위 . 각 섹션은 SectionAlignment X n 의 주소에서 시작해야 한다 . 기본값으로 4K(0x1000) FileAlignment : PE 파일 내에서의 섹션들의 정렬단위 .

SectionAlignment 와 같은 개념 . 보통 0x200 또는 0x100

IMAGE_NT_HEADERS

OPTIONAL_HEADERSECTION HEADER

Section

….

OPTIONAL_HEADER

SECTION HEADER

Section

….

파일상태 메모리에 로드된 상태

FileAlign-ment 를 맞춰주기 위한 padding

SectionAlign-ment 를 맞춰주기 위한 padding

파일상태 메모리에 로드된 상태

Page 11: 실행파일 (PE) 의 구조

SizeOfImage : 메모리에 로드된 PE Image 전체의 크기를 나타내며 , 이 값은 ImageBase 필드가 가리키는 주소값으로 부터 해당 PE 의 마지막 섹션까지의 크기이다 . SectionAlignment의 배수가 되어야 한다 .

SizeOfHeaders : DOS HEADER 에서부터 패딩을 포함한 sec-tion

table 까지의 크기의 총합 . FileAlignment 의 배수가 되어야 한다 . NumberOfRvaAndSizes : IMAGE_DATA_DIRECTORY 구조체 배열 의 원소의 개수를 나타낸다 . DATA_DIRECTORY 를 가지고 있다면 16(0x10) 값을 가진다 . IMAGE_DATA_DIRECTORY : Virtualaddress 와 Size 로 구성된 구조 체로서 마지막 구조체의 값은 0x00 으로 채워져 있다 .

IMAGE_NT_HEADERS

Page 12: 실행파일 (PE) 의 구조

DOS HEADERPE SignatureFILE_HEADER

OPTIONAL_HEADER

SECTION HEADER

Section

….

SizeOfHead-ers

파일상태

DOS HEADERPE SignatureFILE_HEADER

OPTIONAL_HEADER

SECTION HEADER

Section

….

SizeOfIm-age

메모리에 로드된 상태

IMAGE_NT_HEADERS

Page 13: 실행파일 (PE) 의 구조

IMAGE_DATA_DIRECTORY

IMAGE_DIRECTORY_ENTRY_EXPORT [00]IMAGE_DIRECTORY_ENTRY_IMPORT [01]

………

IMAGE_DIRECTORY_ENTRY_TLS [09]…

IMAGE_DIRECTORY_ENTRY_IAT [12]…

IMAGE_DIRECTORY_ENTRY_NULL [15]

IMAGE_NT_HEADERS

EXPORT TABLE

VirtualAddress

Size

IMPORT TA-BLE

VirtualAddress

Size

……

임포트 테이블의 메모리상에서의 시작점과 크기에 대한 정보를 가지고 있다 .

Page 14: 실행파일 (PE) 의 구조

임포트 섹션이 존재하지 않을수도 있으며 , 다른 섹션에 포함되어 있을 수 있다 . 임포트 섹션이 존재하지 않을 경우 IMAGE_DATA_DIRECTORY 내의

IMAGE_DIRECTORY_ENTRY_IMPORT 를 통하여 임포트 테이블의 위치를 알아낼수 있다 .

임포트 테이블은 IMAGE_IMPORT_DESCRIPTOR 라는 구조체의 배열로 구성되며 , 이 구조체는 임포트한 DLL 의 정보를 담고 있다 .

Import_Section

Typedef struct _IMAGE_IMPORT_DESCRIPTOR{union{

DWORD Characteristics;DWORD OriginalFirstThunk;

};DWORD TimeDateStamp;DWORD ForwarderChain;DWORD Name;DWORD FirstThunk;

} IMAGE_IMPORT_DESCRIPTOR;

Page 15: 실행파일 (PE) 의 구조

IMAGE_IMPORT_DESCRIPTOR • OriginalFirstThunk

– INT(Import Name Table)( 또는 ILT(Import Lookup Table))을 가르키는 RVA 값으로서 INT 는 IMAGE_THUNK_DATA 라는 구조체의 배열로 구성된다 .– 이때 IMAGE_THUNK_DATA 배열의 각 원소는

IMAGE_IMPORT_BY_NAME 이라는 구조체를 가리키는 RVA 값을 가진다 .• TimeDateStamp

– 시간과 날짜를 나타내는 시간 스탬프이다 .– 바인딩 전에는 항상 0 이다 .

• ForwarderChain– 일반적으로 바인딩되지 않은 경우 0 이다 .

Import_Section

Page 16: 실행파일 (PE) 의 구조

IMAGE_IMPORT_DESCRIPTOR • Name

– 임포트된 DLL 의 이름을 담과 있는 NULL 로 끝나는 아스키 문자열에 대한 RVA 값을 가진다 .• FirstThunk

– OriginalFirstThunk 와 마찬가지로 IMAGE_THUNK_DATA 의 배열을 가리키며 , IMAGE_THUNK_DATA 의 배열의 각 원소 역시IMAGE_IMPORT_BY_NAME 을 가리킨다 .

– PE 가 가상주소 공간에 매핑되면 IMAGE_THUNK_DATA 는 임포트한 DLL 내의 사용할 실제 함수의 주소를 담게 된다 .– 실제 함수의 주소를 담고 있는 IMAGE_THUNK_DATA 의 이 배열을 IAT(Import Address Table) 이라고 하며 , 실제 함수의 주소가

IAT 에 설정된 것을 바인딩 되었다고 한다 .

Import_Section

Page 17: 실행파일 (PE) 의 구조

IMAGE_THUNK_DATA• AddressOfData

– INT 와 IAT 가 바인딩 전에 모두 IMAGE_IMPORT_BY_NAME 구조체를 가리키고 있을 때 , IMAGE_THUNK_DATA 는 AddressOf-Data의 의미로 사용되었다고 볼수 있다 .

• Ordinal– 모듈정의 파일을 통하여 서수 파일을 지정하게 되면 링커는

DLL 링크시 함수명을 통하지 않고 , 서수를 통해서 사용된 함수를 링크하게 된다 . • Function

– 바인딩 후에 IAT 테이블이 실제 함수의 주소로 변경되었을 경우 Function 의 의미로 사용된 것이며 , INT 는 Function 의 의미로 사용될 일이 없다 .

– IAT 는 바인딩전에는 AddressOfData, 또는 Ordinal 의 의미로 사용되고 , 바인딩 후에는 Function 의 의미로 사용된다 .

Import_Section

Page 18: 실행파일 (PE) 의 구조

OriginalFirst-Thunk

TimeDateStampForwarderChain

NameFirstThunk

Import_Section

…..…..…..

…..…..…..

…..…..…..

IMAGE_THUNK_DATA

IMAGE_THUNK_DATA

IMAGE_IMPORT_BY_NAME

바인딩 전

<INT>

<IAT>

임포트된 DLL 내의실제 함수코드

바인딩 후

Page 19: 실행파일 (PE) 의 구조

Import_Section

임포트 테이블의 내용OriginalFirst-ThunkFirstThunk

INTIAT

바인딩 후의 IAT 변경모습

Page 20: 실행파일 (PE) 의 구조

임포트 과정 PE 파일을 메모리에 로드한 후 데이터 디렉토리의 두번째 엔트리인

IMAGE_DIRECTORY_ENTRY_IMPORT 로 부터 임포트 테이블의 주소를 구한다 . 임포트 테이블의 Name 필드를 통해 임포트 할 DLL 의 이름을 알아낸 후 , 공간 확보후 DLL 을 가상주소공간에 맵핑 시킨다 . INT 를 통해서 임포트 할 함수의 이름 또는 서수 (Ordinal) 값을 알아낸다 . 위의 정보를 이용하여 해당 DLL 의 익스포트 테이블을 통해 필요한 함수의 실제 주소를 알아내서 IAT 를 수정한다 .

Import_Section

Page 21: 실행파일 (PE) 의 구조

IMAGE_SECTION_HEADER 는 40byte 로 구성되며 다음과 같이 정의된다 .

IMAGE_SECTION_HEADER

Typedef struct _IMAGE_SECTION_HEADER{BYTE Name[8];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;

Page 22: 실행파일 (PE) 의 구조

IMAGE_SECTION_HEADER

DWORD Name 섹션의 아스키 이름을 나타낸다 . 8 바이트까지 지정가능하며 , NULL 문자는 제외된다 . 로딩과정과 상관이 없다 .

DWORD VirtualAddress PE 에서 해당 섹션을 매핑시켜야 할 가상 주소 공간 상의 RVA 값이다 . 메모리에서 본 해당 섹션의 시작주소를 의미한다 .

DWORD SizeOfRawData 파일 상태에서의 섹션의 사이즈 값 ( 패딩된 상태 ) FileAlignment 값의 배수이다 .

DWORD PointerToRawData 파일 상태에서의 섹션이 시작하는 offset 값이다 .

DWORD Characteristics 해당 섹션의 속성을 나타내는 플래그의 집합이다 .

Page 23: 실행파일 (PE) 의 구조

…Name : .textVirtualAddressSizeOfRawDataPointerToRawDataCharcteristics

.text

IMAGE_SECTION_HEADER

파일상태 메모리에 로드된 상태

…Name : .textVirtualAddressSizeOfRawDataPointerToRawDataCharcteristics

.text

PointerToRawData 가 지정한 곳에서 부터 SizeOfRawData 만큼의 데이터를 읽어들여 VirtualAddress 가 가르키는 곳에 맵핑한 후에 Characteristics 에 설정된 속성 정보적용

Page 24: 실행파일 (PE) 의 구조

섹션은 같은 성질의 데이터들을 로더가 구분할 수 있도록 저정해둔 영역을 말한다 .

SECTION

코드 .text 프로그램을 실행하기 위한 코드를 담고 있는 섹션이다 .

데이터 .data 초기화된 전역변수나 정적변수들을 담고 있는 읽기 , 쓰기가 가능한 섹션이다 .

.rdata 읽기 전용 데이터 섹션으로 소스상에서 상수로 정의한 것들이 배치된다 .

임포트 API 정보 .idata 임포트할 DLL 과 그 API 들에 대한 정보를 담고 있는

섹션이다 . .rdata 에 병합되는 추세이다 .

재배치 정보 .reloc 실행파일에 대한 기본 재배치 정보를 담고 있는 섹션이다 .

TLS .tls 스레드 지역 저장소를 위한 섹션이다 .

Page 25: 실행파일 (PE) 의 구조

참고 자료 Zesrever 의 지식펌프

• 조립하면서 배우는 PE• http://zesrever.xstone.org/

Null2root• PE 포멧 분석 (PDF)• http://hdp.null2root.org/

Windows 시스템 실행파일의 구조와 원리 – 이호동 저