
안드로이드 앱 리버스 엔지니어링을 더 쉽게 만들어주며, APK 풀링, 디코딩, 리빌드 및 패칭 같은 반복적인 작업을 자동화합니다.
apk.sh는 APK를 가져오기(pull), 디코딩(decoding), 재빌드(rebuilding), 패치(patching)와 같은 반복 작업을 자동화하여 Android 앱의 리버스 엔지니어링을 더 쉽게 만드는 Bash 스크립트입니다.
apk.sh는 기본적으로 apktool을 사용하여 리소스를 디스어셈블, 디코딩 및 재빌드하고, 일부 bash를 사용하여 frida 가젯 인젝션 프로세스를 자동화합니다. 또한 앱 번들/분할 APK를 지원합니다.
⬅️ 기기에서 APK를 가져오는 것은 ./apk.sh pull <package_name>을 실행하는 것만큼 간단합니다.
🔧 APK를 디코딩하는 것은 ./apk.sh decode <apk_name>을 실행하는 것만큼 간단합니다.
🔩 APK를 재빌드하는 것은 ./apk.sh build <apk_dir>을 실행하는 것만큼 간단합니다.
apk.sh pull 기기에서 APK를 가져옵니다.
앱 번들/분할 APK를 지원하므로, 분할 APK가 단일 APK로 결합됩니다 (이는 패치에 유용합니다).
패키지가 앱 번들이나 분할 APK인 경우 apk.sh는 APK를 단일 APK로 결합하고 모든 공용 리소스 식별자를 수정합니다.
apk.sh patch는 시작 시 frida-gadget.so를 로드하도록 APK를 패치합니다.
frida-gadget.so는 계측될 프로그램이 로드하도록 설계된 Frida의 공유 라이브러리입니다 (주입 모드가 적합하지 않을 때). 라이브러리를 로드하기만 하면 frida-trace와 같은 기존 Frida 기반 도구를 사용하여 상호 작용할 수 있습니다. 또한 외부 통신 없이 파일 시스템에서 스크립트를 실행할 수 있는 완전 자율 접근 방식을 지원합니다.
APK 패치는 ./apk.sh patch <apk_name> --arch arm을 실행하는 것만큼 간단합니다.
또한 JSON으로 Frida 가젯 구성을 지정할 수 있습니다: ./apk.sh patch <apk_name> --arch arm --gadget-conf <config.json>
#30과 같은 "already interned" apktool d 오류가 발생하면 --only-main-classes 플래그를 전달할 수 있으며, 이 플래그는 APK 디코딩 시 apktool에 전달됩니다.
기본 상호 작용에서 Frida Gadget은 localhost:27042에서 수신 대기하는 frida-server 호환 인터페이스를 노출합니다.早期 계측을 달성하기 위해 Frida는 Gadget의 생성자 함수가 프로세스에 attach()하거나 일반적인 spawn() -> attach() -> ...계측 적용... 단계를 거친 후 resume()을 호출할 때까지 차단하도록 합니다.
이 차단 동작을 원하지 않고 프로그램이 바로 부팅되도록 하거나 다른 인터페이스나 포트에서 수신 대기하도록 하려면 JSON 구성 파일을 통해 이를 사용자 정의할 수 있습니다.
기본 구성은 다음과 같습니다:
{
"interaction": {
"type": "listen",
"address": "127.0.0.1",
"port": 27042,
"on_port_conflict": "fail",
"on_load": "wait"
}
}
--gadget-conf 옵션으로 가젯 구성 파일을 apk.sh에 전달할 수 있습니다.
일반적으로 제안되는 구성은 다음과 같습니다:
{
"interaction": {
"type": "script",
"path": "/data/local/tmp/script.js",
"on_change":"reload"
}
}
script.js는 다음과 같을 수 있습니다:
var android_log_write = new NativeFunction(
Module.getExportByName(null, '__android_log_write'),
'int',
['int', 'pointer', 'pointer']
);
var tag = Memory.allocUtf8String("[frida-script][ax]");
var work = function() {
setTimeout(function() {
android_log_write(3, tag, Memory.allocUtf8String("ping @ " + Date.now()));
work();
}, 1000);
}
work();
android_log_write(3, tag, Memory.allocUtf8String(">--(O.o)-<"));
adb push script.js /data/local/tmp
./apk.sh patch <apk_name> --arch arm --gadget-conf <config.json>
adb install file.gadget.apk
스크립트 상호 작용 유형을 사용할 때 frida codeshare의 모든 스크립트에서 console.log 출력을 logcat에 출력하려면 다음 코드를 추가하세요.
// print to logcat the console.log output
// see: https://github.com/frida/frida/issues/382
var android_log_write = new NativeFunction(
Module.getExportByName(null, '__android_log_write'),
'int',
['int', 'pointer', 'pointer']
);
var tag = Memory.allocUtf8String("[frida-script][ax]");
console.log = function(str) {
android_log_write(3, tag, Memory.allocUtf8String(str));
}
apk.sh [SUBCOMMAND] [APK FILE|APK DIR|PKG NAME] [FLAGS]
apk.sh pull [PKG NAME] [FLAGS]
apk.sh decode [APK FILE] [FLAGS]
apk.sh build [APK DIR] [FLAGS]
apk.sh patch [APK FILE] [FLAGS]
apk.sh rename [APK FILE] [PKG NAME] [FLAGS]
pull 기기/에뮬레이터에서 apk를 가져옵니다.
decode apk를 디코딩합니다.
build apk를 재빌드합니다.
patch apk를 패치합니다.
rename apk 패키지 이름을 변경합니다.
-a, --arch <arch> 패치 시 필수인 대상 아키텍처를 지정합니다.
-g, --gadget-conf <json_file> frida-gadget 구성 파일을 지정합니다. 패치 시 선택 사항입니다.
-n, --net 빌드 시 허용적인 네트워크 보안 구성을 추가합니다. 선택 사항입니다. patch, pull, rename과도 함께 사용할 수 있습니다.
-r, --no-res 디코딩 시 리소스를 디코딩하지 않습니다 (예: apktool -r). 선택 사항입니다. 패치 시 사용할 수 있습니다.
-s, --no-src 디코딩 시 dex를 디스어셈블하지 않습니다 (예: apktool -s). 선택 사항입니다. 패치 시 사용할 수 있습니다.
https://lief-project.github.io/doc/latest/tutorials/09_frida_lief.html
https://koz.io/using-frida-on-android-without-root/
https://github.com/sensepost/objection/
https://github.com/NickstaDB/patch-apk/
https://neo-geo2.gitbook.io/adventures-on-security/frida-scripting-guide/frida-scripting-guide