security/리버싱핵심원리

UPack 파일 분석 - HXD, Ollydbg

민사민서 2023. 3. 12. 17:25

* 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)의 배수로 강제로 맞춰서 인식한다

0x28 위치에는 문자열 존재
0x18 로 가면 제대로 된 EP code 만남

 

주의할 점 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 증가

PUSH EAX 이후 스택 주소에 Hardware BP 걸고 F9 하면 정확히 OEP에서 멈춘다

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