1. PE란 ?


PE( Portable Executable )는 윈도우 운영체제에서 사용되는 실행파일, DLL, object 코드 등을 위한 파일형식이다. 이는 윈도우 로더가 실행 가능한 코드를 관리하는데 필요한 정보를 캡슐화한 데이터 구조체이다.



2. PE 구성요소



PE는 위와 같은 구조를 갖고 있으며, DOS stub은 PE 파일의 필수 구성요소가 아니기 때문에 생략이 가능하다.


- DOS Header

PE 파일은 DOS Header로 시작한다. 따라서 디스크 상에서는 파일의 첫 부분이 DOS header가 된다. 메모리 상에서 PE 파일은 ImageBase에서 시작하기 때문에 DOS header는 ImageBase에서 찾을 수 있다.

stud_PE 프로그램으로 Test.exe 파일을 열었을 때 확인할 수 있는 PE 헤더의 일부분이다.

실제로 해당 위치에 존재하는지 Immunity Debugger로 확인을 하면 다음과 같다.

00400000 번지에 MZ 문자가 찍혀있는 것을 볼 수 있다.

MZ는 DOS Header의 시그니처다. 이로써 메모리에 Image base에 DOS Header가 로드됨을 알 수 있다.


- DOS stub

윈도우용 어플리케이션을 도스 모드에서 실행시킨 경우 어플리케이션이 정상적으로 동작하지 않는다. 이러한 경우 윈도우는 어플리케이션 대신에 스텁 코드를 실행한다. 스텁 코드에는 DOS 모드에서 실행 가능한 프로그램이면 어느 것이나 삽입이 가능하다. 


- PE Header

PE Header는 위와 같은 구조체로 정의되어 있다.

디스크 상이나 메모리 상에서 PE 헤더의 위치는 DOS Header에 있는 e_lfanew 값을 이용하여 계산할 수 있다. e_lfanew는 DOS Header구조체의 마지막에 위치한다.

e_lfanew에는 파일의 시작점에서부터 PE 헤더까지의 오프셋 값이 저장되어 있다.

Hex 에디터로 열어보게 되면 위와 같이 DOS Header 마지막에 e_lfanew 값이 들어 있고, 이 값과 DOS Header의 시작 주소를 더하면 PE Header를 찾을 수 있다.


- 섹션 테이블

섹션 테이블은 PE Header 바로 뒤에 위치한다. 즉, 섹션 테이블을 찾으려면 PE Header 시작 주소에서 PE Header 사이즈를 더해주면 된다.

PE 헤더는 PE 시그너처( 4바이트 고정 )와 File Header( 20바이트 고정 ) 그리고 Optional Header( 224바이트, 가변 )로 구성되어 있다. Option Header의 크기는 File Header에 저장되어 있다.


- 섹션 위치

각 섹션의 위치는 섹션 테이블에 저장된 섹션 헤더를 통해서 확인이 가능하다. 섹션 헤더에는 해당 섹션의 위치와 관련하여 Virtual Address라는 값과 PointerToRawData라는 값이 저장되어 있다. PointerToRawData는 디스크 상의 섹션의 위치를 가리키는 offset 값이고, VirtualAddress는 메모리 상에서의 section의 위치를 가리키는 offset 값이다.

Stud_PE로 Section Header를 보면 위와 같다.

.text 섹션의 RawOffset 값이 0x200임을 알 수 있다. 이는 디스크 상의 .text 섹션이 파일의 시작점으로부터 0x200 떨어진 곳에서 시작한다는 것을 의미한다.

마우스 오른쪽 클릭한 후 "GoTo Section Start"를 선택하면 .text 섹션의 시작 위치로 이동할 수 있다.

Cursor를 첫번째 바이트에 위치하고 하단 정보를 확인하면 Cursor offset이 앞서 살펴본 PointerToRawData 값과 같음을 확인할 수 있다. Virtual offset 값은 ImageBase 값인 0x400000에 Virtual offset 값인 0x1000을 더하면 된다.

Immunity Debugger로 보면 위와 같다. 


* PE 파일은 디스크 상의 모습과 메모리 상의 모습이 거의 같다.


DOS Header에서 Section table까지의 구성은 디스크 상의 PE 파일이나 메모리 상의 PE 파일 모두 동일하다. 이는 디스크 상의 PE 파일이 메모리로 로드될 때 DOS Header부터 Section table까지는 그대로 로드됨을 의미한다. 차이가 발생하는 부분은 각 세션인데, 이는 alignment와 관련이 있다. alignment와 관련해서 기억해야 할 사실은 아래와 같다.


> 섹션들의 디스크 상의 정렬 단위와 메모리 상의 정렬단위가 다를 수 있다.

> 디스크 상의 정렬 단위와 메모리 상의 정렬 단위는 각각 Optional Header의 File Alignment와 Section Alignment에 저장된다.

> 디스크 상의 섹션은 File Alignment의 배수가 되는 주소에서 시작한다.

> 메모리 상의 섹션은 Section Alignment의 배수가 되는 주소에서 시작한다.



참고

http://zesrever.tistory.com

Posted by Imp3rio