Android 앱은 apk(Android Application Package)로 구성되어있다.
Play Store에 AAB(Android App Bundle)로 앱을 등록해도 실제 사용자가 다운로드 받는 앱은 apk 파일이다. apk 파일은 디컴파일을 통해 소스 형태로 되돌릴 수 있으며, 이는 공격자가 소스를 통해 악의적인 행위를 하는 것을 가능케 하기 때문에 앱 배포 시 난독화가 필수이다.
난독화를 위한 다양한 도구들이 있는데, 그 중 Android에서 제공하는 오픈소스 도구인 Proguard로 난독화를 수행한다.
Proguard를 통한 난독화 적용 방법
Android Studio에서 build.gradle(Module :app)을 열어 buildTypes를 찾는다.
buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } |
minifyEnabled가 처음에는 false로 되어있을텐데, 이를 true로 바꿔주면 된다.
간혹 구글링을 하다보면 debug 버전 apk파일도 난독화가 된다며
buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } |
이런 코드를 볼 수 있는데, https://developer.android.com/studio/build/shrink-code?hl=ko 에 따르면 Android Gradle 플러그인 3.4.0 이상부터는 debug 버전에서 Proguard를 지원하지 않는다고 한다.
Android Release 버전 APK 파일 추출하기
Proguard 설정을 true로 바꿔주고 gradle sync를 맞춘 후, 난독화가 잘 되었는지 확인하기 위해 apk 파일을 추출해야 한다.
release 버전 apk 파일 추출을 위해서는 Android Studio 상단에 있는 메뉴 중,
Build -> Generate Signed Bundle or APK를 눌러 진행한다.
APK 선택 후 Next 클릭
APK 파일을 처음 만드는 과정이라면 key가 없을테니 Create New를 눌러 key를 만들어준다.
key 경로는 해당 프로젝트 안에 만들어준다.
key store와 key의 패스워드를 각각 입력해주고 유효기간을 설정해준 뒤, 내용을 적당히 입력하고(Country Code는 나라코드인데 KR을 입력해준다.) OK를 누른다.
debug와 release 버전 중 release 버전을 선택하고 Create을 누르면 release 버전의 APK 파일이 만들어진다.
빌드가 완료되면 다음과 같이 APK파일 생성이 완료되었다는 알림이 뜬다. locate을 누르면 해당 폴더를 열어준다.
프로젝트 app\release 폴더 안에 apk 파일과 메타데이터가 담긴 json 파일이 생성되었다.
APK 파일 디컴파일하기
APK파일은 설치 파일로, 해당 파일의 소스 코드를 보고 싶다면 디컴파일을 통해 소스 형태로 되돌려야 한다.
이를 위해서는 두 가지 방법이 있는데,
- apktool을 사용하여 smali 코드로 디컴파일하는 방법
- dex2jar를 사용하여 jar 파일로 디컴파일하는 방법이 있다.
smali는 dalvik에서 사용하는 dex 형식의 어셈블리어이다. dex는 Android에서 궁극적으로 실행되는 코드가 포함되어 있으며, 기계어로 구성되어있다. 기계어는 읽기 힘드므로 이를 읽기 쉽게 해주는 것이 smali 코드이다. smali 파일은 코드 수정 후 다시 컴파일이 가능하기 때문에 코드 패치를 할 때 사용된다.
하지만 smali는 어셈블리어이기 때문에 공부가 필요하다. 좀 더 읽기 쉽게 java로 이루어진 버전으로 디컴파일을 하고 싶다면, dex2jar를 사용해 jar파일로 디컴파일하면 된다. 보통 디컴파일된 java 코드를 분석한 후 smali 코드를 수정하는 방식으로 코드 패치를 진행한다고 한다.
Apktool을 사용해 smali 파일로 디컴파일하기
Apktool은 bash or cmd script 파일과 apktoo.jar 파일 두 개로 구성되어 있다.
https://apktool.org/docs/install/ 에 접속하여 script 파일과 apktool.jar 파일을 다운받으면 된다.
- Wrapper script 다운로드 Window script (마우스 오른쪽 메뉴로 'apktool.bat'로 저장)
- 최신 apktool.jar 파일 다운로드
- 다운로드한 Jar파일을 apktool.jar로 이름을 변경
- apktool.bat와 apktool.jar 파일을 C:\Windows 경로에 배치
- cmd에서 apktool 명령어 실행
apktool 명령어를 입력하여 다음과 같이 나오면 apktool을 사용하여 디컴파일할 준비가 끝난 것이다.
release용 apk파일을 추출했던 폴더로 이동하여 디컴파일을 진행한다.
디컴파일을 위해 다음과 같은 명령어를 입력한다.
> apktool d {apk 파일} -o {디컴파일한 파일의 폴더} |
공식 문서에 따르면, d는 특정한 파일을 디코딩(Decoding)한다는 의미이다. 그리고 -o 옵션을 넣어 만들어질 소스 폴더의 경로를 설정할 수 있다. -o 옵션을 생략하면 자동으로 apk 파일명과 동일한 이름의 폴더가 생성된다.
다음과 같이 디컴파일이 진행된다.
I: Using Apktool 2.8.1 on app-release.apk I: Loading resource table... I: Decoding AndroidManifest.xml with resources... → Resource 파일 중에서 AndroidManifes.xml을 디코딩 I: Loading resource table from file: C:\Users\eeeun\AppData\Local\apktool\framework\1.apk I: Regular manifest package... I: Decoding file-resources... → files-resources 디코딩 I: Decoding values */* XMLs... → res/ 하위에 xml을 모두 디코딩 I: Baksmaling classes.dex... I: Baksmaling classes2.dex... I: Baksmaling classes3.dex... I: Baksmaling classes4.dex... → class.dex 파일을 samli로 디코딩 I: Copying assets and libs... → assets과 library파일은 copy I: Copying unknown files... I: Copying original files... I: Copying META-INF/services directory → Signing 관련된 파일을 original folder에 copy |
디컴파일이 끝나면 다음과 같이 디컴파일된 소스 파일이 생성된다.
Dex2jar를 사용해 jar 파일로 디컴파일하기
dex2jar를 사용하여 jar파일로 디컴파일할 때는 jd-gui라는 툴도 함께 설치하여 jar파일의 내용(소스코드 및 프로젝트 구조)을 보는 것이 좋다.
dex2jar는 말 그대로 dex를 jar로 변환해주는 도구이다.
https://github.com/pxb1988/dex2jar 다음 링크에서 dex2jar를 다운받는다.
그리고 http://java-decompiler.github.io/ 다음 링크에서 jd-gui를 다운받는다.
dex2jar 파일은 apktool처럼 C:\Windows 경로에 배치시켜 cmd에서 바로 사용할 수 있게 한다. (다른 경로에 위치해도 무관)
그리고 다음과 같이 명령어를 입력하면 jar파일로 디컴파일된다.
> d2j-dex2jar.bat {apk 파일} |
다음과 같이 실행되면 jar파일로 디컴파일된 것이다.
디컴파일을 실행한 폴더에 다음과 같이 jar파일이 생성되었다.
해당 파일을 jd-gui 툴로 열면 아래와 같이 자바 코드를 확인할 수 있다.
클래스명이 의미없는 알파벳으로 바뀌고, 소스코드 안 변수명들도 모두 의미없는 문자로 변경된 것을 확인할 수 있다.
난독화 전, 후 비교 사진
'Android' 카테고리의 다른 글
Android Manifest에 <queries> 추가하여 패키지 공개 상태 요구사항 선언하기 (0) | 2023.08.13 |
---|---|
Android FCM 알림 샘플앱 개발가이드 (0) | 2023.08.13 |
안드로이드 개발하면서 참고했던 글 모음(2019~2021) (0) | 2023.08.13 |
[Android] 안드로이드 log 찍기, logcat 확인 (0) | 2022.09.15 |
[Android] 화면 터치 좌표값 얻기, 파일 입출력 (0) | 2022.09.06 |