본문 바로가기

*집필*/*집필* Reverse

PE 구조 정리

----------용어 설명----------------------------------------------------------
PE포멧  :  윈도우 OS가 파일을 실행시키기 위해서 Portable Executable 포멧(확장자 .exe 와 .dll)을 동적 라이브러리를 링킹하기 휘한 참조값과 API export and import tables, 리소스 데이터와 TLS 데이터를 캡슐화한 것으로 마이크로소프트에서 1993년 표준안을 디자인 했다.

MZ  :  PE를 만든 Mark Zbikowski의 이니셜로써 MS-DOS 헤더의 시작을 알리는 문자이다.
----------설명에 앞서 이해해야할 Little Endian and Big Endian------------------
Little Endian  :  낮은 주소에 낮은 자릿수를 기록하고, 주소값이 증가할수록 높은 자릿수에 기록하는 방식. 산술 유닛에서 산술 연산의 순서가 낮은 자릿수에서 높은 쫃으로 가면서 처리되기 때문에 프로세서의 산술연산이 더 쉬워진다.
<인텔, X86 계열>

Big Endian  :  정수로 정렬된 큰 수에 대한 비교를 메모리의 작은 주소부터 큰 주소 방향으로 읽으면서 바로 비교할 수 있어 더 빨리 처리 할 수 있으며, 모든 정수와 문자열을 같은 순서 방향으로 읽을 수 있다는 장점이 있다.
============================================================================
PE구조
DOS Header
DOS Stub
PE File Header
Optional Header
Section Table
Sections

 
CodeView Debug Information    -옵션
COFF Symbols                        -옵션
COFF Line Numbers                 -옵션
.reloc                                      ------|
.idata                                               |
.edata                                              |---Sections
.data                                                |
.text                                         ----- |
Section table
Data Directory
IMAGE_FILE_HEADER              -도스헤더
PE\0\0
DOS 'MZ" HEADER

도스에더 'IMAGE_DOS_HEADER' 라는 구조체로 구성되어 있다.
typedef struct _IMAGE_DOS_HEADER {
WORD      e_magic;
WORD      e_cblp;
WORD      e_cp;
WORD      e_crlc;
WORD      e_cparhdr;
WORD      e_minalloc;
WORD      e_maxalloc;
WORD      e_ss;
WORD      e_sp;
WORD      e_csum;
WORD      e_ip;
WORD      e_cs;
WORD      e_lfarlc;
WORD      e_ovno;
WORD      e_res[4];
WORD      e_oemid;
WORD      e_oeminfo;
WORD      e_res2[10];
LONG      e_lfanew;
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

            e_magic : DOS헤더를 구별하는 식별자.
            e_lfanew : PE헤더가 있는 곳의 offset 값.

-----------------------------------------------------------------------------

typedef struct _IMAGE_NT_HEADERS{
DWORD      Signature;
IMAGE_FILE_HEADER      FileHeader;
IMAGE_OPTIONAL_HEADER      OptionalHeader;
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;


 
typedef struct _IMAGE_FILE_HEADER{
WORD      Machine;
WORD      NumberOfSections;
DWORD    TimeDataStamp;
DWORD    PointerToSymbolTable;
DWORD    NumberOfSymbols;
WORD      SizeOfOptionalHeader;
WORD      Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

 
Machine  :   어느 플랫폼(CPU)에서 실행되는지에 대한 정보
NumberOfSections  :  섹션을 분석하기 위해 사용되는 값. ->파일을 Hex 파일등으로 열어 하드 코딩시에 이 값을 변경시켜 섹션 수를 늘리고 코드를 추가할 수 있다.
TimeDataStemp  :  파일이 생성된 날짜와 시간
SizeOfOptionalHeader  :  IMAGE_FILE_HEADER 바로 다음에 위치한 IMAGE_OPTIONAL_HEADER 구조체의 크기. 32비트 윈도우즈에서는 0xE0 이다.
Characteristics  :  현재 파일이 exe 인지 dll파일인지 플래그를 가지고 있다.

typedef struct _IMAGE_OPTIONAL_HEADER {
  WORD Magic;
  BYTE MajorLinkerVersion;
  BYTE MinorLinkerVersion;
  DWORD SizeOfCode;
  DWORD SizeOfInitializedData;
  DWORD SizeOfUninitializedData;
  DWORD AddressOfEntryPoint;
  DWORD BaseOfCode;
  DWORD BaseOfData;
  DWORD ImageBase;
  DWORD SectionAlignment;
  DWORD FileAlignment;
  WORD MajorOperatingSystemVersion;
  WORD MinorOperatingSystemVersion;
  WORD MajorImageVersion;
  WORD MinorImageVersion;
  WORD MajorSubsystemVersion;
  WORD MinorSubsystemVersion;
  DWORD Win32VersionValue;
  DWORD SzieOfImage;
  DWORD SizeOfHeaders;
  DWORD CheckSum;
  WORD Subsystem;
  WORD DllCharacteristics;
  DWORD SizeOfStackReserve;
  DWORD SizeOfStackCommit;
  DWORD SizeOfHeapReserve;
  DWORD SizeOfHeapCommit;
  DWORD LoaderFlags;
  DWORD NumberOfRvaAndSizes;
      IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;

 
typedef struct _IMAGE_DATA_DIRECTORY{
DWORD    VirtualAddress;
DWORD    VirtualSize;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
-----------------------------------------------------------------------------

섹션 헤더(섹션 테이블)
typedef struct _IMAGE_DECTION_HEADER{
BYTE      Name[IMAGE_SIZEOF_SHORT_NAME];
union{
DWORD    PhysicalAddress;
DWORD    VirtualSize;
} Misc;
DWORD    VirtualAddress;
DWORD    SizeOfRawData;
DWORD    PointerToRawData;
DWORD    PointerToRelocations;
DWORD    PointerToLinenumbers;
WORD      NumberOfRelocations;
WORD      NumberOfLinenumbers;
DWORD    Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;


참고 : Reverse Engineering 리버스엔지니어링 역분석 구조와 원리 _박병익 / 이강석