React & React Native/환경 설정 및 구성

[RN] Android 디컴파일을 통한 소스코드 난독화 적용 방법 : 역분석(Reverse Engineering) 방지

adjh54 2024. 10. 8. 20:00
반응형
해당 글에서는 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 추출하여 디컴파일 과정을 통해서 소스코드 내 정보들을 추출할 수 있습니다.
 

App APK Extractor & Analyzer - Google Play 앱

사용자 앱, 시스템 앱을 APK로 내보내기 및 저장, 앱 정보 분석 및 보기

play.google.com

 

 

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 does not run since Big Sur · Issue #161798 · Homebrew/homebrew-cask

Verification I understand that if I ignore these instructions, my issue may be closed without review. I have retried my command with --force. I ran brew update-reset && brew update and retried my c...

github.com

# 터미널에서 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. 메서드 이름 변경


 

 

 

 

 

오늘도 감사합니다. 😀

 

 

 

 

반응형