← 목록으로

패킹과 언패킹: 실행 파일을 압축/암호화해서 숨기기

[Rev] 리버싱 · 작성: 2026-07-19 19:32:50 · 수정: 2026-07-21 23:29:11 · 조회 9

패킹을 "실행 파일을 압축한 것"이라고만 알면, 압축된 파일이 어떻게 "압축이 풀린 뒤에도 정상 실행"되는지, 그리고 왜 정적 분석 도구(strings, objdump)가 패킹된 바이너리 앞에서는 거의 무용지물이 되는지를 놓치게 된다.

구조 레벨: 패킹된 바이너리의 이중 구조

패킹된 실행 파일은 원본 코드/데이터를 압축(또는 암호화)해서 자기 안에 데이터로 품고 있는 "스텁(stub)" 프로그램이다. 파일의 엔트리 포인트(OEP가 아니라 패커의 엔트리 포인트)는 원본 프로그램이 아니라, 압축 해제 로직으로 이어진다.

  1. OS 로더가 파일을 실행하면 패커의 압축 해제 스텁이 먼저 실행됨
  2. 스텁이 파일 안에 데이터로 품고 있던 압축된 원본 코드/데이터를 메모리 상에서 압축 해제
  3. 압축 해제된 원본 코드를 메모리의 다른(또는 같은) 영역에 써넣음
  4. 스텁이 원본 프로그램의 진짜 시작 주소(OEP, Original Entry Point)로 점프
  5. 이 순간부터는 원본 프로그램이 마치 원래부터 그 자리에 있었던 것처럼 정상 실행됨

strings/objdump가 패킹된 파일에 무력한 이유가 여기 있다 — 파일 안에 정적으로 저장되어 있는 건 압축된 바이트일 뿐, 원본 코드/문자열이 아니기 때문이다. 원본은 오직 런타임에, 메모리 상에서만 잠깐 그 모습을 드러낸다.

언패킹: OEP를 찾아서 메모리 스냅샷을 뜨는 것

언패킹의 핵심 아이디어는 간단하다 — "압축 해제가 다 끝나고, 원본 코드로 점프하기 직전"의 메모리 상태를 그대로 덤프하면, 그게 사실상 원본 바이너리다.

  1. OEP 찾기: 디버거로 실행하며, 스텁이 압축 해제를 마치고 원본으로 점프하는 지점(대개 스택 값이 크게 바뀌거나, jmp/call 대상이 스텁 코드 영역 밖의 새로 써진 메모리 영역을 가리키는 지점)을 찾는다. UPX 같은 잘 알려진 패커는 관용적인 패턴("popad" 직후의 큰 점프 등)이 있어 도구(upx -d)로 자동 언패킹이 되는 경우도 많다
  2. 메모리 덤프: OEP에 브레이크포인트를 걸고 그 시점의 프로세스 메모리를 통째로 파일로 떠낸다(Scylla, ProcDump 등의 도구)
  3. Import Table 재구성: 여기가 가장 까다로운 부분이다 — 압축 해제 과정에서 원본의 IAT(Import Address Table, 어떤 외부 함수를 어디서 가져오는지 기록한 표)가 스텁에 의해 임시로 다르게 채워져 있는 경우가 많아서, 덤프한 메모리만으로는 어떤 함수가 어떤 라이브러리의 몇 번째 함수였는지 정보가 소실되어 있다. Scylla 같은 도구가 메모리를 스캔해서 실제 라이브러리 함수 주소와 대조해 IAT를 다시 만들어준다(IAT rebuilding)
  4. 이렇게 재구성한 덤프 파일이 이제 정상적인 정적 분석 도구로 열리는 "언패킹된" 바이너리다

왜 이 기법이 악성코드/DRM에 널리 쓰이는가

여기서 끝나지 않는다

패킹을 "압축"이 아니라 **"원본 코드가 오직 런타임 메모리에만 잠깐 존재하도록 만드는 실행 시점 지연 기법"**으로 이해하면, 왜 언패킹의 핵심이 압축 해제 알고리즘 분석이 아니라 **"OEP를 찾아 그 순간의 메모리를 캡처하는 타이밍 문제"**인지가 같은 논리로 설명된다.

리버싱 카테고리의 글 (5/11)

  1. 리버싱이란 무엇인가: 정적 분석 기초
  2. 어셈블리어 읽기 기초 (x86-64)
  3. 동적 분석: 디버거로 실행 흐름 추적하기
  4. 안티 디버깅 / 안티 리버싱 기법과 우회
  5. 패킹과 언패킹: 실행 파일을 압축/암호화해서 숨기기
  6. Frida로 동적 계측/후킹하기
  7. 안드로이드 앱 리버싱: APK 분석 기초
  8. iOS 앱 리버싱 기초
  9. 크랙미(Crackme) 실습 방법론
  10. PE 포맷 내부 구조: Windows 실행 파일 뜯어보기
  11. 코드 난독화 해제: Control Flow Flattening 분석하기
← 안티 디버깅 / 안티 리버싱 기법과 우회 Frida로 동적 계측/후킹하기 →