ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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에 대해서 알아보도록 하자.

     

     

    댓글

Designed by Tistory.