개요
필자가 개발한 TodoList앱의 Frida 경로 검사 기능은 Frida를 사용할 때 자동으로 생성되는 파일이나 Frida와 관련된 파일들이 저장되어 있는지 검사하여 Frida를 탐지한다.
일반적으로 Frida를 동작시키기 위해 기기 내에 Frida에 필요한 파일들을 저장해놓는 경우가 많다. 또한 Frida가 동작하면서 기기 내에 자동으로 생성하는 파일/디렉토리 또한 존재한다. 만약 이와 관련된 파일들이 기기에서 발견된다면 해당 기기는 높은 확률로 Frida를 통해 앱을 조작하고 있다고 판단할 수 있다.
이번 포스팅에서는 TodoList 앱의 경로검사 우회 소스 코드를 살펴보면서 Frida 탐지 기법 중 경로를 탐지하는로직을 구현해보고, 이를 우회하는 스크립트도 구현해 보겠다.
탐지 로직
checkPath 함수 분석
public boolean checkPath() {
String dirName = "/data/local/tmp";
try {
AtomicBoolean found = new AtomicBoolean(false);
Files.list(new File(dirName).toPath())
.limit(200)
.forEach(path -> {
if (path.toString().contains("frida")) {
found.set(true);
}
});
if (found.get()) {
return true;
}
} catch (IOException ignore) {
}
return false;
}
- 일반적으로 Frida 서버를 열기 위한 frida-server 파일은 안드로이드 내의 임시 경로인 "/data/local/tmp" 내에 저장한다.
Frida 경로 탐지는 이와 같이 생성되는 디렉터리 및 Frida 서버 파일을 탐지하기 위해 "/data/local/tmp" 경로를 탐색한다.
1. Frida 관련 파일 존재 여부를 검사할 /data/local/tmp 경로를 dirName 변수에 저장한다.
String dirName = "/data/local/tmp";
2. 검사 결과를 저장할 AtomicBoolean 객체 found의 값을 False로 설정하여 생성한다.
AtomicBoolean found = new AtomicBoolean(false);
3. File 객체로 dirName 경로의 디렉터리를 열고, Files.list 함수를 이용해 디렉터리 내의 파일 이름 중 frida 라는 이름이 포함된 파일이 있는지 검사한다.
파일이 존재한다면 found 변수를 True로 설정한다.
Files.list(new File(dirName).toPath())
.limit(200)
.forEach(path -> {
if (path.toString().contains("frida"))
found.set(true);
});
- found.set함수를 통해 found 값을 확인하고, 확인된 값에 따라 True나, False를 반환한다.
탐지 우회
환경 설정
Frida 탐지 기능을 우회하기 전에 실습을 위해 Frida 경로를 탐지한 상태가 되도록 만들어야 한다.
- 앞선 코드 분석 과정에서 /data/local/tmp 경로의 파일 중 "frida" 라는 문자열이 포함된 파일명을 가진 경우 탐지된다는 사실을 확인했다.
- 따라서 /data/local/tmp 경로에 Frida 서버 파일과 같이 파일명에 frida 를 포함하는 파일을 생성하여 Frida 파일 검사 기능에서 탐지가 되도록 설정한다.
Frida 서버를 실행 중이라면 앱을 실행하면 경고 메시지가 뜨면서 차단이 될 것이다.
다만 "/data/local/tmp"는 일반 앱 권한으로 열람할 수 없는 디렉토리이다. 따라서 해당 디렉토리에 권한을 부여해야 올바르게 탐지할 수 있다.
설정 방법
"/data/local/tmp" 디렉토리의 권한 부여
generic_x86_64_arm64:/ # chmod 777 /data/local/tmp
안드로이드 7.0(API 24) 이상부터는 SELinux 정책 및 앱 샌드박스 보안 강화로 인해 일반 권한의 앱이 "/data/local/tmp" 디렉터리를 직접 리스팅(Files.list())할 수 없게 차단된다.
따라서 진단 환경에서 이 탐지 로직이 정상 작동(True 반환)하는지 검증하기 위해, 테스트 기기에서 "chmod 777" 명령을 통해 임시로 권한을 개방한 뒤 실습을 진행하였다.
설정 확인

우회 아이디어
checkPath 함수 반환값 조작
- checkPath 함수의 반환 값은 Frida 파일 탐지 여부를 의미한다.
- 따라서 해당 함수가 항상 False 를 반환하도록 후킹한다면 Frida 관련 파일이 있어도 이를 탐지되지 않은 것처럼 조작할 수 있다.
String.contains 함수 파라미터 변조
- checkPath 함수의 반환 값은 path변수 중 "frida"라는 문자열이 포함되어 있는지 여부를 통해 결정된다.
- 따라서 String.contains 함수를 후킹 하여 만약 "frida"라는 문자열이 파라미터로 전달되면, 이를 조작하여 "frida"가 아닌 다른 문자열이 전달되도록 할 수 있다.
우회 스크립트 작성
function modifyCheckPathRet() {
Java.perform(function() {
var FridaDetector = Java.use("com.example.todolist_for_frida.FridaDetector");
FridaDetector.checkPath.implementation = function() {
return false;
};
});
}
function modifyStrContainsParameter() {
Java.perform(function() {
var String_ = Java.use("java.lang.String");
String_.contains.overload('java.lang.CharSequence').implementation = function(s) {
if (s == "frida")
s = "**NOT_EXIST**";
return String_.contains.overload('java.lang.CharSequence').call(this, s);
};
});
}
modifyCheckPathRet();
modifyStrContainsParameter();
modifyCheckPathRet 함수 : checkPath 반환값 조작
먼저 Java.use 함수를 사용해 Frida 내에서 FridaDetector 클래스에 접근할 수 있도록 Wrapper를 제공받는다.
var FridaDetector = Java.use("com.example.todolist_for_frida.FridaDetector");
제공받은 Wrapper를 통해 클래스 내의 checkPath 함수에 접근할 수 있다.
Frida에서 자바 단의 함수를 후킹할 때에는 일반적으로 클래스 Wrapper를 제공받아 후킹할 함수의 implementation을 자바스크립트 함수로 덮는 방식을 사용한다.
- 따라서 checkPath 함수의 implementation에 항상 False 를 반환하도록 작성된 함수를 전달하여 checkPath 함수가 매번 False를 반환하도록 후킹할 수 있다.
FridaDetector.checkPath.implementation = function() {
return false;
}
modifyStrContainsParameter 함수 : String.contains 함수 파라미터 변조
Strings.contains 는 문자열 객체 내의 특정 문자열이 포함되어있는지 검사하기 위한 함수이다.
TodoList 앱은 디렉토리 내의 파일 이름 중 "frida" 라는 문자열이 존재하는지 검사하기 위해 해당 함수를 사용한다.
- 일반적인 앱이 "frida"라는 문자열이 특정 문자열 내에 존재하는지 확인할 경우가 거의 없기 때문에 "frida"라는 문자열이 포함되었는지 검사한다면 이는 Frida 경로 탐지를 위한 것이라고 볼 수 있다.
var String_ = Java.use("java.lang.String");
(...)
if (s == "frida")
s = "**NOT_EXIST**";
- String 클래스의 Wrapper를 제공받고, contains 함수를 후킹하여 만약 파라미터로 전달된 값이 "frida" 와 일치한다면 이를 *NOT_EXIST*라는 문자열로 변경하도록 함수를 후킹하였다.
return String_.contains.overload('java.lang.CharSequence').call(this, s);
- String.contains 함수는 다양한 형태의 파라미터를 받을 수 있도록 오버로딩으로 선언되어 있다.
- 만약 Frida에서 오버로딩으로 선언된 함수를 후킹하고 싶을 때에는 overload(signature)를 통해 어떤 타입을 가지는 함수를 후킹할지 선택할 수 있다.
- checkPath 함수의 경우 CharSequence 타입을 인자로 받는 함수를 사용했기 때문에 overload('java.lang.CharSequence')를 통해 후킹할 함수를 선택할 수 있다.
String.contains 함수 파라미터 변조 방식의 한계
- String.contains를 오버라이딩하는 방식은 강력하지만, 만약 앱 내에서 정상적인 비즈니스 로직(예: 특정 URL, 텍스트 처리 등) 중에 'frida'라는 문자열이 포함되어 있다면 원치 않는 로직 오작동이나 크래시(Crash)를 유발할 수 있다.
- 따라서 실무 진단 시에는 무분별한 표준 API 후킹보다는 대상 함수의 호출 스택(Call Stack)을 확인하거나, 특정 클래스 범위 내에서만 동작하도록 예외 처리를 정교하게 구성하는 것이 안전합니다.
스크립트 실행 결과
> frida -U -f com.example.todolist_for_frida -l ./Bypass_Frida_checkPath.js
____
/ _ | Frida 16.1.3 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to Android Emulator 5554 (id=emulator-5554)
Spawned `com.example.todolist_for_frida`. Resuming main thread!
[Android Emulator 5554::com.example.todolist_for_frida ]->

'Mobile App Hacking : Android > Frida 탐지 우회' 카테고리의 다른 글
| 모듈 검사 우회 (0) | 2026.05.27 |
|---|---|
| 포트 검사 우회 (0) | 2026.05.27 |