PE 파일 분석

리버싱 2019. 11. 7. 16:27

1. PE 구조

  - PE 헤더 : IMAGE_DOS_HEADER, MS-DOS Stub Program , IMAGE_NT_HEADERS , IMAGE_SECTION_HEADER

  - PE 바디 : 실제 데이터 정보가 있는 영역 ( text , data , rsrc , reloc )

 

 

IMAGE_DOS_HEADER

- PE 파일 시그니처와 IMAGE_NT_HEADER의 위치 정보를 갖고 있다

- 64Byte 로 구성되어 있으며 19개 필드로 구성 되어 있음 

 

 - Signature

    - e_magic : '5A4D' -> MZ ( PE 파일 시그니처를 의미한다 )

    

 

 - Offset to New Header

    - e_ifanew : IMAGE_NT_HEADER 의 위치를 의미 (0x000000D8)

      0x000000D8에 504A(PE 파일 시그니처) 를 확인할 수 있다

 

 

인텔 cpu             저장 방식   ( 12 34 56 78 )

리틀 엔디언       78 56 34 12  <-- 반대로

빅 엔디언          12 34 56 78  <-- 정상으로

 

 

 

 

MS-DOS Stub Program

  - MS-DOS , windows 3.1에서 실행하면 'This program cannot be run in DOS mode' 라는 문자열을 출력하는 영역

  - 152Byte로 구성되어있음

 

 

 

 

IMAGE_NT_HEADERS

  - Signature

    - 4Byte

    - PE 파일 시그니처

    - 50 45 00 00

 

  - IMAGE_FILE_HEADER

    - CPU 정보 , 섹션 수 , 파일 생성 / 컴파일 시간 , IMAGE_OPTIONAL_HEADER 크기 , 파일 특성들이 포함 됨 

    - 20Byte

    - Machine : CPU 별 고유 값 ( intel 368/x86 : 0x14C , intel 64 : 0x0200 , AMD64 : 0x8664 )

    - Number of Sections : 실행 파일이 갖고 있는 총 섹션 개수

    - Time Date Stamp : 파일 생성 / 컴파일된 시간

    - Size of Optional Header : IMAGE_OPTIONAL_HEADER의 크기 ( 0x00E0 -> 224Byte )

    - Characteristics : PE 파일에 대한 특정 정보를 나타내는 플래그

        - 0x0002 IMAGE_FILE_EXECUTABLE_IMAGE  <-- PE 파일을 의미함

        - 0X0100 IMAGE_FILE_32BIT_MACHINE  <-- 32bit PE 파일을 의미함

        - 0x2000 IMAGE_FILE_DLL  <-- DLL 파일을 의미함

 

 - IMAGE_OPTIONAL_HEADER

    - 224Byte

 

    - 표준 필드 , NT 추가 필드 , DataDirectory 배열 정보들이 포함되어 있음

    - 표준 필드 : 실행 파일 로드 및 실행에 사용되는 정보

    - 표준 필드 영역 : Magic ~ Base of Code

 

    - NT 추가 필드 : 윈도우 링커 / 로더가 요구하는 정보

    - NT 추가 필드 영역 : Base of Data ~ Loader Flags

    - DataDirectory 배열 영역 : Numver of Data Directories

 

    Magic : IMAGE_OPTIONAL_HEADER 시그니처

                   0x010B : 32bit PE 파일

                   0x020B : 64bit PE 파일

   Size of Code : text 섹션 크기 ( 0x52E00 )

   Address of Entry Point : 파일이 메모리에서 시작되는 주소 ( 0x12D6C )

         PE 로더가 실행을 개시할때 사용하는 RVA 주소 , text 섹션 내의 특정 번지 주소가 된다

         이 필드의 값은 프로그램이 처음으로 실행될 코드를 담고 있는 EP(entry Point) RVA 주소다

 

RVA

  - PE 파일이 가상 주소 공간 내에서 로드된 후 이미지의 시작 주소에 대한 상대 주소

  - PE 시작 주소에서 어느정도 떨어져 있는지를 계산할 수 있다

 

VA

  - 가상 메모리 주소 공간에서 프로세스의 절대 주소

 

VA 계산식

  - VA = ImageBase 주소 + RVA 주소

  - VA = 0x0100000000 + 0x00012D6C = 0x010012D6C

 

Base of Code : 실행 코드의 위치를 의미  첫번째 섹션이 시작되는 RVA 주소

Base of Data : 첫번째 데이터 섹션이 시작되는 RVA 주소

Image Base : 로드할 가상 메모리의 주소

  - DLL 파일 : 윈도우 제공 exe 파일 :  0x01000000

  - EXE 파일 : 0x00400000

  - DLL/EXE 파일 -> User 메모리 영역인 '0x00000000 ~ 0x7FFFFFFFF'에 로드

  - SYS파일 -> 커널 메모리 영역인 '0x800000000 ~ 0xFFFFFFFF'에 로드 

  

Section Alignment : 메모리 상에서 섹션의 최소 단위 ( File Alignment 보다 커야함 )

 

Ex1 ) text 섹션의 데이터가 512byte인 경우

   - 섹션 얼라이먼트에 의해서 4096Byte 할당

 

Ex2 ) text 섹션의 데이터가 6000byte인 경우

   - 섹션 얼라이먼트에 의해서 8192Byte 할당

 

File Alignment : 파일의 최소 단위 (0x200 -> 512byte)

 

Size of Image : PE 파일이 메모리에 로드되었을 때  ,가상 메모리 상에 PE 이미지 크기

                    0xC0000 -> 786432Byte

                    Section Alignment 보다 커야함

 

Size of Headers : PE 헤더 전체 크기

                       0x400 -> 1024Byte

                       File Alignment 보다 커야함

 

 

Subsystem : 프로그램 파일 유형

                1: SYS 파일과 같은 디바이스 파일

                2: Windows GUI 환경 프로그램

                3: CMD 기반 콘솔 프로그램

 

DLL Characteristics

  - 시스템 보호 기능 ( ASLR , DEP , SHE... )을 사용 유무 플래그

     ASLR 기능 : 0x0040  IMAGE_DLLCHARACTERISTIC_DYNAMIC_BASE

 

 

Number of Data Directories : IMAGE_DATA_DIRECTORY 구조체 배열

  - 각각의 배열 항목(16개)마다 RVA(4byte) , Size (4byte) 로 구성되어 있음

    EXPORT Table : Export 섹션 시작 주소

    IMPORT Table : Import 섹션 시작 주소

    Resource Table : Resource 섹션 시작 주소

 

 

 

 

IMAGE_SECTION_HEADER

  - 섹션 헤더는 각 섹션의 속성 정보들을 갖고 있는 구조체다

  - 섹션이란 프로그램의 실제 내용(어셈블리 코드 , 전역 변수 , 정적 변수)을 담고 있는 영역을 의미한다

  - 섹션 유형은 다음과 같다

    - .text : 프로그램 코드를 담고 있는 섹션 , IAT 정보를 갖고 있다 

    - .data : 전역변수 , 정적 변수의 할당을 위한 섹션 , 읽기/쓰기 가능한 데이터를 갖고 있음

    - .rdata :  읽기 전용 섹션 , 문자열 , 상수 정보를 갖고 있음

    - .bss : 초기화되지 않은 변수를 갖고 있는 섹션

    - .rsrc : 아이콘 , 커서 , 추가 바이너리 등의 리소스 관련 정보를 갖고 있는 섹션

    - .idata : Import 할 DLL/API 정보를 갖고 있는 섹션

    - .edata : Export 할 DLL/API 정보를 갖고 있는 섹션

    - .reloc : 재배치 정보를 갖고 있는 섹션

 

 

섹션 헤더 구조

 - 40byte

 - Name : 섹션 이름                                            8byte

 - Virtual Size : 메모리에서 섹션이 차지하는 크기       4byte

 - RVA : 메모리에서 섹션의 시작 주소                      4byte

 - Size of Raw Data : 파일에서 섹션이 차지하는 크기  4byte

 - Pointer to Raw Data : 파일에서 섹션의 시작 주소    4byte

 

 

'.text' 섹션 헤더

 - 코드 정보 , 실행 , 읽기 속성(권한) 정보가 포함된 섹션

  - Name  8byte  2E 64 61 74 61 00 00 00 (.text)

     - 섹션의 ASCII 16진수 값

     - 이름은 프로그램 동작과 무관하므로 변경해도 상관 없음

 

 - Virtual Size  4byte  00 05 2C A1 ( 339105byte)

    - 메모리에서 섹션이 차지하는 크기

   

 - RVA  4byte  00 00 10 00

    - 메모리에 로드될 때 시작 주소 

    VA = ImageBase + RVA = 0x01000000 + 0x00001000 = 0x01001000

 

 - Size of Raw Data 4byte  00 05 2E 00 (339456byte)

   - 파일에서 섹션이 차지하는 크기

 

 - Pointer to Raw Data  4byte  00 00 04 00 

   - 파일에서 섹션의 시작 주소

 

 - Characteristics  4byte  60 00 00 20

   - 섹션 속성(권한)에 대한 정보

     

   - IMAGE_SCN_CNT_CODE        00 00 00 20   실행 가능한 코드를 포함한 속성

   - IMAGE_SCN_MEM_EXECUTE   20 00 00 00   실행 가능한 속성

   - IMAGE_SCN_MEM_READ       40 00 00 00   읽기 가능한 속성

 

 

'.data' 섹션 헤더

  - 전역변수 , 정적 변수의 할당을 위한 섹션 , 읽기/쓰기 가능한 데이터를 갖고 있음

 

  - Name  8byte  2E 64 61 74 61 00 00 00 (.data)

     - 섹션의 ASCII 16진수 값

     - 이름은 프로그램 동작과 무관하므로 변경해도 상관 없음

 

 - Virtual Size  4byte  00 00 40 C0 (16576byte)

    - 메모리에서 섹션이 차지하는 크기

   

 - RVA  4byte  00 05 40 00

    - 메모리에 로드될 때 시작 주소 

    VA = ImageBase + RVA = 0x01000000 + 0x00054000 = 0x01054000

 

 - Size of Raw Data 4byte  00 00 42 00 (16896byte)

   - 파일에서 섹션이 차지하는 크기

 

 - Pointer to Raw Data  4byte  00 05 32 00 

   - 파일에서 섹션의 시작 주소

 

 - Characteristics  4byte  C0 00 00 40

   - 섹션 속성(권한)에 대한 정보

     

   - IMAGE_SCN_INITALIZED_DATA      00 00 00 40    초기화된 데이터  속성

   - IMAGE_SCN_MEM_READ              40 00 00 00   읽기 가능한 속성

   - IMAGE_SCN_MEM_WRITE             80 00 00 00   쓰기 가능한 속성

 

 

 

 

'.rsrc' 섹션 헤더

  - 아이콘 , 커서 , 추가 바이너리 등의 리소스 관련 정보를 갖고 있는 섹션 

 

  - Name  8byte  2E 72 73 72 63 00 00 00 (.rsrc)

     - 섹션의 ASCII 16진수 값

     - 이름은 프로그램 동작과 무관하므로 변경해도 상관 없음

 

 - Virtual Size  4byte  00 06 27 98 (403352byte)

    - 메모리에서 섹션이 차지하는 크기

   

 - RVA  4byte  00 05 90 00

    - 메모리에 로드될 때 시작 주소 

    VA = ImageBase + RVA = 0x01000000 + 0x00059000 = 0x01059000

 

 - Size of Raw Data 4byte  00 06 28 00 (403456byte)

   - 파일에서 섹션이 차지하는 크기

 

 - Pointer to Raw Data  4byte  00 05 74 00 

   - 파일에서 섹션의 시작 주소

 

 - Characteristics  4byte  40 00 00 40

   - 섹션 속성(권한)에 대한 정보

     

   - IMAGE_SCN_INITALIZED_DATA      00 00 00 40    초기화된 데이터  속성

   - IMAGE_SCN_MEM_READ             40 00 00 00   읽기 가능한 속성

   

 

 

 

'.reloc' 섹션 헤더

  - 재배치 정보 갖고 있는 섹션 

 

  - Name  8byte  2E 72 65 6C 6F 63 00 00 (.reloc)

     - 섹션의 ASCII 16진수 값

     - 이름은 프로그램 동작과 무관하므로 변경해도 상관 없음

 

 - Virtual Size  4byte  00 00 3B 3C (15164byte)

    - 메모리에서 섹션이 차지하는 크기

   

 - RVA  4byte  00 0B C0 00

    - 메모리에 로드될 때 시작 주소 

    VA = ImageBase + RVA = 0x01000000 + 0x000BC000 = 0x010BC000

 

 - Size of Raw Data 4byte  00 00 3C 00 (15360byte)

   - 파일에서 섹션이 차지하는 크기

 

 - Pointer to Raw Data  4byte  00 0B 9C 00 

   - 파일에서 섹션의 시작 주소

 

 - Characteristics  4byte  42 00 00 40

   - 섹션 속성(권한)에 대한 정보

     

   - IMAGE_SCN_INITALIZED_DATA       00 00 00 40    초기화된 데이터  속성

   - IMAGE_SCN_MEM_DISCARDABLE   02 00 00 00    실행 파일이 메모리에 로딩되고 버려지는 속성

   - IMAGE_SCN_MEM_READ              40 00 00 00    읽기 가능한 속성

   

 

 

ImageBase

  - PE 파일이 메모리에 로드되는 시작 주소

  - DLL/EXE 파일 -> User 메모리 영역인 '0x00000000 ~ 0x7FFFFFFFF'에 로드

  - SYS파일 -> 커널 메모리 영역인 '0x80000000 ~ 0xFFFFFFFF'에 로드 

  - DLL 파일/윈도우 제공 EXE 파일 : 0x01000000

  - 그 외 EXE 파일 : 0x004000000

 

VA 주소를 구하기 위한 요소

  - VA : 메모리 상에 프로세스 절대 주소

  - Virtual Size : 메모리에서 차지하는 섹션의 크기(패딩/Null 포함)

  - RVA : 메모리에서 찾고자 하는 어떤 데이터의 주소

  - Size of Raw Data : 파일에서 섹션의 크기(패딩/Null 포함)

  - Pointer to Raw Data : 파일에서 섹션의 주소

 

 

각 섹션에 대한 RVA to VA 구하기

 - .text 섹션

  - ImageBase               0x01000000

  - RVA                        0x00001000 

  - Virtual Size               0x00052CA1

  - 다음 섹션의 VA         0x01054000

 - VA = 0x01000000 + 0x00001000 = 0x01001000

 - .text 섹션 범위 : 0x01001000 ~ 0x01053CA1

                           ( VA )              ( ImageBase + RVA + Virtual Size ) 

 - .text 섹션 패딩 : 0x01054000 - 0x0153CA1 = 0x0000035F         

 

 

- .data 섹션

  - ImageBase               0x01000000

  - RVA                        0x00054000 

  - Virtual Size               0x000040C0

  - 다음 섹션의 VA          0x01059000

 - VA = 0x01000000 + 0x00054000 = 0x01054000

 - .data 섹션 범위 : 0x01054000 ~ 0x010580C0

 - .data 섹션 패딩 : 0x01059000 - 0x010580C0 = 0x00000F40          

 

 

 

- .rsrc 섹션

  - ImageBase               0x01000000

  - RVA                        0x00059000 

  - Virtual Size               0x00062798

  - 다음 섹션의 VA          0x010BC000

 - VA = 0x01000000 + 0x00059000 = 0x01059000

 - .rsrc 섹션 범위 : 0x01059000 ~ 0x010BB798

 - .rsrc 섹션 패딩 : 0x010BC000 - 0x010BB798 = 0x00000868   

 

 

- .reloc 섹션

  - ImageBase               0x01000000

  - RVA                        0x000BC000

  - Virtual Size               0x00003C00

 

 - VA = 0x01000000 + 0x000BC000= 0x010BC000

 - .reloc 섹션 범위 : 0x010BC000 ~ 0x010BFB3C

 - .reloc 섹션 패딩 : (0x010BFBFF + 1) - 0x010BFB3C = C4  

 

 

 

 

'리버싱' 카테고리의 다른 글

화면 잠금 프로그램 'Lock Workstation' 제작  (0) 2019.11.13
PE 파일 분석 IAT & Pre Binding  (0) 2019.11.11
PE 파일 분석 ( PE 바디 - 섹션 )  (0) 2019.11.11
PE 파일 분석 ( RVA to RAW )  (0) 2019.11.11
리버싱 선수 지식  (0) 2019.11.07

설정

트랙백

댓글