ASCとは?使い方・速さを実際に使って調べてみた動いた
この日に実際に動かした結果です。内容の誤りに気づかれた場合はお問い合わせください。確認のうえ訂正します。
使う前に分かること
| 必要なもの | Python 3.10以上、pip |
|---|---|
| 動かした環境 | Linux、Python 3.11.17。 |
| 日本語 | 画面・文書は英語 |
| 確認日 | 2026-10-11(この日に実際に動かした) |
ASC(PyPIでの配布名はdroidasc)は、Androidアプリのパッケージファイル(APK)を分解して、中にあるJavaのコードを読める形に戻す「逆コンパイラ」というソフトです。元のソースコードそのものではありませんが、クラスの構造やif文・try文のかたまりまでそのまま追える程度のコードが出てきます。作者はセキュリティの国際カンファレンス「Black Hat Europe」でこのツールを発表していて、売りは速さです。普通の逆コンパイラはAPKを丸ごと展開して、中のコードの関係を全部調べ上げるための索引を作るところから始まるため、大きなAPKだと索引作りだけで何分もかかります。ASCはその索引作りをせず、必要なクラスだけをその場で直接取り出して逆コンパイルする作りになっています。画面を使った専用のGUI(ウィンドウの形の操作画面)も用意されていますが、画面(ディスプレイ)につながったパソコンでないと起動できません。今回の検証環境には画面が無いため、GUIは確認できませんでした。その代わり、公式に案内されているコマンドライン側の4つの使い方(クラス一覧・マニフェスト・逆コンパイル・参照検索)を、実際のAndroidアプリのAPKに対して最後まで試しました。コマンドラインというのは、ターミナル(文字でコマンドを打ってパソコンを操作する画面)に文字を打って操作する使い方のことです。
pipで入れる
ASCはPythonで作られていて、Pythonのパッケージ置き場であるPyPIからpipで入れます。配布元が最初に案内している入れ方です。ターミナルを開き、好きなフォルダに移動してから、次のコマンドを打ちます(これより後のコマンドも、同じターミナルの同じフォルダで続けて打ちます)。
pip install droidasc
Successfully installed axml-0.0.2 droidasc-0.1.1.post5 lxml-6.1.3 markdown-it-py-4.2.0 mdurl-0.1.2 mutf8-1.1.0 pygments-2.21.0 rich-15.0.0
末尾にSuccessfully installedと出ていれば入れ終わった印です。これでdroidascというコマンドが使えるようになります。--helpを付けて呼ぶと、使える機能の一覧が出ます。
droidasc --help
usage: droidasc [-h] {getclass,listclass,getmanifest,findrefs} ...
ASC tooling entry.
positional arguments:
{getclass,listclass,getmanifest,findrefs}
getclass Locate the target class in APK, extract one DEX in
memory, then decompile.
listclass List classes across all DEX entries; use --prefix to
filter by package/class prefix.
getmanifest Decode AndroidManifest.xml from APK and print it as
XML.
findrefs Find code references for string/type/method/field
across all DEX entries in APK.
試すAPKを用意する
ASCに渡すには、何か1つAPKファイルが必要です。今回は、ASCが内部で使っているandroguardというライブラリが、テストの実例として同梱していたAPKファイルをそのまま使いました。架空のダミーファイルではなく、「A2DP Volume」という、Bluetooth機器をつないだときに自動で音量を調整するオープンソースのAndroidアプリ(GitHub: jroal/a2dpvolume)の、実際にビルドされたAPKです。自分で試す場合は、手元のAndroidの端末に入っているアプリのAPKファイルを取り出して渡すか、F-Droidのようにアプリ本体を.apk形式のファイルで直接ダウンロードできる配布元から用意すれば、同じ手順で試せます。できたAPKファイルは、ターミナルで今いるフォルダに置いておきます(a2dp.Vol.apkのように、以降のコマンドで打つファイル名と同じ名前で置いてください)。
クラスの一覧を出す(listclass)
まず、このAPKの中にどんなクラスが入っているかを一覧にします。-oで指定したファイル名で、今いるフォルダに結果が保存されます。
droidasc listclass a2dp.Vol.apk -o classes.txt
保存されたclasses.txtに何行書き出されたかを、wc -l(ファイルの行数を数えるコマンド)で確かめてみます。
wc -l classes.txt
1353 classes.txt
ファイルの中身を見ると、こうなっています。
La2dp/Vol/ALauncher;
La2dp/Vol/AppChooser$1;
La2dp/Vol/AppChooser$2;
1353個のクラス名が、Android内部で使われている書き方でそのまま出てきます(La2dp/Vol/AppChooser;は、普段目にする「a2dp.Vol.AppChooser」というクラス名の、Android内部での書き方です)。中身を調べたいクラスが決まっていないときは、ここから目当てのクラス名を探す使い方になります。
マニフェストを覗く(getmanifest)
AndroidManifest.xmlは、そのアプリがどんな画面(アクティビティ)を持ち、どんな権限を使うかが書かれたファイルです。APKの中ではバイナリ形式で入っているため、普通には読めませんが、ASCはこれをそのままXMLの文字として出してくれます。
droidasc getmanifest a2dp.Vol.apk -o AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="137" android:versionName="2.12.9.2" android:installLocation="1" package="a2dp.Vol" platformBuildVersionCode="24" platformBuildVersionName="7.000000">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="25"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Bluetoothの音量を調整するだけのアプリのはずですが、位置情報や連絡先、電話の状態まで権限を求めていることが、このマニフェストを見るとすぐにわかります。普段使っているアプリが実際にどんな権限を持っているかを、インストールせずに確かめられるのがこの使い方です。
クラスをその場で逆コンパイルする(getclass)
ここがASCの本題です。クラス名を1つ指定すると、そのクラスだけをAPKの中から直接取り出して、読めるJavaのコードに戻してくれます。
droidasc getclass a2dp.Vol.apk a2dp.Vol.main -o Main.java
package a2dp.Vol;
public class main extends android.app.Activity {
static final int CHECK_TTS = 3;
...
private int loadFromDB()
{
int v1_0 = 0;
this.myDB.getDb().close();
if (this.myDB.getDb().isOpen()) {
try {
this.vec = this.myDB.selectAlldb();
} catch (Exception v0_1) {
v0_1.printStackTrace();
}
できあがったMain.javaは、見た目はコードですが中身は普通の文字なので、メモ帳のようなテキストエディタで開けば読めます。変数名はAPKの中に元の名前が残っていなかったためv1_0のような機械的な名前になっていますが、クラスの構造やif・try文のかたまりはそのまま追えます。
このクラス1個の逆コンパイルにどれくらい時間がかかるか、timeという、コマンドの実行にかかった時間を測るコマンドを先頭に付けて計ってみました。
time droidasc getclass a2dp.Vol.apk a2dp.Vol.main -o Main2.java
real 0m0.241s
「real」が実際にかかった時間で、0.241秒でした。APK全体を事前に読み込んで索引を作る普通の逆コンパイラだと、このAPK程度の大きさでも開くだけで数十秒から数分かかることがありますが、ASCはクラス単位でその場で処理するため、見たいクラスが決まっていればほぼ待ち時間なく読めます。
ある関数がどこから呼ばれているかを調べる(findrefs)
逆コンパイルしたコードの中に出てきたloadFromDBというメソッドが、他のどこから呼ばれているかを調べてみます。
droidasc findrefs a2dp.Vol.apk method loadFromDB
classes.dex | La2dp/Vol/main;->access$100 | matched=(La2dp/Vol/main;->loadFromDB)
classes.dex | La2dp/Vol/main;->getBtDevices | matched=(La2dp/Vol/main;->loadFromDB)
classes.dex | La2dp/Vol/main;->onActivityResult | matched=(La2dp/Vol/main;->loadFromDB)
classes.dex | La2dp/Vol/main;->onCreate | matched=(La2dp/Vol/main;->loadFromDB)
classes.dex | La2dp/Vol/main;->onResume | matched=(La2dp/Vol/main;->loadFromDB)
先頭のclasses.dexは、APKの中にあるコード本体のファイル名です(複数ある場合に、どのファイルで見つかったかを示しています)。画面が開くonCreateや、画面に戻ってきたときのonResumeなど、5箇所から呼ばれていることが一度にわかりました。access$100は自分で付けた名前ではなく、ASCが元のコードから自動で付け直した名前です。文字列を検索することもできます。アプリの設定を保存する場所の名前(btVol)で探すと、使っている場所が1つだけ見つかりました。
droidasc findrefs a2dp.Vol.apk string btVol
classes.dex | La2dp/Vol/Preferences;->onDestroy | matched=(btVol)
「このクラスはどこから呼ばれているか」「この文字列はどこで使われているか」を、APK全体を開き直さずに次々調べられるのが、逆コンパイルと合わせたときの使い方です。
確認した環境
検証にはディスプレイの無いLinux環境を使ったため、tkinter製のGUI(droidasc <apk> --gui)は試せていません。GUIを呼ぶコマンドは標準出力・標準エラーとも何も出さずに終了コード0で返ってきて、裏でGUI用のプロセスを起動しようとした形跡はありましたが、画面が開いたかどうかは確認できていません。本文で試したのはすべてコマンドライン側(listclass・getmanifest・getclass・findrefs)です。試したAPKは、架空のファイルではなく実際に配布されているオープンソースのAndroidアプリ「A2DP Volume」(GitHub: jroal/a2dpvolume)です。
まとめ
ASCは、Androidアプリの中の1クラスだけをすぐ見たい、知っている関数がどこから呼ばれているかだけを知りたい、という場面にかなり早く答えが出るツールでした。クラス名を1つ知っていれば、インストールから数秒でそのクラスのJavaコードが手に入りますし、関数名や文字列からの逆引き検索も同じ速さで返ってきます。一方で、クラス名を何も知らない状態からAPK全体をじっくり眺めて「このアプリは何をしているか」を探る使い方には、今回はGUIを確認できなかったこともあり、コマンドラインのlistclassで名前を眺めるくらいしかできませんでした。手がかりとなるクラス名や関数名がすでにある調査には向きますが、何も手がかりが無い状態から全体を探索する用途には、他の逆コンパイラのGUIの方が向くかもしれません。