반응형
해당 글에서는 React Native 환경에서 Andriod App의 디컴파일 과정을 통해서 소스코드를 난독화하는 과정을 확인해 봅니다.
1) 역 분석(Reverse Engineering) 방지
💡 역 분석(Reverse Engineering) 방지
- 역 분석이란 앱 내의 소스코드를 탐색하여서 이를 분석하고 불법 복제 및 해킹을 하려는 시도에 대해서 이를 막는 기술적인 방법을 의미합니다. 이를 방지하는 것이 역 분석 방지입니다.
- 모바일 앱 개발에서는 이 방법이 중요한 이유는 지적 재산권 보호, 사용자 데이터 보안, 불법 복제 방지, 해킹 방지에 도움을 줄 수 있기에 중요합니다.
1. 문제점 : APK 파일 디컴파일 후 자바 소스코드로 변환 시 소스코드 분석이 가능함을 확인
💡문제점 : APK 파일 디컴파일 후 자바 소스코드로 변환 시 소스코드 분석이 가능함을 확인
- Google Play Store나 다른 소스코드에서 APK 파일을 다운로드하여서 dex2jar, JD-GUI와 같은 도구를 사용하여 APK 파일을 디컴파일합니다.
- 이러한 디 컴파일을 자바 소스코드 형태로 변환하고, 변환된 자바 소스코드를 검토하여 앱의 구조, 로직, 보안 메커니즘 등을 분석하여 소스코드를 분석할 수 있습니다.
- 이를 통해 악의적인 사용자가 앱을 분석할 수 있기에 이에 대한 보안적인 조치가 필요합니다.
💡 아래와 같이 디컴파일 과정을 통해서 APK 파일을 확인하였을 때, 모든 소스코드가 노출이 되었음이 확인되었습니다.
💡아래의 과정을 통해서 소스코드를 난독화를 하면 아래와 같이 변경이 됩니다.
- 일부 변경되지 않은 소스코드는 해당 기능이 수행되기 위해서는 난독화를 허용하지 않는 경우입니다.
2. Google Play Store에 올린 건 안전할까?
💡Google Play Store에 올린 건 안전할까?
- 아닙니다. Google Play에서 다운로드한 프로그램도 APK 추출하여 디컴파일 과정을 통해 이를 분석할 수 있기에 이에 대한 난독화 작업을 통해서 앱의 보안을 강화해야 합니다.
💡 아래와 같은 앱을 통해서 다양한 앱 내의 APK 추출하여 디컴파일 과정을 통해서 소스코드 내 정보들을 추출할 수 있습니다.
2) 디컴파일(Decompile)
💡디컴파일(Decompile)
- 컴파일된 프로그램을 원래의 소스 코드나 그와 유사항 형태로 변환하는 과정을 의미합니다.
- 프로그램 분석, 버그 수정, 보안 취약점 탐지, 호환성 확보와 같은 분석을 위해서 사용이 됩니다.
특징 | 설명 |
원리 | 컴파일된 프로그램을 원본 소스 코드 또는 유사한 형태로 변환 |
목적 | 프로그램 분석, 버그 수정, 보안 취약점 탐지, 호환성 확보 |
장점 | 소스 코드 복원, 프로그램 구조 이해, 레거시 시스템 분석 |
단점 | 완벽한 원본 복원 어려움, 법적/윤리적 문제 가능성 |
적용 분야 | 소프트웨어 역공학, 악성코드 분석, 호환성 문제 해결 |
3) 디컴파일 수행 도구 준비
1. apktool, dex2jar 설치
💡apktool, dex2jar 준비
- homebrew를 통해서 각각을 설치합니다.
도구 | 설명 |
apktool | Android 애플리케이션 패키지(APK) 파일을 디컴파일하고 리컴파일하는 데 사용되는 도구입니다. |
dex2jar | Android 앱의 DEX (Dalvik Executable) 파일을 Java JAR 파일로 변환하는 도구입니다. |
# homebrew를 통해 apktool과 dex2jar를 설치합니다.
$ brew install apktool dex2jar
[ 더 알아보기 ]
💡 리컴파일(Recompile)은 뭘까?
- 디컴파일된 코드나 수정된 소스 코드를 다시 실행 가능한 형태로 변환하는 과정
2. JD-GUI 설치 및 설정
💡JD-GUI(Java Decompiler - Graphical User Interface) 설치 및 설정
- Java 클래스 파일이나 JAR 파일을 소스 코드 형태로 볼 수 있게 해주는 도구입니다.
- jar, war, aar 파일 내부의 클래스 파일을 쉽게 탐색하고 볼 수 있는 기능을 제공하며 디컴파일 된 소스코드를 저장하고 내보낼 수 있는 기능을 제공합니다.
- 주로 소프트웨어 개발자, 보안 연구원, 리버스 엔지니어링 전문가들이 코드 분석, 디버깅, 보안 취약점 검사 등의 목적으로 사용합니다.
2.1. MacOS용 JD-GUI를 다운로드합니다.
💡 MacOS용 JD-GUI를 다운로드합니다
- 아래의 사이트에 접근하여 파일을 다운로드합니다.
2.2. 실행을 하면 아래와 같은 오류가 발생합니다. : ERROR launching 'JD-GUI'
💡실행을 하면 아래와 같은 오류가 발생합니다. :ERROR launching 'JD-GUI'
- ERROR launching 'JD-GUI'No suitable Java version found on your system! This program requires Java 1.8+ Make sure you install the required Java version.
2.3. 다운로드 한 JD-GUI를 선택하고 ‘패키지 내용 보기’를 선택합니다.
💡다운로드 한 JD-GUI를 선택하고 ‘패키지 내용 보기’를 선택합니다.
- JD-GUI를 선택하고 패키지 내용 보기를 선택합니다.
2.4. 패키지 내의 /Contents/MacOS/universalJavaApplicationStub.sh 경로에 접근하여 파일을 수정합니다.
💡 패키지 내의 /Contents/MacOS/universalJavaApplicationStub.sh 경로에 접근하여 파일을 수정합니다.
- 패키지 내용 보기가 선택되었으면 아래의 경로로 이동하여 .sh 파일을 열어서 아래와 같이 JAVA_HOME에 대한 설정 정보를 추가하고 저장합니다.
# 아래의 내용을 추가합니다.
$ export JAVA_HOME=$(/usr/libexec/java_home -v11)
2.5. 추가하고 실행하였지만, JD-GUI.app에서 즉시 꺼짐 증상이 발생하였습니다.
💡추가하고 실행하였지만, JD-GUI.app에서 즉시 꺼짐 증상이 발생하였습니다.
- 이를 위한 해결 방법으로는 터미널에서 다운로드한 jd-gui-osx-1.6.6 디렉터리에 접근하여 아래의 명령어를 수행하여 실행하면 정상적으로 수행되었음을 확인할 수 있습니다.
# 터미널에서 JD-GUI.app을 실행합니다.
$ java -jar JD-GUI.app/Contents/Resources/Java/jd-gui-1.6.6-min.jar
4) 디컴파일 수행
1. APK를 준비합니다.
2. apktool을 이용하여 디 컴파일을 수행합니다.
# apktool을 사용하여 '19.apk'파일을 디컴파일 합니다.
$ apktool d -s -o decompile 19.apk
💡 아래와 같은 폴더와 파일들이 생성이 되었습니다.
3. decomplie 폴더에 접근하여 d2j-dex2jar를 통해서 .jar 파일을 생성합니다.
💡decomplie 폴더에 접근하여 d2j-dex2jar를 통해서 .jar 파일을 생성합니다.
- 디 컴파일된 폴더 내에서 classes.dex 파일은 Android 앱의 컴파일된 코드를 포함하고 있는 파일입니다.
# decomplie 폴더에 접근합니다.
$ cd decompile
# d2j-dex2jar 도구는 이 DEX 파일을 Java 클래스 파일로 변환합니다.
$ d2j-dex2jar classes.dex
4. 생성된 classes-dex2jar.jar 파일을 확인합니다.
5. JD-GUI를 이용하여 생성된 파일을 열어줍니다.
6. 생성된 파일의 소스코드를 모두 확인할 수 있습니다.
💡[참고] 이전의 소스코드에 비해서 바뀜을 확인하였습니다.
5) 디컴파일에 대한 난독화 방법 : ProGuard
1. Progruard
💡Progruard
- Java 바이트코드를 최적화하고 난독화하는 오픈 소스 도구입니다. Android 앱 개발에서 주로 사용됩니다.
- 앱의 크기를 줄이고, 성능을 개선하며, 소스 코드를 보호할 수 있습니다.
- 특히 난독화 기능은 앱의 리버스 엔지니어링을 어렵게 만들어 지적 재산권 보호에 도움을 줍니다.
기능 | 설명 |
코드 축소 (Shrinking) | 사용되지 않는 클래스, 필드, 메서드 등을 제거하여 앱 크기를 줄입니다. |
최적화 (Optimization) | 바이트코드를 분석하고 최적화하여 앱 성능을 향상시킵니다. |
난독화 (Obfuscation) | 클래스, 필드, 메서드 이름을 의미 없는 짧은 이름으로 변경하여 역공학을 어렵게 만듭니다. |
사전 검증 (Preverification) | Java 6 이상의 클래스 파일에 대해 사전 검증을 수행하여 런타임 검증 과정을 최적화합니다. |
2. ProGuard 적용방안
💡 ProGuard 적용방안
- app/build.gradle 파일 내에 아래와 같이 지정이 되어 있습니다.
1. enableProguardInReleaseBuilds = true : ProGuard의 설정을 활성화하였습니다.
2. minifyEnabled enableProguardInReleaseBuilds : 이 설정은 release 빌드에서 코드 최소화(난독화 포함)를 활성화합니다.
3. proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" : 이 부분은 ProGuard 규칙 파일을 지정합니다.
파일 명 | 설명 |
proguard-android.txt | Android SDK에서 제공하는 기본 ProGuard 규칙 파일. 일반적인 Android 앱 개발에 필요한 기본적인 난독화 규칙들이 포함되어 있음. |
proguard-rules.pro | 개발자가 직접 작성하고 관리하는 프로젝트 특정 ProGuard 규칙 파일. 앱의 특정 요구사항에 맞춰 추가적인 난독화 규칙이나 예외 사항을 정의할 수 있음. |
def enableProguardInReleaseBuilds = true // proGuard 활성화
android {
buildTypes {
debug {
debuggable true
signingConfig signingConfigs.debug
}
release {
debuggable false
signingConfig signingConfigs.release
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
firebaseCrashlytics {
mappingFileUploadEnabled true
}
}
}
}
3. proguard-rules.pro
💡proguard-rules.pro
- Android 프로젝트에서 ProGuard 도구의 동작을 제어하는 중요한 설정 파일입니다.
기능 | 설명 |
커스텀 규칙 정의 | 프로젝트에 특화된 ProGuard 규칙을 정의하여 기본 설정을 보완하거나 수정 |
코드 보존 설정 | -keep 옵션으로 특정 코드를 난독화나 최적화에서 제외하여 앱의 정상 작동 보장 |
라이브러리 관련 설정 | 외부 라이브러리의 정상 작동을 위한 특별 규칙 정의 |
최적화 및 난독화 조정 | 특정 클래스나 패키지에 대한 최적화 및 난독화 수준을 세밀하게 조정 |
💡라이브러리 사용에 따라서 아래와 같이 적용을 합니다.
- 각 라이브러리나 프레임워크의 핵심 기능이 난독화로 인해 손상되지 않도록 보호합니다.
- 이를 통해 앱의 정상적인 작동을 보장하면서도, 다른 부분의 코드는 난독화하여 보안을 강화할 수 있습니다.
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# <http://developer.android.com/guide/developing/tools/proguard.html>
# Add any project specific keep options here:
-keep class com.facebook.react.** { *; }
-keep class com.swmansion.** { *; }
-keep class expo.modules.** { *; }
-keep class io.xogus.reactnative.versioncheck.** { *; }
-keep class ai.onnxruntime.** { *; }
6) 작업 결과
💡작업 결과
- 난독화를 통해서 아래와 같은 난독화 기법이 적용되었고, 적용 결과를 확인해 봅니다.
난독화 기법 | 설명 |
패키지 이름 변경 | 의미 있는 패키지 이름을 무의미한 짧은 이름(예: a, b, c)으로 변경 |
클래스 이름 변경 | 클래스 이름을 알아보기 어려운 문자열로 대체 |
구조 변경 | 패키지 구조를 재배치하여 원래의 구조를 파악하기 어렵게 만듦 |
메서드 이름 변경 | 메서드 이름을 난독화하여 기능 유추를 어렵게 함 |
1. 패키지 이름 변경
💡패키지 확인
- 난독화 적용 이후 a1, b1, c1 등등 판별이 불가능하게 패키지가 구성이 되었음을 확인되었습니다.
2. 클래스 이름 변경
3. 메서드 이름 변경
오늘도 감사합니다. 😀
반응형