본문 바로가기

REVERSING

[SWING] Reversing 10

패킹

 

비손실 압축 (LOSSLESS DATA COMPRESSION)

- 압축된 파일을 100% 복원 가능한 경우
- 파일 크기를 줄여서 보관 및 이동에 용이하도록 하려는 목적
- 7-zip, 빵집과 같은 압축 프로그램으로 파일을 압축시키는 경우
- 대표적인 비손실 압축 알고리즘: Run-Length, Lempel-Ziv, Huffman

 

손실 압축 (LOSS DATA COMPRESSION)

- 원래대로 복원할 수 없는 경우
- 파일(데이터)에 의도적인 손상을 주어서 그 대가로 압축률을 높이는 목적
- 주로 멀티미디어 파일들(jpg, mp3, mp4)은 손실 압축기법
- mp3의 핵심 알고리즘은 가청 주파수 범위를 벗어나는 영역 제거

 

실행 압축

- PE 파일을 대상으로 파일 내부에 압축해제 코드를 포함하고 있어서 실행되는 순간에 메모리에서 압축을 해제시킨 후 실행시키는 기술
- 파일 내부에 원본 PE 파일과 decoding 루틴이 존재
- EP (실행 시작 위치, Entry Point) 코드에 decoding 루틴이 실행되면서 메모리에서 압축을 해제시킨 후 실행된다

 

패커 (PACKER)

- PE 패커(Packer)란 실행 파일 압축기
- 정확한 명칭은 Run-Time 패커로, PE 파일 전문 압축기
- PE 파일의 크기를 줄이고자 하는 목적
- 내부 코드와 리소스를 감추기 위한 목적
- 순수한 의도의 패커: UPX, ASPack 등
- 불순한 의도의 패커: UPack, PESpin, NSAnti 등

 

프로텍터 (PROTECTOR)

- PE 파일을 리버싱으로부터 보호하기 위한 유틸리티

- 일반적인 패커처럼 실행 압축을 해주는 것만이 아닌 리버싱을 막기 위한 다양한 기법이 추가

- 기법 : 안티 디버깅(anti-debugging), 가상 머신 탐지(anti-vm), 코드 난독화(code obfuscating), 다형성 코드(polymorphic code), 더미 코드(garbage code), 디버거 탐지(debugger detection)
- 원본 PE 파일 크기 < 프로텍터로 압축된 PE 파일의 크기
- 크래킹 방지, 코드 및 리소스 보호 목적
- 상용 프로텍터: ASProtect, Themida, SVKP 등
- 공개용 프로텍터: UtraProtect, Morphine 등



UPX 실행 압축된 notepad_upx.exe를 디버깅

UPX 실행 압축된 notepad_upx.exe를 디버깅하여 실행압축에 대한 개념을 이해하는 것이 목표이다. 즉, 코드를 트레이싱하면서 원본 notepad.exe 코드를 찾아내는 것이라고 할 수 있다.

 

https://github.com/upx/upx/releases

 

위의 링크에서 upx-3.96-win64.zip 을 다운받는다.

 

 

 

 

코드 트레이싱 명령

 

 

위의 것이 원본 EP 코드이고 아래의 것이 실행 압축된 메모장의 EP 코드이다.

 

 

 

Notepad_upx.exe를 디버거로 열어보면 위와 같이 UPX EP 코드가 나타난다. 

 

UPX 파일 트레이싱을 해볼 것인데, 이때 루프(Loop)를 만나면 그 역할을 살펴본 후 탈출한다 라는 방대한 코드에 대한 원칙이 있다고 한다. 압축 해제 과정은 무수히 많은 루프의 연속임으로, 적절히 루프를 탈출할 줄 알아야 한다. 방대한 코드를 트레이싱 할 때는 일반적인 Step Into(F7)을 사용하지 않고, 디버거에서 별도로 제공되는 명령을 사용한다.

 

Animate Into(Ctrl+F7) : Step Into 명령 반복 (화면 표시 O)

Animate Over(Ctrl+F8): Step Over 명령 반복 (화면 표시 O)

Trace Into(Ctrl+F11): Step Into 명령 반복 (화면 표시 X)

Trace Over(Ctrl+F12): Step Over 명령 반복 (화면 표시 X)

 

애니메이트 명령어와 트레이스 명령어로 나뉘는데, 애니메이트 명령어는 트레이싱 과정이 화면이 표시되기 때문에 속도가 느리다는 점이 있다. 트레이스 명령어는 미리 설정한 트레이스 조건에서 자동으로 멈출 수 있고, 로그를 남길 수도 있다는 장점이 있다. 이번 UPX 파일 트레이싱에서는 Animate Over(Ctrl+F8)을 사용할 것이다.

 

 

EP 코드에서 Animate Over(Ctrl+F8)을 누르면 트레이싱이 시작되면서, 커서가 계속 루프를 돌 것 이다. 조금 진행하다 보면 짧은 루프가 나타나는데, Step Into(F7)을 눌러 트레이스를 멈추고 해당 루프를 살펴보자.

 

 

첫번째 루프문

 

위에 보이는 사진의 범위를 계속해서 반복한다. 루프의 내용을 보면, EDX(01001000)에서 한 바이트를 읽어 EDI에 쓰는 것이다. EDI가 가리키는 01001000의 주소는 첫 번째 섹션(UPX0)의 시작 주소이며, 메모리에서만 존재하는 섹션이다.

 

 

이러한 루프를 빠져 나오기 위해서 반복문의 마지막줄 아래에 Break Point(F2)를 설정해주고, 실행명령(F9)를 이용해 탈출한다.

 

 

두번째 루프문

 

 

 

두번째 루프문은 이전보다 꽤 길다. 두번째 루프가 본격적인 디코딩 루프, 또는 압축해제 루프라고 할 수 있다. ESI가 가리키는 두번째 섹션의 주소에서 차례대로 값을 읽어서 적절한 연산을 거쳐 압축을 해제하여, EDI가 가리키는 첫번째 섹션의 주소에 값을 써주는 형식으로 돌아가고 있다. 위에서 AL(EAX)에는 압축 해제된 데이터가 있고, EDI는 첫번째 섹션의 주소를 가리키고 있다.

 

세번째 루프문

 

 

또다시 Ctrl+F8을 사용해 트레이싱을 시작하면 위와 같은 세번째 루프를 만날 수 있다. 이 루프는 원본 코드의 CALL/JMP 명령어의 destination 주소를 복원시켜주는 코드이다. 반복되는 구간은 010153FA 부터 01015401 까지인듯 하다. 0105426주소에 BP를 걸어주고 탈출하면 된다.

 

네번째 루프문

 

 

반복되는 구간은 위와 같지만 중요한 구간은 아래와 같다.

 

 

더 내려가다 보면 위와 같은 네번째 루프가 나타난다. 이 부분이 바로 IAT를 세팅하는 루프이다. 일반적인 실행 압축 파일은 원본 파일의 코드, 데이터 ,리소스의 압축 해제 과정이 끝나면 IAT를 세팅하고 OEP로 간다. 01015426 주소에서 EDI 01014000으로 세팅되고, 이곳이 두번째 섹션영역이다.

 

 

마지막에 0100739D는 처음에 UPX 실행 압축하기 전의 PUSH 70 의 코드와 같다.

 

 

UPX OEP를 빨리 찾는 방법

1. POPAD 명령어 이후의 JMP 명령어에 BP 설치

UPX 패커의 특징 중 하나는 EP 코드가 PUSHAD/POPAD 명령어로 둘러싸여 있다는 것이다. 여기서 PUSHAD 8개의 범용 레지스터의 값을 스택에 저장하는 명령어이고, POPAD PUSHAD 명령에 의해서 스택에 저자된 값을 다시 각 레지스터들에게 입력하는 명령어이다. OEP코드로 가는 JMP 명령어가 POPAD 명령어 바로 이후에 나타나기에,  JMP명령어에 BP를 설치하고 실행하면 바로 OEP로 갈 수 있다.


2. 
스택에 하드웨어 브레이크포인트 설치

이 방법도 PUSHAD/POPAD의 특성을 이용하는 것이다. 하드웨어 BP CPU에서 지원하는 브레이크 포인터로, 4개까지 설치 가능하며, 일반적인 BP와는 다르게 BP 설치된 명령어가 실행된 이후에 제어가 멈추게 된다.

 

 

 

 

언패킹

 

언패킹이란

- 패킹된 실행 파일을 패킹하기 전 상태로 되돌리는 것

- 실행 압축된 프로그램은 실행되어 언패킹 코드가 먼저 수행된다.

- 언패킹 과정을 통해서 패킹되기 전의 상태를 복원하고, EP를 실제 실행할 위치 OEP(Original Entry Point)로 옮겨준다.

 

언패킹의 목표

 - 언패킹을 수행하기 위해서는 패킹된 실행 파일에서 언패킹을 수행하는 코드를 추출할 필요가 있다. 언패킹 코드는 대부분 반복 작업을 수행하는 루프 형태의 코드가 많다. 그러나 일부만 언패킹하고 실행한 다음 다시 일부 코드를 언패킹하는 과정을 반복하도록 만들 수도 있어 수동 언패킹을 이해할 필요가 있다.

 

언패킹 방법

- 자동 : 도구로 PEiD, PE Explorer 등이 있다.

- 수동 : 디버거나 스크립트를 사용하는 방법

 

- 먼저 디버거를 사용하여 OEP를 찾고 해당 영역의 메모리를 덤프 하여 저장한 후에 파일을 재구성

- 그리고 OEP를 찾기 위해 디버거를 사용하여 언패킹 과정을 분석 후 디버거 스크립트를 작성

- 수동 언패킹 과정에서는 IAT 복구와 EP 재설정과 같은 작업이 동반된다.

 

언패킹 과정

 

  1. 운영체제의 Loader가 패킹된 실행파일을 메모리에 로딩한다.
  2. 패킹된 파일의 진입점(Entry Point)부터 프로그램이 시작된다. 이 때, 패킹된 파일의 진입점은 Unpacking Code 영역 내에 있다.
  3. Unpacking code에서 Packed Data를 하나씩 읽어 압축을 풀고 Empty Space에 원본 코드(Original Data)를 저장한다.
  4. 모든 데이터가 언패킹 되면 원 진입점(Original Entry Point; OEP)에서부터 프로그램이 다시 시작된다.

 

'REVERSING' 카테고리의 다른 글

리버싱 5주차  (0) 2024.05.08
리버싱 스터디 5~8주차  (1) 2024.01.31
[SWING] Reversing 09  (0) 2023.05.13
[SWING] Reversing 08  (0) 2023.04.30
[SWING] Reversing 07  (0) 2023.04.02