Android Obfuscation, Optimization 위한 Proguard 적용하기

 안드로이드는 자바를 기반으로 개발하기 때문에 기본적인 역공학이나 APKManager 같은걸로 디컴파일이 비교적 쉬운편입니다. 그래서 소스코드와 리소스들이 외부로 쉽게 유출될 수 있습니다. 이런 부분에서는 iOS에 비해 취약한게 사실입니다. so 같은 lib로 만들면 디컴파일보다는 어려운 리버싱을 해야하므로 조금더 안전하게 만든 앱을 보호할 수 있겠네요. 네이티브 언어가 아닌 스크립트 언어는 어쩔수 없는 부분인 듯 합니다.

 일단 이런 것들과 관련해서 피해를 최소화하는 방법에는 여러가지가 있겠지만 안드로이드와 게임에만 한정해본다면 게임 보안과 관련된 솔루션을 도입할 수 있겠습니다. 그중에서도 난독화 또는 코드 난독화를 통해서 안드로이드 또는 자바를 비교적 손쉽게 보안 이슈 처리할 수 있는 것 같습니다. 물론 100% 완벽한 대안은 아니지만 안하는 것보단 적용해서 역공학에 조금이라도 대비하는게 좋겠죠.

 이번 포스팅에서는 솔루션 중 하나인 프로가드(Proguard)를 안드로이드 프로젝트에 적용해보는 것을 정리하겠습니다.  안드로이드 개발자센터 프로가드 문서도 있고 예전에는 따로 소스포지에서 다운받아 설치해야했지만 이제는 최신의 안드로이드 SDK에 포함이 되어 있는거 보면 구글에서도 사용하는 것을 추천하는 것 같네요.

 이클립스로 안드로이드 프로젝트를 생성하면 기본적으로 proguard-project.txt와 project.properties 파일이 있습니다.

 project.properties 파일을 열어보면 # To enable ProGuard 어쩌고 밑의 #을 지워서 프로가드를 활성화 시켜줍니다.

 이제 프로젝트를 빌드하고 Run이 아닌 apk로 익스포트해주면 그림과 같이 프로젝트에 proguard 폴더가 생깁니다. 그러면 프로가드가 성공적으로 적용이 된 것이죠.


 결과를 확인해보겠습니다. 왼쪽은 일반 APK고 오른쪽이 프로가드를 적용한 APK입니다. 같은 안드로이드 프로젝트를 APK 메니져로 디컴파일 해본 것입니다. 폴더명이 다 바겼네요. 그리고 최적화가 된 것인지 폴더수도 줄었습니다.

 app라는 폴더를 각각 들어가봤습니다. 역시 파일명과 수가 차이가 있습니다.

 실제로도 apk 용량이 다릅니다. 프로가드 적용된 것이 83.3kb이고 일반 apk가 191입니다. 약 2배가 조금 넘는 용량 차이를 보이네요. 과연 프로가드 적용된 apk가 잘 작동할까?란 생각이 들었는데 디바이스에서 테스트도 이상이 없었습니다.

android.support.v4.app.ActivityCompatHoneycomb -> android.support.v4.app.a:
    void invalidateOptionsMenu(android.app.Activity) -> a
android.support.v4.app.BackStackRecord -> android.support.v4.app.b:
    android.support.v4.app.FragmentManagerImpl mManager -> a
    android.support.v4.app.BackStackRecord$Op mHead -> b
    android.support.v4.app.BackStackRecord$Op mTail -> c
    int mNumOp -> d
    int mEnterAnim -> e
    int mExitAnim -> f
    int mPopEnterAnim -> g
    int mPopExitAnim -> h
    int mTransition -> i
    int mTransitionStyle -> j
    boolean mAddToBackStack -> k
    boolean mAllowAddToBackStack -> l
    java.lang.String mName -> m
    boolean mCommitted -> n
    int mIndex -> o
    int mBreadCrumbTitleRes -> p
    java.lang.CharSequence mBreadCrumbTitleText -> q
    int mBreadCrumbShortTitleRes -> r
    java.lang.CharSequence mBreadCrumbShortTitleText -> s
    java.lang.String toString() -> toString
    void dump(java.lang.String,java.io.FileDescriptor,java.io.PrintWriter,java.lang.String[]) -> a
    void dump(java.lang.String,java.io.PrintWriter,boolean) -> a
    void addOp(android.support.v4.app.BackStackRecord$Op) -> a
    android.support.v4.app.FragmentTransaction add(int,android.support.v4.app.Fragment,java.lang.String) -> a
    void doAddOp(int,android.support.v4.app.Fragment,java.lang.String,int) -> a
    android.support.v4.app.FragmentTransaction detach(android.support.v4.app.Fragment) -> a
    android.support.v4.app.FragmentTransaction attach(android.support.v4.app.Fragment) -> b
    void bumpBackStackNesting(int) -> a
    int commit() -> a
    int commitInternal(boolean) -> a
    void run() -> run
    void popFromBackStack(boolean) -> b
    java.lang.String getName() -> b

 프로가드 적용후 생성된 proguard폴더에서 mapping.txt의 내용입니다. 왼쪽이 오른쪽으로 매핑이 되었다는 것을 뜻하는 것 같네요. 이런식으로 변수나 함수명등을 줄이는 식으로 용량 최적화를 하는 것 같네요. 그와 동시에 코드 난독화도 하고요.

 간단하게 프로가드를 안드로이드 프로젝트에 적용해봤습니다. 기본적인 것만 적용한 것이라 아무런 이슈가 없었는데요, 추후 이슈가 발생하면 따로 정리해보겠습니다. 또한 유니티3D 안드로이드 플러그인에도 프로가드를 적용해볼 예정입니다.

댓글

이 블로그의 인기 게시물

'xxx.exe' 프로그램을 시작할 수 없습니다. 지정된 파일을 찾을 수 없습니다.

goorm IDE에서 node.js 프로젝트로 Hello World Simple Server 만들어 띄워보기

애드센스 수익을 웨스턴 유니온으로 수표대신 현금으로 지급 받아보자.