PE File Format and Packer - Inc0gnito 2016

83
2016 년 8 년 16 년 PE File Format & Packer KUICS 년년년

Transcript of PE File Format and Packer - Inc0gnito 2016

Page 1: PE File Format and Packer - Inc0gnito 2016

2016 년 8 월 16 일

PE File Format & PackerKUICS 장하진

Page 2: PE File Format and Packer - Inc0gnito 2016

KUICS 2

Who am I?

고려대학교 정보보호동아리 KUICS 12 대 회장 (2015.12 ~ 현재 ) 차세대 보안리더 양성프로그램 BoB 4 기 수료생

https://joveler.kr https://ied206.github.io https://github.com/ied206 http://www.slideshare.net/ied206

Page 3: PE File Format and Packer - Inc0gnito 2016

PE File Formatexe 파일의 정체는 ?

Page 4: PE File Format and Packer - Inc0gnito 2016

KUICS 4

PE File 이란 ?

Windows 에서 사용하는 실행 파일 포맷 Portable Executable 의 약자

대표적인 PE File Format- exe ( 실행 파일 )- dll ( 동적 링크 라이브러리 )- sys ( 드라이버 )

Page 5: PE File Format and Packer - Inc0gnito 2016

KUICS 5

PE File 구조

다음과 같은 구조로 이루어져 있다 .

DOS Header DOS Stub COFF File Header Optional Header Section Header Sections

- .text, .data 등

Page 6: PE File Format and Packer - Inc0gnito 2016

KUICS 6

PE File 구조 – 1) DOS Header & Stub

PE File 은 DOS 의 MZ 실행 파일 규격에 대한 하위 호환성을 지닌다 . MS-DOS 에서 Windows 의 exe 파일을 실행할 경우 다음과 같은

문구를 볼 수 있다 .

동일 exe 파일은 Windows 에서 다음과 같이 실행된다 .

즉 , 하나의 파일이 운영체제에 따라 다르게 실행된다 .

Page 7: PE File Format and Packer - Inc0gnito 2016

KUICS 7

PE File 구조 – 1) DOS Header & Stub

이러한 구조가 가능한 이유 ? PE File 은 DOS MZ 규격을 확장한 형태이다 .

DOS Header

DOS Stub

DOS 에서 PE File 을 실행하면 DOS Stub 을 실행하고 종료한다 . Windows 에서 PE File 을 실행할 때 , 이 DOS 관련 부분을 곧바로

건너뛴다 .

Page 8: PE File Format and Packer - Inc0gnito 2016

KUICS 8

PE File 구조 – 2) COFF File Header

PE File 은 MZ 포맷의 확장이기도 하지만 COFF 포맷의 확장이기도 하다 .

대표적으로 다음과 같은 값을 지닌다 .

Machine SizeOfOptionalHeader Characteristics

Page 9: PE File Format and Packer - Inc0gnito 2016

KUICS 9

PE File 구조 – 3) Optional File Header

PE File 이 메모리에 로드되기 위해 필요한 정보들이 이곳에 담겨 있다 .

AddressOfEntryPoint ImageBase SectionAlignment FileAlignment SizeOfImage SizeOfHeader Subsystem NumberOfRavAndSizes DataDirectory

Page 10: PE File Format and Packer - Inc0gnito 2016

KUICS 10

PE File 구조 – 3) Optional File Header

AddressOfEntryPoint- 처음 실행될 때 어디부터 시작할지 결정

ImageBase- 가상 메모리 주소에서 PE File 이 로드되는 기준 위치

FileAlignment & SectionAlignment- Section 의 크기는 반드시 특정 값의 배수여야 한다 .- 파일 상태 : FileAlignment 의 배수- 메모리 : SectionAlignment 의 배수

SizeOfImage- PE 파일이 메모리에 로드되었을 때 차지하는 크기

Subsystem- PE 파일이 실행될 때 사용하는 Windows 의 Subsystem

Page 11: PE File Format and Packer - Inc0gnito 2016

KUICS 11

PE File 구조 – 4) Section

실행 파일은 크게 기계어와 기계어가 사용하는 데이터로 이루어져 있다 . PE File 은 이들을 별도의 영역에 분리해 보관한다 .

.text- 기계어 코드

.data- 데이터 ( 전역변수 , 상수 등 )

.rsrc- 아이콘 등의 리소스

Page 12: PE File Format and Packer - Inc0gnito 2016

KUICS 12

PE File 구조 – 4) Section

각각의 Section 은 별도의 권한을 가진다 . Ex) Read, Write, Execute

.text- Read, Execute

.data- Read, Write

.rsrc- Read, Write

Page 13: PE File Format and Packer - Inc0gnito 2016

KUICS 13

PE File 구조 – 4) Section

Section Header- 각 섹션에 대한 정보가 담겨 있다 .

VirtualSize VirtualAddress (VirtualOffset)

- 섹션이 메모리에 로딩되었을 상태의 크기와 시작 위치- VirtualAddress 는 SectionAlignment 의 배수

SizeOfRawData (RawSize) PointerToRawData (RawOffset)

- 파일 상태일때의 섹션의 크기와 시작 위치- PointerToRawData 는 FileAlignment 의 배수

Characteristics- 섹션의 속성 (Ex 권한 )

Page 14: PE File Format and Packer - Inc0gnito 2016

KUICS 14

PE File 구조 – 4) Section

PE(File).text

.data

.rsrc

PE(Memory)

.text

.data

.rsrc

Page 15: PE File Format and Packer - Inc0gnito 2016

KUICS 15

VA & RVA

하나의 exe 파일이 실행될 때는 다음과 같이 메모리 구역을 용도에 맞게 나눠 사용한다 .

다양한 dll 도 함께 로드된다 .

Page 16: PE File Format and Packer - Inc0gnito 2016

KUICS 16

VA & RVA

Virtual Memory (VA)- 가상 메모리의 절대주소

Relative Virtual Memory (RVA)- Base Address 부터의 상대주소

PE File 내부의 메모리 주소는 RVA 로 표현되어 있다 . PE File 이 메모리에 올라갈 때 RVA 주소값은 절대주소인 VA 로

변환된다 . RVA 로 메모리 주소를 표현한 이유는 Base Address 는 로드시마다

다르게 바뀔 수 있기 때문이다 .

PE 파일을 조작하고 분석하기 위해선 RVA 와 RAW 의 관계를 잘 알아야 한다 .

Page 17: PE File Format and Packer - Inc0gnito 2016

KUICS 17

VA & RVA

다음 이유들로 인해 메모리와 파일 형태에 차이가 생긴다 . - FileAlignment 와 SectionAlignment 의 차이- RVA 의 사용

메모리 형태에서 본 주소를 PE 파일과 매핑하려면 , VA 와 RVA 사이의 관계를 알아야 한다 .

VA = BaseAddress + RVA RAW – PointerToRawData = RVA – VirtualAddress

PointerToRawData : 파일에서 RVA 가 속해 있는 섹션의 시작 위치

VirtualAddress : 메모리에서 RVA 가 속해 있는 섹션의 시작 위치

Page 18: PE File Format and Packer - Inc0gnito 2016

KUICS 18

PE File 구조 – 4) Section

PE(File).text

.data

.rsrc

PE(Memory)

.text

.data

.rsrc

Page 19: PE File Format and Packer - Inc0gnito 2016

KUICS 19

IAT

Import Address Table- dll 에서 불러 사용하는 함수의 주소값을 보관할 영역

dll 에서 불러 사용하는 함수의 주소는 PE 파일의 상태에 따라 다르다 .- 파일 형태에서는 RVA 로 표현되어 있다 .- 메모리에 로드되면 이 RVA 가 VA 값으로 바뀐다 .

Page 20: PE File Format and Packer - Inc0gnito 2016

KUICS 20

IAT

CloseHandle 의 주소가 0x400000 + 0x122B8 로 표기되어 있다 . 0x4122B8 를 통해 0x73BB9660 에 있는 Kernel32.dll 의 CloseHan-

dle 로 간다 .

dll 에 있는 함수를 호출하는 경우 , 이와 같이 IAT 를 활용한 간접 호출을 한다 .

Page 21: PE File Format and Packer - Inc0gnito 2016

KUICS 21

IAT

실행파일 내부에서 API 를 호출할 때 다음과 같은 과정을 거친다 .- 코드 -> API (X)- 코드 -> IAT -> API (O)

후자는 속도가 더 느려지지 않을까 ?

DLL 이 메모리에 로드될 때 ImageBase 값이 변경될 수 있다 . VA 는 ImageBase 값에 따라 변동된다 . 이러한 특징 때문에 API 의 주소를 VA 로 하드코딩할 수 없다 . 따라서 , API 의 주소는 dll 에 대한 RVA 로 적혀 있으며 dll 이

로딩되는 시점에 VA 로 변환된다 .

Page 22: PE File Format and Packer - Inc0gnito 2016

PE Packer 분석UPX 와 UPack 의 세계로 !

KUICS

Page 23: PE File Format and Packer - Inc0gnito 2016

KUICS 23

PE Packer

Packer 의 종류

Compressor- 실행 프로그램의 용량을 줄인다 .

Ex) UPX

Protector- 실행 프로그램의 역공학을 방해한다 .- 상용프로그램의 경우 , 핵심 알고리즘의 역공학을 막기 위해 사용

Ex) Themida- 악성코드는 백신 탐지를 어렵게 할 목적으로 사용

Ex) UPack

Page 24: PE File Format and Packer - Inc0gnito 2016

KUICS 24

Compressor : UPX

실행 압축계의 No1 패커- http://upx.sourceforge.net/

다양한 운영체제와 아키텍쳐를 지원한다 .- OS : Windows, macOS, Linux, FreeBSD, OpenBSD, NetBSD, MS-DOS 등- Arch : amd64, i386, arm, mips, powerpc 등

압축해제 속도가 매우 빠른 UCL 라이브러리를 사용- 실행 압축 특성상 압축해제가 빨라야 한다 .

작동 방법- 1) SFX 형태로 임시 폴더에 압축을 해제하여 실행 (extract to temp file)- 2) 실행되는 시점에 메모리에 압축 해제를 하고 실행 (in-place)- 대부분 2 번 in-place 방법을 사용

Page 25: PE File Format and Packer - Inc0gnito 2016

KUICS 25

Compressor : UPX

구조를 알아보기 위해 한 실행 프로그램을 패킹하고 , 분석해보자 .

패킹 전

- 다양한 섹션이 존재하는 것을 확인할 수 있다 .- 섹션의 용도에 맞는 권한들을 가지고 있다 .

Page 26: PE File Format and Packer - Inc0gnito 2016

KUICS 26

Compressor : UPX

패킹 중

212KB 가 175KB 로 줄어들었다

Page 27: PE File Format and Packer - Inc0gnito 2016

KUICS 27

Compressor : UPX

패킹 후

- rsrc 섹션을 제외한 나머지 섹션들이 사라졌다 .- UPX0, UPX1 모두 Read/Write/Execute 권한을 가지고 있다 .- UPX0 의 RawSize 는 0 이다 ( 파일 상태에서는 존재하지 않는다 ).- UPX0 의 VirtualSize 는 원본 파일의 섹션의 크기를 다 더한 것보다 크다 .- UPX1 은 RawSize 를 가지고 있으며 VirtualSize 의 크기와 같다 .- UPX1 에 EntryPoint 가 존재한다 .

이것들이 의미하는 바는 ?

Page 28: PE File Format and Packer - Inc0gnito 2016

KUICS 28

Compressor : UPX

패킹 후

가정- UPX1 섹션에 EP 가 존재하므로 , 압축해제 코드가 존재하리라 알 수 있다 .- UPX0 섹션의 RawSize 가 0 이지만 VirtualSize 는 값이 크다는 점에서 ,

이 프로그램이 실행되는 시점에 원래의 데이터가 UPX0 에 압축해제됨을 추측할 수 있다 .

- rsrc 섹션의 크기는 거의 똑같으므로 , 압축된 데이터는 UPX1 섹션에 존재할 것이다 .

- UPX0 섹션은 Read/Write/Execute 권한을 모두 가지고 있으므로 , code 섹션 (Read/Execute) 과 data 섹션 (Read/Write) 의 역할을 모두 할 것이다 .

Page 29: PE File Format and Packer - Inc0gnito 2016

KUICS 29

Compressor : UPX

패킹 후

섹션 Offset (ImageAddress + VirtualOffset)- UPX0 = 0x400000 + 0x01000 = 0x401000 (~0x436FFFF)- UPX1 = 0x400000 + 0x37000 = 0x437000 (~0x43CFFFF)

EntryPoint- EP = 0x400000 + 0x3CC50 = 0x43CC50- EP 는 UPX1 섹션에 존재한다 .

Page 30: PE File Format and Packer - Inc0gnito 2016

KUICS 30

Compressor : UPX

UPX 의 압축 해제 코드를 분석해보자 .

IDA 로 패킹된 프로그램을 열 경우 IAT 가 깨져있다는 경고가 나타난다 . -> UPX 는 압축시 IAT 를 건드린다는 점을 알 수 있다 .

Page 31: PE File Format and Packer - Inc0gnito 2016

KUICS 31

Compressor : UPX

패킹 전의 IAT

Page 32: PE File Format and Packer - Inc0gnito 2016

KUICS 32

Compressor : UPX

패킹 후의 IAT

압축 해제에 필수적인 API 만 제대로 표시되고 있다 .

Page 33: PE File Format and Packer - Inc0gnito 2016

KUICS 33

Compressor : UPX

패킹된 파일은 단 두개의 함수만을 가지고 있다 .

start 함수가 압축해제 코드일 가능성이 높다 .

Page 34: PE File Format and Packer - Inc0gnito 2016

KUICS 34

Compressor : UPX

start 함수는 PUSHA 로 시작하여 POPA ~ JMP 문으로 끝난다 .

Page 35: PE File Format and Packer - Inc0gnito 2016

35

Compressor : UPX

첫 부분에서 ESI 와 EDI 를 세팅하고 있다 .

어셈블리어에서 ESI 와 EDI 가 쓰일 경우 관용적으로 다음을 가리킨다 .- ESI : Source, 데이터를 읽어올 주소- EDI : Destination, 데이터를 쓸 주소

즉 , 다음 가능성이 높다 .- ESI : 압축된 데이터의 주소- EDI : 원본 데이터가 들어가야 할 위치

KUICS

Page 36: PE File Format and Packer - Inc0gnito 2016

36

Compressor : UPX

첫 부분에서 ESI 와 EDI 를 세팅하고 있다 .

세팅되는 값을 살펴보자 .- ESI = 0x437015- EDI = 0x401000

즉 , ESI 는 UPX1 섹션 , EDI 는 UPX0 섹션을 가리키고 있다 .- UPX0 = 0x401000 ~ 0x436FFFF- UPX1 = 0x437000 ~ 0x43CFFFF

KUICS

Page 37: PE File Format and Packer - Inc0gnito 2016

37

Compressor : UPX

[EDI] 에 쓰기를 하는 코드가 있는 곳이 패킹된 파일을 원래 상태로 복구하는 핵심 부분이다 .

KUICS

Page 38: PE File Format and Packer - Inc0gnito 2016

38

Compressor : UPX

CALL 을 만났다 . 뭐하는 녀석이지 ?

KUICS

Page 39: PE File Format and Packer - Inc0gnito 2016

39

Compressor : UPX

더 진행하면 CALL 로 함수를 호출하는 부분이 존재한다 .

KUICS

Page 40: PE File Format and Packer - Inc0gnito 2016

40

Compressor : UPX

동적 분석 결과 , LoadLibrary 와 GetProcAddress 를 호출하고 있음을 알 수 있다 .

KUICS

Page 41: PE File Format and Packer - Inc0gnito 2016

41

Compressor : UPX

UPX 로 패킹된 프로그램은 IAT Table 에 함수의 RVA 가 없어 불완전하다 .

LoadLibrary 로 dll 을 로드하고 그 주소를 EBP 에 저장한다 . dll 명단은 IAT 에서 직접 가져온다 .

KUICS

Page 42: PE File Format and Packer - Inc0gnito 2016

42

UPX 로 패킹된 프로그램은 IAT Table 에 함수의 RVA 가 없어 불완전하다 .

GetProcAddress 을 dll 주소 (EBP), 함수 이름 (EDI) 을 인자로 주고 호출한다 .

API 의 주소 (VA) 를 얻어 (EAX) EBX 가 가리키는 곳에 복사한다 .

Compressor : UPX

KUICS

Page 43: PE File Format and Packer - Inc0gnito 2016

KUICS 43

Compressor : UPX

마무리로 , 메모리 특정 구역의 권한을 설정한다 .

Page 44: PE File Format and Packer - Inc0gnito 2016

KUICS 44

Compressor : UPX

동적 분석 결과 , 다음과 같은 작업을 한다 .

VirtualProtect(0x400000, 0x1000, PAGE_READWRITE, &지역변수 );

VirtualProtect(0x400000, 0x1000, PAGE_READONLY, &지역변수 );

TlsCallback(…);

Page 45: PE File Format and Packer - Inc0gnito 2016

KUICS 45

Compressor : UPX

마지막 단계

POPA 명령으로 레지스터를 복구한다 . 그 뒤 원래의 EP 로 JMP 한다 .

Page 46: PE File Format and Packer - Inc0gnito 2016

KUICS 46

Compressor : UPX

패킹 전 원본 파일의 EP

Page 47: PE File Format and Packer - Inc0gnito 2016

KUICS 47

Compressor : UPX

패킹된 프로그램의 압축해제 전 ( 원본의 EP)

NULL Padding 만 존재한다 .

Page 48: PE File Format and Packer - Inc0gnito 2016

KUICS 48

Compressor : UPX

패킹된 프로그램의 압축해제 후 ( 원본의 EP)

원본과 같은 코드가 나타난 것을 볼 수 있다 .

Page 49: PE File Format and Packer - Inc0gnito 2016

KUICS 49

Compressor : UPX

UPX 압축해제가 정상적으로 끝난 상태에서 F9 를 눌러주면 ?

원본이 실행되듯이 정상적으로 잘 실행된다 .

Page 50: PE File Format and Packer - Inc0gnito 2016

KUICS 50

Compressor : UPX

결론

UPX 의 압축 해제는 다음과 같은 순서로 진행된다 . UCL 알고리즘으로 압축된 PE 섹션의 압축 해제 -> IAT 복구

Page 51: PE File Format and Packer - Inc0gnito 2016

KUICS 51

Compressor : UPX

사족 : 디버거의 빼애애액 패커가 적용되었을 때 디버거에서 BP 를 걸면 다음과 같은 경고 메시지가 뜬다 .

디버거는 EP 를 보고 어떤 섹션이 code 섹션인지 구분한다 . 패커가 EP 를 다른 섹션으로 바꿔버렸기 때문에 디버거에 혼동이 온 것 .

Page 52: PE File Format and Packer - Inc0gnito 2016

KUICS 52

Protector : UPack

PE 파일을 난독화시키는 패커이다 . 헤더를 꼬아 파일의 구조를 완벽하게 바꿔 버리기에 리버싱에 큰 지장이 온다 .

Windows 의 PE 로더가 PE 표준 규격보다 너그럽게 구현된 것을 악용한다 .

Page 53: PE File Format and Packer - Inc0gnito 2016

KUICS 53

Protector : UPack

원본 PE 파일 헤더 구조- 헤더들이 순서대로 붙어 있다 .

DOS MZ Header

COFFHeader

DOSStub

Optional Header

Page 54: PE File Format and Packer - Inc0gnito 2016

KUICS 54

Protector : UPack

UPack 으로 패킹한 후의 PE 헤더- 헤더들이 이리저리 꼬여 있다 .

DOS MZ Header

COFFHeader

Optional Header

Page 55: PE File Format and Packer - Inc0gnito 2016

KUICS 55

Protector : UPack

헤더 겹치기 Windows 는 DOS Stub 을 전혀 참고하지 않으며 , MZ Header 의 맨 마지막 값 , e_lfnew 값을 보고 PE 헤더의 시작점을 찾는다 .

PE 규격에 COFF Header 의 시작 오프셋은 정해져 있지 않다 . MZ Header 의 e_lfnew 값을 MZ Header 의 바깥이 아닌 ,

안을 향하게 만들어서 헤더를 겹치게 만든다 .

DOS MZ Header

COFFHeader

Optional Header

Page 56: PE File Format and Packer - Inc0gnito 2016

KUICS 56

Protector : UPack

Section 겹치기 + Alignment 꼬기

섹션의 메모리상 Offset (ImageAddress + VirtualOffset)- Sec01 = 0x400000 + 0x01000 = 0x401000 (~0x43BFFFF)- Sec02 = 0x400000 + 0x3C000 = 0x43C000 (~0x46DFFFF)- Sec03 = 0x400000 + 0x6E000 = 0x46E000 (~0x46EFFFF)

섹션의 파일상 Offset (PointerToRawData)- Sec01 = 0x000010 ~ 0x0001FF- Sec02 = 0x000200 ~ 0x02AAB7- Sec03 = 0x000010 ~ 0x0001FF

파일상 Offset 이 이상하다 ?

Page 57: PE File Format and Packer - Inc0gnito 2016

KUICS 57

Protector : UPack

Section 겹치기 + Alignment 꼬기

섹션의 파일상 Offset (PointerToRawData)- Sec01 = 0x000010 ~ 0x0001FF- Sec02 = 0x000200 ~ 0x02AAB7- Sec03 = 0x000010 ~ 0x0001FF

파일상 Offset 이 이상하다 ?- 파일상의 Offset 은 반드시 FileAlignment 의 배수여야 한다 .- 일반적으로 FlieAlignment 는 0x200 (512) 의 값을 가진다 .- 그런데 0x10 은 0x200 의 배수가 아니다 .

Windows 의 PE Loader 는 이 경우 강제로 배수에 맞춘다 .

Page 58: PE File Format and Packer - Inc0gnito 2016

KUICS 58

Protector : UPack

Section 겹치기 + Alignment 꼬기

즉 여기서 0x10 의 RawOffset 은 0x0 또는 0x200 으로 교정된다 .- 테스트 결과 0x00 으로 계산됨

실제 파일상 Offset (PointerToRawData)- Sec01 = 0x000000 ~ 0x0001EF- Sec02 = 0x000200 ~ 0x02AAB7- Sec03 = 0x000000 ~ 0x0001EF

RAW to RVA 를 계산할 때도 이 점에 유의해야 한다 .

Page 59: PE File Format and Packer - Inc0gnito 2016

KUICS 59

Protector : UPack

Section 겹치기 + Alignment 꼬기

EntryPoint (RAW) 를 계산해보자 . 헤더에 따르면 , EntryPoint (RVA) 는 0x00001018 이다 . 이 RAW 주소는 Sec01 및 Sec03 에 속한다 . RAW = RVA–VirtualOffset + RawOffset EP (RAW) = 0x1018 – 0x1000 + 0x10 = 0x28 (X)

그러나 RawOffset 이 0x10 으로 , 0x200 의 배수가 아니므로 0x0 으로 교정한다 .

EP (RAW) = 0x1018 – 0x1000 + 0x0 = 0x18(O)

Page 60: PE File Format and Packer - Inc0gnito 2016

KUICS 60

Protector : UPack

x64dbg 의 경우 , Sec01 에 진입을 시도할 시 크래시가 발생한다 .

Page 61: PE File Format and Packer - Inc0gnito 2016

KUICS 61

Protector : UPack

ImmunityDebugger

패킹된 프로그램의EP 로 접근하지못한다 .

Page 62: PE File Format and Packer - Inc0gnito 2016

KUICS 62

Protector : UPack

UPack 이 RAW to RVA 변환법을 꼬아놓기에 Immunity De-bugger 가 EP 를 제대로 계산하지 못해 발생하는 문제이다 .

EP 를 강제로 지정해야 디버깅이 가능하다 .

EP = ImageBase + EntryPoint (RVA)

EP = 0x400000 + 0x001018 = 0x401018

Page 63: PE File Format and Packer - Inc0gnito 2016

KUICS 63

Protector : UPack

EP 를 강제로 지정해야 디버깅이 가능하다 . Ctrl + G -> 00401018 (EP) 입력 New origin here 로 EP 강제 지정 .

Page 64: PE File Format and Packer - Inc0gnito 2016

KUICS 64

Protector : UPack

정상적인 PE 파일이 아니기에 Ctrl + G 를 통해 00401018 로 직접 이동하지 않으면 어셈블리 코드가 비정상적으로 표기된다 .

정상

디버거의 표시

Page 65: PE File Format and Packer - Inc0gnito 2016

KUICS 65

Protector : UPack

IDA Pro 는 ?

경고 5 관왕 달성 !

Page 66: PE File Format and Packer - Inc0gnito 2016

KUICS 66

Protector : UPack

4) Section 겹치기 + Alignment 꼬기

섹션의 파일상 Offset (PointerToRawData)- Sec01 = 0x000010 ~ 0x0001FF- Sec02 = 0x000200 ~ 0x02AAB7- Sec03 = 0x000010 ~ 0x0001FF

파일상 Offset 이 이상하다 ?- 파일상의 Offset 은 반드시 FileAlignment 의 배수여야 한다 .- 일반적으로 FlieAlignment 는 0x200 (512) 의 값을 가진다 .- 그런데 0x10 은 0x200 의 배수가 아니다 .

Windows 의 PE Loader 는 이 경우 강제로 배수에 맞춘다 .

Page 67: PE File Format and Packer - Inc0gnito 2016

KUICS 67

Protector : UPack

가정

Sec01 은 파일 상태의 크기는 작으나 , 메모리 상태의 크기는 크다 . Sec02 는 파일 상태의 크기와 메모리 상태의 크기가 모두 크다 . Sec03 은 파일 상태의 크기와 메모리 상태의 크기가 모두 작다 .

용량으로 보아 Sec02 에 압축된 원본 데이터가 존재하리라 추측할 수 있다 .

Sec01 이 Sec02 보다 메모리 상태의 크기가 더 크다 . 이를 통해 Sec01 에 원본 데이터가 압축해제 된다는 점을 추측할 수

있다 .

Page 68: PE File Format and Packer - Inc0gnito 2016

KUICS 68

Protector : UPack

EP 에서 몇가지 연산을 수행한 이후 0x004667A3 으로 JMP 한다 .

Page 69: PE File Format and Packer - Inc0gnito 2016

KUICS 69

Protector : UPack

0x4667A3 이후부터는 CALL DWORD PTR [ESI] 구문이 자주 등장한다 .

Page 70: PE File Format and Packer - Inc0gnito 2016

KUICS 70

Protector : UPack

CALL DWORD PTR DS:[ESI] 실행시 0x46675B 함수를 호출한다 .

인자를 EAX 와 EDX 로 받는다 . 자주 호출되는 것을 보아 압축 해제를 담당하는 코드일 가능성이 높다 .

Page 71: PE File Format and Packer - Inc0gnito 2016

KUICS 71

Protector : UPack

[ESI] 뿐만 아니라 [ESI+54], [ESI+50] 도 호출하고 있다 .

Page 72: PE File Format and Packer - Inc0gnito 2016

KUICS 72

Protector : UPack

BP 를 걸고 F9 를 계속 눌러보자 .

Page 73: PE File Format and Packer - Inc0gnito 2016

KUICS 73

Protector : UPack

원본 프로그램의.text 섹션

패킹된 프로그램디버깅 중 살펴본동일 영역

압축 해제가 이루어지고 있다 .

Page 74: PE File Format and Packer - Inc0gnito 2016

KUICS 74

Protector : UPack

이 시점에서 다시 IAT 를 살펴보자 .

IAT 를 복구할 때 필요한 두 API 만 여기에 존재한다 . 원래의 IAT 명단을 복구해야 하므로 , IAT 를 복구하는 코드가 존재할

것이다 .

Page 75: PE File Format and Packer - Inc0gnito 2016

KUICS 75

Protector : UPack

그런데 이 주소를 직접 부르고 있지 않아 정적 분석으로는 추적이 불가능하다 !

동적 분석 중 0x4011E8 나 0x4011EC 를 CALL 하는 부분을 찾자 . 모든 CALL 에 BP 를 걸고 진행하며 찾다보면 나오지 않을까 ?

Page 76: PE File Format and Packer - Inc0gnito 2016

KUICS 76

Protector : UPack

0x466923 LoadLibraryA("GDI32.DLL");

Page 77: PE File Format and Packer - Inc0gnito 2016

KUICS 77

Protector : UPack

0x46693A GetProcAddress([HANDLE of GDI32.DLL], "BitBlt");

Page 78: PE File Format and Packer - Inc0gnito 2016

KUICS 78

Protector : UPack

EAX 에 BitBlt 값이 반환되고 , STOS 를 통해 EAX 의 값을 [EDI]에 복사한다 .

Page 79: PE File Format and Packer - Inc0gnito 2016

KUICS 79

Protector : UPack

F9 를 반복해서 눌러 상황을 보자 .

IAT 가 복구되고 있다 .

Page 80: PE File Format and Packer - Inc0gnito 2016

KUICS 80

Protector : UPack

IAT 를 복구한 뒤 원래의 EP 로 JMP 한다 .

패킹 전 원본 파일

패킹 복구 후

Page 81: PE File Format and Packer - Inc0gnito 2016

KUICS 81

Protector : UPack

결론

UPack 도 UPX 와 마찬가지로 실행시 압축 해제 -> IAT 복구 순서를 거친다 .

용량을 줄이기 위해 압축만 하는 UPX 와는 달리 , UPack 은 PE 헤더의 값을 꼬아 분석의 난이도를 높인다 .

결과적으로 리버싱과 같은 바이너리 분석을 크게 방해한다 .

Page 82: PE File Format and Packer - Inc0gnito 2016

Q&A

KUICS

Page 83: PE File Format and Packer - Inc0gnito 2016

05/03/2023 동아리이름