
Cercatore di metodi APK/DEX multipiattaforma con tracciamento della catena di chiamate, deoffuscamento ProGuard e rilevamento di API nascoste
Sito web: junelegency.github.io/dexfinder
Strumento multipiattaforma per la ricerca di riferimenti a metodi e campi in APK/DEX con tracciamento della catena di chiamate, deoffuscamento ProGuard/R8 e rilevamento di API nascoste Android.
Ispirato dallo strumento veridex di Android, reimplementato in Go con capacità migliorate: rilevamento più rapido della reflection, tracciamento della catena di chiamate (veridex mostra solo un livello) e formati di output flessibili.
--fail-on blocked termina con codice diverso da zero quando vengono trovate API ristrette.dexfinder.yaml per impostazioni predefinite del progetto, i flag CLI sovrascrivonoHomebrew (macOS / Linux):```bash brew install junelegency/tap/dexfinder
**Script** (rileva automaticamente OS/arch):```bash
curl -sSL https://raw.githubusercontent.com/JuneLeGency/dexfinder/main/install.sh | bash
Go install:```bash go install github.com/JuneLeGency/dexfinder/cmd/dexfinder@latest
**Binario**: scarica da [Releases](https://github.com/JuneLeGency/dexfinder/releases).
## Avvio rapido```bash
# Show APK overview
dexfinder --dex-file app.apk --stats
# Find all calls to getDeviceId (IMEI)
dexfinder --dex-file app.apk --query "getDeviceId"
# Trace call chains as merged tree
dexfinder --dex-file app.apk --query "getDeviceId" --trace
# Trace as flat call stacks (Java crash style)
dexfinder --dex-file app.apk --query "getDeviceId" --trace --layout list
# Exact JNI signature query
dexfinder --dex-file app.apk \
--query "Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;" \
--trace --depth 8
# Hidden API detection
dexfinder --dex-file app.apk --api-flags hiddenapi-flags.csv
Il flag --query accetta più stili di input. dexfinder rileva e converte automaticamente tra di essi.
| Formato | Esempio | Comportamento |
|---|---|---|
| Simple name | getDeviceId | Corrispondenza fuzzy per sottostringa in tutte le API |
| Java class | android.telephony.TelephonyManager | Tutti i metodi/campi di quella classe |
| Java class#method | android.telephony.TelephonyManager#getDeviceId | Tutti gli overload di quel metodo |
| Java full signature | ...TelephonyManager#getDeviceId() | Esatta + fallback agli overload |
| DEX/JNI signature | Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String; | Solo corrispondenza esatta |
dexfinder --dex-file app.apk --query "requestLocationUpdates" dexfinder --dex-file app.apk --query "android.location.LocationManager#requestLocationUpdates" dexfinder --dex-file app.apk --query "Landroid/location/LocationManager;->requestLocationUpdates(Ljava/lang/String;JFLandroid/location/LocationListener;)V"
## Controllo Output
Tre assi indipendenti, liberamente combinabili:```
--format (text / json / model / html / sarif) what to output
--layout (tree / list) how to arrange traces
--style (java / dex) how to display names
--color (auto / always / never) terminal colors
--format| Valore | Descrizione |
|---|---|
text | Output di testo semplice con tag colorati (predefinito) |
json | JSON — risultati di scansione o trace con layout ad albero/elenco |
model | JSON strutturato con tipi MethodInfo/FieldInfo completi (per IDE/CI) |
html | Report HTML autonomo con alberi collassabili e ricerca |
sarif | Formato di analisi statica SARIF 2.1.0 (GitHub / VS Code) |
--layout (usato con --trace)| Valore | Descrizione |
|---|---|
tree | Albero unito — percorsi di chiamata condivisi collassati in un unico albero (predefinito) |
list | Elenco piatto — ogni catena di chiamata unica mostrata come stack indipendente |
--style| Valore | Esempio | Caso d'uso |
|---|---|---|
java | com.example.Foo.method(Foo.java) | Leggibile dall'uomo (predefinito) |
dex | Foo.method(Ljava/lang/String;)V | Analisi precisa della firma |
--scope (ambito di ricerca)Controlla che tipo di riferimenti la query corrisponde. Questo è fondamentale per comprendere i risultati.
| Valore | Cosa cerca | Domanda a cui risponde | Tag di output |
|---|---|---|---|
all | API callee + campi + stringhe di codice | "Chi chiama questa API?" (predefinito) | [METHOD] [FIELD] [STRING] |
callee | Solo firme API target nelle istruzioni invoke-* / get/put | "Chi chiama questo specifico metodo/campo?" | [METHOD] [FIELD] |
caller | Solo la firma del metodo chiamante | "Cosa chiama internamente questo metodo?" | [CALLER→] |
string | Costanti stringa nelle istruzioni const-string | "Dove viene usata questa stringa nel codice?" | [STRING] |
string-table | Stringhe di codice + intera tabella stringhe DEX | "Questa stringa esiste da qualche parte in DEX?" (include annotazioni, codice morto) | [STRING] [STRING_TABLE] |
everything | Tutto quanto sopra combinato | Quadro completo | tutti i tag |
Comprendere callee vs caller:``` scope=callee: "Who calls finish()?" onCreate ──calls──→ finish() ← these callers are shown onResume ──calls──→ finish()
scope=caller: "What does finish() call internally?" finish() ──calls──→ Log.i() ← these callees are shown finish() ──calls──→ super.finish()
`--scope=all` (default) = `callee` + `string`. La direzione `caller` è intenzionalmente esclusa dal default perché risponde a una domanda fondamentalmente diversa. Usa `--scope=caller` o `--scope=everything` esplicitamente quando ne hai bisogno.
**Comprendere i tag di output:**