Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
dexfinder — Buscador de métodos APK/DEX multiplataforma con trazado de cadenas de llamadas, desofuscación de ProGuard y detección de API ocultas. | Kitploit
Herramientas/GitHubGitHub/junelegency/dexfinder
Seguridad AndroidAnálisis EstáticoAnálisis de VulnerabilidadesAnálisis de CódigoIngeniería InversaRecopilación de InformaciónDevSecOpsSeguridad MóvilAnálisis de Binarios
GitHubjunelegency/dexfinder

dexfinder

Buscador de métodos APK/DEX multiplataforma con trazado de cadenas de llamadas, desofuscación de ProGuard y detección de API ocultas.

9210hace 4 mesesRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Ver Repositorio

dexfinder

Inglés | 中文 | Sitio web demostración de dexfinder


Sitio web: junelegency.github.io/dexfinder

Buscador de referencias a métodos y campos de APK/DEX multiplataforma con trazado de cadenas de llamadas, desofuscación ProGuard/R8 y detección de API ocultas de Android.

Inspirado en la herramienta veridex de Android, reimplementado en Go con capacidades mejoradas: detección de reflexión más rápida, trazado de cadenas de llamadas (veridex solo muestra un nivel) y formatos de salida flexibles.

Características

  • Escaneo de APK/DEX/JAR — Analiza el bytecode DEX y extrae todas las referencias a métodos, campos y cadenas
  • Consulta multi-formato — Busca por nombre Java, firma DEX/JNI o palabra clave simple
  • Trazado de cadenas de llamadas — Traza llamadores hasta N niveles de profundidad, árbol combinado o lista plana, con detección de ciclos
  • Desofuscación ProGuard/R8 — Carga mapping.txt y muestra los nombres originales junto a los ofuscados
  • Detección de API ocultas — Carga hiddenapi-flags.csv y detecta API bloqueadas o no admitidas
  • Detección de reflexión — Compara de forma cruzada clases × cadenas para encontrar usos de API ocultas basados en reflexión
  • Salida flexible — text / json / model / html / sarif, diseño de árbol / lista, estilo de nombre java / dex — todo ortogonal
  • Salida de terminal en color — Colores ANSI autodetectados para etiquetas, conectores de árbol y niveles de API
  • Diff de APK — Compara dos versiones de APK/DEX y detecta referencias de API añadidas, eliminadas o modificadas
  • Informes HTML — HTML interactivo autocontenido con árboles plegables, búsqueda y tema oscuro
  • Salida SARIF — SARIF 2.1.0 para GitHub Code Scanning, VS Code y pipelines de CI
  • Integración con CI — --fail-on blocked termina con un código de salida distinto de cero cuando se encuentran API restringidas
  • Archivo de configuración — .dexfinder.yaml para los valores predeterminados del proyecto; las opciones de CLI lo sobrescriben
  • Cero dependencias externas — Go puro, analizador DEX autocontenido
  • Multiplataforma — macOS (Intel / Apple Silicon), Linux (amd64 / arm64), Windows

Instalación

Homebrew (macOS / Linux):```bash brew install junelegency/tap/dexfinder

root@kitploit:~
**Script** (detecta automáticamente SO/arquitectura):```bash
curl -sSL https://raw.githubusercontent.com/JuneLeGency/dexfinder/main/install.sh | bash

Instalación con Go:```bash go install github.com/JuneLeGency/dexfinder/cmd/dexfinder@latest

root@kitploit:~
**Binario**: descargar desde [Releases](https://github.com/JuneLeGency/dexfinder/releases).

## Inicio rápido```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

Formatos de consulta

El indicador --query acepta múltiples estilos de entrada. dexfinder los detecta automáticamente y convierte entre ellos.

All equivalent — find requestLocationUpdates in LocationManager:

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"

root@kitploit:~
## Control de Salida

Tres ejes independientes, libremente combinables:```
--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

--layout (usado con --trace)

ValueDescription
treeÁrbol combinado: las rutas de llamada compartidas se colapsan en un único árbol (predeterminado)
listLista plana: cada cadena de llamadas única se muestra como una pila independiente

--style

ValueExampleUse case
javacom.example.Foo.method(Foo.java)Legible para humanos (predeterminado)
dexFoo.method(Ljava/lang/String;)VAnálisis preciso de firmas

--scope (alcance de búsqueda)

Controla qué tipo de referencias coincide con la consulta. Esto es fundamental para entender los resultados.

Entendiendo 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()

root@kitploit:~
`--scope=all` (predeterminado) = `callee` + `string`. La dirección `caller` se excluye intencionalmente del valor predeterminado porque responde a una pregunta fundamentalmente distinta. Usa `--scope=caller` o `--scope=everything` explícitamente cuando lo necesites.

**Entender las etiquetas de salida:**

| Etiqueta | Significado |
|---|---|
| `[METHOD]` | Un método **que se está llamando** coincide con tu consulta (coincidencia de callee). Las líneas indentadas son los llamadores. |
| `[FIELD]` | Un campo **que se está accediendo** coincide con tu consulta. Las líneas indentadas son los accesores. |
| `[CALLER→]` | Un **método llamador** coincide con tu consulta. La línea indentada muestra qué API está llamando. |
| `[STRING]` | Una constante de cadena en el código coincide con tu consulta. Las líneas indentadas son donde se usa. |
| `[STRING_TABLE]` | La cadena existe en la tabla de cadenas DEX pero no tiene ninguna referencia `const-string` en el código (puede estar en anotaciones, optimizada por R8, etc.) |

## Ejemplos

### 1. Escanear estadísticas de APK```bash
dexfinder --dex-file app.apk --stats
root@kitploit:~
Loaded 31 DEX file(s): 183913 classes, 1250566 method refs
Method references: 680610
Field references:  625572
String constants:  654353
Referenced types:  192586
Time: 3.9s

2. Encuentra todas las llamadas de seguimiento de ubicación```bash

dexfinder --dex-file app.apk --query "requestLocationUpdates"

root@kitploit:~

[METHOD] Landroid/location/LocationManager;->requestLocationUpdates(Ljava/lang/String;JFLandroid/location/LocationListener;)V (3 ref) Lcom/example/TestEntry;->init(Landroid/content/Context;)V (2 occurrences) Lcom/example/service/LocationService;->onStartCommand(Landroid/content/Intent;II)I

root@kitploit:~
### 3. Trazar cadenas de llamadas — vista de árbol```bash
dexfinder --dex-file app.apk \
  --query "Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;" \
  --trace --depth 5
root@kitploit:~
android.telephony.TelephonyManager.getDeviceId()
└── com.example.aopsdk.TelephonyManager.getDeviceId(TelephonyManager.java)
    ├── com.example.session.PhoneInfo.getImei(PhoneInfo.java)
    ├── com.example.logging.ClientIdHelper.initClientId(ClientIdHelper.java)
    │   └── com.example.logging.ContextInfo.<init>(ContextInfo.java)
    │       ├── com.example.logging.LogStrategyManager.getInstance(LogStrategyManager.java)
    │       └── com.example.logging.LogContextImpl.<init>(LogContextImpl.java)
    ├── com.example.msp.DeviceInfo.k(DeviceInfo.java)
    │   └── com.example.msp.DeviceInfo.<init>(DeviceInfo.java)
    │       └── com.example.msp.DeviceInfo.getInstance(DeviceInfo.java)
    │           ├── com.example.msp.TidHelper.getIMEI(TidHelper.java)
    │           ├── com.example.msp.TidHelper.getIMSI(TidHelper.java)
    │           └── com.example.msp.DeviceCollector.collectData(DeviceCollector.java)
    └── com.example.weex.WXEnvironment.getDevId(WXEnvironment.java)
        └── com.example.weex.WXEnvironment.<clinit>(WXEnvironment.java)

4. Trazar cadenas de llamadas — vista de lista (estilo crash de Java)```bash

dexfinder --dex-file app.apk
--query "Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;"
--trace --depth 5 --layout list

root@kitploit:~

--- Call chain #1 for android.telephony.TelephonyManager.getDeviceId() --- at com.example.session.PhoneInfo.getImei(PhoneInfo.java) at com.example.aopsdk.TelephonyManager.getDeviceId(TelephonyManager.java) at android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java)

--- Call chain #2 for android.telephony.TelephonyManager.getDeviceId() --- at com.example.logging.LogStrategyManager.getInstance(LogStrategyManager.java) at com.example.logging.ContextInfo.(ContextInfo.java) at com.example.logging.ClientIdHelper.initClientId(ClientIdHelper.java) at com.example.aopsdk.TelephonyManager.getDeviceId(TelephonyManager.java) at android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java)

root@kitploit:~
### 5. Rastrear con estilo de firma DEX```bash
dexfinder --dex-file app.apk --query "getDeviceId" --trace --depth 3 --style dex
root@kitploit:~
Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;
└── TelephonyManager.getDeviceId(Landroid/telephony/TelephonyManager;)Ljava/lang/String;
    ├── PhoneInfo.getImei(Landroid/content/Context;)Ljava/lang/String;
    ├── ClientIdHelper.initClientId(Landroid/content/Context;)Ljava/lang/String;
    └── DeviceInfo.k(Landroid/content/Context;)V

6. Salida JSON — árbol```bash

dexfinder --dex-file app.apk --query "getDeviceId" --trace --depth 2 --format json

root@kitploit:~
```json
{
  "targets": [{
    "api": "android.telephony.TelephonyManager.getDeviceId()",
    "tree": {
      "method": "android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java)",
      "callers": [
        { "method": "com.example.aopsdk.TelephonyManager.getDeviceId(TelephonyManager.java)",
          "callers": [
            { "method": "com.example.session.PhoneInfo.getImei(PhoneInfo.java)" },
            { "method": "com.example.logging.ClientIdHelper.initClientId(ClientIdHelper.java)" }
          ]}
      ]
    }
  }]
}

7. Salida JSON — lista```bash

dexfinder --dex-file app.apk --query "getDeviceId" --trace --depth 2 --format json --layout list

root@kitploit:~
```json
{
  "targets": [{
    "api": "android.telephony.TelephonyManager.getDeviceId()",
    "chains": [
      ["com.example.session.PhoneInfo.getImei(PhoneInfo.java)",
       "com.example.aopsdk.TelephonyManager.getDeviceId(TelephonyManager.java)",
       "android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java)"],
      ["com.example.logging.ClientIdHelper.initClientId(ClientIdHelper.java)",
       "com.example.aopsdk.TelephonyManager.getDeviceId(TelephonyManager.java)",
       "android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java)"]
    ]
  }]
}

8. Salida estructurada del modelo (para CI/IDE)```bash

dexfinder --dex-file app.apk --query "getDeviceId" --trace --format model | jq '.call_chains[0]'

root@kitploit:~
```json
{
  "target": "Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;",
  "chain": [
    { "method": { "dex_signature": "...", "class": "...", "name": "getImei",
                   "param_types": ["Landroid/content/Context;"], "return_type": "Ljava/lang/String;",
                   "java_readable": "com.example.session.PhoneInfo.getImei(...)" }},
    { "method": { "dex_signature": "...", "java_readable": "...TelephonyManager.getDeviceId(...)" }},
    { "method": { "dex_signature": "...", "java_readable": "...TelephonyManager.getDeviceId(...)" }}
  ],
  "depth": 2
}

9. Mapeo ProGuard/R8 — consulta y visualización

Con --mapping, tanto la entrada como la salida admiten nombres originales (sin ofuscar).

Consulta por nombre original → se convierte automáticamente al nombre ofuscado para la búsqueda en DEX:```bash

Query with original simple class name (mapping converts "KotlinCases" → "LJ7;" internally)

dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt

Query with original Java full name

dexfinder --dex-file app.apk --query "com.example.app.utils.Helper" --mapping mapping.txt

Query with obfuscated name still works

dexfinder --dex-file app.apk --query "LJ7;" --mapping mapping.txt

root@kitploit:~
**Salida de nombres desofuscados en el rastreo:**```bash
# Tree trace with deobfuscated names
dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --trace --depth 3
root@kitploit:~
com.example.kotlin.KotlinCases$$ExternalSyntheticLambda1.<init>(int)
└── com.example.TestEntry.runAllTests(TestEntry.java)
    └── com.example.MainActivity.onCreate(MainActivity.java)

Mostrar tanto nombres ofuscados como originales:```bash dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --show-obf --trace

root@kitploit:~

com.example.kotlin.KotlinCases.fetchLocationAsync(KotlinCases.java) └── com.example.kotlin.KotlinCases$testCoroutines$3.invokeSuspend(KotlinCases.java) [obf: G7.e] └── com.example.kotlin.KotlinCases$testCoroutines$3.create(KotlinCases.java) [obf: G7.b]

root@kitploit:~
**Todas las combinaciones con otras banderas:**```bash
# Original name + trace as flat list
dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --trace --layout list

# Original name + DEX signature style
dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --trace --style dex

# Original name + JSON tree + show-obf
dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --show-obf --trace --format json

# Original name + reverse direction (what does this class call?)
dexfinder --dex-file app.apk --query "com.example.kotlin.KotlinCases" --mapping mapping.txt --scope caller

Matriz de entrada × salida:

10. Detección de API oculta```bash

Download CSV (one-time)

curl -o hiddenapi-flags.csv
https://dl.google.com/developers/android/baklava/non-sdk/hiddenapi-flags.csv

Full scan — linking + reflection detection

dexfinder --dex-file app.apk --api-flags hiddenapi-flags.csv

root@kitploit:~

#1: Linking unsupported Lsun/misc/Unsafe;->allocateInstance(Ljava/lang/Class;)Ljava/lang/Object; use(s): Lcom/google/gson/internal/UnsafeAllocator;->create()Lcom/google/gson/internal/UnsafeAllocator;

#2: Reflection blocked Landroid/location/ILocationManager;->getCurrentLocation potential use(s): Lcom/example/monitor/LocationMonitor;->hookSystemLocationManager(Landroid/content/Context;)V

root@kitploit:~
### 11. Constantes de cadenas de búsqueda (URIs content://, claves de API, etc.)```bash
# Find content:// URIs in code
dexfinder --dex-file app.apk --query "content://com.android.contacts" --scope string

# Include strings only in DEX table (optimized out by R8, annotations, etc.)
dexfinder --dex-file app.apk --query "content://com.android.contacts" --scope everything
root@kitploit:~
[STRING] "content://com.android.contacts/" (1 ref)
       Lcom/example/imageloader/BaseImageDownloader;->getStreamFromContent(Ljava/lang/String;)Ljava/io/InputStream;
[STRING_TABLE] "content://com.android.contacts" (in DEX string table, no code reference found)

12. Filtrar por prefijo de clase```bash

Only scan classes in your own package

dexfinder --dex-file app.apk --query "getDeviceId" --class-filter "Lcom/mycompany/"

Scan multiple packages

dexfinder --dex-file app.apk --query "getDeviceId" --class-filter "Lcom/mycompany/,Lcom/mylib/"

root@kitploit:~
### 13. Combina todo```bash
# Deobfuscated JSON tree of location API usage, filtered to your code
dexfinder --dex-file app.apk \
  --query "android.location.LocationManager#requestLocationUpdates" \
  --trace --depth 8 \
  --format json --layout tree --style java \
  --mapping mapping.txt --show-obf \
  --class-filter "Lcom/mycompany/"

14. Informe HTML```bash

dexfinder --dex-file app.apk --query "getDeviceId" --trace --format html --output report.html

root@kitploit:~
Se abre en cualquier navegador — árboles de llamadas plegables, barra de búsqueda, tema oscuro.

### 15. SARIF para GitHub Code Scanning```bash
dexfinder --dex-file app.apk --api-flags hiddenapi-flags.csv --format sarif > results.sarif
# Upload to GitHub:
# gh api repos/OWNER/REPO/code-scanning/sarifs -f "[email protected]"

16. APK diff```bash

Compare two APK versions

dexfinder --dex-file new.apk --diff old.apk --query "getDeviceId"

root@kitploit:~
  • 1 added method(s)
    • Lcom/new/Feature;->trackDevice()V
  • 1 removed method(s)
    • Lcom/old/Legacy;->getIMEI()V

Summary: +1 added, -1 removed, ~0 changed

root@kitploit:~
### 17. Puerta de CI con --fail-on```bash
# Fail CI if any blocked hidden APIs are used
dexfinder --dex-file app.apk --api-flags hiddenapi-flags.csv --fail-on blocked
# Exit code: 0 = clean, 2 = violations found

Rendimiento

Probado en Apple M-series, un solo hilo:

En comparación con veridex (C++, modo impreciso) en el mismo APK de ~300MB:

  • veridex preciso: 27s (sin reflexión vía Binder/AIDL)
  • veridex impreciso: >32 min (terminado, explosión de producto cartesiano)
  • dexfinder: 5.4s (optimización de índice inverso)

Todas las opciones

Archivo de configuración

Crea .dexfinder.yaml en la raíz de tu proyecto para establecer valores predeterminados:```yaml mapping: ./build/outputs/mapping.txt class-filter: "Lcom/mycompany/" api-flags: ./hiddenapi-flags.csv style: java depth: 8 color: auto

root@kitploit:~
Los indicadores de la CLI siempre anulan los valores del archivo de configuración.

## Compilar desde el código fuente```bash
git clone https://github.com/JuneLeGency/dexfinder.git
cd dexfinder
go build -o dexfinder ./cmd/dexfinder/
go test ./...

License

Apache License 2.0


dexfinder

Sitio web oficial: junelegency.github.io/dexfinder

Buscador multiplataforma de referencias a métodos y campos en APK/DEX, con soporte para seguimiento de cadenas de llamadas, ofuscación inversa ProGuard/R8 y detección de API ocultas de Android.

Basado en el principio de Android veridex, reimplementado y mejorado en Go: detección de reflexión más rápida, seguimiento de cadenas de llamadas de varios niveles (veridex solo tiene un nivel), formatos de salida flexibles.

Características

  • Escaneo de APK/DEX/JAR — Analiza el bytecode DEX y extrae todas las referencias a métodos/campos/cadenas
  • Consultas de múltiples formatos — Compatible con nombres de clase Java, firmas DEX/JNI y palabras clave simples
  • Seguimiento de cadenas de llamadas — Rastrea N niveles de llamadores hacia arriba, combina árboles o expande listas, detecta bucles de recursión automáticamente
  • Ofuscación inversa ProGuard/R8 — Carga mapping.txt y muestra los nombres originales
  • Detección de API ocultas — Carga hiddenapi-flags.csv, detecta API bloqueadas o no soportadas
  • Detección de reflexión — Coincidencia cruzada de nombres de clase×cadenas para descubrir API ocultas invocadas por reflexión (compatible con veridex)
  • Salida flexible — formatos text / json / model / html / sarif, diseños tree / list, estilos de nomenclatura java / dex — combinación ortogonal
  • Salida de terminal en color — Detección automática de TTY, etiquetas, líneas de conexión de árbol y colores por nivel de API
  • Comparación de diferencias de APK — Compara dos versiones de APK, detecta referencias a API añadidas/eliminadas/cambiadas
  • Informe HTML — HTML interactivo autocontenido, árbol colapsable, filtro de búsqueda, tema oscuro
  • Salida SARIF — formato SARIF 2.1.0, compatible con GitHub Code Scanning y VS Code
  • Integración con CI — devuelve un código de salida distinto de cero cuando --fail-on blocked detecta API restringidas
  • Archivo de configuración — configuración predeterminada del proyecto .dexfinder.yaml, los parámetros de la línea de comandos la sobrescriben
  • Cero dependencias externas — implementación pura en Go, analizador DEX autocontenido
  • Multiplataforma — macOS (Intel / Apple Silicon), Linux (amd64 / arm64), Windows

Instalación

Homebrew (macOS / Linux):```bash brew install junelegency/tap/dexfinder

root@kitploit:~
**Instalación de scripts** (detección automática del sistema):```bash
curl -sSL https://raw.githubusercontent.com/JuneLeGency/dexfinder/main/install.sh | bash

Instalación de Go:```bash go install github.com/JuneLeGency/dexfinder/cmd/dexfinder@latest

root@kitploit:~
**Descarga de binarios**: [Releases](https://github.com/JuneLeGency/dexfinder/releases)

## Inicio rápido```bash
# 查看 APK 概况
dexfinder --dex-file app.apk --stats

# 查找所有 getDeviceId 调用(获取 IMEI)
dexfinder --dex-file app.apk --query "getDeviceId"

# 追踪调用链(合并树形视图)
dexfinder --dex-file app.apk --query "getDeviceId" --trace

# 追踪调用链(展开为独立调用栈)
dexfinder --dex-file app.apk --query "getDeviceId" --trace --layout list

# 用精确 JNI 签名查询
dexfinder --dex-file app.apk \
  --query "Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;" \
  --trace --depth 8

Formato de consulta (--query)

Control de salida

Tres dimensiones independientes, combinables libremente:``` --format (text / json / model / html / sarif) 输出什么 --layout (tree / list) 怎么排列调用链 --style (java / dex) 怎么显示名称 --color (auto / always / never) 终端着色

root@kitploit:~
### Comparación de `--layout` (con `--trace`)

**tree** — combina las rutas comunes y muestra el panorama completo en un solo árbol:```
android.telephony.TelephonyManager.getDeviceId()
└── ...aopsdk...TelephonyManager.getDeviceId(TelephonyManager.java)
    ├── PhoneInfo.getImei(PhoneInfo.java)
    ├── ClientIdHelper.initClientId(ClientIdHelper.java)
    │   └── ContextInfo.<init>(ContextInfo.java)
    └── DeviceInfo.k(DeviceInfo.java)
        └── DeviceInfo.getInstance(DeviceInfo.java)
            ├── TidHelper.getIMEI(TidHelper.java)
            └── DeviceCollector.collectData(DeviceCollector.java)

list — cada cadena se muestra de forma independiente (estilo Java crash):``` --- Call chain #1 --- at PhoneInfo.getImei(PhoneInfo.java) at ...aopsdk...TelephonyManager.getDeviceId(TelephonyManager.java) at android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java)

--- Call chain #2 --- at ContextInfo.(ContextInfo.java) at ClientIdHelper.initClientId(ClientIdHelper.java) at ...aopsdk...TelephonyManager.getDeviceId(TelephonyManager.java) at android.telephony.TelephonyManager.getDeviceId(TelephonyManager.java)

root@kitploit:~
### `--style` 对比

**java** (predeterminado): `com.example.Foo.method(Foo.java)`
**dex**: `Foo.method(Ljava/lang/String;)V`

### Salida JSON```bash
# JSON 树
dexfinder --dex-file app.apk --query "getDeviceId" --trace --format json

# JSON 列表
dexfinder --dex-file app.apk --query "getDeviceId" --trace --format json --layout list

--scope Ámbito de búsqueda

Controla qué tipo de referencia coincide la consulta. Comprender este parámetro es crucial para interpretar correctamente los resultados.

Diferencia entre callee y caller:``` scope=callee: "谁调了 finish()?" onCreate ──调用──→ finish() ← 显示这些调用者 onResume ──调用──→ finish()

scope=caller: "finish() 内部调了什么?" finish() ──调用──→ Log.i() ← 显示这些被调用者 finish() ──调用──→ super.finish()

root@kitploit:~
`--scope=all`(默认)= `callee` + `string`。`caller` 方向被故意排除在默认之外,因为它回答的是完全不同的问题。需要时用 `--scope=caller` 或 `--scope=everything` 显式启用。

**输出标签含义:**

| 标签 | 含义 |
|---|---|
| `[METHOD]` | 你搜的方法**被别人调用了**。缩进行是调用者。 |
| `[FIELD]` | 你搜的字段**被别人访问了**。缩进行是访问者。 |
| `[CALLER→]` | 你搜的方法名出现在某个**调用方**中,缩进行显示它调了什么 API。 |
| `[STRING]` | 代码中的字符串常量匹配。缩进行是使用该字符串的方法。 |
| `[STRING_TABLE]` | 字符串仅存在于 DEX 字符串表中,代码里没有 `const-string` 引用(可能在注解中、被 R8 优化掉等)。 |

## 更多用法

### 反混淆(--mapping)

加载 `--mapping` 后,**输入和输出**都支持原始(未混淆)名称。

**用原始名查询 → 自动转换为混淆名搜索 DEX:**```bash
# 用原始简短类名查(mapping 内部将 "KotlinCases" 转为 "LJ7;")
dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt

# 用原始 Java 全名查
dexfinder --dex-file app.apk --query "com.example.app.utils.Helper" --mapping mapping.txt

# 用混淆名查也正常工作
dexfinder --dex-file app.apk --query "LJ7;" --mapping mapping.txt

Nombre de salida desofuscado:```bash

trace 树形 + 反混淆

dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --trace

root@kitploit:~
**Mostrar simultáneamente el nombre ofuscado y el nombre original:**```bash
dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --show-obf --trace
root@kitploit:~
com.example.KotlinCases.fetchLocationAsync(KotlinCases.java)
└── com.example.KotlinCases$testCoroutines$3.invokeSuspend(KotlinCases.java)  [obf: G7.e]

Combinar libremente con otros parámetros:```bash

原始名 + 展开列表

dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --trace --layout list

原始名 + DEX 签名风格

dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --trace --style dex

原始名 + JSON 树 + 显示混淆名

dexfinder --dex-file app.apk --query "KotlinCases" --mapping mapping.txt --show-obf --trace --format json

原始名 + 反向查看(这个类内部调了什么)

dexfinder --dex-file app.apk --query "com.example.KotlinCases" --mapping mapping.txt --scope caller

root@kitploit:~
**Matriz de entrada × salida:**

| Entrada de consulta | Sin mapping | `--mapping` | `--mapping --show-obf` |
|---|---|---|---|
| Nombre ofuscado `LJ7;` | ✓ Salida ofuscada | ✓ Salida desofuscada | ✓ Ambos en paralelo |
| Nombre corto original `KotlinCases` | ✗ No se encuentra | ✓ Conversión automática + salida desofuscada | ✓ Conversión automática + ambos en paralelo |
| Nombre completo original `com.example...` | ✗ No se encuentra | ✓ Conversión automática + salida desofuscada | ✓ Conversión automática + ambos en paralelo |

### Detección de API oculta```bash
# 下载 CSV(一次性)
curl -o hiddenapi-flags.csv \
  https://dl.google.com/developers/android/baklava/non-sdk/hiddenapi-flags.csv

# 全量检测(直接链接 + 反射检测)
dexfinder --dex-file app.apk --api-flags hiddenapi-flags.csv

Búsqueda de cadenas```bash

搜索代码中的 content:// URI

dexfinder --dex-file app.apk --query "content://com.android.contacts" --scope string

包含被 R8 优化掉的字符串(注解、死代码等)

dexfinder --dex-file app.apk --query "content://com.android.contacts" --scope everything

root@kitploit:~
### Filtrar por nombre de paquete```bash
# 只扫描自己的代码
dexfinder --dex-file app.apk --query "getDeviceId" --class-filter "Lcom/mycompany/"

Uso combinado```bash

反混淆 + JSON 树形输出 + 定位 API 调用 + 过滤自己的代码

dexfinder --dex-file app.apk
--query "android.location.LocationManager#requestLocationUpdates"
--trace --depth 8
--format json --layout tree --style java
--mapping mapping.txt --show-obf
--class-filter "Lcom/mycompany/"

root@kitploit:~
### Informe HTML```bash
dexfinder --dex-file app.apk --query "getDeviceId" --trace --format html --output report.html

Listo para usar en el navegador — árbol de llamadas plegable, barra de búsqueda y tema oscuro.

SARIF (GitHub Code Scanning)```bash

dexfinder --dex-file app.apk --api-flags hiddenapi-flags.csv --format sarif > results.sarif

root@kitploit:~
### Comparación de versiones de APK```bash
dexfinder --dex-file new.apk --diff old.apk --query "getDeviceId"
root@kitploit:~
+ 1 added method(s)
  + Lcom/new/Feature;->trackDevice()V

- 1 removed method(s)
  - Lcom/old/Legacy;->getIMEI()V

Summary: +1 added, -1 removed, ~0 changed

Punto de control de CI```bash

检测到 blocked API 时 CI 失败

dexfinder --dex-file app.apk --api-flags hiddenapi-flags.csv --fail-on blocked

退出码: 0 = 通过, 2 = 有违规

root@kitploit:~
## Rendimiento

Apple M 系列芯片,单线程:

| APK 大小 | DEX 数 | 类数 | 方法引用 | 扫描 | Hidden API |
|---|---|---|---|---|---|
| ~1 MB | 1 | ~2K | ~18K | **24ms** | — |
| ~10 MB | 2 | ~25K | ~100K | **335ms** | — |
| ~300 MB | 30+ | ~180K | ~1.2M | **3.9s** | **5.4s** |

与 veridex (C++) 在同一 ~300MB APK 上对比:
- veridex precise: **27s**(无法追踪 Binder/AIDL 反射)
- veridex imprecise: **>32 分钟**(笛卡尔积爆炸,被 kill)
- **dexfinder: 5.4s**(反向索引优化)

## Todos los parámetros

| Parámetro | Descripción | Valor predeterminado |
|---|---|---|
| `--dex-file` | Ruta del archivo APK/DEX/JAR **(obligatorio)** | — |
| `--query` | Palabra clave de búsqueda (Java / DEX/JNI / nombre simple) | — |
| `--trace` | Habilita el rastreo de cadenas de llamadas (requiere `--query`) | `false` |
| `--depth` | Profundidad máxima de la cadena de llamadas | `5` |
| `--layout` | Disposición del rastreo: `tree` (árbol combinado) o `list` (lista expandida) | `tree` |
| `--style` | Estilo de nombres: `java` (legible) o `dex` (firmas JNI) | `java` |
| `--format` | Formato de salida: `text`, `json`, `model`, `html`, `sarif` | `text` |
| `--output` | Escribe en un archivo en lugar de stdout | — |
| `--color` | Modo de color: `auto`, `always`, `never` | `auto` |
| `--mapping` | Ruta de ProGuard/R8 mapping.txt | — |
| `--show-obf` | Muestra tanto los nombres ofuscados como los desofuscados | `false` |
| `--api-flags` | Ruta de hiddenapi-flags.csv | — |
| `--class-filter` | Filtro por prefijo de descriptor de clase (separado por comas) | — |
| `--exclude-api-lists` | Niveles de API excluidos | — |
| `--scope` | Alcance de búsqueda: `all`, `callee`, `caller`, `string`, `string-table`, `everything` | `all` |
| `--diff` | Compara con otro APK/DEX y muestra las diferencias de API | — |
| `--fail-on` | Devuelve un código de salida distinto de cero cuando se detecta una API de nivel especificado (punto de control de CI) | — |
| `--stats` | Muestra solo el resumen de estadísticas | `false` |
| `--version` | Muestra el número de versión | `false` |

### Archivo de configuración

Crea un `.dexfinder.yaml` en la raíz del proyecto para establecer los valores predeterminados:```yaml
mapping: ./build/outputs/mapping.txt
class-filter: "Lcom/mycompany/"
api-flags: ./hiddenapi-flags.csv
style: java
depth: 8
color: auto

Los argumentos de la línea de comandos siempre sobrescriben el archivo de configuración.

Compilar desde el código fuente```bash

git clone https://github.com/JuneLeGency/dexfinder.git cd dexfinder go build -o dexfinder ./cmd/dexfinder/ go test ./...

root@kitploit:~
## Licencia

Apache License 2.0
Descargar herramienta
FormatoEjemploComportamiento
Nombre simplegetDeviceIdCoincidencia difusa de subcadena en todas las APIs
Clase Javaandroid.telephony.TelephonyManagerTodos los métodos/campos de esa clase
Clase Java#métodoandroid.telephony.TelephonyManager#getDeviceIdTodas las sobrecargas de ese método
Firma completa de Java...TelephonyManager#getDeviceId()Coincidencia exacta + respaldo de sobrecarga
Firma DEX/JNILandroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;Solo coincidencia exacta
ValueDescription
textSalida de texto plano con etiquetas de colores (predeterminado)
jsonJSON: resultados del escaneo o trace con diseño de árbol/lista
modelJSON estructurado con tipos completos MethodInfo/FieldInfo (para IDE/CI)
htmlInforme HTML autónomo con árboles plegables y búsqueda
sarifFormato de análisis estático SARIF 2.1.0 (GitHub / VS Code)
ValueQué buscaPregunta que respondeEtiqueta de salida
allAPIs callee + campos + strings de código"¿Quién llama a esta API?" (predeterminado)[METHOD] [FIELD] [STRING]
calleeSolo las firmas de API objetivo en instrucciones invoke-* / get/put"¿Quién llama a este método/campo específico?"[METHOD] [FIELD]
callerSolo la firma del método que llama"¿Qué llama este método internamente?"[CALLER→]
stringConstantes de cadena en instrucciones const-string"¿Dónde se usa esta cadena en el código?"[STRING]
string-tableStrings de código + tabla completa de strings de DEX"¿Existe esta cadena en algún lugar del DEX?" (incluye anotaciones, código muerto)[STRING] [STRING_TABLE]
everythingTodo lo anterior combinadoPanorama completotodas las etiquetas
Entrada de consultaSin mapeo--mapping--mapping --show-obf
Ofuscado: LJ7;✓ salida ofuscada✓ salida desofuscada✓ ambos nombres
Original simple: KotlinCases✗ no encontrado✓ auto-convierte, salida desofuscada✓ auto-convierte, ambos nombres
Original completo: com.example...KotlinCases✗ no encontrado✓ auto-convierte, salida desofuscada✓ auto-convierte, ambos nombres
Tamaño del APKArchivos DEXClasesReferencias de métodosEscaneoAPI oculta
~1 MB1~2K~18K24ms—
~10 MB2~25K~100K335ms—
~300 MB30+~180K~1.2M3.9s5.4s
OpciónDescripciónPor defecto
--dex-fileArchivo APK/DEX/JAR para analizar (obligatorio)—
--queryPalabra clave de búsqueda (Java, DEX/JNI o nombre simple)—
--traceHabilitar trazado de cadena de llamadas (requiere --query)false
--depthProfundidad máxima de cadena de llamadas5
--layoutDiseño del trazado: tree o listtree
--styleEstilo de nombre: java o dexjava
--formatFormato de salida: text, json, model, html, sariftext
--outputEscribir la salida en un archivo en lugar de stdout—
--colorModo de color: auto, always, neverauto
--mappingRuta de mapping.txt de ProGuard/R8—
--show-obfMostrar nombres ofuscados junto a los desofuscadosfalse
--api-flagsRuta a hiddenapi-flags.csv—
--class-filterPrefijos de descriptores de clase separados por comas—
--exclude-api-listsListas de API que excluir del informe—
--scopeAlcance de búsqueda: all, callee, caller, string, string-table, everythingall
--diffComparar con otro APK/DEX y mostrar diferencias de API—
--fail-onSalir con código no cero si se encuentran API ocultas en este nivel (puerta de CI)—
--statsMostrar solo estadísticas de resumenfalse
--versionMostrar versiónfalse
FormatoEjemploComportamiento
Nombre simplegetDeviceIdCoincidencia difusa de subcadena
Nombre de clase Javaandroid.telephony.TelephonyManagerCoincide con todos los métodos de esa clase
Nombre de clase Java#método...TelephonyManager#getDeviceIdCoincide con todas las sobrecargas de ese método
Firma completa de Java...#getDeviceId()Coincidencia exacta + retroceso a sobrecargas
Firma DEX/JNILandroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String;Coincidencia exacta
ValorContenido de búsquedaPregunta que respondeEtiqueta de salida
allAPI invocada + campos + cadenas de código"¿Quién llamó a este método?" (predeterminado)[METHOD] [FIELD] [STRING]
calleeSolo la firma destino en instrucciones invoke-* / get/put"¿Quién llamó a este método/campo específico?"[METHOD] [FIELD]
callerSolo la firma del método que llama"¿Qué llama este método internamente?"[CALLER→]
stringConstantes de cadena en instrucciones const-string"¿Dónde se usa esta cadena en el código?"[STRING]
string-tableCadenas de código + tabla completa de cadenas del DEX"¿Esta cadena existe en el DEX?" (incluye anotaciones, código muerto)[STRING] [STRING_TABLE]
everythingTodo lo anteriorVista completaTodas las etiquetas