HyeM

[3]패킹&UPX패킹(디버거로 언패킹) 본문

Study/Reversing

[3]패킹&UPX패킹(디버거로 언패킹)

Hailey_HyeM207 2020. 10. 26. 22:25

00. 데이터 압축

  • 비손실 압축 : 파일(데이터)크기를 줄여 보관, 이동에 용이하도록 함.
    압축프로그램 이용하여 파일 압축. 
    대표 비손실 압축 알고리즘 : Run-Length, Lempel-Ziv, Huffman 

  • 손실 압축 : 파일(데이터)에 의도적인 손상 줌. 압축률 높임. ex. jpj,mp3, mp4 대부분은 손실 압축 기법

  • 실행 압축 : PE파일 내부에 압축 해제 코드를 포함하고 있어, 실행되는 순간 메모리에서 압축 해제 시켜 실행함.
    실행 압축된 것도 PE파일. 내부엔 '원본 PE 파일 + decoding 루틴' 존재 -> EP코드에서 decoding 루틴이 실행되면서 압축해제시켜 실행함.

항목 일반 압축 실행 압축
대상 파일  모든 파일  PE파일 (exe, dll, sys)
압축 결과물 압축(zip,rar)파일 PE파일 (exe, dll, sys)
압축해제 방식 전용 압축해제 프로그램 사용 내부의 decoding 루틴
파일 실행 여부 자체 실행 불가능 자체 실행 가능
장점 모든 파일에 대해 높은 압축율 별도의 해제 프로그램 없이 바로 실행 ok
단점 전용 압축 해제 프로그램이 없으면 해당 압축 파일 사용 못함 실행할 때 마다 decoding 루틴이 호출되기 때문에, 실행시간이 아주 미세하게 느려짐

 

 

 

01. 패커  

: 일반 PE 파일을 실행 압축 파일로 만들어주는 유틸리티 (실행 파일 압축기, Run-Time 패커)

 Anti-Reversing 기법에 특화된 패커를 '프로텍터'라고 함.

 

: 사용목적

  1.  PE파일 크기 줄임
  2.  PE 파일 내부코드와 리소스(문자열 , API, name String) 감춤

: 사용현황 

최근엔 유틸리티, 패치 파일, 일반 프로그램 등 널리 사용됨.

 

: 패커종류

크게 두 종류

  • 순수한 의도의 패커(VirusTotal에서 진단 안됨.) : 평범한 PE파일 만듦 _ UPX, ASPack 등
  • 불순한 의도의 패커(VirusTotal에서 진단 됨.) : 원본 파일 크게 변형, PE헤더 심하게 훼손시킴 _ UPack, PESpin, NSAnti 등

 

 

02. 프로텍터

 : PE파일을 'Reverse Code Engineering'으로 부터 보호하기 위한 유틸리티

- 패커처럼 실행 압축 + 리버싱 막기 위한 다양한 기법 적용(Anti-Debugging, Anti-Emulating, Code Obfuscating 등)

- 디버깅 하기 어려움

 

: 사용목적 

  1. 크래킹 방지
  2. 코드 및 리소스 보호

: 사용 현황

- 크래킹에 민감한 보안 프로그램(ex. 게임 보안 프로그램)

- 일반적인 악성코드(Trojan, Worm)에서 사용.  _ AV제품의 진단을 막거나 늦추기 위해 사용

 

: 프로텍터 종류

  • 공개용 프로텍터 : UltraProtect, Morphine 등
  • 상용 프로텍터 : ASProtect, Themida, SVKP 등

 

03. UPX 실행 압축 &  디버거로 OEP 찾기(언패킹) (실습) 

사용할 패커 : UPX (x32버전)

압축 대상 : notepad.exe (win7 32bit) 

실습환경 : win 7 32bit

 

upx 다운받아, notepad 압축시킴
notepad_upx.exe새로 생긴거 확인

upx 다운 받아서, 위의 명령어로 notepad.exe파일을 실행 압축한다.

이를 pe viewer로 보면 다음과 같다.

 

notepad_upx.exe의 SizeofRawData는 0

사진을 보면 VirtualSize는 28000인데, SizeOfRawData는 0인것을 볼 수 있다.

이유 : UPX로 실행 압축된 파일이 실행 되는 순간, 압축된 코드를 첫번째 섹션에 푼다.

      +  두번째 섹션에 압축해제코드와  있음.

 

지금 부터는 upx 압축한 notepad_upx.exe파일을 디버거로 열어 OEP를 찾아가는 과정에 대한 실습이다.

 OEP : Original Entry Point _ 패킹된 파일의 실제 시작 부분이다.

 참고로 notepad_upx.exe로 확인한 프로그램 시작 부분 코드는 다음과 같다.

 

 


 

notepad_upx.exe의 EP Code

notepad_upx.exe를 x32dbg로 열면 다음과 같다. 

pushad와 ESI,EDI 값 세팅

EP주소는 009E21B0 이고, 이 부분은 두 번째 섹션의 끝 부분이다.

코드를 보면 PUSHAD 명령으로 EAX~EDI 레지스터 값을 스택에 저장한다. 그리고 

ESI두번째 섹션 시작 주소(00D8 9000)를,

EDI에는 첫 번째 섹션 시작 주소(00D6 1000)로 세팅한다. 

 

뒤의 코드 흐름을 미리 예측해 보면 다음과 같다.

UPX파일에서 첫번째 섹션은 메모리에서만 존재하고, 압축 해제된 원본 파일의 코드가 저장될 것이다.

ESI 가 가리키는 버퍼에서 EDI가 가리키는 버퍼로 메모리 복사 발생할 것이다.

(ESI에서 데이터를 읽어 압축 해제 후, EDI에 저장시킴)

 

트레이싱 시작전에 덤프 부분확인 


UPX파일 트레이싱

# 루프1

첫번째 루프

esi 의 값을 al로 옮김

esi++

al값을 edi로 옮김

edi++

ebx+=ebx

0이 아니라면 D121D1분기

뒤에 값이 더 크면 D121C0로 분기

 

루프의 내용은 ESI(009D 9000)에서 한 바이트를 읽어 EDI(009B 1000)에 쓰는 것이다. 즉, 두번째 섹션에서 첫번째 섹션에 바이트를 읽어 쓰는 것이다. 

루프를 빠져나오기 위해, 009121D3에 BP를 걸고 F9로 탈출한다.

 

 

#루프2

두번째 루프(끝부분)

두번째 루프는 크게 돌게 되는데, 이 루프에서는 첫번째 섹션 영역(00D6 1000)에 압축해제 된 코드를 쓰게 된다.

==> 본격적인 디코딩(decoding) 루프.(압축해제 루프)

두번째 섹션주소(UPX1)에서 차례대로 값을 읽어, 연산을 거친후, 압축해제하여 EDI가 가리키는 첫번재 섹션(UPX0)의 주소에 값을 써준다. 

여기서 핵심 명령어는 다음과 같다.

mov byte ptr ds:[edi], al
inc edi

mov dword ptr ds:[edi], eax
add edi, 0x4

이 루프를 탈출하기 위해, 00D9 227A에 BP를 두고 F9로 탈출한다.

그러고 나서 ESI와 EDI가 가리키고 있던 덤프 창을 확인해보면, 00으로 채워졌던 첫번째 영역 부분에 압축해제된 코드들로 쓰여진 것을 확인할 수 있다.

시작시 덤프와 비교해보면, EDI부분에 코드가 쓰여졌다.

 

 

#루프3

세번째 루프

이 부분은 원본 코드의 CALL/JMP 명령어의 destination 주소를 복원시켜주는 코드 이다.

이 루프도 역시 009D22AE에 BP를 걸고 F9로 탈출한다.

 

 

#루프 4

4번째 루프

이 부분은 IAT를 세팅하는 루프이다.

00D9 22AE주소에서 EDI= 00D9 0000 로 세팅되고, 이곳은 두 번째 섹션(UPX1)영역이다.

이 주소(00D9 0000)에는 원본 notepad.exe에서 사용되는 API이름 문자열이 저장되어 있다.

API 이름 문자열

이 문자열은 UPX가 notepad.exe를 실행 압축할때, 원본 파일의 IAT를 분석하여 사용하는 API이름 목록을 따로 뽑아 놓은 것이다.

 

API이름 문자열이 저장된 곳을 가리키는 EDI에서 연산을 통해 문자열을 하나씩 뽑아(=API이름 하나씩 뽑아), 

00D9 22E8주소의 GetProcAddress()를 호출하여 API시작 주소를 얻어, EBX가  레지스터가 가리키는 원본 notepad.exe의 IAT 영역에 API주소를 입력한다.

이 과정을 API 이름 문자열이 끝날때까지 반복하면 , 원본 notepad.exe의 IAT 복원과정이 마무리 된다.

 

==>원본 notepad.exe의 압축 해제 모두 완료. 남은 단계는 OEP로 제어 돌려주는 것이다. 

 

 

 

#마지막 OEP로 이동

JUMP to OEP(디버거 재시작으로 명령어 주소가 위의 실습 사진들과 다름)

루프4를 빠져나온 뒤, 코드 몇개를 지나고 나면 popad 명령어를 만날 수 있는데 ,

POPAD명령어는 위에서 봤던 UPX 코드 중 가장 첫 번째 명령어인 PUSHAD에 대응하는 명령어로, 레지스터를 원래대로 복원시키는 명령어이다.

최종적으로, 'jmp notepad_opx. 323689' 명령어로 OEP로 간다. JMP하는 323689주소는 원본 notepad.exe 의 EP주소로 확인가능하다. 

원본 notepad.exe의 EP코드
notepad_upx.exe에서 찾은 OEP

원본 notepad를 열어, EP코드를 위에서 jump한 OEP코드와 비교하니 같은 것을 확인할 수 있다.

==> OEP 코드 찾기 완료 <==

 

 

 

 

 

04. 디버거로 OEP 찾기(언패킹)_빠르게 찾는 방법 

1. UPX 패커의 특징인 , EP코드가 PUSHAD/POPAD명령어로 둘러쌓인 것을 이용하여, POPAD명령어 이후의 JMP명령어에 BP 설치

  1. POPAD 명령어 이후의 JMP명령어에 BP설치
    UPX 패커의 특징으로 EP코드가 PUSHAD/POPAD명령어로 둘러 쌓인 것이니, POPAD명령어 이후 JMP명령어에 BP를 걸어 한번에 OEP코드로 이동한다.
  2. 스택에 Hardware Break Point설치이 방법 역시 UPX 특징인 PUSHAD/POPAD 명령어 특성을 이용한 것이다.
    Hardware BP란 CPU에서 지원하는 BP로, 일반적인 BP와 달리, BP설치된 명령어가 실행된 이후에 제어가 멈추게 된다.

레지스터
PUSHAD명령어 이후 스택 모습

PUSHAD 명령어를 실행하면 , 레지스터 값이 스택에 저장된 것을 확인할 수 있다.

덤프창에서 저 스택주소(0008 FAEC)로 이동하여, 마우스 커서를 이 주소에 정확히 위치시킨후, 우클릭하여 하드웨어 BP를 설치한다.

HardwareBP설치

설치한 후, 이 상태로 실행하면 압축이 해제가 되면서 코드가 실행되고, POPAD를 호출한 순간에  하드웨어 BP가 설치된 0008 FAEC주소를 엑세스 하고 그때 제어가 멈춘다. 그러면 밑에 바로 OEP로 가는 JMP명령어를 만날 수 있다.

 

 

'Study > Reversing' 카테고리의 다른 글

DLL Injection(개념+실습)  (0) 2020.11.05
[3]IAT, EAT 로딩 과정  (0) 2020.10.25
[3]Dreamhack_Rev 4번 문제  (0) 2020.10.12
[3]Dreamhack_Rev 5번 문제  (0) 2020.10.12
[2]PE구조&wow64 fs redirection + a  (0) 2020.09.20
Comments