1. 패킹 (Packing)
패킹은 압축의 한 종류로 볼 수 있는데, 패킹은 실행 압축을 의미한다.
일반적으로 흔히 알고 있는 압축(zip, rap)은 압축을 해제 시켜야 해당 프로그램을 실행할 수 있다. 하지만 패킹은 있는 그대로 일반 프로그램처럼 실행이 가능하다.
실행(PE) 파일을 대상으로 파일 내부에 압축해제코드를 포함하고 있어 실행되는 순간에 메모리에서 압축을 해제 시킨 후 실행시키는 기술이다. 다시 말하면 압축을 푸는 과정 없이 바로 프로그램을 실행할 수 있는 것을 실행 압축이라고 한다.
패킹을 하는 이유
패킹을 하는 이유에는 여러 가지가 있다.
- 데이터 압축 (프로그램 크기 줄이기)
- 악성코드에서는 작은 용량으로 빠르게 많이 퍼지게 하여, 분석이 불가능하도록 하기 위한 목적
- 데이터 보호: anti-reversing, anti-diassembling, anti-dumping
- 취약하게 나타날 수 있는 중요 정보를 포함한 어플리케이션에 대한 노출 최소
1-1. 여러 가지 압축
1) 비손실 압축
원본의 데이터를 훼손하지 않고 용량을 줄이는 것을 비손실(또는 무손실) 압축이라고 한다. 파일의 크기를 줄여서 보관과 이동에 용이하도록 하려는 목적을 가지고 있다. 파일을 사용할 때는 해당 압축을 해제해서 사용한다. (이 과정에서 무결성이 보장되어야 한다.)
이 방식은 크기만 줄일 뿐 실제 데이터의 손실은 없기 때문에 완벽하게 복원이 가능하다.
Ex) zip
2) 손실 압축
파일에 의도적으로 손상을 주어 압축률을 높이는 것을 손실 압축이라고 한다. 압축을 하는 과정에서 원본 데이터가 손실되기 때문에 원본으로 되돌릴 수 없다. 주로 멀티미디어 파일들에서 사람이 자각하기 힘든 범위의 데이터를 버리고 압축하는 방법을 사용한다. 데이터 측면에서 볼 때 차이가 많이 발생한다. 하지만 사람이 보기에는 그 차이가 거의 구분할 수 없을 수준이기 때문에 많이 사용되는 압축 방법이다.
3) 일반 압축 vs 실행 압축
일반 압축은 위에서 봤던 비손실 압축과 손실 압축으로 나뉘어진다.
실행 압축은 실행(PE, Portable Executable)파일을 대상으로 파일 내부에 압축해제 코드를 포함하고 있어 실행되는 순간에 메모리에서 압축을 해제 시킨 후 실행되는 기술이다.
항목 | 일반 압축 | 실행 압축 |
대상 파일 | 모든 파일 | PE 파일(exe, dll, sys) |
압축 결과물 | 압축(zip, rar) 파일 | PE 파일(exe, dll, sys) |
압축해제 방식 | 전용 압축해제 프로그램 사용 | 내부의 decoding 루틴 |
피일 실행 여부 | 자체 실행 불가 | 자체 실행 가능 |
장점 | 모든 파일에 대해 높은 압축율로 압축 가능 | 별도의 해제 프로그램 없이 바로 실행 가능 |
단점 | 전용 압축해제 프로그램이 없으면 해당 압축 파일을 사용할 수 없다. | 실행할 때마다 decoding 루틴이 호출되기 때문에 실행시간이 아주 미세하게 느려진다. |
1-2. 패킹

위에서 계속 언급했던 바와 같이 패킹이란 프로그램의 코드를 압축시키는 것이라고 볼 수 있다. 프로그램 코드 크기를 줄이기 위해 압축(Compressing)하거나, 프로그램 분석을 어렵게 만들기 위해서 암호화(Protecting)하는 것이다.
패킹은 Compressor와 Protector 두 가지로 나뉜다.
- 컴프레싱(Compressing): 단순 압축하는 것
- 초기엔 메모리와 하드디스크 용량이 작아 프로그램 크기를 줄이기 위해 컴프레싱 기술 사용
- 실행 코드를 압축해서 PE 파일의 특정 섹션에 저장한 후, 프로그램이 실행될 때 공간에 압축을 풀어 실행하는 구조
- 요즘엔 파일 배포 시 전송 시간과 데이터 요금을 줄이기 위해 압축 사용
- 프로텍팅(Protecting): 실행 파일을 암호화해서 분석을 어렵게 하는 기술
- 프로그램의 소스 코드를 숨기려는 목적 (분석의 어려움)
- 실행 코드를 암호화된 상태로 배포하고, 실행 시점에서 복호화하여 동작을 수행
- 속도 저하
2. 언패킹
기본 원리는 실행 압축 프로그램이 실행되는 어느 시점에서는 압축되기 전 상태로 돌아가야 하며, 그 때 메모리 상태를 Dump(메모리 내용을 그대로 파일로 저장)하고, 엔트리 포인트를 압축하기 전 위치로 설정해주면 된다는 점이다. 어느 시점을 OEP(Original Entry Point)라고 하며, PEP(Packed Entry Point, 실행 압축 된 프로그램에서 처음 시작하는 코드위치)와 비교한다. 이 OEP만 찾을 수 있다면 실행 압축 해제는 아주 쉽게 이루어질 수 있다.
> EntryPoint?
프로그램에 대한 제어권이 운영체제에서 사용자 코드로 넘어가는 지점
프로세서가 메모리에 있는 Code Section으로 처음 들어가는 지점
EntryPoint 위치는 PE 헤더의 AddressOfEntryPoint에 저장된다. 이 위치는 상대 주소이므로, PE 헤더의 Image Base 값과 합한 메모리 주소가 프로세서가 인식하는 실제 EntryPoint 주소이다.
> OEP?
패킹된 파일의 실제 프로그램 시작 부분. OEP 이전의 실행 부분은 패킹된 파일이 메모리에 로드되어 압축을 푸는 명령어가 들어있다.

패킹된 파일은 원본 코드를 정상적으로 실행하기 위해 언패킹 루틴을 가지고 있고, 언패킹 루틴이 정상적으로 제 역할을 다하면 원본 코드가 동작하게 된다. 여기서 언패킹루틴이 끝나고 원본 파일의 엔트리 포인트로 점프(분기)를 해줘야 원본 코드가 정상 동작할 조건을 만들어준다.
그렇기 때문에 언패킹 루틴이 마지막에 원본 코드의 엔트리 포인트로 점프해준다. OEP로 점프하기 전에는 언패킹이 마무리 되어야 한다. OEP로 순서가 달라지는 부분을 찾게 된다면, 메모리에 위치하는 언패킹 된 데이터를 얻을 수 있다는 것이다!
여기서 언패킹 된 데이터를 덤핑 즉, 복사하게 되면 원본 코드를 얻을 수 있다. 프로그램이 실행되면 메모리에 프로그램이 로드가 되면서 *IAT를 *바인딩 하는 작업을 수행한다.
*IAT(Important Address Table): 프로그램에서 사용되는 라이브러리에서 어떤 함수를 사용하는지 또는 함수명 그리고 함수 시작 수소 등에 대한 정보를 갖고 있는 테이블
*바인딩: 변수에 값을 할당하는 것
프로그램에 로드되면서 메모리에 상주하게 되고, IAT를 바인딩한다. 이 상태의 메모리를 덤프하게 되기 때문에 추후에 덤프된 코드를 실행할 때 IAT를 바인딩할 수 없게 된다. 즉, IAT가 고정값이 되어버린다는 것이고, IAT를 수정해주어야 하는 문제가 발생하게 된다.
언패킹을 할 때 유의할 점은 결과적으로 프로그램은 작동해야 하고 프로그램 기본 구조 자체는 바꿀 수 없다는 것이다. (내용은 변경될 수 있음)
3. 패커 종류
패커는 크게 두가지 종류로 나눌 수 있다.
평범한 PE파일을 만들어 내는 순수한 의도의 패커와 원본 파일을 크게 변경하고, PE 헤더를 심하게 훼손시키는 약간 불순한 의도의 패커로 나눌 수 있다.
- 순수한 의도의 패커(VirusTotal에서 진단 X): UPX, ASPack 등
- 불순한 의도의 패커(VirusTotal에서 진단 O): UPack, PESpin, NSAnti 등
'Reversing' 카테고리의 다른 글
[Reversing] Direct3D FPS_WirteUp (0) | 2023.05.27 |
---|---|
[Reversing] Position_WirteUp (1) | 2023.05.24 |
[Reversing] Replace_WirteUp (0) | 2023.05.13 |
[Reversing] Music Player_WirteUp (0) | 2023.05.13 |
DLL, IAT, EAT 분석 (0) | 2023.05.12 |