0. 준비물
1. 루팅 된 휴대폰 기기 [노트북 유선 연결]
2. adb 설치
3. IDA, JEB, JADX gui 설치
4. frida-server 및 frida 설치
1. APK 다운로드
APKPure: 안드로이드에서 무료 APK 다운로드기로 APK 다운로드
APKPure는 안드로이드용 무료 APK 다운로드 프로그램입니다. 안전하고 신뢰할 수 있으며 바이러스가 없습니다. APKPure를 사용하면 인기 있는 앱과 게임을 쉽게 다운로드하고, APK/XAPK 파일을 안드로
apkpure.com
진단하기 앞서 APK 가 필요하기에 원하는 애플리케이션을 선택하여 APK를 다운로드하아야 한다.
2. adb install
원하는 app를 다운로드했다면 휴대폰에도 설치를 해줘야 한다.
adb 가 깔려있어 휴대폰과 유선 연결이 된 상태라면 APK 파일을 가지고 설치할 수 있다.
[컴퓨터(CMD) => 휴대폰]
adb install "{설치 시킬 APK 경로}"
[완료 되었을 때 예시]
Performing Streamed Install
Success
3. 베이스라인 확인


보통 어플을 실행할 때 루팅체크를 하고 탐지가 되면 어플이 나가지는 게 보통이다.
이 어플은 테스트 용도라 그런지 루팅만 탐지하는 걸로 보인다.
4. JEB => APK 분석
4-1. 문자열 리소스 확인
가장 먼저 JEB의 'Quick Search' 기능을 통해서 앱이 루팅을 감지했을 때 출력하는 'DETECTED'를 검색한다.

검색 결과 RootingFragment 위치에서 해당 문자열이 사용되고 있음을 확인헀다.
4-2. UI와 로직 연결 고리 확인
화면에 ' DETECTED'를 띄우기 전에 어떤 클래스가 판단을 내리는지 확인한다.

RootingFragment 소스 코드로 점프를 한 상태이다.
코드를 확인해 보면 RootingDetector 객체를 생성하고 클래스의 결과값에 따라 'Detected!' 또는 'Passed'를 출력하는 조건문이 있다.
어떻게 탐지하는지 알아내기 위해서 RootingDetector로 이동해 보자.
4-3. 탐지 엔진 분석

RootingDetector 클래스 내부에는 두 가지 핵심 메서드가 존재한다.
checkRootingPackage(), checkSuBinary()
이 함수들은 직접 값을 가지고 있지 않고 Constants 클래스에 정의된 리스트를 참조하여 검사를 수행하는 구조이다.
구체적으로 어떤 리스트를 참조하는지 확인해 보자.
4-4. 리스트 확인

너무 많아서 요약하자면
관리 앱 패키지 [Magisk, KingRoot, SuperSU 등등] ,
SU 바이너리 파일명 [su 권한 감지, busybox, magisk 파일들 감지]
특정 애뮬레이터 파일 [Genymotion, NOX, Andy 등]
시스템 속성, 가상화 통신 여부 확인 많다.
이걸 전부 하나하나 우회할 건 아니니까 이 정도 리스트에서 탐지하고 있다는 정도만 알면 될 거 같다.
5. frida 우회
블랙리스트를 일일이 피하는 대신에 탐지결과에 대한 메서드의 리턴값을 조작하는 게 편하다.
따라서 RootingDetector의 탐지 결과가 무엇이든 상관없이 무조건 'false'(탐지되지 않음)을 반환시키도록 한다.
Java.perform(function() {
console.log("[*] Starting Dream Detector Bypass...");
// 1. RootingDetector 우회
var RootingDetector = Java.use("android.com.dream_detector.RootingDetector");
RootingDetector.checkRootingPackage.implementation = function() {
console.log("[+] Bypassing Rooting Package Check -> Returned FALSE");
return false;
};
RootingDetector.checkSuBinary.implementation = function() {
console.log("[+] Bypassing SU Binary Check -> Returned FALSE");
return false;
};
// 2. DebuggingDetector 우회
var DebuggingDetector = Java.use("android.com.dream_detector.DebuggingDetector");
DebuggingDetector.checkPath.implementation = function() {
console.log("[+] Bypassing Debugging Path Check -> Returned FALSE");
return false;
};
DebuggingDetector.checkProp.implementation = function() {
console.log("[+] Bypassing Debugging Prop Check -> Returned FALSE");
return false;
};
DebuggingDetector.checkProcStatus.implementation = function() {
console.log("[+] Bypassing TracerPid Check -> Returned FALSE");
var BooleanClass = Java.use("java.lang.Boolean");
return BooleanClass.valueOf(false);
};
console.log("[*] All checks are now hooked. Press CHECK buttons in the app!");
});
이 코드를 통해서 frida로 실행해 보자

Check를 요청하면 PASSED 가 출력되는 걸 확인할 수 있다.
'Mobile_security' 카테고리의 다른 글
| 0. Android - NDK 학습 (0) | 2025.12.22 |
|---|---|
| 0. Android - 아키텍처 (0) | 2025.12.17 |
| 0. Android,IOS - 모바일 사전 지식 정리 (0) | 2025.12.11 |
| 0. Android - AVD, ADB, Rooting, Pm (1) | 2025.07.22 |
| 0. Android Components (글 주의) (0) | 2025.02.01 |
