-
PE 구조 (4) - 계산기의 PE 구조 / NT HEADER - IMAGE FILE HEADER 분석Knowledge/Reversing 2019. 9. 20. 01:40
오늘 알아볼 내용은 NT Header이다.
NT Header는 3가지 변수로 정의되어 있는 구조체이다.
typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;Signatere는 4bytes 짜리 변수로 보통 50 45 00 00으로 되어있다.
word가 아니라 dword로써 00 00까지 시그니쳐 범위라는 것을 명심하도록 하자.
그다음으로 나오는 것은 IMAGE_FILE_HEADER 구조체인 FileHeader이다.
IMAGE_FILE_HEADER는 어떠한 구조체인지 찾아보자.
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;WORD * 4 + DWORD * 3 = 2 * 4 + 4 * 3 = 20
20bytes 크기를 갖고 있는 구조체이다.
각 변수들이 나타내는 의미를 파악해보자.
Machine : CPU별 고유값
NumberOfSections : 섹션의 개수
TimeDateStamp : 빌드 된 시간 (유닉스 기반 시간 표현 방식)
SizeOptionalHeader : Optional_Header의 크기
Characteristics : 파일 속성 / 비트 or 연산으로 옵션 표시
PointerToSymbolTable, NumberOfSymbols은 현재는 쓰이지 않는 값들임으로 넘어가도록 하자.
이제 변수들의 의미를 알았으니 값을 확인해 보도록 하자.
Machine : 4C 01 (14C)
Machine의 값을 보면 14C라고 적혀 있다.
무슨 의미일까?
#define IMAGE_FILE_MACHINE_UNKNOWN 0
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
#define IMAGE_FILE_MACHINE_R3000 0x0162 // MIPS little-endian, 0x160 big-endian
#define IMAGE_FILE_MACHINE_R4000 0x0166 // MIPS little-endian
#define IMAGE_FILE_MACHINE_R10000 0x0168 // MIPS little-endian
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 // MIPS little-endian WCE v2
#define IMAGE_FILE_MACHINE_ALPHA 0x0184 // Alpha_AXP
#define IMAGE_FILE_MACHINE_SH3 0x01a2 // SH3 little-endian
#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
#define IMAGE_FILE_MACHINE_SH3E 0x01a4 // SH3E little-endian
#define IMAGE_FILE_MACHINE_SH4 0x01a6 // SH4 little-endian
#define IMAGE_FILE_MACHINE_SH5 0x01a8 // SH5
#define IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM Little-Endian
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
#define IMAGE_FILE_MACHINE_AM33 0x01d3
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0 // IBM PowerPC Little-Endian
#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
#define IMAGE_FILE_MACHINE_IA64 0x0200 // Intel 64
#define IMAGE_FILE_MACHINE_MIPS16 0x0266 // MIPS
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 // ALPHA64
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 // MIPS
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 // MIPS
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE 0x0520 // Infineon
#define IMAGE_FILE_MACHINE_CEF 0x0CEF
#define IMAGE_FILE_MACHINE_EBC 0x0EBC // EFI Byte Code
#define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8)
#define IMAGE_FILE_MACHINE_M32R 0x9041 // M32R little-endian
#define IMAGE_FILE_MACHINE_CEE 0xC0EE정의된 항목들을 보고 찾아보면
#define IMAGE_FILE_MACHINE_I386 0x014c // Intel 386.
calc.exe는 CPU 고유값이 intel386이라는 것을 알 수 있다.
NumberOfSections : 03 00 (3)
calc.exe는 3개의 섹션으로 이루어 져있다.
TimeDateStamp : 10 84 7D 3B (3B 7D 84 10)
간단한 코드를 사용하면 TimeDateStamp의 값을 보기 쉽게 표현 할 수 있다.
#include <stdio.h> #include <time.h> int main(void){ time_t n = 0x3B7D8410; printf("%s\n", ctime(&n)); return 0; }
출력 값 : Sat Aug 18 05:52:32 2001
요일, 월, 일, 시간, 년 순이다.
SizeOfOptionalHeader : E0 00 (E0)
Optinal Header의 크기가 224bytes라는 뜻이다.
Characteristics : 0F 01 ( 01 0F)
Characteristics는 비트 단위로 보고 옵션값을 확인 할 수 있다.
즉 0000 0001 0000 1111로 보고 옵션값을 확인해야한다.
Characteristics의 값들을 확인해보자.
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 // Agressively trim working set
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 // App can handle >2gb addresses
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 // If Image is on removable media, copy and run from the swap file.
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 // If Image is on Net, copy and run from the swap file.
#define IMAGE_FILE_SYSTEM 0x1000 // System File.
#define IMAGE_FILE_DLL 0x2000 // File is a DLL.
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 // File should only be run on a UP machine
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.값들이 1, 2, 4, 8 등 2진수 비트 단위로 정의되어 있는 것을 확인 할 수가 있다.
즉 우리는 비트단위로 캐릭터 옵션을 체크하면 되는 것이다.
1, 2, 4, 8 자리에 1이 적혀있고 256에 1이 적혀있는 것을 확인할 수 있다.
256은 16진수로 0x100이다.
즉, calc.exe는
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 // 파일에서 제거된 위치 정보.
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // exe 파일이라는 뜻
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // 파일에서 제거된 라인 번호.?
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 //파일에서 제거된 로컬 기호.?#define IMAGE_FILE_32BIT_MACHINE 0x0100 // 32bit 체제
의 속성값을 갖고 있다는 것이다.
4, 8의 주석값은 번역기를 돌린 것으로 도저히 뭔 소린지 모르겠다;;;;
이렇게 IMAGE_FILE_HEADER에 대해서 알아보았다.
다음 글에선 OPTIONAL HEAER에 대해서 알아보도록 하자.
'Knowledge > Reversing' 카테고리의 다른 글
PE 구조 (6) - 계산기의 PE 구조 / SECTION Header (0) 2019.09.26 PE 구조 (5) - 계산기의 PE 구조 / NT HEADER - IMAGE OPTIONAL HEADER 분석 (0) 2019.09.25 PE 구조 (3) - 계산기의 PE 구조 / PE offset 확인하는 법 (2) 2019.09.18 PE 구조 (2) - PE의 기본 구조 (0) 2019.05.16 PE 구조 (1) - (Portable Executable)PE의 종류 (0) 2019.04.27