일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 갤럭시탭S8울트라
- 삼성소프트웨어멤버십
- NarwalFreo
- 삼성전자 소프트웨어멤버십 SSM
- 물걸레자동세척로봇청소기
- 빅데이터
- 파이썬
- Bidirectional Associative Memory
- Neural Network
- 하이퍼바이저
- hopfield network
- 신경망
- 나르왈프레오
- 증강현실
- 패턴인식
- 삼성
- 물걸레로봇청소기추천
- Python
- 신경회로망
- 인공지능
- 가상화
- 동아리
- Google App Engine
- SSM
- 멤버십
- 고려대학교
- Friendship
- 구글 앱 엔진
- BAM
- 패턴 인식
- Today
- Total
정보공간_1
[5기 강남 김영현] PE File Format #1 본문
PE File Format이라고 들어보셨나요?
PE File이란 Portable Executable File의 약자로, Windows 운영체제에서 사용되고 있는 실행 파일의 형식입니다. 기존 UNIX에서 사용되는 COFF(Common Object File Format)을 기반으로 제작되어, 여러 가지 종류의 형식으로 Windows 운영체제에서 사용됩니다. 예를 들면, 실행 파일 계열인 EXE파일, SCR파일, 그리고 라이브러리 계열인 DLL파일, OCX파일, 드라이버 계열인 SYS파일 등이 존재합니다. 이런 확장자를 가진 파일들을 종종 보셨을 거라고 생각합니다. 그렇다면 PE File이 어떤 구조를 가지고 있는지 알아보겠습니다.
PE File Format의 전체 레이아웃은 다음 링크에서 확인할 수 있습니다.
http://www.openrce.org/reference_library/files/reference/PE%20Format.pdf
수많은 구조체들이 나열되어 있는데요. 정신이 없을 정도입니다. 하지만 PE File의 구조를 파악하기 위해서는 각각의 구조체들이 어떤 역할을 하고 있는지 하나씩 살펴봐야겠죠. 구조체들을 관찰해보면 HEADER라는 이름을 포함하는 것들이 많습니다. 사실 PE File은 PE Header 부분과 PE Body 부분으로 이루어져 있습니다. 그 중 PE Header 부분에 해당 파일이 실행되기 위해 필요한 모든 정보가 저장되어 있는 것입니다.
- 메모리에 어떻게 적재되는지
- 어디서부터 실행되어야 하는지
- 실행에 필요한 DLL(Dynamic Link Library)들은 어떤 것들이 있는지
- 필요한 stack 메모리, heap 메모리의 크기를 얼마로 할 것인지
- 기타 등등…
파일 하나를 실행시키기 위해 필요한 정보가 생각보다 많네요. 이러한 정보들을 무작정 쫓아가기 전에 PE File의 구조를 Section 단위로 나누어, 어디서부터 어떻게 확인해볼지 차근차근 계획을 세워보도록 하겠습니다. PE File 구조에서 DOS header부터 Section header까지를 PE Header라고 하고, 그 아래의 Section들을 PE Body라고 합니다. 위에서부터 차례대로 하나씩 역할을 알아보겠습니다.
- DOS header : DOS 파일과의 하위 호환성 제공
- DOS stub : 위와 동일하나 존재 여부는 옵션
- NT header :
파일의 개략적인 속성을 나타내는 IMAGE_FILE_HEADER 구조체와, 파일 실행에 필수적인 IMAGE_OPTIONAL_HEADER 구조체를 포함
- 각 Section header : 각 Section의 속성을 정의
- .text section : 실제 실행 코드
- .rdata section : 문자열 상수 등
- .data section : 전역변수, 정적변수 등
- .edata section : EAT에 관련된 정보 (DLL에만 존재)
- .idata section : IAT에 관련된 정보
- .rsrc section : 리소스
- .reloc section : relocation과 관련된 정보
갑자기 EAT, IAT, Relocation 등 복잡한 용어들이 나오기 시작했습니다. 이것들에 대해서는 나중에 다시 살펴보기로 하겠습니다. 위에서 보시다시피 PE Body 부분이 각 역할에 따른 Section으로 나뉘어져 있습니다(그 이유는 프로그램의 안정성 때문입니다). 그러다 보니 Section의 속성을 정의할 Section header라는 것이 필요해졌고, 각 Section의 크기, 시작 위치, 액세스 권한 등을 마찬가지로 나누어 저장하는 것입니다. 한편, Section은 Alignment라는 최소단위를 가지고 있어서, Section의 크기는 반드시 Alignment의 배수가 되어야 합니다. 이 배수에 맞추다 보니 빈 공간이 발생하게 되는데, 이 부분을 NULL로 채우며 이를 NULL padding이라고 부릅니다. PE header의 끝 부분과 각 Section의 끝에는 이런 NULL padding 영역이 존재합니다. 이렇게 최소 기본 단위 개념을 사용함으로써 파일, 메모리, 네트워크 패킷 등을 처리할 때 효율을 높일 수 있다고 합니다.
파일을 실행하기 전과 후의 차이점이 있습니다. 평소에는 로컬 디스크 등의 저장 장치에 저장되어 있다가, 파일을 실행하면 메모리에 적재된다는 것이죠. 파일에서는 그 내용의 위치를 offset으로 표현하고, 메모리에서는 VA(Virtual Address)로 표현합니다. 또한, 메모리에 적재되면 Section의 크기와 위치 등 그 모양이 달라지게 됩니다. Alignment같은 경우도 파일에서의 최소단위를 FileAlignment, 메모리에서의 최소단위를 SectionAlignment로 각각 구분하고 있습니다. PE File이 메모리에 적재되는 모습은 다음과 같습니다. 정확한 Section의 이름을 생략하였습니다.
실제로 PE File을 메모리에 적재해보겠습니다. 간단하게 제가 만든 실행 파일로 테스트를 하겠습니다. 우선, Windows 7 32bit 운영체제에서 Visual Studio로 컴파일 한 실행 파일임을 밝힙니다(개발 도구에 따라 PE File 구조가 달라질 수 있습니다). PE File 구조 분석을 도와주는 툴이 다양하게 있는데, 저는 PEView를 사용하도록 하겠습니다.
PEView는 다음 링크에서 무료로 다운로드 할 수 있습니다.
http://wjradburn.com/software/
PEView를 실행시키고 실행 파일을 로드한 모습입니다. 좌측에 아까 살펴보았던 PE File 구조가 보입니다. DOS header부터 DOS stub, NT header, 그리고 Section header까지 PE header 부분이 있고, 그 아래로 Section들이 존재하는 PE Body 부분이 있습니다. 우측에는 파일이 적재된 메모리의 모습을 Virtual Address, Raw Data, Value로 함께 보여주고 있습니다. 이를 통해 자신이 찾고자 하는 정보가 저장되어 있는 주소를 따라가 그 값을 확인해 볼 수 있습니다. PEView에서는 간편하게 좌측에 각 PE File 구조 부분을 클릭하면 해당 주소와 내용으로 이동해 우측에 바로 출력해 줍니다. 현재 Raw Data를 byte단위로 출력하고 있는데, 설정을 통해 word, dword 단위로도 출력할 수 있습니다.
지금 메모리에 적재한 파일의 VA 0x0040000부터 0x0040003F까지 DOS header이며, VA 0x00400040부터 0x004000DF까지 DOS stub, VA 0x004000E0부터 0x004001D7까지 NT header입니다. 그리고 그 아래 VA 0x004001D8부터는 Section header가 나오겠죠. 실제로 “textbss”라는 Value가 0x004001D8에 출력된 것으로 보아 .textbss Section의 header가 시작되는 부분임을 확인할 수 있습니다. 우측 창에서는 이러한 영역의 구분 없이 처음부터 끝까지의 데이터가 연속적으로 보여지고 있습니다. 좌측에 표시된 각 영역을 클릭해보도록 하겠습니다.
우선, IMAGE_DOS_HEADER (DOS header)를 클릭해보았습니다. 우측 창이 처음과는 다르게 Value에 대한 설명도 포함하고 있습니다. VA 0x00400000을 보시면 “Signature”라고 되어 있고, 그 값은 4D5Ah이며, 실제로 “MZ”라는 Value를 가지고 있습니다. 이렇게 모든 PE File의 시작 부분 2byte에는 DOS Signature인 “MZ”가 존재해야 합니다. 만약 다른 값을 가지고 있다면 PE 스펙에 어긋나기 때문에 정상적으로 실행되지 않을 것입니다. 그리고 그 아래에 계속 여러가지 DOS와 관련된 정보들이 나타나고 있습니다.
다음으로 MS-DOS Stub Program (DOS stub)을 클릭해보았습니다. 우측에 Value가 보이시나요? VA 0x00400040부터 0x0040004D까지는 16비트 어셈블리 명령어로, Windows 32비트 운영체제에서는 실행되지 않습니다. 만약 DOS 환경이라면, 이 명령어를 실행하여 0x0040004E부터 존재하는 “This program cannot be run in DOS mode” 라는 문자열을 출력하고 종료됩니다.
이번에는 IMAGE_NT_HEADER (NT header)를 클릭해보았습니다. 하위 영역들(Signature, IMAGE_FILE_HEADER, IMAGE_OPTIONAL_HEADER)을 따로 선택할 수 있도록 되어 있습니다. 처음 4byte(0x004000E0~0x004000E3)는 아무래도 Signature Value인 것 같네요. Signature 영역을 클릭해보겠습니다.
예상했던 대로, 50450000h 값을 가지는 “PE”00 이라는 IMAGE_NT_SIGNATURE가 존재하고 있었습니다. 그렇다면 그 다음 주소인 VA 0x004000E4부터는 file header가 존재하고 있을 것입니다.
이 File header에는 앞서 설명 드렸던 것처럼, 파일의 개략적인 속성을 나타내는 정보들이 포함되어 있습니다. 몇 가지만 살펴보겠습니다.
- “Machine” 정보는 CPU 별로 고유한 값을 나타내는데, 저는 32비트 Intel x86 호환 칩을 사용한 컴퓨터이기 때문에 IMAGE_FILE_MACHINE_I386(0x014C)의 값이 출력되고 있습니다.
- “Number of Sections” 정보는 말 그대로 Section의 개수를 나타내며, 정의된 Section 개수와 실제 Section이 다르면 실행 에러가 발생할 것입니다.
- “Time Data Stamp” 정보는 해당 파일의 빌드 시간을 나타낸 값으로, PEView에서는 우측의 Value 항목을 통해 쉽게 날짜와 시각을 확인할 수 있지만, ctime() 함수를 통해 소스 코드에서 직접 문자열로 변환해볼 수 있습니다.
- “Characteristics” 정보는 파일이 실행 가능한 형태인지, 혹은 DLL 파일인지 등의 정보들을 bit OR 형식으로 조합하여 파일의 특성을 나타내는 값입니다. 우측의 Value 항목에 IMAGE_FILE_EXECUTABLE_IMAGE는 실행 가능한 파일임을 나타내고, IMAGE_FILE_32BIT_MACHINE은 32비트 워드 사이즈를 가지는 컴퓨터임을 나타냅니다.
이번 포스팅에서는 PE File이 무엇인지, 그리고 그 구조는 어떻게 되어있는지 간단하게 살펴보았습니다. 다음 포스팅에서는 PE File의 Section Header와 Section을 살펴보고, 주소 매핑 방법, IAT(Import Address Table), EAT(Export Address Table)에 대해서 알아볼 계획입니다. 이것으로 이번 포스팅을 마치도록 하겠습니다. 감사합니다.
※ 해당 포스팅은 『리버싱 핵심 원리(이승원 저)』를 참고하여 작성하였습니다.
'IT 놀이터 > Elite Member Tech & Talk' 카테고리의 다른 글
[5기 강남 김영현] PE File Format #2 (0) | 2014.06.07 |
---|---|
[5기 수원 정영진] NAND 플래시 메모리 (0) | 2014.05.30 |
[5기 강북 강현호] HTML5 게임 프레임워크 LimeJS Introduction (0) | 2014.05.02 |
[5기 부산 정우진] 자바 제네릭 이야기 (0) | 2014.04.24 |
[5기 부산 정우진] 람다표현식(Lambda Expressions)과 클로저(Closure) (0) | 2014.04.24 |