mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/mobile-pentesting/android-app-pentesting/reversing-nati
This commit is contained in:
parent
bcb503f577
commit
008567976f
@ -24,8 +24,8 @@ sudo apt-get install -y yara
|
||||
```
|
||||
#### 규칙 준비
|
||||
|
||||
이 스크립트를 사용하여 github에서 모든 yara malware rules를 다운로드하고 병합하세요: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\
|
||||
_**rules**_ 디렉토리를 생성하고 스크립트를 실행하세요. 그러면 malware에 대한 모든 yara rules를 포함하는 _**malware_rules.yar**_ 파일이 생성됩니다.
|
||||
이 스크립트를 사용하여 github에서 모든 yara malware rules을 다운로드하고 병합하세요: [https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9](https://gist.github.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9)\
|
||||
_**rules**_ 디렉토리를 생성하고 실행하세요. 그러면 모든 yara rules for malware가 포함된 _**malware_rules.yar**_ 파일이 생성됩니다.
|
||||
```bash
|
||||
wget https://gist.githubusercontent.com/andreafortuna/29c6ea48adf3d45a979a78763cdc7ce9/raw/4ec711d37f1b428b63bed1f786b26a0654aa2f31/malware_yara_rules.py
|
||||
mkdir rules
|
||||
@ -36,9 +36,9 @@ python malware_yara_rules.py
|
||||
yara -w malware_rules.yar image #Scan 1 file
|
||||
yara -w malware_rules.yar folder #Scan the whole folder
|
||||
```
|
||||
#### YaraGen: malware 확인 및 규칙 생성
|
||||
#### YaraGen: malware 검사 및 yara rules 생성
|
||||
|
||||
도구 [**YaraGen**](https://github.com/Neo23x0/yarGen)을(를) 사용하여 binary에서 yara rules를 생성할 수 있습니다. 다음 튜토리얼을 확인하세요: [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/)
|
||||
바이너리에서 yara rules를 생성하기 위해 [**YaraGen**](https://github.com/Neo23x0/yarGen) 도구를 사용할 수 있습니다. 다음 튜토리얼을 참조하세요: [**Part 1**](https://www.nextron-systems.com/2015/02/16/write-simple-sound-yara-rules/), [**Part 2**](https://www.nextron-systems.com/2015/10/17/how-to-write-simple-but-sound-yara-rules-part-2/), [**Part 3**](https://www.nextron-systems.com/2016/04/15/how-to-write-simple-but-sound-yara-rules-part-3/)
|
||||
```bash
|
||||
python3 yarGen.py --update
|
||||
python3.exe yarGen.py --excludegood -m ../../mals/
|
||||
@ -49,7 +49,7 @@ python3.exe yarGen.py --excludegood -m ../../mals/
|
||||
```
|
||||
sudo apt-get install -y clamav
|
||||
```
|
||||
#### Scan
|
||||
#### 스캔
|
||||
```bash
|
||||
sudo freshclam #Update rules
|
||||
clamscan filepath #Scan 1 file
|
||||
@ -57,24 +57,25 @@ clamscan folderpath #Scan the whole folder
|
||||
```
|
||||
### [Capa](https://github.com/mandiant/capa)
|
||||
|
||||
**Capa**는 실행 파일(PE, ELF, .NET)에서 잠재적으로 악성인 **capabilities**를 탐지합니다. 따라서 Att\&ck tactics와 같은 항목이나 다음과 같은 의심스러운 **capabilities**를 찾아냅니다:
|
||||
**Capa**는 실행 파일(PE, ELF, .NET)에서 잠재적으로 악의적인 **기능**을 탐지합니다. 따라서 Att\&ck 전술이나 다음과 같은 의심스러운 기능들을 찾아냅니다:
|
||||
|
||||
- OutputDebugString 오류 확인
|
||||
- 서비스로 실행
|
||||
- 프로세스 생성
|
||||
- check for OutputDebugString error
|
||||
- run as a service
|
||||
- create process
|
||||
|
||||
다음에서 구하세요: [**Github repo**](https://github.com/mandiant/capa).
|
||||
설치는 [**Github repo**](https://github.com/mandiant/capa)에서 받으세요.
|
||||
|
||||
### IOCs
|
||||
|
||||
IOC는 Indicator Of Compromise의 약자입니다. IOC는 잠재적으로 원치 않는 소프트웨어나 확정된 **malware**를 식별하는 **식별하는 조건들**의 집합입니다. Blue Teams는 이러한 정의를 사용해 자신들의 **시스템**과 **네트워크**에서 해당 유형의 악성 파일을 **검색**합니다.\
|
||||
이 정의들을 공유하는 것은 매우 유용합니다. 어떤 컴퓨터에서 malware가 식별되어 그 malware에 대한 IOC가 만들어지면, 다른 Blue Teams는 이를 사용해 malware를 더 빠르게 식별할 수 있습니다.
|
||||
IOC는 Indicator Of Compromise의 약자입니다. IOC는 일부 잠재적으로 원치 않는 소프트웨어나 확인된 **malware**를 식별하는 **조건들의 집합**입니다. Blue Teams는 이러한 정의를 사용해 자신들의 **시스템**과 **네트워크**에서 이러한 종류의 악성 파일을 **검색합니다**.\
|
||||
이 정의들을 공유하는 것은 매우 유용합니다. 한 컴퓨터에서 malware가 식별되어 해당 malware에 대한 IOC가 생성되면, 다른 Blue Teams가 이를 사용해 malware를 더 빠르게 식별할 수 있기 때문입니다.
|
||||
|
||||
IOC를 생성하거나 수정하는 도구로는 [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\\ [**Redline**](https://www.fireeye.com/services/freeware/redline.html)과 같은 도구를 사용하여 장치에서 정의된 IOC를 **검색할 수 있습니다**.
|
||||
IOC를 생성하거나 수정하는 도구는 [**IOC Editor**](https://www.fireeye.com/services/freeware/ioc-editor.html)**.**\
|
||||
또한 [**Redline**](https://www.fireeye.com/services/freeware/redline.html)과 같은 도구를 사용해 **장치에서 정의된 IOCs를 검색**할 수 있습니다.
|
||||
|
||||
### Loki
|
||||
|
||||
[**Loki**](https://github.com/Neo23x0/Loki)는 Simple Indicators of Compromise용 스캐너입니다.\\
|
||||
[**Loki**](https://github.com/Neo23x0/Loki) 는 Simple Indicators of Compromise를 위한 스캐너입니다.\
|
||||
탐지는 네 가지 탐지 방법에 기반합니다:
|
||||
```
|
||||
1. File Name IOC
|
||||
@ -91,41 +92,41 @@ Compares process connection endpoints with C2 IOCs (new since version v.10)
|
||||
```
|
||||
### Linux Malware Detect
|
||||
|
||||
[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/)는 GNU GPLv2 라이선스로 배포되는 Linux용 malware 스캐너로, 공유 호스팅 환경에서 직면하는 위협을 중심으로 설계되었습니다. 네트워크 엣지 침입 탐지 시스템으로부터의 위협 데이터를 사용하여 공격에 실제로 사용되는 malware를 추출하고 탐지용 시그니처를 생성합니다. 또한 위협 데이터는 LMD checkout 기능을 통한 사용자 제출과 malware 커뮤니티 리소스에서도 얻습니다.
|
||||
[**Linux Malware Detect (LMD)**](https://www.rfxn.com/projects/linux-malware-detect/)는 GNU GPLv2 license 하에 배포되는 Linux용 malware scanner로, 공유 호스팅 환경에서 직면하는 위협을 중심으로 설계되었습니다. 네트워크 에지 intrusion detection systems로부터의 위협 데이터를 이용해 공격에 실제로 사용되는 malware를 추출하고 탐지용 signatures를 생성합니다. 또한 위협 데이터는 LMD checkout feature를 통한 사용자 제출과 malware community resources에서도 파생됩니다.
|
||||
|
||||
### rkhunter
|
||||
|
||||
[**rkhunter**](http://rkhunter.sourceforge.net)와 같은 도구는 파일 시스템에서 가능한 **rootkits** 및 malware를 검사하는 데 사용할 수 있습니다.
|
||||
Tools like [**rkhunter**](http://rkhunter.sourceforge.net) can be used to check the filesystem for possible **rootkits** and malware.
|
||||
```bash
|
||||
sudo ./rkhunter --check -r / -l /tmp/rkhunter.log [--report-warnings-only] [--skip-keypress]
|
||||
```
|
||||
### FLOSS
|
||||
|
||||
[**FLOSS**](https://github.com/mandiant/flare-floss)는 다양한 기법을 사용해 실행 파일 내부의 obfuscated strings를 찾아내려고 시도하는 도구입니다.
|
||||
[**FLOSS**](https://github.com/mandiant/flare-floss)는 실행 파일 내의 난독화된 문자열을 다양한 기법으로 찾아내려고 시도하는 도구입니다.
|
||||
|
||||
### PEpper
|
||||
|
||||
[PEpper ](https://github.com/Th3Hurrican3/PEpper)checks 일부 실행 파일 내부의 기본 항목들(바이너리 데이터, entropy, URLs and IPs, 일부 yara rules)을 검사합니다.
|
||||
[PEpper ](https://github.com/Th3Hurrican3/PEpper)는 실행 파일 내부의 몇 가지 기본 항목(binary data, entropy, URLs and IPs, some yara rules)을 검사합니다.
|
||||
|
||||
### PEstudio
|
||||
|
||||
[PEstudio](https://www.winitor.com/download)는 imports, exports, headers 등 Windows 실행 파일의 정보를 얻을 수 있게 해주며, virus total을 확인하고 잠재적인 Att\&ck techniques를 찾아냅니다.
|
||||
[PEstudio](https://www.winitor.com/download)는 Windows 실행 파일의 imports, exports, headers 등의 정보를 얻을 수 있게 해주는 도구이며, 또한 virus total을 확인하고 잠재적인 Att\&ck 기법을 찾아냅니다.
|
||||
|
||||
### Detect It Easy(DiE)
|
||||
|
||||
[**DiE**](https://github.com/horsicq/Detect-It-Easy/)는 파일이 **encrypted** 되었는지 감지하고 **packers**도 찾아내는 도구입니다.
|
||||
[**DiE**](https://github.com/horsicq/Detect-It-Easy/)는 파일이 **암호화된**지 여부를 감지하고 **packers**도 찾아내는 도구입니다.
|
||||
|
||||
### NeoPI
|
||||
|
||||
[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI)은 텍스트/스크립트 파일 내의 **obfuscated** 및 **encrypted** 내용을 감지하기 위해 다양한 **statistical methods**를 사용하는 Python 스크립트입니다. NeoPI의 목적은 **detection of hidden web shell code**을 돕는 것입니다.
|
||||
[**NeoPI** ](https://github.com/CiscoCXSecurity/NeoPI)은 다양한 **통계적 방법**을 사용하여 텍스트/스크립트 파일 내의 **난독화된** 및 **암호화된** 콘텐츠를 탐지하는 Python 스크립트입니다. NeoPI의 의도된 목적은 숨겨진 **web shell 코드**의 **탐지**를 돕는 것입니다.
|
||||
|
||||
### **php-malware-finder**
|
||||
|
||||
[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder)은 **obfuscated**/**dodgy code**뿐만 아니라 자주 악용되는 **PHP** 함수들을 사용하는 파일(예: **malwares**/webshells)을 탐지하려 최선을 다합니다.
|
||||
[**PHP-malware-finder**](https://github.com/nbs-system/php-malware-finder)는 **난독화된**/**의심스러운 코드**와 malwares/webshells에서 자주 사용되는 **PHP** 함수들을 사용하는 파일들을 탐지하는 데 최선을 다합니다.
|
||||
|
||||
### Apple Binary Signatures
|
||||
|
||||
어떤 **malware sample**을 확인할 때는 서명한 **developer**가 이미 **related** with **malware**일 수 있으므로 항상 바이너리의 **check the signature**를 해야 합니다.
|
||||
어떤 **malware sample**을 확인할 때는 바이너리의 **서명을 확인**해야 합니다. 서명한 **developer**가 이미 **malware**와 **관련되어** 있을 수 있기 때문입니다.
|
||||
```bash
|
||||
#Get signer
|
||||
codesign -vv -d /bin/ls 2>&1 | grep -E "Authority|TeamIdentifier"
|
||||
@ -140,23 +141,23 @@ spctl --assess --verbose /Applications/Safari.app
|
||||
|
||||
### File Stacking
|
||||
|
||||
만약 웹 서버의 **파일**들을 포함한 어떤 폴더가 **마지막으로 업데이트된 날짜**를 알고 있다면, 웹 서버 내 모든 **파일들의 생성 및 수정 날짜**를 **확인**하고 어떤 날짜가 **의심스럽다면**, 해당 파일을 조사하라.
|
||||
If you know that some folder containing the **files** of a web server was **last updated on some date**. **Check** the **date** all the **files** in the **web server were created and modified** and if any date is **suspicious**, check that file.
|
||||
|
||||
### Baselines
|
||||
|
||||
폴더의 파일이 **변경되지 않았어야 한다면**, 그 폴더의 **원본 파일**들의 **해시(hash)**를 계산하여 **현재** 파일들과 **비교**할 수 있다. 변경된 항목은 **의심스러울** 것이다.
|
||||
If the **files** of a folder **shouldn't have been modified**, you can calculate the **hash** of the **original files** of the folder and **compare** them with the **current** ones. Anything modified will be **suspicious**.
|
||||
|
||||
### Statistical Analysis
|
||||
|
||||
정보가 로그에 저장되어 있다면, 웹 서버의 각 파일이 몇 번 접근되었는지 같은 통계를 **확인**할 수 있다 — web shell이 가장 많이 접근된 파일 중 하나일 수 있다.
|
||||
When the information is saved in **logs** you can **check statistics like how many times each file of a web server was accessed as a web shell might be one of the most**.
|
||||
|
||||
---
|
||||
|
||||
### Android in-app native telemetry (no root)
|
||||
|
||||
Android에서는 다른 JNI 라이브러리가 초기화되기 전에 작은 로거 라이브러리를 프리로딩함으로써 타깃 앱 프로세스 내부의 native 코드를 계측할 수 있다. 이는 시스템 전역 훅이나 root 없이 native 동작에 대한 조기 가시성을 제공한다. 널리 사용되는 방법은 SoTap이다: 적절한 ABI용 libsotap.so를 APK에 넣고 System.loadLibrary("sotap") 호출을 초기에 삽입(예: static initializer 또는 Application.onCreate)한 뒤 내부/외부 경로 또는 Logcat을 통해 로그를 수집한다.
|
||||
Android에서는 다른 JNI 라이브러리들이 초기화되기 전에 작은 로거 라이브러리를 프리로딩하여 대상 앱 프로세스 내부의 native code를 계측할 수 있습니다. 이렇게 하면 시스템 전역 훅이나 root 없이도 native 동작을 조기에 관찰할 수 있습니다. 널리 쓰이는 접근법은 SoTap입니다: 적절한 ABI에 맞는 libsotap.so를 APK에 넣고 초기에 System.loadLibrary("sotap") 호출을 삽입(예: static initializer 또는 Application.onCreate)한 뒤, internal/external 경로나 Logcat을 통해 로그를 수집합니다.
|
||||
|
||||
설정 세부사항과 로그 경로는 Android native reversing 페이지를 참조하라:
|
||||
See the Android native reversing page for setup details and log paths:
|
||||
|
||||
{{#ref}}
|
||||
../../mobile-pentesting/android-app-pentesting/reversing-native-libraries.md
|
||||
@ -166,9 +167,9 @@ Android에서는 다른 JNI 라이브러리가 초기화되기 전에 작은 로
|
||||
|
||||
## Deobfuscating Dynamic Control-Flow (JMP/CALL RAX Dispatchers)
|
||||
|
||||
Modern malware families heavily abuse Control-Flow Graph (CFG) obfuscation: 대신 직접적인 jump/call 대신 실행 시 목적지를 계산하여 `jmp rax` 또는 `call rax`를 실행한다. 작은 *dispatcher*(대개 9개 명령어)가 CPU의 `ZF`/`CF` 플래그에 따라 최종 타겟을 설정하여 정적 CFG 복구를 완전히 무력화한다.
|
||||
Modern malware families heavily abuse Control-Flow Graph (CFG) obfuscation: instead of a direct jump/call they compute the destination at run-time and execute a `jmp rax` or `call rax`. A small *dispatcher* (typically nine instructions) sets the final target depending on the CPU `ZF`/`CF` flags, completely breaking static CFG recovery.
|
||||
|
||||
이 기법은 SLOW#TEMPEST loader에서 보여진 바와 같이, IDAPython과 Unicorn CPU emulator만을 사용한 세 단계 워크플로로 무력화할 수 있다.
|
||||
The technique – showcased by the SLOW#TEMPEST loader – can be defeated with a three-step workflow that only relies on IDAPython and the Unicorn CPU emulator.
|
||||
|
||||
### 1. Locate every indirect jump / call
|
||||
```python
|
||||
@ -179,7 +180,7 @@ mnem = idc.print_insn_mnem(ea)
|
||||
if mnem in ("jmp", "call") and idc.print_operand(ea, 0) == "rax":
|
||||
print(f"[+] Dispatcher found @ {ea:X}")
|
||||
```
|
||||
### 2. 디스패처 바이트코드 추출
|
||||
### 2. dispatcher byte-code 추출
|
||||
```python
|
||||
import idc
|
||||
|
||||
@ -210,9 +211,9 @@ mu.reg_write(UC_X86_REG_RAX, 0)
|
||||
mu.emu_start(BASE, BASE+len(code))
|
||||
return mu.reg_read(UC_X86_REG_RAX)
|
||||
```
|
||||
다음 명령을 실행하여 `run(code,0,0)` 및 `run(code,1,1)`로부터 *false* 및 *true* 분기 대상을 얻는다.
|
||||
`run(code,0,0)` 및 `run(code,1,1)`을 실행하여 *false* 및 *true* 분기 타겟을 얻습니다.
|
||||
|
||||
### 4. 직접적인 jump / call을 패치하여 되돌리기
|
||||
### 4. 직접적인 jump / call 복원
|
||||
```python
|
||||
import struct, ida_bytes
|
||||
|
||||
@ -221,22 +222,22 @@ op = 0xE8 if is_call else 0xE9 # CALL rel32 or JMP rel32
|
||||
disp = target - (ea + 5) & 0xFFFFFFFF
|
||||
ida_bytes.patch_bytes(ea, bytes([op]) + struct.pack('<I', disp))
|
||||
```
|
||||
패치 후, 전체 CFG와 Hex-Rays 출력이 복원되도록 IDA에 함수를 재분석하도록 강제하십시오:
|
||||
패치 후에는 전체 CFG와 Hex-Rays 출력이 복원되도록 IDA에 함수를 강제로 다시 분석시키세요:
|
||||
```python
|
||||
import ida_auto, idaapi
|
||||
idaapi.reanalyze_function(idc.get_func_attr(ea, idc.FUNCATTR_START))
|
||||
```
|
||||
### 5. 간접 API 호출에 레이블 지정
|
||||
|
||||
각 `call rax`의 실제 목적지를 알게 되면 IDA에 이를 알려 매개변수 타입 및 변수 이름이 자동으로 복원되도록 할 수 있다:
|
||||
모든 `call rax`의 실제 목적지를 알게 되면 IDA에 그 정보를 알려 매개변수 타입 및 변수 이름이 자동으로 복구되도록 할 수 있습니다:
|
||||
```python
|
||||
idc.set_callee_name(call_ea, resolved_addr, 0) # IDA 8.3+
|
||||
```
|
||||
### 실용적 이점
|
||||
|
||||
* 실제 CFG를 복원 → decompilation이 *10* 줄에서 수천 줄로 증가.
|
||||
* string-cross-reference & xrefs를 활성화하여 행위 재구성이 쉬워짐.
|
||||
* Scripts는 재사용 가능: 같은 트릭으로 보호된 어떤 loader에도 넣어 재사용할 수 있음.
|
||||
* 실제 CFG를 복원 → decompilation이 *10* 줄에서 수천 줄로 늘어납니다.
|
||||
* string-cross-reference & xrefs를 활성화하여 동작 재구성을 용이하게 합니다.
|
||||
* Scripts는 재사용 가능합니다: 동일한 기법으로 보호된 어떤 loader에도 넣어 사용할 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
|
@ -1,16 +1,16 @@
|
||||
# Reversing Native Libraries
|
||||
# 네이티브 라이브러리 리버싱
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
**For further information check:** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
|
||||
**자세한 정보:** [**https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html**](https://maddiestone.github.io/AndroidAppRE/reversing_native_libs.html)
|
||||
|
||||
Android 앱은 일반적으로 성능이 중요한 작업을 위해 C 또는 C++로 작성된 native libraries를 사용할 수 있습니다. Malware 제작자들도 이러한 라이브러리를 악용하는데, ELF shared objects는 여전히 DEX/OAT byte-code보다 디컴파일하기 더 어렵기 때문입니다.
|
||||
이 페이지는 Android `.so` 파일을 역분석하기 쉽게 해주는 *실용적인* 워크플로우와 *최근* 툴링 개선사항(2023-2025)에 초점을 맞춥니다.
|
||||
Android 앱은 일반적으로 성능이 중요한 작업을 위해 C 또는 C++로 작성된 네이티브 라이브러리를 사용할 수 있습니다. 악성 코드 제작자들도 ELF shared objects가 DEX/OAT 바이트코드보다 디컴파일하기 더 어렵기 때문에 이러한 라이브러리를 악용합니다.
|
||||
이 페이지는 Android `.so` 파일 리버싱을 더 쉽게 만드는 *실용적인* 워크플로우와 *최신* 도구 개선사항(2023-2025)에 중점을 둡니다.
|
||||
|
||||
---
|
||||
|
||||
### Quick triage-workflow for a freshly pulled `libfoo.so`
|
||||
### 새로 확보한 `libfoo.so`에 대한 빠른 분류 워크플로우
|
||||
|
||||
1. **라이브러리 추출**
|
||||
```bash
|
||||
@ -19,7 +19,7 @@ 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/
|
||||
```
|
||||
2. **아키텍처 및 보호 확인**
|
||||
2. **아키텍처 및 보호 식별**
|
||||
```bash
|
||||
file libfoo.so # arm64 or arm32 / x86
|
||||
readelf -h libfoo.so # OS ABI, PIE, NX, RELRO, etc.
|
||||
@ -30,21 +30,21 @@ checksec --file libfoo.so # (peda/pwntools)
|
||||
readelf -s libfoo.so | grep ' Java_' # dynamic-linked JNI
|
||||
strings libfoo.so | grep -i "RegisterNatives" -n # static-registered JNI
|
||||
```
|
||||
4. **Decompiler에 로드** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) 및 자동 분석 실행.
|
||||
Newer Ghidra versions introduced an AArch64 decompiler that recognises PAC/BTI stubs and MTE tags, greatly improving analysis of libraries built with the Android 14 NDK.
|
||||
5. **정적 vs 동적 역분석 결정:** stripped, obfuscated 코드의 경우 종종 *instrumentation*이 필요합니다 (Frida, ptrace/gdbserver, LLDB).
|
||||
4. **디컴파일러에서 로드** (Ghidra ≥ 11.0, IDA Pro, Binary Ninja, Hopper or Cutter/Rizin) 및 자동 분석 실행.
|
||||
신규 Ghidra 버전은 AArch64 decompiler가 PAC/BTI stubs 및 MTE tags를 인식하도록 도입되어 Android 14 NDK로 빌드된 라이브러리 분석이 크게 향상되었습니다.
|
||||
5. **정적 vs 동적 리버싱 결정:** 스트립되었거나 난독화된 코드는 종종 *instrumentation*(Frida, ptrace/gdbserver, LLDB)이 필요합니다.
|
||||
|
||||
---
|
||||
|
||||
### Dynamic Instrumentation (Frida ≥ 16)
|
||||
|
||||
Frida’s 16-series brought several Android-specific improvements that help when the target uses modern Clang/LLD optimisations:
|
||||
Frida의 16 시리즈는 대상이 최신 Clang/LLD 최적화를 사용할 때 도움이 되는 여러 Android 전용 개선사항을 도입했습니다:
|
||||
|
||||
* `thumb-relocator`는 이제 LLD의 공격적 정렬(`--icf=all`)로 생성된 *작은 ARM/Thumb 함수에 hook*할 수 있습니다.
|
||||
* Enumerating and rebinding *ELF import slots*는 Android에서 동작하며, inline hooks가 거부될 때 모듈별로 `dlopen()`/`dlsym()` 패치가 가능하게 합니다.
|
||||
* Java hooking은 Android 14에서 `--enable-optimizations`로 컴파일된 앱이 사용하는 새로운 **ART quick-entrypoint**에 대해 수정되었습니다.
|
||||
* `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이 수정되었습니다.
|
||||
|
||||
Example: enumerating all functions registered through `RegisterNatives` and dumping their addresses at runtime:
|
||||
예: `RegisterNatives`를 통해 등록된 모든 함수를 열거하고 런타임에 그 주소를 덤프하기:
|
||||
```javascript
|
||||
Java.perform(function () {
|
||||
var Runtime = Java.use('java.lang.Runtime');
|
||||
@ -61,16 +61,16 @@ console.log('[+] RegisterNatives on ' + clazz.getName() + ' -> ' + count + ' met
|
||||
});
|
||||
});
|
||||
```
|
||||
Frida will work out of the box on PAC/BTI-enabled devices (Pixel 8/Android 14+) as long as you use frida-server 16.2 or later – earlier versions failed to locate padding for inline hooks.
|
||||
Frida는 PAC/BTI-enabled 장치(Pixel 8/Android 14+)에서 frida-server 16.2 이상을 사용하면 바로 동작합니다 – 이전 버전은 inline hooks용 패딩을 찾지 못했습니다.
|
||||
|
||||
### preloaded .so를 통한 프로세스 로컬 JNI 텔레메트리 (SoTap)
|
||||
### Process-local JNI telemetry via preloaded .so (SoTap)
|
||||
|
||||
완전한 기능의 instrumentation이 과잉이거나 차단된 경우, 대상 프로세스 내부에 작은 로거를 preload하여 네이티브 수준의 가시성을 확보할 수 있습니다. SoTap은 동일 앱 프로세스 내의 다른 JNI (.so) 라이브러리들의 런타임 동작을 로깅하는 경량 Android native (.so) 라이브러리입니다(루트 권한 불필요).
|
||||
완전한 instrumentation이 과하거나 차단된 경우, 대상 프로세스 내부에 작은 로거를 사전 로드하여 네이티브 수준의 가시성을 확보할 수 있습니다. SoTap은 동일 앱 프로세스 내 다른 JNI (.so) 라이브러리의 런타임 동작을 기록하는 경량 Android 네이티브(.so) 라이브러리입니다(루트 불필요).
|
||||
|
||||
Key properties:
|
||||
- 일찍 초기화되어 이를 로드하는 프로세스 내부의 JNI/native 상호작용을 관찰합니다.
|
||||
- 쓰기 가능한 여러 경로에 로그를 지속하며, 저장소가 제한될 경우 Logcat으로 우아하게 폴백합니다.
|
||||
- 소스 커스터마이징 가능: sotap.c를 편집해 기록할 내용을 확장/조정한 뒤 ABI별로 다시 빌드하세요.
|
||||
- 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):
|
||||
1) Drop the proper ABI build into the APK so the loader can resolve libsotap.so:
|
||||
@ -92,30 +92,30 @@ Log paths (checked in order):
|
||||
# If all fail: fallback to Logcat only
|
||||
```
|
||||
Notes and troubleshooting:
|
||||
- ABI 정렬은 필수입니다. 불일치하면 UnsatisfiedLinkError가 발생하고 logger가 로드되지 않습니다.
|
||||
- 현대 Android에서는 저장소 제약이 흔합니다; 파일 쓰기가 실패하면 SoTap은 여전히 Logcat을 통해 출력합니다.
|
||||
- 동작/출력 레벨은 사용자화하도록 설계되었습니다; sotap.c를 수정한 뒤 소스에서 재빌드하세요.
|
||||
- ABI 정렬은 필수입니다. 불일치는 UnsatisfiedLinkError 를 발생시키고 logger 가 로드되지 않습니다.
|
||||
- 저장 공간 제약은 현대 Android 에서 흔합니다; 파일 쓰기가 실패하면 SoTap 은 여전히 Logcat 을 통해 출력합니다.
|
||||
- 동작/출력 수준(verbosity)은 사용자화하도록 설계되었습니다; sotap.c 를 편집한 뒤 소스에서 다시 빌드하세요.
|
||||
|
||||
이 접근법은 프로세스 시작 시점부터 네이티브 호출 흐름을 관찰해야 하는 malware triage와 JNI 디버깅에 유용합니다. 다만 root/시스템 전체 훅을 사용할 수 없는 경우에 해당합니다.
|
||||
이 접근법은 프로세스 시작 시점부터 네이티브 호출 흐름을 관찰해야 하는 malware 정리(malware triage)와 JNI 디버깅에 유용합니다. 특히 root/시스템 전체 훅이 불가능한 경우에 중요합니다.
|
||||
|
||||
---
|
||||
|
||||
### Recent vulnerabilities worth hunting for in APKs
|
||||
|
||||
| 연도 | CVE | 영향받는 라이브러리 | 설명 |
|
||||
| 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`를 포함합니다.|
|
||||
|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 권고사항과 대조하세요. 모바일에서는 SCA (Software Composition Analysis)가 드물기 때문에 구버전의 취약한 빌드가 널리 퍼져 있습니다.
|
||||
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 관련 의사명령을 표시하고; 동적 분석에서는 Frida가 PAC를 제거한 뒤 트램폴린을 주입하지만, 사용자 지정 트램폴린은 필요한 경우 pacda/autibsp를 호출해야 합니다.
|
||||
* **MTE & Scudo hardened allocator:** memory-tagging은 옵트인입니다만 많은 Play-Integrity 인식 앱이 `-fsanitize=memtag`로 빌드합니다; 태그 폴트를 캡처하려면 `setprop arm64.memtag.dump 1`과 `adb shell am start ...`를 사용하세요.
|
||||
* **LLVM Obfuscator (opaque predicates, control-flow flattening):** 상용 packer들(예: Bangcle, SecNeo)은 점점 *native* 코드를 보호합니다(Java만이 아님); `.rodata`에 잘못된 제어 흐름과 암호화된 문자열 블랍이 있을 것으로 예상하세요.
|
||||
* **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` 에서 가짜 제어 흐름과 암호화된 문자열 블롭을 예상하세요.
|
||||
|
||||
---
|
||||
|
||||
|
@ -1,57 +1,57 @@
|
||||
# Smali - 디컴파일/[수정]/컴파일
|
||||
# Smali - Decompiling/[Modifying]/Compiling
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
때때로 애플리케이션 코드를 수정하여 숨겨진 정보를 얻는 것이 흥미로울 수 있습니다(예: 잘 난독화된 비밀번호나 플래그). 이럴 때 apk를 디컴파일하고 코드를 수정한 뒤 다시 컴파일하는 것이 유용합니다.
|
||||
때로는 애플리케이션 코드를 수정하여 숨겨진 정보를 얻는 것이 흥미로울 수 있습니다(예: 잘 난독화된 비밀번호나 플래그). 그런 경우 apk를 decompile하고 코드를 modify한 뒤 recompile하는 것이 유용할 수 있습니다.
|
||||
|
||||
**Opcodes reference:** [http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html](http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html)
|
||||
|
||||
## 빠른 방법
|
||||
|
||||
Visual Studio Code와 [APKLab](https://github.com/APKLab/APKLab) 확장 기능을 사용하면, 어떤 명령도 실행하지 않고도 애플리케이션을 **자동으로 디컴파일**, 수정, **재컴파일**, 서명 및 설치할 수 있습니다.
|
||||
**Visual Studio Code**와 [APKLab](https://github.com/APKLab/APKLab) 확장(extension)을 사용하면 명령을 실행하지 않고도 애플리케이션을 **automatically decompile**, modify, **recompile**, sign & install할 수 있습니다.
|
||||
|
||||
또한 이 작업을 훨씬 쉽게 해주는 또 다른 **script**는 [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh) 입니다.
|
||||
또 다른 이 작업을 크게 편리하게 해주는 **script**는 [**https://github.com/ax/apk.sh**](https://github.com/ax/apk.sh)입니다.
|
||||
|
||||
## APK 디컴파일
|
||||
## Decompile the APK
|
||||
|
||||
APKTool을 사용하면 **smali code and resources**에 접근할 수 있습니다:
|
||||
```bash
|
||||
apktool d APP.apk
|
||||
```
|
||||
만약 **apktool**이 어떤 오류를 발생시키면, [ installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/ )을 시도해 보세요
|
||||
If **apktool** gives you any error, [installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/)을 시도해보세요
|
||||
|
||||
살펴봐야 할 몇 가지 **흥미로운 파일들**:
|
||||
Some **interesting files you should look are**:
|
||||
|
||||
- _res/values/strings.xml_ (and all xmls inside res/values/*)
|
||||
- _res/values/strings.xml_ (및 res/values/* 내부의 모든 xml 파일)
|
||||
- _AndroidManifest.xml_
|
||||
- Any file with extension _.sqlite_ or _.db_
|
||||
|
||||
만약 `apktool`이 애플리케이션 디코딩에 **문제가** 있다면 [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) 를 확인하거나 인자 **`-r`**(리소스 디코딩 안 함)을 사용해 보세요. 그러면 문제가 소스 코드가 아니라 리소스에 있었다면 해당 문제는 발생하지 않습니다(리소스도 디컴파일하지 않습니다).
|
||||
If `apktool` has **problems decoding the application** take a look to [https://ibotpeaches.github.io/Apktool/documentation/#framework-files](https://ibotpeaches.github.io/Apktool/documentation/#framework-files) or try using the argument **`-r`** (Do not decode resources). Then, if the problem was in a resource and not in the source code, you won't have the problem (you won't also decompile the resources).
|
||||
|
||||
## smali 코드 변경
|
||||
## Change smali code
|
||||
|
||||
명령(instructions)을 **변경**하거나, 일부 변수의 **값(value)**을 바꾸거나, 새로운 명령을 **추가**할 수 있습니다. 저는 Smali 코드를 [**VS Code**](https://code.visualstudio.com)로 수정합니다. 그 다음 **smalise extension**를 설치하면 에디터가 어떤 **instruction이 잘못되었는지** 알려줍니다.\
|
||||
몇 가지 **예제**는 다음에서 찾을 수 있습니다:
|
||||
명령을 변경하거나 일부 변수의 값을 바꾸거나 새 명령을 추가할 수 있습니다. 저는 Smali 코드를 [**VS Code**](https://code.visualstudio.com)에서 편집합니다. 그 후 **smalise extension**을 설치하면 에디터가 잘못된 **instruction**이 있는지 알려줍니다.\
|
||||
Some **examples** can be found here:
|
||||
|
||||
- [Smali changes examples](smali-changes.md)
|
||||
- [Google CTF 2018 - Shall We Play a Game?](google-ctf-2018-shall-we-play-a-game.md)
|
||||
|
||||
또는 [**아래의 일부 Smali 변경 설명을 확인해 보세요**](smali-changes.md#modifying-smali).
|
||||
Or you can [**check below some Smali changes explained**](smali-changes.md#modifying-smali).
|
||||
|
||||
## APK 재컴파일
|
||||
## Recompile the APK
|
||||
|
||||
코드를 수정한 후 다음을 사용해 코드를 **재컴파일**할 수 있습니다:
|
||||
코드를 수정한 후 다음 명령으로 APK를 다시 컴파일할 수 있습니다:
|
||||
```bash
|
||||
apktool b . #In the folder generated when you decompiled the application
|
||||
```
|
||||
새 APK를 _**dist**_ 폴더 **내부**에서 **컴파일**합니다.
|
||||
새 APK는 _**dist**_ 폴더 **내부에서** **컴파일**됩니다.
|
||||
|
||||
만약 **apktool**이 **오류**를 발생시키면, [ installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/)을 시도해 보세요
|
||||
만약 **apktool**가 **오류**를 발생시키면, [installing the **latest version**](https://ibotpeaches.github.io/Apktool/install/)을 시도해보세요
|
||||
|
||||
### **새 APK 서명**
|
||||
### **새 APK에 서명하기**
|
||||
|
||||
그런 다음, **키를 생성**해야 합니다 (비밀번호와 무작위로 채워도 되는 몇 가지 정보를 입력하라는 요청을 받습니다):
|
||||
그런 다음, **키를 생성**해야 합니다 (비밀번호와 무작위로 입력해도 되는 몇 가지 정보를 요구합니다):
|
||||
```bash
|
||||
keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias <your-alias>
|
||||
```
|
||||
@ -61,14 +61,14 @@ jarsigner -keystore key.jks path/to/dist/* <your-alias>
|
||||
```
|
||||
### 새 애플리케이션 최적화
|
||||
|
||||
**zipalign**은 Android 애플리케이션(APK) 파일에 중요한 최적화를 제공하는 아카이브 정렬 도구입니다. [자세한 정보는 여기](https://developer.android.com/studio/command-line/zipalign).
|
||||
**zipalign**은 Android 애플리케이션(APK) 파일에 중요한 최적화를 제공하는 아카이브 정렬 도구입니다. [More information here](https://developer.android.com/studio/command-line/zipalign).
|
||||
```bash
|
||||
zipalign [-f] [-v] <alignment> infile.apk outfile.apk
|
||||
zipalign -v 4 infile.apk
|
||||
```
|
||||
### **새 APK에 (다시?) 서명하기**
|
||||
### **새 APK에 서명 (다시?)**
|
||||
|
||||
jarsigner 대신 [**apksigner**](https://developer.android.com/studio/command-line/)를 **선호한다면**, **zipaling으로 최적화를 적용한 후** APK에 **서명해야 합니다**. 하지만 jarsigner로(zipalign 이전에) 또는 aspsigner로(zipaling 이후에) **애플리케이션을 한 번만 서명하면 된다는 점에 유의하세요**.
|
||||
jarsigner 대신 [**apksigner**](https://developer.android.com/studio/command-line/)를 **선호**한다면, **zipalign으로 최적화를 적용한 후** APK에 **서명해야 합니다**. 하지만 주의: 애플리케이션은 jarsigner(이전에 zipalign)으로 또는 apksigner(이후에 zipalign)로 **한 번만 서명하면 됩니다**.
|
||||
```bash
|
||||
apksigner sign --ks key.jks ./dist/mycompiled.apk
|
||||
```
|
||||
@ -96,7 +96,7 @@ Smali 명령어 집합은 [here](https://source.android.com/devices/tech/dalvik/
|
||||
|
||||
### 함수 내부 변수의 초기값 수정
|
||||
|
||||
일부 변수들은 함수 시작 부분에서 opcode _const_를 사용해 정의됩니다. 해당 값을 수정하거나 새 변수를 정의할 수 있습니다:
|
||||
몇몇 변수들은 함수 시작 부분에서 opcode _const_를 사용해 정의되어 있으며, 그 값을 수정하거나 새로운 변수를 정의할 수 있습니다:
|
||||
```bash
|
||||
#Number
|
||||
const v9, 0xf4240
|
||||
@ -129,7 +129,7 @@ goto :goto_6 #Always go to: :goto_6
|
||||
```
|
||||
### 더 큰 변경사항
|
||||
|
||||
### 로깅
|
||||
### Logging
|
||||
```bash
|
||||
#Log win: <number>
|
||||
iget v5, p0, Lcom/google/ctf/shallweplayagame/GameActivity;->o:I #Get this.o inside v5
|
||||
@ -138,19 +138,19 @@ move-result-object v1 #Move to v1
|
||||
const-string v5, "wins" #Save "win" inside v5
|
||||
invoke-static {v5, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I #Logging "Wins: <num>"
|
||||
```
|
||||
권장사항:
|
||||
권장 사항:
|
||||
|
||||
- 함수 안에서 선언된 변수를 사용할 예정이라면 (선언된 v0,v1,v2...) 이 줄들을 _.local <number>_와 변수 선언들 (_const v0, 0x1_) 사이에 넣으세요.
|
||||
- 함수 코드의 중간에 로깅 코드를 넣고 싶다면:
|
||||
- 선언된 변수 수에 2를 더하세요: Ex: from _.locals 10_ to _.locals 12_
|
||||
- 새 변수들은 이미 선언된 변수들의 다음 번호여야 합니다 (이 예에서는 _v10_과 _v11_이어야 합니다, v0부터 시작하는 것을 기억하세요).
|
||||
- 로깅 함수의 코드를 변경하여 _v10_과 _v11_을 _v5_와 _v1_ 대신 사용하세요.
|
||||
- 만약 함수 내부에서 선언된 변수를 사용할 예정이라면(선언된 v0,v1,v2...) 이 줄들을 _.local <number>_과 변수 선언들(_const v0, 0x1_) 사이에 넣으세요
|
||||
- 함수 코드의 중간에 logging 코드를 넣고 싶다면:
|
||||
- 선언된 변수 수에 2를 더하세요: 예: _.locals 10_에서 _.locals 12_
|
||||
- 새 변수들은 이미 선언된 변수의 다음 번호여야 합니다(이 예제에서는 _v10_과 _v11_이어야 합니다, v0부터 시작한다는 것을 기억하세요).
|
||||
- logging 함수의 코드를 변경하여 _v10_과 _v11_을 _v5_와 _v1_ 대신 사용하세요.
|
||||
|
||||
### Toasting
|
||||
### 토스트 표시
|
||||
|
||||
함수 시작 부분에 있는 _.locals_의 숫자에 3을 더하는 것을 잊지 마세요.
|
||||
함수 시작 부분의 _.locals_ 수에 3을 더해야 합니다.
|
||||
|
||||
이 코드는 **함수의 중간**에 삽입되도록 준비되어 있습니다 (**변경**해야 하는 **변수**의 수를 필요에 따라 조정하세요). 이 코드는 **this.o의 값**을 **변환**하여 **String**으로 만들고, 그 값으로 **toast**를 **만듭니다**.
|
||||
이 코드는 **함수의 중간**에 삽입되도록 준비되어 있습니다 (**필요에 따라** **변수**의 수를 변경하세요). 이 코드는 **this.o의 값**을 가져와 **String으로 변환**한 다음 해당 값으로 **toast**를 생성합니다.
|
||||
```bash
|
||||
const/4 v10, 0x1
|
||||
const/4 v11, 0x1
|
||||
@ -164,7 +164,7 @@ invoke-virtual {v12}, Landroid/widget/Toast;->show()V
|
||||
```
|
||||
### 시작 시 네이티브 라이브러리 로드 (System.loadLibrary)
|
||||
|
||||
때때로 다른 JNI 라이브러리보다 먼저 초기화되도록 네이티브 라이브러리를 미리 로드해야 할 때가 있습니다(예: 프로세스 로컬 telemetry/logging을 활성화하기 위해). 정적 초기화자(static initializer)나 Application.onCreate() 초기에 System.loadLibrary() 호출을 주입할 수 있습니다. 정적 클래스 초기화자(<clinit>)용 예제 smali:
|
||||
때때로 다른 JNI 라이브러리보다 먼저 초기화되도록 네이티브 라이브러리를 사전 로드해야 할 때가 있습니다 (예: 프로세스 로컬 텔레메트리/로깅을 활성화하기 위해). 정적 초기화자나 Application.onCreate() 초기에 System.loadLibrary() 호출을 주입할 수 있습니다. 정적 클래스 초기화자 (<clinit>)에 대한 smali 예:
|
||||
```smali
|
||||
.class public Lcom/example/App;
|
||||
.super Landroid/app/Application;
|
||||
@ -189,11 +189,11 @@ return-void
|
||||
.end method
|
||||
```
|
||||
참고:
|
||||
- 라이브러리의 올바른 ABI 변형이 lib/<abi>/ (예: arm64-v8a/armeabi-v7a) 아래에 존재하는지 확인하여 UnsatisfiedLinkError를 방지하세요.
|
||||
- 매우 일찍 로드(class static initializer)하면 native logger가 이후의 JNI 활동을 관찰할 수 있습니다.
|
||||
- 라이브러리의 올바른 ABI 변종이 lib/<abi>/ (예: arm64-v8a/armeabi-v7a) 아래에 존재하는지 확인하여 UnsatisfiedLinkError를 방지하세요.
|
||||
- 매우 초기에 로드하면 (class static initializer) native logger가 이후 JNI activity를 관찰할 수 있습니다.
|
||||
|
||||
## 참고
|
||||
## 참고 자료
|
||||
|
||||
- SoTap: 경량의 앱 내 JNI (.so) 동작 로거 – [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
|
||||
- SoTap: 경량 인앱 JNI (.so) 동작 로거 – [github.com/RezaArbabBot/SoTap](https://github.com/RezaArbabBot/SoTap)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user