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 안드로이드 플러그인에도 프로가드를 적용해볼 예정입니다.
일단 이런 것들과 관련해서 피해를 최소화하는 방법에는 여러가지가 있겠지만 안드로이드와 게임에만 한정해본다면 게임 보안과 관련된 솔루션을 도입할 수 있겠습니다. 그중에서도 난독화 또는 코드 난독화를 통해서 안드로이드 또는 자바를 비교적 손쉽게 보안 이슈 처리할 수 있는 것 같습니다. 물론 100% 완벽한 대안은 아니지만 안하는 것보단 적용해서 역공학에 조금이라도 대비하는게 좋겠죠.
이번 포스팅에서는 솔루션 중 하나인 프로가드(Proguard)를 안드로이드 프로젝트에 적용해보는 것을 정리하겠습니다. 안드로이드 개발자센터 프로가드 문서도 있고 예전에는 따로 소스포지에서 다운받아 설치해야했지만 이제는 최신의 안드로이드 SDK에 포함이 되어 있는거 보면 구글에서도 사용하는 것을 추천하는 것 같네요.
이클립스로 안드로이드 프로젝트를 생성하면 기본적으로 proguard-project.txt와 project.properties 파일이 있습니다.
이제 프로젝트를 빌드하고 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 안드로이드 플러그인에도 프로가드를 적용해볼 예정입니다.
댓글
댓글 쓰기