코드 난독화의 원리와 기술

정지효·2025년 4월 23일
0

모든 소프트웨어는 누군가에게는 기술의 결정체, 또 다른 누군가에게는 해킹의 대상이다. 하지만 아무리 정교하게 프로그램을 설계하더라도, 바이너리를 다운로드한 공격자는 리버스엔지니어링을 통해 코드의 핵심 로직을 꿰뚫어볼 수 있다. 이런 리버스엔지니어링을 방지하기 위한 대표적인 기법이 바로 코드 난독화 이다. 필자는 이번 글에서 코드 난독화의 원리, 기술 종류, 장단점에 대해서 알아보도록 하겠다.


1. 코드 난독화란?

코드 난독화는 말 그대로 사람이 이해하기 어렵게 코드를 복잡하게 만드는 기술이다. 이런 코드 난독화의 목표는 코드가 실행은 되지만 분석자는 해석하지 못하게 만드는 것이다.
일반적으로, 리버싱, 해킹, 크랙, 디컴파일을 어렵게 만들기 위해 사용된다.


2. 난독화의 종류

2.1 제어 흐름 난독화(Control Flow Obfuscation)

  • 원리: if-else, 반복문, switch 같은 로직을 분기 트리, 중첩된 루프, 상태머신으로 변경하여 코드 흐름을 비논리적으로 만들고 가독성이 없는 수준으로 만든다.

    Before

    if (user.isAdmin){
    	grantAccess();
       }

    After

    switch(x^x){
    	case 0: if(flag + 3 - 3) break;
      	default: if(((x^x) | 0x0) == 0) grantAccess);
       	break;

2.2 문자열 암호화(String Encryption)

  • 원리: 로그 메시지, API 이름, 키워드 등을 암호화 후 런타임에 복호화하여 정적 분석 도구에서 민감한 문자열의 노출을 방지한다.

    Before

    printf("license key");

    After

    char* mas = decrpt("7abjfc9d987am..."); //AES or XOR

2.3 가짜 코드 삽입(Dead/Opaque Code Insertion)

  • 원리: 절대 실행되지 않는 무위미한 코드를 삽입하여 분석자의 혼란을 유발하여 리버서가 중요한 로직을 구분하지 못하게 한다.

2.4 API 호출 난독화

  • 원리: 함수 포인터, 인라인 어셈블리, GetProcAddress 등으로 API 호출 흐름을 숨겨서 크랙 및 훅킹 지점 탐지를 방해한다.

2.5 가상화(Virtualization Obfuscation)

  • 원리: 실제 명령어를 사용자 정의 바이트 코드로 변환하고, 이를 해석하는 VM을 탑재한다 분석자는 바이트코드도 분석해야 하므로 분석 난이도가 매우 어렵다.

3. 난독화 도구

  • ProGuard / R8
    • 대상언어: Java / Android
    • 특징: 클래스 이름 제거, 코드 경량화
  • ConfuserEx
    • 대상언어: .NET
    • 특징: 문자열 암호화, 흐름 난독화
  • Obfuscator-LLVM(OLLVM)
    • 대상언어: C/C++
    • 특징: Control Flow Flattening, API hiding
  • Dorfuscator
    • .NET (MS 공식)
    • 상용 난독화 솔루션
  • Tigress
    • 대상언어: C
    • 고급 가상머신 기반 난독화
  • JScrambler
    • JavaScript
    • JS 난독화 및 디버깅 방지

코드 난독화는 코드 분석을 지연시키는 방법이다. 하지만 요즘에는 AI기반 난독화 탐지 툴이 증가하면서 난독화가 더욱 복잡해질 필요가 있다. 또한 복호화된 문자열과 API 이름을 런타임 메모리에서 추출하는 등 여러가지 우회 방법이 있으니 난독화만 하지 말고 실행 환경 보호까지 하자. 그럼 이번 글은 여기서 마치고 필자는 다음 글로 돌아오겠다.

profile
SRIHS infoSec 119th

0개의 댓글