With 리버싱 핵심원리
남은 P1 내용은 추후 공부를 좀 더 하고 여유가 될 때 작성하도록 하겠습니다. P1의 Stack, Stack Frame, IA-32, 함수 호출 방법 들은 아주 중요한 내용들이라서 책이 아니더라도 따로 익혀두셔야 합니다. 그 외에 crack me를 푸는 부분은 인터넷에도 정보가 많고 난이도가 쉬운 편이어서 빠르게 넘어가셔도 될 거 같습니다.
이번 파트는 직접 정리하면서 공부해야 머리에 잘 들어올 것 같아 겸사겸사 글을 작성하게 되었습니다.
PE(Portable Executable)
Windows 운영체제에서 사용되는 실행 파일 형식
PE 파일 종류
종류 | 주요 확장자 | 종류 | 주요 확장자 |
실행 계열 | EXE, SCR | 드라이버 계열 | SYS, VXD |
라이브러리 계열 | DLL, OCX, CPL, DRV | 오브젝트 파일 계열 | OBJ |
PE 파일에는 PE 파일의 헤더 부분(PE 헤더)에 프로그램을 실행하는데 있어 필요한 모든 정보가 포함되어 있습니다. PE File Format을 공부하는 것은 곧 PE 헤더 구조체를 공부한다는 것입니다. 그래서 이번 파트는 PE 헤더의 구조체를 분석하는 파트입니다.
PE(Portable Executable) File Format (1) - PE Header
Introduction Windows 운영체제의 PE(Portable Executable) File Format 에 대해서 아주 상세히 공부해 보도록 하겠습니다. PE format 을 공부하면서 Windows 운영체제의 가장 핵심적인 부분인 Process, Memory, D..
reversecore.com
그림 2 참고하여 설명하겠습니다.
DOS header부터 Section header까지가 PE header, 그 밑은 PE body입니다. 파일에서는 offset으로, 메모리에서는 VA(Virtual Adress)로 위치를 나타냅니다. 중간중간에 존재하는 NULL padding은 컴퓨터에서 처리할 때 최대한의 효율을 내기 위해 설정한 최소 기본단위의 배수로 만들기 위해 각 섹션에 NULL padding을 하여 기본단위의 배수로 만든 것입니다.
VA(Virtual Address)는 가상 메모리의 주소를 말하며, RVA(Relative Virtual Address)는 ImageBase부터의 주소를 말합니다.
RVA + ImageBase = VA
즉, 어떤 기준(ImageBase)에 RVA값을 더하면, 원하는 메모리 상의 위치 값 VA를 얻을 수 있는 것입니다.(쉽게 말하면, RVA는 메모리 상의 offset이라고 볼 수 있습니다.)
PE Header
위 사진은 PEview로 메모장을 열어 본 것으로 해당 프로그램을 사용하면 더 수월하게 분석할 수 있습니다.
- DOS Header
DOS 파일에 대한 하위 호환성을 고려하여 만들었으며, PE 헤더 제일 앞부분에 IMAGE_DOS_HEADER 구조체가 존 재합니다. 구조체의 크기는 40이며, e_magic과 e_lfanew 멤버가 가장 중요합니다.
e_magic : DOS signature(MZ) / e_lfanew : NT header의 오프셋을 표시(파일에 따라 다름)
- NT Header
NT Header 구조체 IMAGE_NT_HEADERS는 DWORD Signature(PE), IMAGE_FILE_HEADER FileHeader, IMAGE_OPTIONAL_HEADER32 OptionalHeader 멤버로 구성되어 있습니다.
FileHeader는 파일의 대략적인 정보가 저장된 구조체입니다. 멤버 중 Machine은 CPU별로 고유한 값, NumberOfSections는 섹션의 개수, SizeOfOptionalHeader는 IMAGE_OPTIONAL_HEADER32 구조체의 크기를 마지막으로 Characteristics는 파일의 속성을 나타내는 값입니다.
Optional Header는 PE 헤더의 구조체 중 가장 크기가 큰(크기가 크면 => 중요하다) 구조체 입니다. 프로그램 실행에 있어서 필수적인 정보들이 모여있어 하나라도 빠지면 실행이 되지 않을 정도록 매우 매우 중요합니다.
사진의 크기 만으로도 구조체의 크기가 크다는 점을 느낄 수 있고, 크기가 큰 만큼 많은 구조체 멤버들이 존재합니다.
Magic : IMAGE_OPTIONAL_HEADER32 구조체면 10B, IMAGE_OPTIONAL_HEADER64인 경우에는 20B 값
AddressOfEntryPoint : EP(Entry Point)의 offset인 RVA 값을 가지고 있고, 프로그램의 시작 주소입니다.
ImageBase : 앞서 RVA와 VA값을 설명할 때 함께 언급한 값입니다. RVA+Imagebase = VA
SectionAlignment : 메모리에서 각 섹션의 최소단위
FileAlignment : 파일에서 각 섹션의 최소 단위
SizeOfImage : PE 파일이 메모리에 로딩됐을 때 파일이 메모리에서 차지하는 크기
SizeOfHeader : PE 헤더의 전체 크기
Subsystem : 값 1(Driver File), 값 2(GUI 파일), 값 3(CUI 파일) 임을 나타냅니다.
NumberOfRvaAndSizes : IMAGE_OPTIONAL_HEADER32 구조체의 DataDirectory 배열의 개수
DataDirectory : IMAGE_DATA_DIRECTORY 구조체의 배열로 각 항목마다 정의된 값을 가집니다.
- Section Header
Section Header에는 각 섹션의 속성이 정의되어있습니다. PE 파일은 code, data, resource 등을 각각의 섹션으로 나누어 저장합니다.
각 섹션의 섹션 헤더는 IMAGE_SECTION_HEADER 구조체의 배열로 되어있습니다.
VirtualSize : 메모리에서 섹션이 차지하는 크기
VirtualAddress : 섹션의 VA 값
SizeOfRawData : 파일에서 섹션이 차지하는 크기
PointerToRawData : 파일에서 섹션의 시작 위치
Characteristics : 섹션의 속성
- RVA to RAW
RVA to RAW란, 각 섹션에서 어떤 RVA 값을 파일에서의 오프셋(RAW)을 매핑하는 방법
RAW - PointerToRawData = RVA - VirtualAddress
RAW = RVA - VirtualAddress + PointerToRawData
해석) RVA에서 섹션의 VA값을 빼면 해당 값의 Offset이 나옵니다. 거기에 PointerToRawData(파일에서의 섹션 Offset)을 더하게 되면 자연스레 RAW가 나오게 되는 것입니다.
마치며
PE File Format 파트의 내용이 꽤 많아 여기서 끊고 다음에는 아주 중요하고 중요한 내용인 IAT, DLL 등의 내용을 작성하겠습니다.
'Reversing > 리버싱핵심원리' 카테고리의 다른 글
P2 - Unpackme #1 (0) | 2022.09.18 |
---|---|
P2 - 13 PE File Format 정리 #2 (0) | 2022.09.12 |
P1-1,2 리버싱 기초 (0) | 2022.04.17 |