본문 바로가기

Reversing/Theory

Chapter 6. PE header I - PE Format

Chapter 6. PE header I - PE Format
1. PE(Portable Executable) Format

 - Microsoft Windows에서 지원하는 실행파일의 유형
 - 유닉스 COFF(Common Object File Format)를 기반으로 한다.
 - PE Format을 사용하는 File 확장자
  · Execute File
  ◦ exe
  ◦ scr
  · Library File
  ◦ dll
  ◦ ocx
  ◦ cpl
  ◦ drv
  · Driver File
  ◦ sys
  ◦ vxd
  · Object File
  ◦ obj
 - PE Structure

  · PE 구조는 PE Header와 Body 부분으로 나뉜다.
  · 해당 실행 Program이 어떻게 Memory에 쌓이고, 관련 DLL File 등 해당 Program의 정보가 PE 구조 안에 담긴다.
  · Windows의 실행 File은 File상으로 나타냈을 때의 구조를 살펴보면 위 그림의 PE File Structure의 구조처럼 이루어지며 File 상에서는 지점은 Offset으로 표현된다.
  · 실행 File을 Memory에 Process로 올렸을 때의 구조를 살펴보면 위 그림의 PE Memory Structure의 구조처럼 이루어지며 Memory 상의 지점은 VA(Virtual Address)와 RVA(Relative Virtual Address)로 나타낸다.
  · PE Structure의 File, Memory상 지점 표현방식
  ◦ Offset
   ▹ 동일 객체(Object) 내에서 객체(Object) 처음부터 주어진 요소나 지점까지의 변위차를 나타내는 정수형
   ▹ 여기서 객체는 PE를 의미하며 주어진 요소나 지점은 구조체를 의미한다.
  ◦ VA(Virtual Address)
   ▹ Process가 Virtual Memory로 올라갔을 때 각 Process의 Memory 절대 주소이며 실제 물리주소를 가상 주소로 사용한다.
  ◦ RVA(Relative Virtual Address)
   ▹ Memory 상에서 ImageBase로부터 상대주소를 의미
   ▹ VA와 관계식으로는 'RVA + ImageBase = VA'라는 식이 성립한다.
  · 각 구조체 설명
  ◦ PE Header Structure
   ▹ DOS Header(IMAGE_DOS_HEADER)

    ▸  DOS에서 지원했던 DOS EXE Header를 확장시킨 IMAGE_DOS_HEADER가 Header의 가장 앞부분에 존재한다.
    ▸  PE File Format이 처음 만들어졌을 때 DOS File에 대한 하위 호환성을 고려해 만들어졌기 때문에 현재는 DOS Header를 확장시켰다.
    ▸  모든 PE File의 시작부분에는 'DOS signature' 'MZ'가 존재하며 DOS Header의 마지막 부분에는 NT Header의 시작부분을 가리키는 Offset이 존재해야한다.
    ▸  특징
     ▫  Size : 0x40
     ▫  주요 Member
      ▪  e_magic : DOS signature, Header의 시작 부분(MZ)
      ▪  e_Ifanew : NT header의 Offset 표시, Header의 마지막 부분
   ▹  DOS Stub
    ▸  DOS Header의 밑에 존재하는 구조체이며 존재여부는 Option으로 있을 수도 없을 수도 있다.
    ▸  Code와 Data의 혼합으로 이루어진다.
   ▹  NT Header(IMAGE_NT_HEADERS)

    ▸  NT Header의 큰 틀로써 Member로는 Signature, FileHeader, OptionalHeader가 있다.
    ▸  특징
     ▫  각 Member를 구성하는 구조체는 각각 따로 존재한다.
     ▫  Total Size : 0xF8
    ▸  각 Member를 구성하는 구조체
     ▫  File Header(IMAGE_FILE_HEADER 32/64)

      ▪  FIle의 대략적인 속성을 나타내며 Member에 정확한 값이 지정되어 있지 않다면 File이 비정상적으로 실행될 수 있다.
      ▪  주요 Member
       ▻  Machine
        ►  CPU의 속성에 따라 고유한 값이 정해지는 Member
       ▻  NumberOfSections
        ►  Section의 개수를 나타내는 Member
        ►  값은 반드시 0보다 커야하며 해당 Member의 값과 실제 Section의 개수가 다르면 Error가 발생할 수 있다.
       ▻  TimeDateStemp
        ►  해당 File이 생성될 때의 Build 시간을 나타내는 Member
        ►  실제 실행 시에는 영향을 미치지 않는 Member이다.
       ▻  SizeOfOptionalHeader
        ►  IMAGE_NT_HEADERS의 또 다른 Member인 'IMAGE_OPTIONAL_HEADER32' 구조체의 크기를 나타내는 Member
        ►  실제로 'IMAGE_OPTIONAL_HEADER32' 구조체를 인식하기전에 이 Member의 값을 보고 해당 구조체의 크기를 인식한다.
       ▻  Characteristics
        ►  File의 속성을 나타내는 값을 저장하는 Member
        ►  File 속성의 예 : 실행 유무(Excutable or Unexcutable), DLL etc.
        ►  속성 값의 예 : 0x0002(Excutable), 0x2000(DLL)
          ▫  Optional Header(IMAGE_OPTIONAL_HEADER32/64)

      ▪  PE File의 논리적 정보를 가장 많이 포함한 구조체로 PE Header 내에서 가장 크기가 크다.
      ▪  주요 Member
       ▻  Magic
        ►  File의 종류를 나타내는 Member
        ►  IMAGE_OPTIONAL_HEADER32일 경우 '10B', IMAGE_OPTIONAL_HEADER64일 경우 '20B'를 값으로 가진다.
       ▻  AddressOfEntryPoint
        ►  Entry Point의 RVA 값을 저장하는 Member
        ►  Program이 최초로 실행되는 Code의 시작주소를 가진다.
       ▻  ImageBase
        ►  PE File이 Load되는 주소를 저장하는 Member
        ►  EXE의 ImageBase : 00400000
        ►  DLL의 ImageBase : 10000000
    ※ File 유형별 Memory 영역
     ›  EXE,DLL : user memory Area(00000000 ~ 7FFFFFFF)
     ›  SYS File : kernel memory Area(80000000 ~ FFFFFFFF)

       ▻  SectionAlignment
        ►  Memory에서 PE Body 부분 Section의 최소단위를 나타내는 Member
        ►  Memory에서 Section 크기는 반드시 SectionAlignment의 배수가 되야한다.
       ▻  FileAlignment
        ►  File에서 PE Body 부분 Section의 최소단위를 나타내는 Member
        ►  File에서 Section 크기는 반드시 SectionAlignment의 배수가 되야한다.
       ▻  SizeOfImage
        ►  PE File이 Memory에 Process로써 Load되었을 때 PE Image의 Memory상 크기를 나타내는 Member
       ▻  SizeOfHeader
        ►  PE Header의 전체 크기를 나타내는 Member
       ▻  Subsystem
        ►  File의 종류(sys, exe, dll)를 나타내는 Member
       ▻  NumberOfRvaAndSizes
        ►  DataDirectory Member의 배열 개수를 나타내는 Member
   ▹  Section Header
    ▸  PE Body의 Section 속성을 정의한 구조체
    ▸  각 Section은 Section 별로 'IMAGE_SECTION_HEADER'라는 구조체의 배열로 구성되어 있다.
    ▸  주 Section
     ▫  code Section
     ▫  data Section
     ▫  resource Section
    ▸   IMAGE_SECTION_HEADER

     ▫  Section을 구성하는 구조체
     ▫  주요 Member
      ▪  VirtualSize
       ▻  Memory 상에서 해당 Section이 차지하는 크기를 나타내는 Member
      ▪  VirtualAddress
       ▻  Memory 상에서 Section의 시작 주소(RVA)를 나타내는 Member
      ▪  SizeOfRawData
       ▻  File에서 Section이 차지하는 크기를 나타내는 Member
      ▪  PointerToRawData
       ▻  File에서 Section의 시작 위치를 나타내는 Member
      ▪  Characteristics

       ▻  ​Section의 속성을 나타내는 Member
  · PE Body Element
  ◦  Section
   ▹  각 Section들은 Section Header와 연결되며 해당 Section은 Section의 기능 별로 알맞게 구성되어 있다.
   ▹   Section은 Section Header와 정보가 일치하지 않으면 File이 정상적으로 실행되지 않을 수 있다.
   ▹  PE File은 여러 개의 Section으로 구성되며 이 구조로 인해 안정적으로 실행될 수 있다.
 - PE Format의 구조체 Member 별 관계도


 

'Reversing > Theory' 카테고리의 다른 글

Chapter 8. PE Header III - IAT & EAT  (0) 2015.08.16
Chapter 7. PE Header II - RVA to RAW  (0) 2015.08.16
Chapter 5. Calling Convention  (0) 2015.08.16
Chapter 4. Stack  (0) 2015.08.16
Chapter 3. Memory & Assembly Language  (0) 2015.08.16