티스토리 뷰

[Android] ProGuard 코드 난독화 / 최적화 설정


ᆞProGuard란 

출처 : http://proguard.sourceforge.net/

ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or higher, or for Java Micro Edition.


무료툴이며코드상에서 사용되지 않는 불필요한 코드를 찾고 제거해서 최적화 시켜줌과 동시에 변수의 이름을 의미없는 이름으로 짧게 바꿔 난독화를 해준다. 


* 좀더 강력한 기능을 원하면 http://www.guardsquare.com/dexguard 에서 유료버전을 사용해도 될듯 하다.




ᆞAndroid Studio에서 ProGuard 설정하기 

현재는 안드로이드에서 공직적으로 지원해서 간단한 Gradle 설정으로 적용시킬 수 있다.

출처 : http://developer.android.com/intl/ko/tools/help/proguard.html 


  1    Gradle Builds 설정

프로젝트를 생성하면 아래와 같이 build.gradle의 buildTypes{}에 proguard 설정이 되어있다.

minifyEnabled false라고 기본설정 되어 있는 부분을 true로 바꿔준다. release에서 알 수 있듯 프로젝트를 release할 때 ProGuard가 적용 된다.

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

proguard-android.txt는 android SDK폴더의 tools/proguard/proguard-android.txt에서 수정 할 수 있다. 

ProGuard 메뉴얼을 살펴보면 자세한 설정을 할 수 있다.


추가로 규칙을 정의해 별도로 *-rules.pro 파일을 아래와 같이 적용시켜 주면 기본설정을 변경하지 않고 추가 설정을 할 수 있다

   ...
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
            'proguard-rules.pro', 'proguard-rules-new.pro'
        }
    }
 
   productFlavors {
        flavor1 {
        }
        flavor2 {
            proguardFile 'other-rules.pro'
        }
    }
   ...


Debug Build된 APK로 테스트 하고 싶을 땐 release부분을 복사해서 debug로 바꿔주면 된다.

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

   ...



  2    ProGuard 규칙

-dontoptimize 최적화 하지 않기

-dontshrink 사용하지 않는 메소드 유지

-keep class com.example.classname ClassNotFoundException에러나 난독화를 진행하지 않고 유지하는 옵션

-keepclassmembers class com.example.classname { 접근제어자 *; } # 특정 클래스의 맴버 원상태 유지

-keepattributes InnerClasses 내부클래스 원상태 유지 적용


위 옵션을 proguard-rules-new.pro 또는 proguard-rules-new.pro나 새 .pro 파일에 규칙을 추가해서 등록하도록 한다. 자세한 규칙은  http://proguard.sourceforge.net/manual/usage.html 참조




ᆞ적용 전/후 간단 결과 



아래가 적용 전 화면이다.

라이브러리 클래스 이름이 모두 기존 클래스명으로 나와있고 오른쪽 화면에는 없지만 메소드 명도 그대로 나와있다

Mainactivity의 unusedMethod 메소드 같은 경우에는 상용된 곳이 없지만 그대로 컴파일되어 디컴파일 했을 때에도 나오는걸 알 수 있다.



아래가 적용 화면이다.

라이브러리 클래스 이름이 a,b,c,d...처럼 알파벳 단자리로 표기되어있으며 사용되지 않은 unuesdMethod는 코드에서 사라진 것을 볼 수 있다. 

아래처럼 난독화도 외어있고 최적화도 되어있다. 하지만 난독화가 되어있어도 코드상의 흐름은 더 오랜 시간이 걸리겠지만 충분히 파악 할 수 있을 것이다. 

댓글
  • 프로필사진 만델라 답변이 가능하신가요???
    님께서 하신 방법을 똑같이 따라했지만...추출해서 디컴파일까지 했지만...
    난독화가 안되네요 흑... 그대로네용...

    본 프로젝트내에 있는 proguard-rules.pro를 복붙해서
    이름을 proguard-rules-new-.pro로 변경하고 알려주신 옵션들로만 채워넣었습니다.
    -dontoptimize
    -dontshrink
    -keep class com.example.classname
    -keepclassmembers class com.example.classname { 접근제어자 *; }
    -keepattributes InnerClasses

    그후에 아래와 같이 new.pro도 같이 붙여주고 sync 해주었고 아무이상없이 앱도 실행되오나... 님처럼 난독화는 안되네요 ㅠ
    도움을 요청합니닷~!
    buildTypes {
    debug {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' , 'proguard-rules-new.pro'
    }
    release {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'proguard-rules-new.pro'
    }
    }
    2016.11.01 06:58 신고
  • 프로필사진 DWFOX DWFOX 옵션자체에는 문제가 없는것 같은데
    minifyEnabled 옵션을 true 했음에도 난독화가 적용되지 않은것은 proguard로 빌드가 진행되지 않은 것처럼 보입니다.

    APK Build로 APK 을 생성해서 테스트 하신건지요?
    2016.11.01 11:03 신고
  • 프로필사진 만델라 빠른 댓글 정말 감사해요~!
    님이 말씀하신 apk build로 apk를 생성한다는게 안드로이드 스튜디오에서 build탭 누르면
    generate signed apk 를 통해 만들어진 apk를 말씀하시는건가요???

    그렇게 하진 않고 걍 폰 꽂아서 앱 실행시켜서 생기는 앱을 추출해서 디컴파일 했습니다요.

    release로 시작하는 명령줄은 님이 위에 말씀하신 apk를 직접 생성될 때 난독화가 진행된다고 이해했었구요.
    debug로 시작하는 명령줄이 폰에 꽂고 앱을 실행해서 생기는 앱에 난독화가 진행된다라고 이해했었는데 아닌가요?~?

    지금 몇시간째...proguard 파일들도 수정해보고, 마지막단계인 안드로이드 스튜디오를 재설치 해볼까... 포맷을 해볼까
    생각중였는데...ㅎ 설마 위에 처럼 apk를 안만들어서 생긴거였을려나요...해봐야겠네요 일단!ㅎ
    2016.11.01 11:13 신고
  • 프로필사진 만델라 아...build tab에 혹시 build apk를 말씀하신건가요?
    방금전 시도 해봤습니다... 이렇게 해서 생긴 앱을 가지고 디컴파일 했더니
    님이 설명해주신정도로 딱 난독화가 되어있네요!

    사실... debug와 release도 정확히 구분을 못하고 있는듯 하네요...걍 감으로 하고 있었네요..
    컴퓨터에 단말기를 꽂고 shift+f10을 눌러 앱을 실행 하는것을 뭐라고 하나요?? debug...가 이에 해당하지 않나보네요 ㅎ;
    build apk 명령을 통해 생성된 apk가 debug{} 에 영향을 받고
    generate signed apk 를 통해 생성된 apk가 release{}에 영향을 받는것이라고 이해 해도 될까요?ㅎ

    2016.11.01 11:21 신고
  • 프로필사진 DWFOX DWFOX 저도 정확히 알아본게 아니지만
    Android Studio 2.0 이상버전부터는 instant-run으로 디폴트 옵션이 있을거에요
    그래서 shift+f10으로 진행한 빌드도 디버그 옵션이 적용되지만
    proguard 부분에서는 옵션이 진행되지 않는것 같습니다.

    테스트는 안해봤지만 instant-run 옵션을 끄고 하면 shift+f10으로 빌드후 apk 추출하여 확인하면 난독화가 되어있을것으로 생각됩니다.
    2016.11.01 11:29 신고
  • 프로필사진 만델라 오~! 고수님 감사해요~~~~
    난독화된 코드를 확인햇더니 제가 초기화 해뒀던 배열에 있는 값들과 스트링들이 아주 ~~~~모~두 노출되네요 ㅎㅎ
    혹시 스트링값이나 배열에 있는 초기값들 난독화해도 보여지지 않게 하는 좋은 수가 없을까요???
    현재도 찾고 있긴한데, 상수 클래스라는것을 따로 만드는것을 추천한다는 글을 보게 되었는데요..
    일단..상수클래스가 먼질 모르기에 ㅎㅎㅎ
    좋은 정보 있다면 공유 해주시면 정말 감사하겠습니다~
    2016.11.01 11:45 신고
댓글쓰기 폼