PE Header 영역에는 PE File Signature, PE File Header, PE File Optional Header 영역이 있다.
PE Header 영역은 IMAGE_NT_HEADERS 구조체로 이루어져 있는데 구조체 정보는 다음과 같다.
위에 정의된 구조체는 64bit 구조체이며 아래는 32bit 구조체이다.
어느정도 직관적인 구조체 멤버이름을 통해서 왜 PE 헤더영역이 3가지로 나누어 졌는지 알 수 있다.
이제부터 PE 헤더 영역을 구성하고 3가지 영역에 대하여 알아 볼 것이다.
[PE File Signature]
이 영역은 DOS의 e_magic 구조체멤버처럼 PE 영역의 시작을 알리는 값을 가지고 있는 영역이다. 모든 파일에서 그 값은 항상 동일하며 그 값은 "PE/0/0(0x50/0x45/0x00/0x00)" 이다.
이 Signature 값 또한 메모리나 파일시스템 분석에서 삭제된 실행파일을 찾는데에 중요한 단서가 된다.
아래는 notepad.exe 파일의 PE File Signature 값을 보여주는 이미지이다.
여기서 참고로 봐둘 점이 있다. 이전 글에서 설명했다 싶이 DOS MZ HEADER 영역의 e_lfanew 구조체멤버는 IMAGE_NT_HEADER의 주소를 가지고 있다고 설명하였는데 여기서 그 사실을 확인 할 수 있다.
[PE File Header]
이 영역은 실행 파일 자체의 메타데이터를 가지고 있으며, 길이는 20바이트이다.
구조체는 IMAGE_FILE_HEADER 구조체를 사용하며, 구조체 정보는 아래와 같다.
아래는 notepad.exe의 PE File Header 영역인데 이것을 가지고 각 구조체 멤버에 대해서 설명하겠다.
- Machine : 해당 구조체 멤버는 실행 파일이 사용하는 CPU를 나타내는 번호를 가지고 있다.
오프셋은 0이며, 크기는 2바이트이다. 위 이미지에서는 i386을 뜻하고 있는 "0x014C"를 가지고 있다.
- NumberOfSections : 해당 구조체 멤버는 실행파일이 가지고 있는 섹션의 개수를 의미하며, 오프셋은 2이고, 크기는
2바이트이다. 위 이미지에서는 "0x0004"를 가지고 있어 섹션의 개수가 4개라는 것을 알 수 있다.
만약 섹션의 삭제, 추가를 하게 되면 이 구조체 멤버의 값 또한 변경해줘야 한다.
- TimeDataStamp : 실행파일이 컴파일 된 시가으로 이 시간은 컴파일한 컴퓨터의 시스템 시간을 의미한다. 32비트
유닉스 포맷으로 GMT를 기준으로 한다. 위 이미지에서는 "0x4A5BC60F" 값을 가지고 있으며,
이 값을 10진수로 변환하였을 경우 "1247528463" 라는 숫자가 되며 이 숫자를 우리가 알아 볼 수
있는 날짜로 변환하면 아래와 같다.
- PointerToSymbolTable : COFF 심볼 파일의 오프셋을 값으로 가지고 있다. 이 부분은 컴파일러에 의해 생성된 OBJ
파일이나 디버그 모드로 만들어져서 COFF 디버그 정보를 가진 PE 파일에서만 사용된다.
COFF 심볼 테이블은 이제 더 이상 사용하지 않아 이 값은 반드시 0으로 설정되어야 한다.
위 이미지에에서는 설명과 동일하게 "0"으로 셋팅되어 있다.
- NumberOfSymbols : 심볼 테이블에 있는 엔트리 개수를 나타내며, COFF 심볼 테이블은 더 이상 사용되지 않으므로
반드시 0으로 설정되어야 한다. 위 이미지에서는 설명과 동일하게 "0"으로 셋팅되어 있다.
- SizeOfOptionalHeader : Optional Header의 크기를 값으로 가지고 있다. 이 값은 실행파일에서만 필요하다. 일반적으로
32bit 시스템은 E0의 값을 가진다.
- Characteristics : 파일의 속성을 결정하는 값을 가지고 있다. 위 이미지에서는 32비트 실행파일의 의미를 지닌 "0x0102"
값이 셋팅되어 있는 것을 볼 수 있다.
나머지 하나인 PE File Optional Header는 다음 글에서 알아 볼 것이다.
아직 PE File Header 에 대한 설명이 남았고 참고 할 표도 있어 글이 너무 길어지는 것을 방지하기 위해 다음 글에서
다루기로 한다.
이번에는 포렌식 관점에서의 중요한 구조체멤버들을 되짚어 보자.
[포렌식관점에서의 구조체멤버]
현재 영역에서 모든 정보를 파악 할 필요는 없다. 중요한 내용만 보면 되는 것이다.
Machine 멤버의 경우 라이브 리스폰스나 메모리 분석등 다른 방법으로도 수집할 수 있는 정보이면서 중복되는 정보이므로, 보지 않아도 되고, Symbol 테이블에 관련된 멤버도 요즘에는 사용되지 않는 멤버이므로 보지 않아도 된다.
- TimeDateStamp : 파일의 생성시간에 대해 정보를 제공한다. 하지만 이 시간은 조작가능성을 배제할 수 없고, 다른
증거와 연결지어야 할 필요가 있다.
- SizeOfOptionalHeader : 해당 파일이 어느 시스템에서 만들어졌는가의 대한 정보를 제공한다. 요즘 도구들은 32, 64bit
시스템의 분석을 지원하긴 하지만, 간혹 지원하지 못하는 경우가 있을 수 있어 이럴 경우 해당
시스템에 맞는 분석도구를 사용하여야 한다. 그렇기에 반드시 확인 해 볼 필요가 있다.
- Characterstics : 해당 파일의 속성이 어떤 것인지에 대한 정보를 제공한다. 특히 exe와 dll 파일을 구분 할 때 유용하다.
파일카빙을 하였을 경우 해당 파일이 어떤 파일인지 구분이 가지 않으므로, 이 부분을 확인하면 어떤
파일인지 알 수 있을 것이다.
[참고]
* Machine 멤버에서의 값 목록표
* Characterstics 속성 목록표
참고로 위 notepad.exe에서 Characterstics 값이 0x0102 였는데 이건 IMAGE_FILE_32BIT_MACHINE의 값과
IMAGE_FILE_EXECUTABLE_IMAGE 값이 합쳐진 것이다.