프로가드(ProGuard)란?
코드 난독화 및 최적화 도구이다.
내가 만든 앱은 누군가 디컴파일해서 카피한다해도 아무런 일도 발생하지 않지만 영향력 있는 기업의 앱을 디컴파일해서 카피한다면 회사 입장에서는 크리티컬한 손해를 입을 것이다.
뿐만 아니라 공격자가 앱의 코드를 분석해 취약한 부분을 발견하거나 중요한 데이터를 훔칠 수 있기 때문에 보안적으로도 위험하다.
따라서 앱을 출시할 때 코드 난독화 후 릴리즈를 하여 소스 코드를 보호하는데, 이때 사용할 수 있는 것이 프로가드(현재는 R8)이다.
프로가드는 컴파일된 앱 패키지 코드를 난독화하여 해당 패키지를 디컴파일 했을 때 코드를 해독하기 어렵게 한다.
프로가드는 코드 난독화뿐만 아니라 불필요한 메서드와 미사용 리소스를 제거하는 등 더 작고 빠른 앱을 만들 수 있도록 도와준다.
안드로이드 AGP(Android Gragle Plugin) 3.4.0 미만의 경우 프로가드로 난독화를 진행했지만, AGP 3.4.0 이상부터는 R8 컴파일러를 사용하여 프로가드의 역할을 대신한다.
프로가드의 역할
1. 축소
APK를 축소하지 않으면 다운로드 시간/데이터 사용량 증가, 앱 충돌, 로드 속도 저하 등 여러 문제를 발생시킬 수 있다.
프로가드의 축소 APK파일을 축소하는 것을 말하는데, 코드 축소와 리소스 축소가 있다.
리소스 축소는 코드 축소와 함께 사용할 때만 작동한다.
· 코드 축소(Tree Shaking) : 앱 및 라이브러리 종속 항목에서 미사용되는 클래스, 변수, 메서드, 속성을 삭제하여 멀티 덱스(multiDex)를 제거
· 리소스 축소 : 앱 및 라이브러리 종속 항목에서 미사용되는 리소스와 패키징된 앱에서 미사용되는 리소스를 제거
1개의 DEX파일은 65536개의 메서드를 참조(64k 참조 제한)할 수 있는데, 메서드의 개수가 65536개를 초과하면 여러 DEX파일(멀티 덱스)이 생기게 된다.
이렇게 되면 빌드 속도가 느려지며 APK 용량이 커지게 된다.
DEX(Dalvik Executable) 파일 : 안드로이드 런타임에서 궁극적으로 실행되는 코드가 들어있는 파일
코드 축소는 앱의 동작이 시작되는 지점(entry point)을 찾는다.
Entry point는 Activity나 Service 등이 될 수 있고, R8은 각 시작점에서 출발해 사용되는 코드를 탐색하여 그래프(트리)를 작성한다.
그래프(트리)에 연결되지 않은 코드는 불필요한 코드로 간주하여 삭제한다.(그림 참조)
progaurd-rules.pro에서 -keep 규칙이 적용된 클래스(또는 @keep 어노테이션이 붙은 클래스)가 있는 경우 해당 클래스를 진입점으로 사용하기도 한다.
R8은 -keep 규칙이 적용된 클래스를 삭제하지 않는다.
2. 최적화
코드를 검사하고 다시 작성하여 런타임 성능을 개선하고 DEX 파일 크기를 더 줄이는 것을 말한다.
중복 연산이나 조건문 단순화 등 코드 흐름을 분석해 불필요한 명령어를 제거하거나 단순화하여 더 효율적인 바이트 코드로 변환한다.
축소, 난독화, 최적화를 모두 사용 설정하면 런타임 성능(UI 스레스 시작 시간, 프레임 타이밍) 최대 30% 향상된다고 한다.
프레임 타이밍 : 앱이 매끄럽게 실행되기 위해 초당 몇 개의 프레임을 렌더링하는지 측정한 것 (일반적으로 초당 60fps를 목표로 함)
그럴만도 한게 불필요한 코드가 삭제되면 실행 시 로드할 코드가 줄어들고, 복잡한 코드가 단순화되면 처리 속도가 빨라지는 것이 당연지사기 때문이다.
3. 난독화
클래스와 메서드, 변수 이름을 짧고 의미없는 이름으로 변경하여 분석과 디컴파일을 어렵게하고, DEX 파일 크기를 줄이는 작업이다.
외에도 디버그 심볼이나 주석, 소스코드 참조 등도 제거하여 분석을 어렵게 만든다.
R8이란?
R8은 프로가드의 대체 도구로 Google에서 Android 빌드 시스템에 통합하여 제공하는 최신 난독화 및 최적화 도구이다.
R8은 ProGuard의 기능을 포함하면서 더 고도화된 난독화 및 최적화 기능을 제공한다.
위에서 언급했듯이 AGP(Android Gradle Plugin) 3.4.0 이상부터는 더이상 프로가드가 아닌 R8을 이용해 난독화와 최적화를 처리한다.
다음은 ProGaurd와 R8의 DEX 파일 생성 과정이다.
R8은 .class(자바 바이트 코드) 파일을 최적화 함과 동시에 DEX 바이트 코드로 컴파일 한다. (향상된 성능의 프로가드 + D8= R8)
R8은 빌드 단계가 줄어 프로가드보다 빠르고, D8과 함께 작업하며 DEX 파일 생성 과정에서 성능 향상과 함께 최적화된 바이너리를 생성해 경량화 성능도 더 좋다.
또한, ProGuard 규칙 파일(progaurd-rules.pro)은 R8과 호환되어 그대로 이용할 수 있다.
proguard-rules.pro 옵션
- -keepattributes SourceFile,LineNumberTable : 디버깅 중 stacktrace에서 원래 소스 파일명과 코드 라인 번호를 그대로 유지해 확인할 수 있게 함
- -renamesourcefileattribute SourceFile: 원래 소스 파일명을 숨겨 보안 강화
- -keep class 라이브러리 패키지명.**{*}; : 난독화 할 필요가 없는 라이브러리 처리 옵션
- -ignorewarnings : warning 무시 옵션
- -dontwarn 패키지명.** : 지정한 패키지의 warning 무시 옵션
OkHttp, Retrofit, Glide, Gson, Firebase 등 유명한 서드 파티 라이브러리는 자동 예외 처리가 되고 있다.
R8 사용법
android {
buildTypes {
release {
// 코드 축소
minifyEnabled true
// 리소스 축소
shrinkResources true
//기본 설정
proguardFiles getDefaultProguardFile(
'proguard-android-optimize.txt'),
'proguard-rules.pro'
}
}
...
}
아주 심플하다. Gradle 파일을 다음과 같이 수정하면 코드 축소와 리소스 축소가 활성화된다.
이제 debug와 release apk를 추출해 난독화와 최적화가 어떻게 이뤄졌는지 확인해보자.
debug apk를 살펴보면 dex 파일이 11개이고 사이즈는 16.6MB, release apk는 dex 파일 1개에 사이즈는 8.8MB로 절반으로 감소한 것을 확인할 수 있다.
release.apk의 경우 다음과 같이 클래스와 메서드명도 바뀐 것을 확인할 수 있다.
요약
- 프로가드/R8의 역할 : 자바 및 안드로이드 앱 코드 난독화, 축소, 촤적화 수행 도구
- 축소 : 미참조 클래스, 메서드, 리소스 등을 삭제해 APK 파일 크기 감소
- 최적화 : 효율적으로 코드 구조 개선해 실행 속도와 자원 효율성 향상
- 난독화 : 디컴파일 시 코드 해석 어렵게 만들어 보안 향상
- AGP 3.4.0 이상 부터 R8을 사용해 난독화, 최적화 수행
https://developer.android.com/build/shrink-code?hl=ko#groovy
앱 축소, 난독화 및 최적화 | Android Studio | Android Developers
사용하지 않는 코드와 리소스를 삭제하기 위해 출시 빌드에서 코드를 축소하는 방법을 알아보세요.
developer.android.com
'프로그래밍 > Android' 카테고리의 다른 글
안드로이드 4대 컴포넌트 (Feat. Activity) (0) | 2024.06.03 |
---|---|
[Android] 클린 아키텍쳐 (Clean Architecture) (1) | 2024.04.27 |
Android Studio Project명 바꾸기 (0) | 2024.03.18 |
[HTTP 통신 라이브러리] OkHttp와 Retrofit (0) | 2024.03.11 |
SoundPool Constructor deprecated 해결 (0) | 2024.03.06 |