학사 나부랭이

Reversing - Portable Executable - PE header - DOS header, stub 본문

Dot-Gabi/Reversing

Reversing - Portable Executable - PE header - DOS header, stub

태양왕 해킹 (14세) 2021. 6. 1. 07:56

PE header - DOS header

 마이크로소프트는 PE 파일의 포맷을 만들 때, 당시 사용되던 DOS 파일에 대한 하위 호환성을 고려해서 만들었어요. 그로 인해, PE 헤더의 맨 앞에는 기존 DOS EXE header를 확장시킨 IMAGE_DOS_HEADER 구조체가 존재하죠.

winnt.h

이 구조체의 크기는 40h 즉, 64 바이트이고 여기서 중요한 멤버인 e_magic은 DOS signature(5A4Dh, ASCII: "MZ"), e_lfanewNT header의 오프셋(가변적)을 표시해요.

모든 PE 파일은 시작 부분(e_magic)에 DOS signature("MZ")가 있고, e_lfanew 값이 가리키는 위치에 NT header 구조체가 존재해야 해요.

파일에서의 PE 파일을 분석해보면, 0부터 0x3Fh까지, 총 64바이트가 IMAGE_DOS_HEADER 부분이에요.

여기서 첫 2바이트에 PE 표준 형태인 DOS signature과, 마지막 0x80h인 e_lfanew를 볼 수 있죠.

 

PE header - DOS stub

 DOS header 밑에 존재하는데, 이건 옵션이고 크기도 일정하지 않아요. 그러니까, DOS stub이 없어도 파일 실행에는 문제가 없죠.

이 DOS stub은 코드와 데이터로 이루어져 있으며, 아래 사진에 나타나 있어요.

파랗게 선택된 부분이 16비트 어셈블리 명령어이며, 32비트 이상의 윈도우에서는 PE 파일로 인식해서 무시하고 DOS에서는 PE 파일 포맷을 모르니 DOS-실행 파일의 코드로 인식되어 실행되는 명령어죠.

이는 (당연히) DOS 환경에서 실행하거나 DOS용 디버거(debug.exe)를 이용하면 실행시킬 수 있는데, 특히 자주 사용되는 윈도우 10 64비트에는 아마 안 될 거예요. 링크와 같이 보통 한 단계 아래까지 하위호환을 하는데, 64비트와 16비트는 두 단계가 차이나서 호환성이 거의 없죠. 어쨌든, 만약 실습 가능했다는 가정 하에, 도스용 디버거로 디버깅을 했을 때 결과는 아래와 같아요.

"This program cannot be run in DOS mode"라는 문자열 데이터를 출력시키고 종료하는 명령어였네요.

이를 이용하면 McAfee의 scan.exe처럼 실행 파일 하나로 DOS와 윈도우 모두 실행 가능한 파일을 만들 수 있어요. 단, DOS 환경에서 수행할 코드와 윈도우 환경에서 수행할 코드가 각각 있어야 하겠지만요.

 

현재까지 프로그램 요약

이름 용도 현재 프로그램에서 값
DOS header PE 구조 사용 여부 5A4Dh (MZ)
DOS stub DOS 시스템에서 실행할 때 동작 WriteString() ("This program cannot...")
Exit()

 

Comments