네이티브 라이브러리 리버싱
Reading time: 7 minutes
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.
자세한 정보: https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html
Android 앱은 일반적으로 성능이 중요한 작업을 위해 C 또는 C++로 작성된 네이티브 라이브러리를 사용할 수 있습니다. 악성 코드 제작자들도 ELF shared objects가 DEX/OAT 바이트코드보다 디컴파일하기 더 어렵기 때문에 이러한 라이브러리를 악용합니다.
이 페이지는 Android .so
파일 리버싱을 더 쉽게 만드는 실용적인 워크플로우와 최신 도구 개선사항(2023-2025)에 중점을 둡니다.
새로 확보한 libfoo.so
에 대한 빠른 분류 워크플로우
- 라이브러리 추출
# From an installed application
adb shell "run-as <pkg> cat lib/arm64-v8a/libfoo.so" > libfoo.so
# Or from the APK (zip)
unzip -j target.apk "lib/*/libfoo.so" -d extracted_libs/
- 아키텍처 및 보호 식별
file libfoo.so # arm64 or arm32 / x86
readelf -h libfoo.so # OS ABI, PIE, NX, RELRO, etc.
checksec --file libfoo.so # (peda/pwntools)
- 내보낸 심볼 및 JNI 바인딩 나열
readelf -s libfoo.so | grep ' Java_' # dynamic-linked JNI
strings libfoo.so | grep -i "RegisterNatives" -n # static-registered JNI
- 디컴파일러에서 로드 (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) 및 자동 분석 실행. 신규 Ghidra 버전은 AArch64 decompiler가 PAC/BTI stubs 및 MTE tags를 인식하도록 도입되어 Android 14 NDK로 빌드된 라이브러리 분석이 크게 향상되었습니다.
- 정적 vs 동적 리버싱 결정: 스트립되었거나 난독화된 코드는 종종 instrumentation(Frida, ptrace/gdbserver, LLDB)이 필요합니다.
Dynamic Instrumentation (Frida ≥ 16)
Frida의 16 시리즈는 대상이 최신 Clang/LLD 최적화를 사용할 때 도움이 되는 여러 Android 전용 개선사항을 도입했습니다:
thumb-relocator
은 이제 LLD의 aggressive alignment(--icf=all
)로 생성된 hook tiny ARM/Thumb functions를 처리할 수 있습니다.- Android에서 ELF import slots의 열거 및 재바인딩이 작동하여, inline hooks가 거부될 때 모듈별
dlopen()
/dlsym()
패치가 가능해졌습니다. - 앱이 Android 14에서
--enable-optimizations
로 컴파일될 때 사용되는 새로운 ART quick-entrypoint를 위한 Java hooking이 수정되었습니다.
예: RegisterNatives
를 통해 등록된 모든 함수를 열거하고 런타임에 그 주소를 덤프하기:
Java.perform(function () {
var Runtime = Java.use('java.lang.Runtime');
var register = Module.findExportByName(null, 'RegisterNatives');
Interceptor.attach(register, {
onEnter(args) {
var envPtr = args[0];
var clazz = Java.cast(args[1], Java.use('java.lang.Class'));
var methods = args[2];
var count = args[3].toInt32();
console.log('[+] RegisterNatives on ' + clazz.getName() + ' -> ' + count + ' methods');
// iterate & dump (JNI nativeMethod struct: name, sig, fnPtr)
}
});
});
Frida는 PAC/BTI-enabled 장치(Pixel 8/Android 14+)에서 frida-server 16.2 이상을 사용하면 바로 동작합니다 – 이전 버전은 inline hooks용 패딩을 찾지 못했습니다.
Process-local JNI telemetry via preloaded .so (SoTap)
완전한 instrumentation이 과하거나 차단된 경우, 대상 프로세스 내부에 작은 로거를 사전 로드하여 네이티브 수준의 가시성을 확보할 수 있습니다. SoTap은 동일 앱 프로세스 내 다른 JNI (.so) 라이브러리의 런타임 동작을 기록하는 경량 Android 네이티브(.so) 라이브러리입니다(루트 불필요).
Key properties:
- Initializes early and observes JNI/native interactions inside the process that loads it.
- Persists logs using multiple writable paths with graceful fallback to Logcat when storage is restricted.
- Source-customizable: edit sotap.c to extend/adjust what gets logged and rebuild per ABI.
Setup (repack the APK):
- Drop the proper ABI build into the APK so the loader can resolve libsotap.so:
- lib/arm64-v8a/libsotap.so (for arm64)
- lib/armeabi-v7a/libsotap.so (for arm32)
- Ensure SoTap loads before other JNI libs. Inject a call early (e.g., Application subclass static initializer or onCreate) so the logger is initialized first. Smali snippet example:
const-string v0, "sotap"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
- Rebuild/sign/install, run the app, then collect logs.
Log paths (checked in order):
/data/user/0/%s/files/sotap.log
/data/data/%s/files/sotap.log
/sdcard/Android/data/%s/files/sotap.log
/sdcard/Download/sotap-%s.log
# If all fail: fallback to Logcat only
Notes and troubleshooting:
- ABI 정렬은 필수입니다. 불일치는 UnsatisfiedLinkError 를 발생시키고 logger 가 로드되지 않습니다.
- 저장 공간 제약은 현대 Android 에서 흔합니다; 파일 쓰기가 실패하면 SoTap 은 여전히 Logcat 을 통해 출력합니다.
- 동작/출력 수준(verbosity)은 사용자화하도록 설계되었습니다; sotap.c 를 편집한 뒤 소스에서 다시 빌드하세요.
이 접근법은 프로세스 시작 시점부터 네이티브 호출 흐름을 관찰해야 하는 malware 정리(malware triage)와 JNI 디버깅에 유용합니다. 특히 root/시스템 전체 훅이 불가능한 경우에 중요합니다.
Recent vulnerabilities worth hunting for in APKs
Year | CVE | Affected library | Notes |
---|---|---|---|
2023 | CVE-2023-4863 | libwebp ≤ 1.3.1 | 네이티브 코드에서 WebP 이미지를 디코드할 때 도달 가능한 힙 버퍼 오버플로우. 여러 Android 앱이 취약한 버전을 번들링합니다. APK 내부에 libwebp.so 가 보이면 버전을 확인하고 익스플로잇 또는 패치 시도를 하세요. |
2024 | Multiple | OpenSSL 3.x series | 여러 메모리 안전성 및 padding-oracle 이슈. 많은 Flutter & ReactNative 번들들이 자체 libcrypto.so 를 포함해 배포됩니다. |
APK 내부에서 타사(third-party) .so
파일을 발견하면 항상 해당 해시를 upstream advisory 와 대조하세요. 모바일에서는 SCA (Software Composition Analysis) 가 드물어 오래된 취약 빌드가 널리 존재합니다.
Anti-Reversing & Hardening trends (Android 13-15)
- Pointer Authentication (PAC) & Branch Target Identification (BTI): Android 14 은 지원되는 ARMv8.3+ 실리콘에서 시스템 라이브러리에 PAC/BTI 를 활성화합니다. 디컴파일러는 이제 PAC 관련 의사 명령(pseudo-instructions)을 표시합니다; 동적 분석을 위해 Frida 는 PAC 를 제거한 후 트램폴린을 주입하지만, 커스텀 트램폴린은 필요한 경우
pacda
/autibsp
를 호출해야 합니다. - MTE & Scudo hardened allocator: memory-tagging 은 옵트인(opt-in) 이지만 많은 Play-Integrity 인식 앱들이
-fsanitize=memtag
로 빌드합니다; 태그 폴트를 캡처하려면setprop arm64.memtag.dump 1
과adb shell am start ...
를 사용하세요. - LLVM Obfuscator (opaque predicates, control-flow flattening): 상용 패커들(예: Bangcle, SecNeo) 이 점점 더 네이티브 코드도 보호합니다.
.rodata
에서 가짜 제어 흐름과 암호화된 문자열 블롭을 예상하세요.
Resources
- Learning ARM Assembly: Azeria Labs – ARM Assembly Basics
- JNI & NDK Documentation: Oracle JNI Spec · Android JNI Tips · NDK Guides
- Debugging Native Libraries: Debug Android Native Libraries Using JEB Decompiler
References
- Frida 16.x change-log (Android hooking, tiny-function relocation) – frida.re/news
- NVD advisory for
libwebp
overflow CVE-2023-4863 – nvd.nist.gov - SoTap: Lightweight in-app JNI (.so) behavior logger – github.com/RezaArbabBot/SoTap
- SoTap Releases – github.com/RezaArbabBot/SoTap/releases
- How to work with SoTap? – t.me/ForYouTillEnd/13
tip
AWS 해킹 배우기 및 연습하기:HackTricks Training AWS Red Team Expert (ARTE)
GCP 해킹 배우기 및 연습하기: HackTricks Training GCP Red Team Expert (GRTE)
Azure 해킹 배우기 및 연습하기:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks 지원하기
- 구독 계획 확인하기!
- **💬 디스코드 그룹 또는 텔레그램 그룹에 참여하거나 트위터 🐦 @hacktricks_live를 팔로우하세요.
- HackTricks 및 HackTricks Cloud 깃허브 리포지토리에 PR을 제출하여 해킹 트릭을 공유하세요.