1 / 25

실행파일 (PE) 의 구조

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

katima
Download Presentation

실행파일 (PE) 의 구조

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 실행파일(PE)의 구조

  2. 정의 • PE(Portable Executable) • 정의 : PE구조로 된 PE파일들은 플랫폼에 관계없이 Win32 운영 체제가 돌아가는 시스템이면 어디서든 실행 가능하다는 의미 EXE와DLL등의 파일구조를 PE파일 포맷이라고 명명함 COFF라는 포맷을 계승한 파일 포맷

  3. PE파일의 전체구조

  4. IMAGE_DOS_HEADER 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”라는 메시지를 출력하고 종료하는 코드가 삽 입되어 있으며 사이즈는 가변이다.

  5. IMAGE_DOS_HEADER IMAGE_DOS_HEADER

  6. RVA : PE파일 내의 파일 offset과는 무관하며, PE파일이 가상주소 공간에 로드되었을 때의 그 시작주소에 대한 상대주소를 나타냄. 메모리상에서의 PE파일의 시작주소에 대한 offset • PE파일에서의 절대주소 : Imagebase • PE파일에서의 상대주소 : 모든 RVA값 • RVA를 통해서 파일상의 offset구하기 • RVA값이 속한 섹션을 찾는다.(섹션테이블) • 그 섹션의 RVA값과 PointerToRawData값의 차를 구한다.(converter) • 찾고자 하는 RVA값에서 converter값을 뺀다.

  7. IMAGE_NT_HEADERS • 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값을 가진다.

  8. IMAGE_NT_HEADERS 디버거로 실행(calc.exe) Peview로 calc.exe open • IMAGE_OPTIONAL_HEADER • Magic : IMAGE_OPTIONAL_HEADER를 나타내는 시그너처로서 32bit PE의 경우 0x010b, 64bit의 경우 0x020b값을 가진다. • AddressOfEntryPoint :로더가 실행을 개시할(최초로 실행될 코드) 주소. 이 주소는 RVA로서 보통 .text 섹션의 시작점이다.

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

  10. IMAGE_NT_HEADERS FileAlignment를 맞춰주기 위한 padding SectionAlignment를 맞춰주기 위한 padding 파일상태 메모리에 로드된 상태 파일상태 • SectionAlignment : 메모리상에서 섹션의 각 섹션이 차지해야 하는 최소의 단위. 각 섹션은 SectionAlignment X n 의 주소에 서 시작해야 한다. 기본값으로 4K(0x1000) • FileAlignment : PE파일 내에서의 섹션들의 정렬단위. SectionAlignment와 같은 개념. 보통 0x200 또는 0x100 메모리에 로드된 상태

  11. IMAGE_NT_HEADERS • SizeOfImage : 메모리에 로드된PE Image 전체의 크기를 나타내며, 이 값은 ImageBase 필드가 가리키는 주소값으로부터 해당 PE의 마지막 섹션까지의 크기이다. SectionAlignment 의 배수가 되어야 한다. • SizeOfHeaders : DOS HEADER에서부터 패딩을 포함한 section table까지의 크기의 총합. FileAlignment의 배수가 되어야 한다. • NumberOfRvaAndSizes : IMAGE_DATA_DIRECTORY 구조체 배열 의 원소의 개수를 나타낸다. DATA_DIRECTORY를 가지고 있 다면 16(0x10) 값을 가진다. • IMAGE_DATA_DIRECTORY : Virtualaddress와 Size로 구성된 구조 체로서 마지막 구조체의 값은 0x00으로 채워져 있다.

  12. IMAGE_NT_HEADERS SizeOfImage SizeOfHeaders 파일상태 메모리에 로드된 상태

  13. IMAGE_NT_HEADERS VirtualAddress EXPORT TABLE Size VirtualAddress • 임포트 테이블의 메모리상에서 • 의 시작점과 크기에 대한 정보를 • 가지고 있다. IMPORT TABLE Size ……… • IMAGE_DATA_DIRECTORY

  14. Import_Section Typedef struct _IMAGE_IMPORT_DESCRIPTOR{ union{ DWORD Characteristics; DWORD OriginalFirstThunk; }; DWORD TimeDateStamp; DWORD ForwarderChain; DWORD Name; DWORD FirstThunk; } IMAGE_IMPORT_DESCRIPTOR; 임포트 섹션이 존재하지 않을수도 있으며, 다른 섹션에 포함되어 있을 수 있다. 임포트 섹션이 존재하지 않을 경우 IMAGE_DATA_DIRECTORY내의 IMAGE_DIRECTORY_ENTRY_IMPORT를 통하여 임포트 테이블의 위치를 알아낼수 있다. 임포트 테이블은 IMAGE_IMPORT_DESCRIPTOR라는 구조체의 배열로 구성 되며, 이 구조체는 임포트한 DLL의 정보를 담고 있다.

  15. Import_Section • 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이다.

  16. Import_Section • 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에 설정된 것을 바인딩 되었다고 한다.

  17. Import_Section • IMAGE_THUNK_DATA • AddressOfData • INT와 IAT가 바인딩 전에 모두 IMAGE_IMPORT_BY_NAME 구조 체를 가리키고 있을 때, IMAGE_THUNK_DATA는 AddressOfData 의 의미로 사용되었다고 볼수 있다. • Ordinal • 모듈정의 파일을 통하여 서수 파일을 지정하게 되면 링커는 DLL링크시함수명을 통하지 않고, 서수를 통해서 사용된 함수를 링크하게 된다. • Function • 바인딩 후에 IAT테이블이 실제 함수의 주소로 변경되었을 경우 Function의 의미로 사용된 것이며, INT는 Function의 의미로 사용될 일이 없다. • IAT는 바인딩전에는 AddressOfData, 또는 Ordinal의 의미로 사용되고, 바인딩 후에는 Function의 의미로 사용된다.

  18. Import_Section IMAGE_THUNK_DATA IMAGE_IMPORT_BY_NAME <INT> IMAGE_THUNK_DATA 바인딩 전 바인딩 후 <IAT>

  19. Import_Section 임포트 테이블의 내용 OriginalFirstThunk FirstThunk INT IAT 바인딩 후의 IAT 변경모습

  20. Import_Section • 임포트 과정 • PE파일을 메모리에 로드한 후 데이터 디렉토리의두번째엔트리인IMAGE_DIRECTORY_ENTRY_IMPORT로 부터임포트 테이블의 주소를 구한다. • 임포트 테이블의 Name필드를 통해 임포트 할 DLL의 이름을 알아낸 후, 공간 확보후DLL을 가상주소공간에 맵핑 시킨다. • INT를 통해서 임포트 할 함수의 이름 또는 서수(Ordinal)값을 알아낸다. • 위의 정보를 이용하여 해당 DLL의 익스포트 테이블을 통해 필요한 함수의 실제 주소를 알아내서 IAT를 수정한다.

  21. 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; • IMAGE_SECTION_HEADER는 40byte로 구성되며다음과 같이 정의된다.

  22. IMAGE_SECTION_HEADER • DWORD Name • 섹션의 아스키 이름을 나타낸다. 8바이트까지 지정가능하며, NULL문자는 제외된다. 로딩과정과 상관이 없다. • DWORD VirtualAddress • PE에서 해당 섹션을 매핑시켜야 할 가상 주소 공간 상의 RVA값이다. • 메모리에서 본 해당 섹션의 시작주소를 의미한다. • DWORD SizeOfRawData • 파일 상태에서의 섹션의 사이즈 값(패딩된 상태) • FileAlignment값의 배수이다. • DWORD PointerToRawData • 파일 상태에서의 섹션이 시작하는 offset값이다. • DWORD Characteristics • 해당 섹션의 속성을 나타내는 플래그의 집합이다.

  23. IMAGE_SECTION_HEADER PointerToRawData가 지정한 곳에서 부터 SizeOfRawData만큼의 데이터를 읽어들여 VirtualAddress가 가르키는 곳에 맵핑한 후에 Characteristics에 설정된 속성 정보적용 파일상태 메모리에 로드된 상태

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

  25. 참고 자료 • Zesrever의 지식펌프 • 조립하면서 배우는 PE • http://zesrever.xstone.org/ • Null2root • PE포멧 분석(PDF) • http://hdp.null2root.org/ • Windows 시스템 실행파일의 구조와 원리 – 이호동 저

More Related