Reversing/Reverse Engineering

패킹과 언패킹

패킹과 언패킹

◾ 패킹(packing): 프로그램 코드 크기를 압축 + 프로그램 분석을 어렵게 하기 위해 암호화 하는 것

◽ 컴프레싱(compressing): 단순 압축

◽ 프로텍팅(protecting): 암호화 하는 것패킹 = compressing + protecting

행 파일을 암호화해 분석을 어렵게 만드는 기술이다.

◾ 구조: 암호화된 상태의 실행코드 배포 → 실행 시, 실행 코드를 복화화해 동작 수행

언패킹 동작 방식

UPX로 패킹된 실행파일

UPX로 패킹된 실행파일을 살펴보면 Empty Space, Packed Data, Unpacking Code로 구성되어 있다.

  • Unpacking Code: UPX로 패킹된 파일을 언패킹할 때 필요한 코드 영역
  • Packed Data: 패킹된 데이터가 들어있는 영역
  • Empty Space: 패킹된 데이터(Packed Data)를 Unpacking code를 이용해 언패킹된 데이터를 저장할 공간

언패킹 과정

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

대표적인 패커 UPX (Ultimate Packer for Executables)

UPX는 다양한 운영체제를 지원하고 있는 오픈 소스 실행 압축 파일이다.

특징
고성능 압축 효율 WinZip/zip/gzip 보다 효율성이 높은 압축 성능
빠른 압축 해제 속도 Pentium 133에서도 10MB/sec 이상의 속도로 압축/해제
메모리 효율성 파일을 실행할 때 원본 코드를 읽기 전 효율적으로 압축을 해제 = 메모리 부하 X
다양성 다양한 실행 파일 형식 지원
이식 C++로 작
확장 새로운 실행 파일 형식, 압축 알고리즘을 추가하기 유연한 구조

upx.exe 파일

 

파일 패킹기 (UPX)

📌 패킹할 파일은 upx.exe와 같은 폴더에 있어야한다.

upx -o 패킹후파일 패킹전파일

  • File size : 패킹 전 후 파일의 사이즈 변
  • Ratio : 원본 파일에 대한 출력 파일(패킹된 파일)의 압축 비율
  • Format : 패킹 파일의 형
  • Name : 패킹 후 파일의 이름

01.exe를 패킹한 파일 01_pack.exe가 생성되었다.

upx -h

등등등....

도움말을 볼 수 있는 옵션 -h

설치된 upx의 버전 / 다양한 압축 옵션 / 현재 버전의 UPX가 지원하는 운영체제 등을 확인할 수 있다.

PE 파일 분석 (Detect It Easy)

ex.1 - PE 파일 분석 (01.exe)

01.exe 분석 정보

  • 프로그램을 만들 때 사용한 시스템 소프트웨어 정보

>> 01.exe는 Delphi로 만들어진 프로그램으로, 패킹되지 않은 프로그램이라는 것을 확인할 수 있다.

01.exe PE 파일에 대한 요약 정보

  • PE 파일에 대한 요약 정보

>> 01.exe 파일의 엔트리 포인트의 상대 주소는 1000이다.

PE 파일의 섹션 정보

>> 엔트리 포인트가 Code Section에 위치하고 있다.

>> PE 파일이 CODE, DATA, .idata , .reloc , .rsrc의 다섯 개의 섹션으로 구성되어 있음을 확인할 수 있다.

Entropy: 데이터의 분포 정보

>> Entropy가 섹션마다 고루 분포되어 있는 편이다. 만약, 패킹되어 있다면 Entropy 분포가 불규칙하게 나타난다.

ex.2 - 패킹된 파일 분석 (01_pack.exe)

01_pack.exe

>> 프로그램을 만들 때는 Delphi로 개발되었고, UPX로 패킹되었음을 확인할 수 있다.

01_pack.exe PE 분석 정보

>> 엔트리 포인트의 상대주소는 000071b0이다.

01_pack.exe PE 파일의 section 정보

>> 엔트리 포인트가 UPX 섹션(VA: 00007000 ~ 00008000)에 있음을 확인할 수 있다.

01_pack.exe의 Entropy 정보

>> Entropy 항목에 UPX0 섹션이 나타나지 않는 것은 UPX0에는 데이터가 없다는 것을 의미한다. 일반적으로 이 영역에 언패킹된 original code가 저장된다.


언패킹과 OEP

엔트리 포인트 (Entry Point)

프로그램에 대한 제어권이 "운영체제 → 사용자 코드"로 넘어가는 지점; 프로세서가 메모리에 있는 코드 섹션으로 처음으로 들어가는 지점이다.

엔트리 포인트의 위치는 PE 헤더의 AddressOfEntryPoint에 저장되어 있다. 이 위치는 상대주소이므로, 진짜 엔트리 포인트의 주소PE 헤더의 ImageBase + PE 헤더의 AddressOfEntryPoint로, 이 메모리 주소를 프로세서가 인식해 실행한다.

OEP (Original Entry Point)

패킹되기 이전 프로그램의 실제 엔트리 포인트이다.

언패킹할 때 정확한 OEP를 찾는 것이 가장 중요하다. 메모리 덤프를 파일로 저장했을 때 PE 헤더에 있는 엔트리 포인트 값을 OEP로 수정해줘야 프로그램이 정상적으로 동작한다.

01_pack.exe 예

01_pack.exe를 IDA로 열었을 때의 화면

IDA로 01_pack.exe를 열었을 때 4071B0에서 프로그램 코드가 시작되는 것을 볼 수 있다 >> 이 곳이 패킹된 파일 엔트리포인트이다.

Detect It Easy 프로그램에서 확인한 AddressOfEntryPoint(00071B0) + ImageBase(00400000)와 같다. 프로그램이 메모리에 로딩될 때 ImageBase 값에 상대 주소(AddressOfEntryPoint)를 더해 저장된다.

 

  • UPX로 패킹된 파일의 엔트리 포인트는 PUSHA (PUSHAD) 명령어로 시작한다. 이 명령을 통해 모든 레지스터의 값을 스택으로 백업시킨다.
  • 01_pack.exe 엔트리포인트 아래에는 언패킹 코드가 온다. 언패킹이 모두 끝나고 난 후 POPA(D) 명령어를 수행해 스택에 저장된 레지스터 값을 시 복구한다.
  • 이제 OEP로 점프해서 프로그램 본래의 기능을 수행하게 된다. 이 때, OEP의 값은 00401000이다. OEP 아래에서 패킹 전 원본 코드(original code)를 확인할 수 있다.

OEP와 그 아래 원본 코드

IAT 복구

IAT (Import Address Table)

어떤 DLL에서 어떤 함수를 참조하는지에 대한 정보가 저장된 PE 헤더의 IAT에 저장된다.

메모리 덤프를 하는 과정에서 IAT 테이블은 쉽게 손상되고, 별도의 복구 과정이 필요하다.

IAT 복구

손상된 IAT 정보는 Detect It Easy 프로그램으로 쉽게 확인할 수 있다.

복구하는 방법은 간단하다. 그냥 툴을 사용하면 된다..

대표적으로 LordPE 를 사용한다.

SMALL

'Reversing > Reverse Engineering' 카테고리의 다른 글

매뉴얼 언패킹(MUP) 사례 - ESP Trick으로 OEP 찾기  (1) 2021.05.18
어셈블리 코드 변환  (0) 2021.04.06
HelloWorld.exe  (2) 2021.04.01
Instruction (명령어)  (0) 2021.03.30
리버싱을 위한 기초 지식(구조)  (0) 2021.03.28