* PEView는 여전히 Upack 패킹된 파일 분석 못한다...
IMAGE_DOS_HEADER [ 0x0 ~ 0x3F ]
- "MZ" 시그니쳐
- e_lfanew = 0x10
- 0x2 ~ 0x3B까지는 다른 용도로 쓰인다
DOS Stub 생략
PE Signature [ 0x10 ~ 0x13 ]
IMAGE_FILE_HEADER [ 0x14 ~ 0x27 ]
- Machine 0x14C, 섹션 수 3개
- Optional Header Size 0x148 => 0xE0보다 크다, 남은 공간은 다른 용도로 쓴다
IMAGE_OPTIONAL_HEADER [ 0x28 ~ 0x16F ]
- magic number 0x10B, RVA of EP = 0x1018
- Image Base=0x1000000, Section Alignment = 0x1000, File Alignment = 0x200
- Image Size = 0x28000, Header size = 0x200, Subsystem = 2
- Number of DataDirectories = 0xA => 뒤 6개 원소+Optional Header 뒤 공간(0xD8~0x16F) 까지는 다른 용도로 쓴다
Section Header 1 [ 0x170 ~ 0x197 ]
- 0x14000(VirtualSize), 0x1000(RVA), 0x10F(SizeOfRawData), 0x10(PointerToRawData)
Section Header 2 [ 0x198 ~ 0x1BF ]
- 0x12000, 0x15000, 0xAE28, 0x200
Section Header 3 [ 0x1C0 ~ 1E7 ]
- 0x1000, 0x27000, 0x10F, 0x10
=> Section 1과 Section 3 파일에서의 영역 완전 동일, 메모리에 로딩되면서 다른 영역에 매핑
=> Section 1의 Virtual Size는 원본 파일의 Image Size와 동일, 압축 풀리면서 Section1에 기록됨
주의할 점 1)
RAW of EP = RVA of EP - RVA + PointerToRawData = 0x1018 - 0x1000 + 0x10 0x0 = 0x28 0x18
* PE 로더는 PointerToRawData를 FileAlignment(0x200)의 배수로 강제로 맞춰서 인식한다
주의할 점 2)
IMAGE_OPTIONAL_HEADER.DataDirectory[1] : RVA=0x271EE, Size=0x14
Raw of IDT = 0x271EE - 0x27000 + 0x10 0x0 = 0x1EE
RVA of INT = NULL, 그 뒤 8Byte = NULL, RVA of Name = 0x2, RVA of IAT = 0x11E8
RAW of Name = 0x2 // "KERNEL32.DLL" 제대로 있음
RAW of IAT = 0x11E8 - 0x1000 + 0x10 0x0 = 0x1E8 // 배열에 구조체 주소 두 개 존재 0x28, 0xBE
첫번째 구조체 RAW = 0x28 // Hint(0x10B) + "LoadLibraryA"
두번째 구조체 RAW = 0xBE // Hint(0x0) + "GetProcAddress"
* IID 구조체 배열이 들어갈 공간이 부족하다 (IDT는 섹션 3에 속해있는데, 0x200 부터는 섹션 2 영역)
* terminating NULL 구조체가 나타나지 않는다
* 세번째 섹션이 메모리에 로딩될 때 0x0~0x1FF 영역이 0x27000~0x271FF에 매핑되고 (File Alignment 0x200), 나머지 영역 (Virtual Size 0x1000)은 NULL padding으로 채워짐
* 파일 상태에선 PE 스펙에 어긋나 보이지만 실제 메모리에서는 IDT 제대로 존재
* OllyDbg 분석 시 DataDirectory 원소 수 때문에 "Bad or unknown format of win32 application" 오류 뜸
* 위에서 분석한 EP=1018 이용해 0x1001018(Image Base + EP RVA)를 new origin으로 setting
* LODS 명령어에 의해 EAX에 저장되는 값이 원본 파일의 OEP이다
* LODS 명령어 = ESI가 가리키는 주소의 데이터를 EAX로 로드함, ESI는 4 증가
Ollydbg로 분석해보니 압축 해제 과정은 크게 두 단계
1. 디코딩 루프: 두번째 섹션 데이터의 압축을 해제한 후, 첫번째 섹션에 Load 하는 과정을 반복
2. IAT 세팅: LoadLibraryA로 dll 로드한 후 GetProcAddress를 이용해 함수들의 주소 가져오는 과정을 반복
'security > 리버싱핵심원리' 카테고리의 다른 글
SetWindowsHookEx()을 이용한 Windows 메시지 후킹 (0) | 2023.03.15 |
---|---|
인라인 패치 - unpackme#1 (0) | 2023.03.14 |
PE 재배치 (0) | 2023.03.11 |
UPX 압축 (0) | 2023.03.11 |
tiny PE 분석 (0) | 2023.03.11 |