
人間とAIエージェントのためのAndroidリバースエンジニアリング:型付きJavaをミリ秒で、xref、APIおよびシークレットの偵察、APK差分、再署名、ネイティブビューア、そしてMCPサーバー。単一のRust実行ファイルで、JVM不要。
任意の Android アプリを開き、実際に何をしているのかを確認できます。
何を収集し、どうやってあなたから収益を得て、何を露出しているのか。わずか数秒で、読みやすい Java として。
AI エージェント向けのビューア、CLI、MCP サーバー。単一の実行ファイル。Java は不要です。
それぞれを明らかにするには、マニフェスト、リソース、逆コンパイルされたコードを合わせて読む必要がありました。
http:// を grep しても、そのどれも見つかりません。検出結果をクリックすると証拠が表示されます。重要な行だけに絞った実際の出力です。
Block Blast! 10.9.3 (Play ビルド)、75,938 クラス、3.1 秒でスキャン。
誰があなたのデータを取得するか: AppLovin MAX、AdMob、Meta、Unity、ironSource、Pangle、Liftoff/Vungle、InMobi、
Moloco、Amazon APS、Digital Turbine/Fyber、PubMatic、Bigo。トラッカー: AppsFlyer、Firebase、Facebook と
TikTok のイベント、ThinkingData、スタジオ独自の cn.hsdata。権限: 広告 ID と 4 つすべての
Privacy Sandbox 広告 API。
2 つのエンドポイントはどの SDK のものでもありません。 infer はモデル呼び出しです。このプレイヤーの広告はいくらの価値があるのか?
$ 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());
これらは deviceModel、ram、disk、cpu、carrier、country、ip_country、timeZone、install_time、cold_start_num を埋め、さらに過去の広告とその revenue を埋めます。その回答があなたのフロア価格、つまり広告主があなたに広告を表示するために超えなければならない最低入札額を設定します:
$ 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"
判定: 合法であり、広告収益型ゲームの仕組みである。これで理解できたはずだ。
Block BlastはNetEaseのパッカーを使ってゲームクラスを隠している。org.cocos2dx.javascript.AppActivity は
APK内に存在しない。apkscope dump によってゲーム自身にアンパックさせ、25秒でメモリから15個のDEXを
引き出した。約3,100個の隠しクラスである。スクリプトは JsCallJava を通じてJavaを呼び出しており、
そのメソッドは何を要求しているかを示している:
$ 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 をオンにし、
ゲームはそれを記憶します。ゲームはストアが審査している間、異なる動作をするためにこれを使います。Block Blast が変更するのは暗号化されたスクリプト内であるため、それ以上のことは主張しません。callNativeGetLeftBattery(バッテリー残量 %)、callNativeIsInstallOtherApp
(アプリ X はインストールされているか?)、getDeviceInfoByAdb(CPU 速度、RAM、ストレージ、画面、モデル)。trackGameEndRevenue は各ゲーム終了時に収益データを保存します。BleBumpKit は許可を求めた後、近くの 2 台の端末をペアリングします。示されていないもの: 次のブロックをどう決定するか。それは暗号化されたスクリプト内にあります(制限を参照)。
ファイルデータベースプロバイダーはエクスポートされており、その <path-permission> タグは文字通り
"false" という名前のパーミッションを指定しています。唯一の実質的なガードはコード内にあり、file/、dir/、およびルートをスキップします:
$ 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)) {
(ケースラベルは折りたたみ、コメントを追加。)insert、update、delete は同じチェックを使用する。テーブルは
path、path_decrypted、file_owner、sharees、share_by_link、metadata_gps を保持する...
判定: インストールされた任意のアプリが、あなたのファイル名、フォルダ、共有、およびエンドツーエンド暗号化ファイルの復号済み名を含めて読み取り、行の変更や削除が可能である。GitHub Security Lab は 2021 年にこれを指摘した。 その報告の SQL インジェクションは修正されたが、オープンアクセスは 35.0.1 でも依然として存在する。コードから読み取ったものであり、実機で実行したものではない。
$ 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);
判定: Android 7 以降、アプリはユーザー証明書を無視する。このアプリはそれを再び有効にしているため、管理対象デバイスや証明書をインストールする「VPN」アプリがその HTTPS を読み取ることができる。カスタム TrustManager は実際の各 TrustManager を順に試し、どれも受け入れなければ例外を投げる。これは意図的な選択であり、何でも信頼してしまうバグではない。
scan は Jetpack Compose の PreviewActivity をエクスポート済みとして一覧表示する。これはインテントで指定された任意のクラスを実行する。
$ apkscope decompile thunderbird.apk androidx.compose.ui.tooling.PreviewActivity --method onCreate
int i = getApplicationInfo().flags & 2;
if (i == 0) {
Log.md(str, "Application is not debuggable. Compose Preview not allowed.");
finish();
判定: flags & 2 は FLAG_DEBUGGABLE であり、リリースビルドではそうならない。すべてのスキャナーがこれを指摘する。
コードが安全だと示しているだけであり、誰かがデバッグ可能なビルドを出荷するまでは。
$ apkscope decompile keepassdx.apk com.kunzisoft.encrypt.aes.AESTransformer
cipher = Cipher.getInstance("AES/ECB/NoPadding");
key = (Key) new SecretKeySpec(bArr, "AES");
cipher.init(1, key);
while (UnsignedKt.ulongCompare(j2, j) < 0) {
判定: KeePass の AES-KDF は、パスワード推測を遅くするために 1 ブロックを自身で rounds 回暗号化します。1 ブロックに対する ECB は仕様です。どのフラグを落とすべきかを知ることが仕事の半分です。