모든 윈도우 PE파일은 IMAGE_DOS_HEADER로 시작하며 이때 e_magic은 아스키코드인 "MZ"로 고정되어 있다. WinNT.h에 다음과 같이 매크로로 정의되어 있다.
#define IMAGE_DOS_SIGNATURE 0x5A4D // MZ
PE 파일을 열었을 때 가장 먼저 체크해야 하는 항목이 바로 이 매직넘버이며 다음과 같이 확인 할 수 있다.
PIMAGE_DOS_HEADER pdh = (PIMAGE_DOS_HEADER)m_pImgView;
if (pdh->e_magic != IMAGE_DOS_SIGNATURE)
throw _T("윈도우 실행 파일 포맷이 아닙니다.");
PEPlus 클래스는 인라인 함수 정의를 통해 다음과 같이 도스 시그니처 함수를 제공한다.
inline bool PEPlus::IsDosSigniture(PBYTE pImgBase)
{
return (*PWORD(pImgBase) == IMAGE_DOS_SIGNATURE);
}
이 필드는 PE 파일의 시작이라고 할 수 있는 IMAGE_NT_HEADER의 시작 오프셋 값을 가진다.
위의 이미지를 보면 e_lfanew는 0x000000E0의 값을 가지고 해당 오프셋 위치 값을 확인하면 0x00004550의 값을 가지고 있다. 이는 아스키코드로 "PE"를 나타내며 PE 포맷의 시작을 나타내는 시그니처이다. 따라서 해당 필드인 e_lfanew를 통해 PE 포맷의 실제 시작 오프셋을 알 수 있다.
PE 파일을 열어 e_magic 필드의 값이 "MZ"인지 확인 후, e_lfanew 필드의 값만큼 파일 포인터를 이동시키면 PE 파일 포맷을 분석할 수 있다.
PEPlus.h에서는 해당 방식을 다음과 같이 매크로로 정의하였다.
#define GET_NT_OFFSET(ib) (PIMAGE_NT_HEADER(ib)->e_lfanew)
#define GET_NT_HDRPTR(ib) ((PBYTE)ib + PIMAGE_NT_HEADER(ib)->e_lfanew)
참고 문헌 : (윈도우 실행 파일 구조와 원리로 배우는)리버스 엔지니어링 1권 : 파일 구조 편 - 이호동 (지은이)한빛미디어