글
PE 파일 분석
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 |