PE에 대해 공부하자 #1

안녕하세요


테라트입니다


오늘은 PE에 대한 정의 및 구조에 대해 공부한 것을 정리하고자 합니다




# PE(Portable Executable File Format)

: 이 부분이 손상될 경우 파일이 실행되지 않음

: 여러 개의 구조체로 구성

: Windows 에서의 실행 가능한 파일을 의미

: OS별로 실행 파일의 구조가 다르기 때문에 OS가 달라져도 실행된다는 것을 의미하진 않음



# PE 빌드 과정(실행 파일 컴파일 과정)

Source -- Complie -> Obj -- Link --> Exe


  • Source : 사용자가 알아 볼 수 있는 언어 형태의 소스
  • Compile : 사용자의 소스를 컴퓨터가 인식할 수 있는 형태로 바꾸는 작업
  • Obj : 컴퓨터가 이해하는 형태의 파일, 실행은 불가능한 파일
  • Link : 윈도우의 약속된 규약에 맞춰 파일을 생성하는 과정
  • Exe : PE를 포함한 실행 가능한 최종 파일

# PE 파일 구조

위에서 설명했듯이 PE는 여러 개의 구조체로 이루어졌습니다
한개의 구조체씩 정리하도록 하겠습니다

1. IMAGE_DOS_HEADER : DOS에서도 실행 가능하도록 호환성을 제공하는 헤더
※ 여러개의 변수들이 있지만, 리버싱 공부 시작단계이므로 중요한 정보의 필드만 확인해보도록 하겠습니다
  • e_magic : 현재 파일이 PE 파일 인지 체크
  • e_lfanew : IMAGE_NT_HEADER 구조체의 위치를 저장


2. IMAGE_NT_HEADER : 한 개의 DWORD 변수와 두 개의 구조체로 구성
※ 두 개의 구조체는 여러 개의 변수를 포함하기 때문에 따로 설명하겠습니다

  • Signature : PE 파일임을 표시
  • IMAGE_FILE_HEADER : 파일을 실행하기 위한 데이터를 담고 있는 구조체
  • IMAGE_OPTIONAL_HEADER : 주소값, 시작 주소 등이 저장되어 있는 구조체


3. IMAGE_FILE_HEADER : 파일을 실행하기 위한 데이터를 담고 있는 구조체
  • Machine : 현재 CPU가 이 프로그램을 실행하기 적합한지 확인
  • NumberOfSections : 섹션의 개수를 알려준다.

섹션 : .text , .data 와 같은 코드 섹션이나 데이터 섹션을 의미

  • TimeDateStamp : Obj 파일에서 링커를 통해 Exe 파일로 생성한 시간
  • SizeOfOptionalHeader : IMAGE_OPTIONAL_HEADER32의 구조체 크기 정보
  • Characteristics : 파일 형식의 정보 저장, DLL인지 EXE 파일인지를 구분

4. IMAGE_OPTIONAL_HEADER : PE구조체의 핵심 정보라 할 수 있는 주소값, 시작 주소 등이 저장되어 있는 구조체
  • Magic : 32비트인지, 64비트인지를 저장 32비트는 0x10B, 64비트는 0x20B로 표시
  • SizeOfCode : 코드 전체의 크기를 저장
  • MajorLinkerVersion, MinorLinkerVersion : 어떤 버전의 컴파일로 빌드했는지 저장
  • ImageBase : PE파일이 가상 메모리에 매핑 될 때, 가상 메모리의 시작주소 저장
  • AddressOfEntryPoint : 실제 파일이 메모리에서 실행되는 시작 지점
  • BaseOfCode : 실제코드가 실행되는 번지
※ AddressOfEntryPoint 와 BaseOfCode : 두 변수 모두 시작 지점을 저장하는 것 같아 보일 수 있지만, AddressOfEntryPoint는 PE 파일 전체의 시작 위치를 저장하고, BaseOfCode는 실제 코드가 시작되는 지점을 저장한다. AddressOfEntryPoint 범주 안에 BaseOfCode가 속해있다고 볼 수 있다.
  • SectionAlignment, FileAlignment : 각 섹션을 정렬하기 위한 저장 단위
    1. SectionAlignment : 메모리 상에서의 간격을 의미
    2. FileAlignment : 파일 상에서의 간격을 의미
  • SizeOfImage : EXE/DLL이 메모리에 로딩되었을 때의 전체크기, SectionAlignment 값에 패딩한 값까지 포함
패딩 : 섹션의 빈공간을 0으로 채워지는 행위
  • SizeOfHeaders : PE 헤더의 크기 정보를 저장
  • Subsystem : 프로그램이 GUI인지, 콘솔인지의 정보를 저장
    1. 0x1 : *.sys 같은 드라이버 모듈
    2. 0x2 : Windows GUI
    3. 0x3 : 콘솔 프로그램
  • DataDirectory : 구조체 타입으로, Export Directory, Import Directory, IAT 등의 정보를 저장
5. IMAGE_SECTION_HEADER : 각 섹션에 대한 정보를 관리하는 구조체
  • Name : 섹션의 이름을 나타내는 멤버, 섹션의 속성 파악은 Characteristics 멤버 참조
  • VirtualSize : 메모리에서 섹션의 시작 주소
  • VirtualAddress : 메모리에서 섹션이 차지하는 크기
  • SizeOfRawData : 파일에서 섹션이 차지하는 크기
  • PointerToRawData : 파일에서 섹션의 시작위치
  • Characteristics : 섹션에 대한 정보 정의
VirtualSizeSizeOfRawData는 보통 다른 값을 가지는데, 파일에서의 PE와 메모리에서의 PE가 다른 형태를 가지기 때문이다
※ 메모리에 로딩된 상태를 IMAGE라고 표현한다


댓글, 0

테라트

Since 2018.07.03 / IT 관련 정보, 일상의 공유를 위한 블로그