Android Proguard 난독화

Developer💻·2024년 9월 10일

Android

목록 보기
1/10

Proguard 난독화를 통하여 Apk 파일의 코드 전체를 난독화할 수 있는지 테스트



Proguard란?

Java 및 Android 애플리케이션의 코드 크기를 줄이고 난독화를 통해 소스 코드를 보호하는 도구이다. Android 프로젝트에서 일반적으로 사용되며, APK 크기를 최적화하고 리버스 엔지니어링을 방지하는 데 도움을 준다.

  1. 난독화(Obfuscation) : 클래스 이름, 메서드 이름, 필드 이름 등을 의미 없는 이름으로 변경하여 코드를 분석하기 어렵게 만든다. 디컴파일러로 코드를 봐도 원래 이름을 알 수 없기 때문에 소스 코드를 이해하는 것이 어려진다.
    예시 : com.example.MyClass → a.b.a

  2. 최적화(Optimization) : 사용되지 않는 클래스, 메서드, 필드를 제거하고, 중복 코드를 합치거나 단순화하여 코드의 실행 성능을 최적화한다. 이를 통해 애플리케이션의 크기를 줄이고 성능을 향상시킬 수 있다.

  3. 축소(Shrinking) : 실제로 사용되지 않는 코드를 감지하고 제거하여 애플리케이션 크기를 줄인다. 이 과정에서 코드의 의존성 그래프를 분석하여 불필요한 코드가 포함되지 않도록 한다.

  4. 사전검증(Pre-verification) : Java 바이트코드를 Android 또는 Java 버전의 검증 규칙에 맞춰 검증하여, 배포하기 전에 코드의 오류를 줄일 수 있다.

Android Studio 문서


ProGuard 활성화

minifyEnabled true로 지정

build.gradle

android {
    buildTypes {
        release {
            // ProGuard 활성화
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

debug도 함께 확인하고 싶다면?

android {
    buildTypes {
    debug { 
          minifyEnabled true
          proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

난독화

특정 조건이나 예외처리하고 싶다면 여기에 코드를 넣기

proguard-rules.pro

# 모든 인터페이스 난독화 예외처리
- keep interface com.프로젝트.패키지명.* { *; }

# 모든 클래스 난독화 예외처리
- keep class com.프로젝트.패키지명.* { *; }

# 난독화할 라이브러리
- injars libs/라이브러리.jar // or aar, ... etc

# 난독화할 필요 없는 라이브러리
- libraryjars libs/라이브러리.jar // or aar, ... etc

# 특정 클래스 난독화 제외
-keep class com.example.mypackage.MyClass {
    *;
}

# 모든 public 메서드를 유지 (난독화 제외)
-keepclassmembers class * {
    public *;
}

# 안드로이드 애플리케이션의 엔트리 포인트(Activity, Service) 보호
-keep class android.** { *; }

Log 출력

before

2024-09-10 10:35:16.555  D  [manager] getFromHTTPS()[31] >> [manager] new HttpsClient
2024-09-10 10:35:16.555  D  [manager] getHeader()[93] >> HTTP Post Header Input
2024-09-10 10:35:17.725  E  [Server] setData()[131] >> com.example.mypackage.MyClass.Data
2024-09-10 10:35:17.725  I  [Service] onData()[350] >> success
2024-09-10 10:35:17.725  I  [Service] onData()[332] >> Version : null

after

2024-09-10 13:01:41.755  D  [b] e()[-1] >> [manager] new HttpsClient
2024-09-10 13:01:41.755  D  [b] j()[-1] >> HTTP Post Header Input
2024-09-10 13:01:42.865  E  [b] r()[-1] >> com.example.mypackage.e.a
2024-09-10 13:01:42.865  I  [Service] a()[-1] >> success
2024-09-10 13:01:42.875  I  [Service] a()[-1] >> Version : null

결과

Log상으로 보았을 때 일부만 난독화되는 것으로 확인되어 자세하게 확인하기 위해 apk를 생성하여 그 파일을 jar로 변환한 뒤 코드 확인한다. (아래 링크에서 이어서 설명)
apk를 jar파일로 바꾸는 방법


코드 전체가 난독화 되지 않는 이유?

코드 자체는 난독화가 안되는 이유를 찾아보니, 기본적으로 ProGuard는 식별자(클래스, 메서드, 필드 이름)를 난독화하지만, 코드 로직 자체는 변하지 않는다고 한다.
코드 전체를 난독화하는 방법이 있는지 찾아보니, DashO 또는 Allatori 상용 라이센스를 사용해서 처리하는 방법이 있다. 추후, 사용하게 된다면 다시 한번 테스트 해봐야겠다.

profile
숲을 그리는 개발자

0개의 댓글