일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- NT File Header
- Buffer Overflow
- GetProcAddress()
- 리버싱 핵심원리
- SQL Injection
- attack vector
- Tutorial
- NT Header
- docker
- oh-my-zsh
- PE file format
- IMAGE_IMPORT_DESCRIPTOR
- DOS Stub
- ubuntu
- NT Optional Header
- Windows 11
- BOF
- RVA
- DOS Header
- Windows
- zsh theme customization
- WSL
- powerlevel10k
- web
- IMAGE_EXPORT_DIRECTORY
- sctf 2021
- samsung ctf
- stack based buffer overflow
- PE Header
- Windows Terminal
Archives
- Today
- Total
나만의 메모노트
[리버싱 핵심원리] PE File Format (3) 본문
NT Header
- IMAGE_NT_HEADERS
- NT Header의 구조체
- 3개 멤버로 구성
- PE Signature : 50450000h(“PE”00) 값을 가짐
- File Header 구조체
- Optional Header 구조체
- 크기 : F8 (248byte)
File Header
- IMAGE_FILE_HEADER 구조체
- 파일의 개략적인 속성을 나타냄
- 주요 멤버
- 각 멤버별 값들의 설정이 부정확할 경우 비정상 실행
1) Machine- Machine 넘버는 CPU별로 고유한 값을 가짐 (32bit Intel x86 호환칩 = 14C의 값)
- winnt.h 파일에 정의된 Machine 넘버의 값
- 섹션의 개수
- 해당 값은 반드시 0보다 커야 함
- 정의된 섹션 개수와 실제 섹션이 다르면 실행 에러가 발생
- SizeOfOptionalHeader
- IMAGE_OPTIONAL_HEADER32 구조체의 크기
- IMAGE_OPTIONAL_HEADER32
- IMAGE_NT_HEADERS 구조체의 마지막 멤버
- C언어 구조체로써 이미 그 크기가 결정되지만, Windows의 PE loader는 SizeOfOptionalHeader 값을 보고 해당 구조체의 크기를 인식
- PE32+ 형태의 파일인 경우 IMAGE_OPTIONAL_HEADER64 구조체를 사용
- 두 구조체의 크기가 상이하므로 해당 멤버에 구조체 크기를 명시
- IMAGE_OPTIONAL_HEADER32
- 일반적인 PE 파일 형식을 벗어난 PE Patch 생성 가능
- IMAGE_DOS_HEADER의 e_lfanew 멤버와 IMAGE_FILE_HEADER의 SizeOfOptionalHeader 멤버에 의해
- IMAGE_OPTIONAL_HEADER32 구조체의 크기
- 파일의 속성을 나타내는 값
- 실행 가능한 형태인지 (executable or not) 혹은 DLL 파일인지 등의 정보들이 bit OR 형식으로 조합됨
- PE 파일 중 해당 값에 0002h가 없는 경우도 존재 (not executable)
- *.obj와 같은 object 파일 및 resource DLL 같은 파일
- *.obj와 같은 object 파일 및 resource DLL 같은 파일
- TimeDataStamp
- 실행 파일에 영향을 미치지 않으며, 해당 파일의 빌드 시간을 나타낸 값
- 각 멤버별 값들의 설정이 부정확할 경우 비정상 실행
Optional Header
- IMAGE_OPTIONAL_HEADER32
- 크기가 가장 큰 PE Header 구조체
IMAGE_OPTIONAL_HEADER 구조체 notepad.exe Optional Header - 주요 멤버
- 각 멤버들은 파일 실행에 필수적인 요소
- 해당 값들의 설정이 부정확할 경우 비정상 실행주요 멤버
- IMAGE_OPTIONAL_HEADER32 구조체의 Magic 넘버 = 10Byte
- IMAGE_OPTIONAL_HEADER64 구조체의 Magic 넘버 = 20Byte
- EP(Entry Point)의 RVA (Relative Virtual Address) 값을 가지고 있음
- 프로그램에서 최초로 실행되는 코드의 시작 주소 (매우 중요한 값)
- 프로세스의 가상 메모리(범위 : 0 ~ FFFFFFFF)에서 PE 파일이 로딩되는 시작 주소
- ① PE loader는 PE 파일을 실행시키기 위해 프로세스를 생성
- ② 파일을 메모리에 로딩
- ③ EIP 레지스터 값을 ImageBase + AddressOfEntryPoint 값으로 설정
파일 영역 로딩 범위 Image Base 값 EXE User memory 0~7FFFFFFF 00400000 DLL 10000000 SYS Kernel memory 80000000~FFFFFFFF -
- FileAlignment : 파일에서 Section의 최소단위를 나타낸 것
- SectionAlignment : 메모리에서 Section의 최소단위를 나타낸 것
- 하나의 파일에서 FileAlignment와 SectionAlignment의 값은 같거나 다를 수 있음
- File/Memory의 Section Size는 반드시 FileAlignment와 SectionAlignment의 배수가 되어야 함
- PE 파일이 메모리에 로딩되었을 때 가상 메모리에서 PE Image가 차지하는 크기
- 파일의 크기와 메모리에 로딩된 크기는 다름
- PE 헤더의 전체 크기
- 해당 값은 FileAlignment의 배수여야 함
- 1st Section location : 파일 시작에서 SizeOfHeader offset만큼 떨어진 곳
- 해당 값을 보고 시스템 드라이버 파일(.sys)과 일반 실행 파일(.exe, *.dll)을 구분
값 의미 비고 1 Driver file 시스템 드라이버(예:ntfs.sys) 2 GUI (Graphic User Interface) 파일 창 기반 애플리케이션(예:notepad.exe) 3 CUI (Console User Interface) 파일 콘솔 기반 애플리케이션 (예:cmd.exe)
- IMAGE_OPTIONAL_HEADER32 구조체의 마지막 멤버인 DataDirectory 배열의 개수
- 구조체 정의에 배열 개수 명시되어 있음
- IMAGE_NUMBEROF_DIRECTORY_ENTRIES (16)
- PE loader는 해당 값을 보고 배열의 크기를 인식 (16이 아닐 수도 있다는 의미)
- IMAGE_DATA_DIRECTORY 구조체의 배열로 각 항목마다 정의된 값을 가짐
- 주요 배열
- EXPORT Directory
- IMPORT Directory
- RESOURCE Directory
- TLS Directory
- 크기가 가장 큰 PE Header 구조체
Section Header
- Section Header
- 각 Section의 속성(property)을 정의하는 것
- Section의 속성에는 File/Memory에서의 시작 위치, 크기, 접근 권한 등이 있음
- 각 Section의 속성(property)을 정의하는 것
- 초기 PE File Format
- PE File을 여러 개의 Section 구조로 분류 👉 프로그램의 안정성을 높이기 위함
- 비슷한 성격의 자료를 Section이라고 이름 붙인 곳에 모아두기로 함
- 각각의 Section의 속성을 Section Header에 기술함
- code/data/resourse마다 각각의 특성, 접근 권한, 등을 다르게 설정할 필요가 있음
종류 접근 권한 code 실행, 읽기 권한 data 비실행, 읽기, 쓰기 권한 resourse 비실행, 읽기 권한 - IMAGE_SECTION_HEADER
- Section Header는 각 Section별 IMAGE_SECTION_HEADER 구조체의 배열로 구성
- 주요 멤버
멤버명 의미 VirtualSize 메모리에서 섹션이 차지하는 크기 VirtualAddress 메모리에서 섹션의 시작 주소(RVA) SizeOfRawData 파일에서 섹션이 차지하는 크기 PointerToRawData 파일에서 섹션의 시작 위치 Characteristics 섹션의 속성(bit OR) IMAGE_SECTION_HEADER 구조체 - VirtualAddress와 PointerToRawData는 아무 값이나 가질 수 없음
- 각각 SectionAlignment와 FileAlignment에 맞게 결정됨
- VirtualSize와 SizeOfRaqData는 서로 다른 값을 가짐
- 파일에서의 섹션 크기와 메모리에 로딩된 섹션의 크기가 다르기 때문
- Characteristics는 아래 그림에 표시된 값들의 조합(bit OR)
- Name
- C언어의 문자열처럼 NULL로 끝나지 않음
- ASCll 값만 사용한다는 제한도 없음
- 참고용으로 사용할 뿐 어떤 정보로써 활용하기에는 100% 장담할 수 없음
- PE 스펙에는 Section Name에 대한 어떠한 명시적인 규칙이 없으므로 어떠한 값을 넣어도 되고 심지어 NULL로 채워도 됨
notepad.exe Section Header
- PE 스펙에는 Section Name에 대한 어떠한 명시적인 규칙이 없으므로 어떠한 값을 넣어도 되고 심지어 NULL로 채워도 됨
RVA to RAW
- RVA
- PE 파일이 메모리에 로딩되었을 떄의 메모리 주소
- RAW
- PE 파일이 로딩되기 전에 File Offset
- RVA to RAW
- PE 파일의 각 섹션이 메모리에 로딩되기 전의 File Offset과 메모리에 로딩된 후에 로딩된 위치의 주소를 매칭하는 것 (일반적인 매핑)
- 매핑하는 방법
- RVA가 속해 있는 섹션을 찾는 방법
- 간단한 비례식을 사용해서 파일 offset(RAW)을 계산하는 방법
'Security > Reversing' 카테고리의 다른 글
[리버싱 핵심원리] PE File Format (5) (0) | 2021.08.01 |
---|---|
[리버싱 핵심원리] PE File Format (4) (0) | 2021.08.01 |
[리버싱 핵심원리] PE File Format (2) (0) | 2021.08.01 |
[리버싱 핵심원리] PE File Format (1) (0) | 2021.07.31 |
[리버싱] 치트 엔진으로 싱글 게임 분석해보기 (1) | 2021.07.27 |