
Rétro-ingénierie Android pour les humains et les agents IA : du Java typé en quelques millisecondes, des références croisées, la reconnaissance d'API et de secrets, le diff d'APK, la re-signature, une visionneuse native et un serveur MCP. Un seul exécutable Rust, sans JVM.
Ouvrez n'importe quelle application Android et voyez ce qu'elle fait réellement.
Ce qu'elle collecte, comment elle gagne de l'argent sur votre dos, ce qu'elle expose. En quelques secondes, en Java lisible.
Visionneuse, CLI et serveur MCP pour agents IA. Un seul exécutable. Aucun Java requis.
Chacune a nécessité de lire ensemble le manifeste, les ressources et le code décompilé. Un grep sur
http:// n'en trouve aucune. Cliquez sur une découverte pour la preuve : sortie réelle, réduite aux lignes qui comptent.
Block Blast! 10.9.3 (version Play), 75 938 classes, analysées en 3,1 s.
Qui reçoit vos données : AppLovin MAX, AdMob, Meta, Unity, ironSource, Pangle, Liftoff/Vungle, InMobi,
Moloco, Amazon APS, Digital Turbine/Fyber, PubMatic, Bigo. Traqueurs : AppsFlyer, Firebase, événements Facebook et
TikTok, ThinkingData, le cn.hsdata propre au studio. Permissions : identifiant publicitaire et les quatre
API publicitaires Privacy Sandbox.
Deux endpoints ne proviennent d'aucun SDK. infer est un appel à un modèle : combien valent les pubs de ce joueur ?
$ 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());
Ceux-ci renseignent deviceModel, ram, disk, cpu, carrier, country, ip_country, timeZone,
install_time, cold_start_num ainsi que vos publicités passées avec leur revenue. La réponse fixe votre prix
plancher, l'enchère minimale qu'un annonceur doit dépasser pour vous montrer une publicité :
$ 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"
Verdict : légal, et comment fonctionnent les jeux financés par la publicité. Maintenant vous pouvez le voir.
Block Blast cache ses classes de jeu derrière un packer NetEase : org.cocos2dx.javascript.AppActivity n'est pas
dans l'APK. apkscope dump a permis au jeu de se décompresser lui-même et a extrait 15 DEX de la mémoire en 25 s, soit environ
3 100 classes cachées. Les scripts appellent Java via JsCallJava ; ses méthodes montrent ce qu'ils demandent :
$ 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 dans les scripts du jeu, et le jeu s'en souvient. Les jeux utilisent cela pour se comporter différemment pendant qu'une boutique les examine ; ce que Block Blast modifie se trouve dans ses scripts chiffrés, nous n'affirmons donc rien de plus.callNativeGetLeftBattery (% de batterie), callNativeIsInstallOtherApp (l'application X est-elle installée ?), getDeviceInfoByAdb (vitesses CPU, RAM, stockage, écran, modèle).trackGameEndRevenue stocke les données de revenus à la fin de chaque partie.BleBumpKit appaire deux téléphones à proximité, après avoir demandé la permission.Non montré : comment il décide de vos prochains blocs. Cela se trouve dans les scripts chiffrés (voir limites).
Le fournisseur de base de données de fichiers est exporté, et ses balises <path-permission> nomment une permission littéralement appelée "false". La seule véritable protection est dans le code, et elle ignore file/, dir/ et la racine :
$ 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)) {
(Les libellés de cas sont repliés, des commentaires ajoutés.) insert, update et delete utilisent la même vérification. La table
contient path, path_decrypted, file_owner, sharees, share_by_link, metadata_gps...
Verdict : toute application installée peut lire vos noms de fichiers, dossiers et partages, y compris les noms déchiffrés des fichiers chiffrés de bout en bout, et modifier ou supprimer des lignes. GitHub Security Lab l'a signalé en 2021 ; l'injection SQL de ce rapport a été corrigée, l'accès ouvert est toujours présent dans la 35.0.1. Lecture à partir du code, pas d'exécution sur un appareil.
$ apkscope resource antennapod.apk res/xml/network_security_config.xml
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="user" />
<certificates src="system" />