Translated ['src/mobile-pentesting/android-app-pentesting/reversing-nati

This commit is contained in:
Translator 2025-07-10 21:34:38 +00:00
parent 5427580b0a
commit d18a8c1c45

View File

@ -4,41 +4,92 @@
**자세한 정보는 다음을 확인하세요:** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
안드로이드 앱은 성능이 중요한 작업을 위해 일반적으로 C 또는 C++로 작성된 네이티브 라이브러리를 사용할 수 있습니다. 악성코드 제작자들도 이러한 라이브러리를 사용하며, 이는 DEX 바이트코드보다 리버스 엔지니어링이 더 어렵기 때문입니다. 이 섹션은 어셈블리 언어를 가르치는 대신 안드로이드에 맞춘 리버스 엔지니어링 기술을 강조합니다. 호환성을 위해 ARM 및 x86 버전의 라이브러리가 제공됩니다.
안드로이드 앱은 성능이 중요한 작업을 위해 일반적으로 C 또는 C++로 작성된 네이티브 라이브러리를 사용할 수 있습니다. 악성코드 제작자들도 ELF 공유 객체가 DEX/OAT 바이트코드보다 디컴파일하기 더 어렵기 때문에 이러한 라이브러리를 악용합니다. 이 페이지는 안드로이드 `.so` 파일 리버싱을 더 쉽게 만드는 *실용적인* 워크플로우와 *최근* 도구 개선(2023-2025)에 중점을 둡니다.
### 주요 사항:
---
- **안드로이드 앱의 네이티브 라이브러리:**
- 성능 집약적인 작업에 사용됩니다.
- C 또는 C++로 작성되어 리버스 엔지니어링이 어렵습니다.
- 리눅스 바이너리와 유사한 `.so` (공유 객체) 형식으로 발견됩니다.
- 악성코드 제작자는 분석을 어렵게 만들기 위해 네이티브 코드를 선호합니다.
- **자바 네이티브 인터페이스 (JNI) 및 안드로이드 NDK:**
- JNI는 자바 메서드를 네이티브 코드로 구현할 수 있게 합니다.
- NDK는 네이티브 코드를 작성하기 위한 안드로이드 전용 도구 세트입니다.
- JNI와 NDK는 자바(또는 코틀린) 코드와 네이티브 라이브러리를 연결합니다.
- **라이브러리 로딩 및 실행:**
- 라이브러리는 `System.loadLibrary` 또는 `System.load`를 사용하여 메모리에 로드됩니다.
- 라이브러리 로딩 시 `JNI_OnLoad`가 실행됩니다.
- 자바에서 선언된 네이티브 메서드는 네이티브 함수에 연결되어 실행을 가능하게 합니다.
- **자바 메서드를 네이티브 함수에 연결하기:**
- **동적 링크:** 네이티브 라이브러리의 함수 이름이 특정 패턴과 일치하여 자동 링크가 가능합니다.
- **정적 링크:** `RegisterNatives`를 사용하여 링크하며, 함수 이름 및 구조에 유연성을 제공합니다.
- **리버스 엔지니어링 도구 및 기술:**
- Ghidra 및 IDA Pro와 같은 도구는 네이티브 라이브러리를 분석하는 데 도움을 줍니다.
- `JNIEnv`는 JNI 함수 및 상호작용을 이해하는 데 중요합니다.
- 라이브러리 로딩, 메서드 링크 및 네이티브 함수 식별을 연습할 수 있는 연습문제가 제공됩니다.
### 새로 가져온 `libfoo.so`에 대한 빠른 분류 워크플로우
### 리소스:
1. **라이브러리 추출**
```bash
# 설치된 애플리케이션에서
adb shell "run-as <pkg> cat lib/arm64-v8a/libfoo.so" > libfoo.so
# 또는 APK(압축 파일)에서
unzip -j target.apk "lib/*/libfoo.so" -d extracted_libs/
```
2. **아키텍처 및 보호 확인**
```bash
file libfoo.so # arm64 또는 arm32 / x86
readelf -h libfoo.so # OS ABI, PIE, NX, RELRO 등
checksec --file libfoo.so # (peda/pwntools)
```
3. **내보낸 심볼 및 JNI 바인딩 나열**
```bash
readelf -s libfoo.so | grep ' Java_' # 동적 연결 JNI
strings libfoo.so | grep -i "RegisterNatives" -n # 정적 등록 JNI
```
4. **디컴파일러에 로드** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper 또는 Cutter/Rizin)하고 자동 분석을 실행합니다. 최신 Ghidra 버전은 PAC/BTI 스텁과 MTE 태그를 인식하는 AArch64 디컴파일러를 도입하여 Android 14 NDK로 빌드된 라이브러리 분석을 크게 개선했습니다.
5. **정적 리버싱과 동적 리버싱 결정:** 스트립되거나 난독화된 코드는 종종 *계측* (Frida, ptrace/gdbserver, LLDB)이 필요합니다.
- **ARM 어셈블리 학습:**
- 기본 아키텍처에 대한 깊은 이해를 위해 권장됩니다.
- Azeria Labs의 [ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/)를 추천합니다.
- **JNI 및 NDK 문서:**
- [Oracle의 JNI 사양](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html)
- [안드로이드의 JNI 팁](https://developer.android.com/training/articles/perf-jni)
- [NDK 시작하기](https://developer.android.com/ndk/guides/)
- **네이티브 라이브러리 디버깅:**
- [JEB 디컴파일러를 사용하여 안드로이드 네이티브 라이브러리 디버깅하기](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
---
### 동적 계측 (Frida ≥ 16)
Frida의 16 시리즈는 대상이 최신 Clang/LLD 최적화를 사용할 때 도움이 되는 여러 안드로이드 전용 개선 사항을 도입했습니다:
* `thumb-relocator`는 이제 LLD의 공격적인 정렬(`--icf=all`)로 생성된 *작은 ARM/Thumb 함수*를 *후킹*할 수 있습니다.
* *ELF 가져오기 슬롯*을 나열하고 다시 바인딩하는 것이 안드로이드에서 작동하여 인라인 후크가 거부될 때 모듈별 `dlopen()`/`dlsym()` 패칭을 가능하게 합니다.
* Java 후킹은 안드로이드 14에서 `--enable-optimizations`로 컴파일된 앱에서 사용되는 새로운 **ART 빠른 진입점**에 대해 수정되었습니다.
예: `RegisterNatives`를 통해 등록된 모든 함수 나열 및 런타임에서 주소 덤프:
```javascript
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는 frida-server 16.2 이상을 사용하면 PAC/BTI가 활성화된 장치(Pixel 8/Android 14+)에서 즉시 작동합니다. 이전 버전은 인라인 훅을 위한 패딩을 찾지 못했습니다. citeturn5search2turn5search0
---
### APK에서 추적할 가치가 있는 최근 취약점
| 연도 | CVE | 영향을 받는 라이브러리 | 비고 |
|------|-----|------------------|-------|
|2023|CVE-2023-4863|`libwebp` ≤ 1.3.1|WebP 이미지를 디코딩하는 네이티브 코드에서 접근 가능한 힙 버퍼 오버플로우. 여러 Android 앱이 취약한 버전을 포함하고 있습니다. APK 내에서 `libwebp.so`를 발견하면 버전을 확인하고 익스플로잇 또는 패치 시도를 하십시오.| citeturn2search0|
|2024|다수|OpenSSL 3.x 시리즈|여러 메모리 안전성 및 패딩 오라클 문제. 많은 Flutter 및 ReactNative 번들이 자체 `libcrypto.so`를 포함합니다.|
APK 내에서 *서드파티* `.so` 파일을 발견하면 항상 해시를 업스트림 권고 사항과 교차 확인하십시오. SCA(소프트웨어 구성 분석)는 모바일에서 드물기 때문에 구식 취약 빌드가 만연합니다.
---
### 안티 리버싱 및 하드닝 트렌드 (Android 13-15)
* **포인터 인증(PAC) 및 분기 대상 식별(BTI):** Android 14는 지원되는 ARMv8.3+ 실리콘의 시스템 라이브러리에서 PAC/BTI를 활성화합니다. 디컴파일러는 이제 PAC 관련 의사 명령어를 표시합니다. 동적 분석을 위해 Frida는 PAC을 제거한 후 트램폴린을 주입하지만, 사용자 정의 트램폴린은 필요에 따라 `pacda`/`autibsp`를 호출해야 합니다.
* **MTE 및 Scudo 강화 할당기:** 메모리 태깅은 선택 사항이지만 많은 Play-Integrity 인식 앱이 `-fsanitize=memtag`로 빌드됩니다. 태그 오류를 캡처하려면 `setprop arm64.memtag.dump 1``adb shell am start ...`를 사용하십시오.
* **LLVM 난독화기(불투명한 조건, 제어 흐름 평탄화):** 상업적 패커(예: Bangcle, SecNeo)는 Java뿐만 아니라 *네이티브* 코드를 점점 더 보호합니다. `.rodata`에서 잘못된 제어 흐름 및 암호화된 문자열 블롭을 기대하십시오.
---
### 리소스
- **ARM 어셈블리 학습:** [Azeria Labs ARM Assembly Basics](https://azeria-labs.com/writing-arm-assembly-part-1/)
- **JNI 및 NDK 문서:** [Oracle JNI Spec](https://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html) · [Android JNI Tips](https://developer.android.com/training/articles/perf-jni) · [NDK Guides](https://developer.android.com/ndk/guides/)
- **네이티브 라이브러리 디버깅:** [JEB 디컴파일러를 사용하여 Android 네이티브 라이브러리 디버깅](https://medium.com/@shubhamsonani/how-to-debug-android-native-libraries-using-jeb-decompiler-eec681a22cf3)
### 참고 문헌
- Frida 16.x 변경 로그 (Android 후킹, 작은 함수 재배치) [frida.re/news](https://frida.re/news/) citeturn5search0
- `libwebp` 오버플로우 CVE-2023-4863에 대한 NVD 권고 사항 [nvd.nist.gov](https://nvd.nist.gov/vuln/detail/CVE-2023-4863) citeturn2search0
{{#include ../../banners/hacktricks-training.md}}