4주차에는 유튜브 리버싱 강의를 12강 ~ 14강까지 학습하였다.
https://www.youtube.com/playlist?list=PLY12b4RRLcSdsxgVvTW3mnNzMjVrd8JhO
<NT Header>
IMAGE_NT_HEADERS 구조체
signature은 PE 값을 가짐.(dos에서 MZ를 갖는 것처럼)
IMAGE_FILE_HEADER 구조체 (IMAGE_NT_HEADERS의 멤버)
<#1 WORD Machine>
- CPU 호환칩의 고유한 번호를 저장 (리틀 엔디안 방식)
- 4C 01 → 014C, 32bit 인텔 호환칩에서 사용함
<#2 WORD NumberOfSections>
- PE 파일은 코드, 데이터, 리소스 등이 각각 섹션에 나뉘어 저장
- NumberOfSections는 PE 파일 섹션의 개수를 알려줌 (값은 무조건 0보다 커야함)
- 섹션의 개수와 실제 섹션 개수가 다르면 실행 불가함
<#3 WORD SizeOfOptionalHeader>
- IMAGE_OPTIONAL_HEADER32의 크기를 명시 (운영체제 때문)
- 64bit를 사용하게 되면 크기가 달라짐
- IMAGE_OPTIONAL_HEADER32의 크기가 달라져도 SizeOptionalHeader로 크기를 인식
<#4 WORD Characteristics>
- 파일 속성을 나타내는 값
- 파일 속성: 실행 가능한 형태(exe) 혹은 DLL 파일인지 정보를 Bit OR로 저장
- Characteristics 값이 없는 파일이 존재 (obj, res, dll)
NT Header-OptionalHeader
IMAGE_OPTIONAL_HEADER32은 PE Header의 구조체 중 가장 큰 구조체
<#1. WORD Magic>
- 구조체의 크기를 나타냄. 사이즈를 담는 멤버
- IMAGE_OPTIONAL_HEADER32 = 10B
- IMAGE_OPTIONAL_HEADER64 = 20B
<#2. DWORD AddressOfEntryPoint>
- EP(Entry Point)의 RVA(상대주소) 값을 가짐
- 프로그램의 최초로 실행되는 코드의 시작주소로 매우 중요함
<#3. DWORD ImageBase>
- 프로세스의 가상 메모리는 0~FFFFFF의 범위 (32bit)
- 넓은 가상 메모리에서 PE 파일이 로드되는 시작주소를 나타냄
- PE로더가 PE파일을 실행하기 위해 프로세스를 생성하고 파일을 메모리에 로드한 후 EIP(RIP)레지스터 값을 ImageBase+AddressOfEntryPoint Point 값으로 세팅함
매핑: 메모리에 파일을 적재하는 것, 로드: 매핑을 실제로 하는 것
Cf> Entrypoint & ImageBase 차이점
- EP: 실행파일이 시작될 때 실행되는 시작 함수의 주소
- IB: 실행파일이 로드될 때 BaseAddress(기본주소)를 나타내는 값
- → EP 와 IB 는 모두 파일의 메모리의 로딩과 관련
<#4. DWORD SectionAlignment & DWORD FileAlignment>
- 메모리에서 섹션의 최소단위를 나타내는 것 = SectionAlignment
- PE파일의 바디 부분은 섹션으로 나뉘는데, 이때 파일에서 섹션의 최소단위를 나타내는 것 = FileAlignment
<#5. DWORD SizeOfImage>
- PE 파일이 메모리에 로딩되었을 때 가상 메모리 PE IMAGE(메모리에 로딩된 상태)가 차지하는 크기를 나타냄
- (일반적으로) 파일의 크기와 메모리에 로딩된 파일의 크기는 다름
<#6. DWORD SizeOfHeaders>
- PE 파일 전체의 크기를 나타냄
<#7. WORD Subsystem>
- .sys인지 .dll or .exe인지 구별
<#8. DWORD NumberOfRvaAndSizes>
- IMAGE_OPTIONAL_HEADER32의 마지막 멤버인 DataDirectory의 배열의 개수를 나타냄
<#9. IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]>
- IMAGE_OPTIONAL_HEADER32 구조체의 배열
<Section Header>
- Section Header: 각 섹션의 속성(Property)을 정의
code, data, rsrc 3가지로 나누어서 섹션을 저장하는 이유
- 프로그램 복잡함 감소
- 프로그램 안전성
- → code/data/rsrc 마다 각각의 섹션별로 권한이 주어져 있음
- code: 실행, 읽기 권한
- data: 비실행, 읽기 권한
- rsrc: 비실행, 읽기 권한
Section Header 구조체
<#1. DWORD VirtualSize>
- 메모리에서 섹션이 차지하는 크기
<#2. DWORD VirtualAddress>
- 메모리에서 섹션의 시작주소(RVA = 상대주소, dos header의 VA(절대 주소)가 아님)
- File header의 SectionAlignment값에 따라 저장
<#3. DWORD SizeOfRawData>
- 파일에서 섹션이 차지하는 크기
<#4. DWORD PointerToRawData>
- 파일에서 섹션의 시작주소(RVA = 상대주소)
- File header의 FileAlignment값에 따라 저장
<#5. DWORD Characteristics>
- 섹션의 속성을 Bit OR 연산으로 저장
- WORD Characteristics(파일의 속성을 Bit OR 연산으로 저장)와 다름
→ virtual이 붙은건 메모리, 아닌 건 파일에서 시작
→ VirtualAddress와 PointerToRawData의 값은 일반적으로 다름
'2. Reversing (리버싱)' 카테고리의 다른 글
[2024.11.16]리버씽씽이_6주차 활동 (0) | 2024.11.22 |
---|---|
[2024.11.09]리버씽씽이_5주차 활동 (3) | 2024.11.15 |
[2024.10.26]리버씽씽이_3주차 활동 (0) | 2024.11.01 |
[2024.09.28] 리버씽씽이_2주차 활동 (3) | 2024.10.03 |
[2024.09.21] 리버씽씽이_1주차 활동 (5) | 2024.09.27 |