ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • PE(Portable Executable) 구조
    IT 2020. 5. 31. 17:29

    PE(Portable Executable)란

    Win32(윈도우즈 운영체제)의 실행 파일 포맷을 의미한다.

    PE 파일의 종류는 계열별로 나뉜다.

    실행 계열 : EXE, SCR

    라이브러리 계열 : DLL, OCX

    드라이브 계열 : SYS

    오브젝트 파일 계열 : OBJ

    OBJ를 제외한 나머지는 모두 실행 가능한 파일로 이루어져 있다.

     

    PE 파일의 전체적인 구조는 다음과 같다.

    PE(Portable Executable) 구조

    PE 구조는 크게 헤더섹션으로 묶어서 볼 수 있다.

    헤더 : DOS header, DOS stub, NT header, Section header

    섹션 : Section(".text"), Section(".data"), Section(".rsrc"), Section(".reloc")

     

    ※지금부터 나오는 코드들은 HxD라는 프로그램으로 C:\Windows\System32\calc.exe를 열어서 나온 코드들입니다. 따라서 타 프로그램을 열었을 때 조금 다르게 나올 수도 있습니다. 그리고 제가 찾을 수 있는 코드들만 첨부했으니 양해바랍니다.※

    1. IMAGE_DOS_HEADER

    가장 처음으로 등장하는 도스 헤더(DOS header)의 영역이다.
    필드가 상당히 많지만, e_magic 필드와 e_lfanew 필드만 보면 된다.

    IMAGE_DOS_HEADER : 처음 4D 5A(MZ)가 e_magic 필드이다.

    e_magic : PE 파일이 맞는지 아닌지 체크할 때 사용되며, 4D 5A(MZ)로 시작하는 부분이 e_magic이 차지하는 공간이다.

    e_lfanew : IMAGE_NT_HEADER의 RVA 형태의 주소값을 가지며, 고정되어 있는 것이 아닌 파일에 따라 가변적인 값을 지닌다. 즉, PE 헤더의 주소는 도스 헤더의 e_lfanew 필드를 참조하여 알아낼 수 있다. e_lfanew는 리틀 엔디언(Little Endian) 표기법으로 표기된다.

     

    리틀 엔디언(Little Endian) 표기법 : 하위 바이트부터 상위 바이트 차례로 값을 저장하는 것

    빅 엔디언(Big Endian) 표기법 : 상위 바이트부터 하위 바이트 차례로 값을 저장하는 것

    ex) int value = 0x11223344

    (Big Endian) 11 22 33 44 / (Little Endian) 44 33 22 11

     

    RVA(Relative Virtual Address) : 파일이 메모리에 로딩 되었을 때의 상대 주소

    2. DOS Stub

    PE 구조체를 모르는 DOS에서 실행되는 코드가 포함되어 있는 부분

    윈도우 운영체제에서는 PE 파일로 인식해 실행되지 않는 코드

    16Bit 환경에서 출력될 "This program cannot be run in DOS mode"라는 문자열 등을 포함하고 있다.

    DOS Stub : 오른쪽 문자열을 보면 "This program cannot run in DOS mode"라고 적혀있다.

    3. IMAGE_NT_HEADER

    NT Header 구조체

    도스 헤더의 마지막 멤버가 가리키는 주소에서 시작

    3개의 멤버로 구성되어 있다.

    Signature - File Header - Optional Header

     

    Signature : "50 45 00 00"의 4Byte 공간. ASCII Code로 PE 라는 문자열을 나타내며 PE 구조를 가진 파일이라는 것을 의미한다.

    Signature : "50 45 00 00" = PE..

    IMAGE_FILE_HEADER(File Header) : 동작하는 CPU, 섹션의 수, 생성 시간 등 파일의 대략적인 정보를 저장한다.

    File Header

    주요 멤버는 다음과 같다.

    Machine : CPU별 고유한 값(64 86)

    Number Of Sections : 섹션의 개수(06 00)

    Time Data Stamp : PE 파일이 빌드된 시간

    Size Of Optional Header : Optional Header의 크기(F0 00)

    Characteristics : 파일의 속성값(22 00)

     

    IMAGE_OPTIONAL_HEADER32(Optional Header) : 파일 실행에 필요한 주요 정보들을 저장한다.

    Optional Header

    주요 멤버는 다음과 같다.

    Magic : 이 구조체가 32Bit0x10B, 64Bit0x20B로 저장한다.(0B 02)

    Address Of Entry Point : EPRVA 값을 가지고 있다.(20 18 00 00)

    ImageBase : PE 파일이 로딩되는 시작 주소를 나타낸다.(01 00 00 00)

    SectionAlignment : 메모리에서의 섹션의 최소단위를 나타낸다.(00 10)

    FileAlignment : 파일에서의 섹션의 최소단위를 나타낸다.(00 20)

    Size Of Image : 메모리에서의 PE 구조의 크기를 나타낸다.(00 B0 00 00)

    Size Of Header : PE Header의 크기를 나타낸다.(00 04)

    SubSystem : 1 = 드라이버 파일(SYS, VXD), 2 = GUI 파일, 3 = CUI 파일(02 00)

    Number Of Rva And Sizes : IMAGE_DATA_DIRECTORY 구조체의 배열 개수를 정한다.(0x10으로 일정)(10 00)

    Data Directory : IMAGE_DATA_DIRECTORY 구조체의 배열, 각 항목은 정해진 값을 가지고 각 항목 Table이 어디에 위치해 있는지 RVA 값과 크기를 나타낸다.

    4. IMAGE_SECTION_HEADER(Section header)

    각 섹션을 분리시키고, 섹션들의 속성, 크기, 시작 위치 등을 정하는 곳

    Section Header

    주요 멤버는 다음과 같다.

    Virtual Size : 메모리에서 섹션이 차지하는 크기(80 B0 00 00)

    Virtual Address : 메모리에서의 섹션의 시작 주소(RVA)(00 10 00)

    Size Of Raw Data : 파일에서 섹션이 차지하는 크기(00 0C 00 00)

    Pointer To Raw Data : 파일에서의 섹션의 시작 주소(00 04 00 00)

    Characteristics : 섹션의 정보(bit OR). 다음과 같이 정의되어 있다.(20 00 00 60)

    #define IMAGE_SCN_CNT_CODE // 코드로 채워진 섹션

    #define IMAGE_SCN_CNT_INITIALIZED_DATA // 데이터가 초기화된 섹션

    #define IMAGE_SCN_CNT_UNINITIALIZED_DATA // 데이터가 비초기화된 섹션

    #define IMAGE_SCN_MEM_EXECUTE // 실행 가능한 섹션

    #define IMAGE_SCN_MEM_READ // 읽기가 가능한 섹션

    #define IMAGE_SCN_MEM_WRITE // 쓰기가 가능한 섹션

    05. 섹션(Section)

    실제 실행에 필요한 정보들, 실제 프로그램을 구성하는 어셈블리 코드와 소스 코드 내에서 선언한 변수나 Static 변수 등을 담고 있다.

    종류와 용도는 다음과 같다.

    .text : 파일을 열었을 때 실행될 코드가 저장된다.

    .data : 초기화된 전역 변수, static 변수를 저장한다.

    .rdata : const 변수, 문자열 상수를 저장한다.

    .bss : 초기화 되지 않은 전역 변수, static 변수, 문자열, 기타 상수가 저장된다. 초기화가 진행되면 data영역으로 이동한다.

    .edata : EAT와 관련된 정보가 저장된다.

    .idata : IAT와 관련된 정보가 저장된다.

    .rsrc : 리소스가 저장된다.

     

    EAT(Export Address Table) : 라이브러리 파일에서 제공하는 함수를 다른 프로그램에서 가져다 사용할 수 있도록 해주는 테이블

    IAT(Import Address Table) : 프로그램에서 사용되는 라이브러리에서 어떠한 함수들을 사용하고 있는지, 함수명, 함수시작 주소 등에 대한 정보를 기술한 테이블

     

     

    참조한 사이트들

    https://kali-km.tistory.com/entry/PE%EA%B5%AC%EC%A1%B0%EC%9D%98-%EC%9D%B4%ED%95%B4

    https://unabated.tistory.com/entry/PEPortable-Executable-%EA%B5%AC%EC%A1%B0

    https://hyeonnii.tistory.com/61

    https://jmoon.co.kr/130

    https://babu1447.tistory.com/5

    https://soyammou.tistory.com/24

    luuzun.blog.me/50190920011

    https://indosm.tistory.com/entry/PE-%EA%B5%AC%EC%A1%B0-%EC%A0%95%EB%A6%AC1?category=474683

    https://yokang90.tistory.com/33?category=546886

    댓글

Designed by Tistory.