
Ingeniería inversa de Android para humanos y agentes de IA: Java tipado en milisegundos, xrefs, reconocimiento de API y secretos, diff de APK, re-firma, un visor nativo y un servidor MCP. Un único ejecutable en Rust, sin JVM.
Abre cualquier aplicación Android y descubre lo que realmente hace.
Qué recopila, cómo gana dinero contigo, qué expone. En segundos, como Java legible.
Visor, CLI y servidor MCP para agentes de IA. Un solo ejecutable. Sin necesidad de Java.
Cada uno requirió leer juntos el manifiesto, los recursos y el código descompilado. Un grep de
http:// no encuentra nada de esto. Haz clic en un hallazgo para ver la prueba: salida real, recortada a las líneas que importan.
Block Blast! 10.9.3 (compilación de Play), 75.938 clases, escaneadas en 3,1 s.
Quién recibe tus datos: AppLovin MAX, AdMob, Meta, Unity, ironSource, Pangle, Liftoff/Vungle, InMobi,
Moloco, Amazon APS, Digital Turbine/Fyber, PubMatic, Bigo. Rastreadores: AppsFlyer, Firebase, eventos de Facebook y
TikTok, ThinkingData, el propio cn.hsdata del estudio. Permisos: ID de publicidad y las cuatro
API de anuncios de Privacy Sandbox.
Dos endpoints no provienen de ningún SDK. infer es una llamada a un modelo: ¿cuánto valen los anuncios de este jugador?
$ apkscope search blockblast.xapk urls
q.mb("https://low-ecpm.afafb.com/infer/v1/low_ecpm_cut", appActivity, jSONObject, new c() {
return "https://ecpm.afafb.com/infer/v1/ecpm";
$ apkscope decompile blockblast.xapk me.f # the code calls it AlgorithmInterCutManager
m2.mg(jSONObject, "ActUserInfo", ClassE.ma());
m2.me(jSONObject, "AdHistInfo", jSONArray);
m2.mg(jSONObject, "UserContext", ClassE.mc(str2, appActivity, z, UUID.randomUUID().toString(), "INTER"));
m2.mg(jSONObject, "UserInfo", ClassE.md());
Estos rellenan deviceModel, ram, disk, cpu, carrier, country, ip_country, timeZone,
install_time, cold_start_num y tus anuncios pasados con su revenue. La respuesta establece tu precio
mínimo, la puja más baja que un anunciante debe superar para mostrarte un anuncio:
$ apkscope decompile blockblast.xapk v2.d --method Y # AlgorithmBy1004, AppLovin MAX
double d3 = d * d2; // floor = predicted eCPM x "floor_factor" (remote, default 2.0)
this.g_c.mi(d3);
String.format(Locale.locale_US, "算法接口成功更新底价 - FloorPrice: %.2f, ... // "algorithm API updated the floor price"
Veredicto: legal, y cómo funcionan los juegos financiados por publicidad. Ahora puedes verlo.
Block Blast oculta sus clases de juego detrás de un empaquetador de NetEase: org.cocos2dx.javascript.AppActivity no está
en el APK. apkscope dump permitió que el juego se desempaquetara a sí mismo y extrajo 15 DEX de la memoria en 25 s, alrededor de
3.100 clases ocultas. Los scripts llaman a Java a través de JsCallJava; sus métodos muestran lo que solicitan:
$ apkscope dump com.block.juggle out/ --attach
$ apkscope decompile out/dex/classes9.dex org.cocos2dx.javascript.pay.o --method w # SPayManager.serverControl
if (jSONObject.has("isStatus")) {
boolean z = k0.ma("1", jSONObject.getString("isStatus"));
SPStore.mk().y(z);
JsCallJava.setGameAuditMode(z, "auditMode"); // → window.IPAUtils.respHearingState(1)
auditMode en los scripts del juego, y el juego lo recuerda. Los juegos usan esto para comportarse de forma diferente mientras una tienda los revisa; lo que Block Blast cambia está en sus scripts cifrados, así que no afirmamos más.callNativeGetLeftBattery (% de batería), callNativeIsInstallOtherApp (¿está instalada la app X?), getDeviceInfoByAdb (velocidades de CPU, RAM, almacenamiento, pantalla, modelo).trackGameEndRevenue almacena datos de ingresos al final de cada partida.BleBumpKit empareja dos teléfonos cercanos, tras pedir permiso.No mostrado: cómo decide tus próximos bloques. Eso está en los scripts cifrados (ver límites).
El proveedor de la base de datos de archivos está exportado, y sus etiquetas <path-permission> nombran un permiso literalmente llamado "false". La única protección real está en el código, y omite file/, dir/ y la raíz:
$ apkscope decompile nextcloud.apk com.owncloud.android.providers.FileContentProvider
private boolean isCallerNotAllowed(Uri uri) {
switch (i) {
case 4: case 5: case 6: case 7: case 8: // shares, capabilities, uploads, ...
str = this.mContext.getPackageManager().getNameForUid(Binder.getCallingUid());
}
return false; // file (1), dir (2), root (3): anyone
}
public Cursor query(Uri uri, ...) {
if (i != 1 && i != 2 && i != 3 && isCallerNotAllowed(uri)) {
(Las etiquetas de caso están plegadas, se han añadido comentarios). insert, update y delete usan la misma comprobación. La tabla
contiene path, path_decrypted, file_owner, sharees, share_by_link, metadata_gps...
Veredicto: cualquier aplicación instalada puede leer tus nombres de archivo, carpetas y recursos compartidos, incluidos los nombres descifrados de archivos cifrados de extremo a extremo, y modificar o eliminar filas. GitHub Security Lab lo señaló en 2021; la inyección SQL de ese informe se corrigió, el acceso abierto sigue ahí en 35.0.1. Leído desde el código, no ejecutado en un dispositivo.
$ apkscope resource antennapod.apk res/xml/network_security_config.xml
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="user" />
<certificates src="system" />
$ apkscope decompile antennapod.apk de.danoeh.antennapod.net.ssl.CompositeX509TrustManager --method checkServerTrusted
X509TrustManager x509TrustManager = (X509TrustManager) iterator.next();
try {
x509TrustManager.checkServerTrusted(x509CertificateArr, str);