jadx について
Android のセキュリティ分析向けに、APK 内の DEX を読みやすい Java にデコンパイルする手順を案内するスキルです。CLI と GUI による調査、難読化の解除、検索、Gradle プロジェクトの出力を扱います。
主な機能
- 01DEX を Java にデコンパイル
- 02コードの難読化解除を試行
- 03CLI と GUI の操作
- 04Gradle プロジェクトの出力
活用シーン
- 01ハードコードされた認証情報や API URL の検索
- 02暗号化、認証、保存ロジックの確認
- 03アプリの起点とネットワーク通信の追跡
- 04複数 APK の一括デコンパイル
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ brownfinesecurity/ iothackbot --skill jadxインストール後、Claude Code で/jadxを入力して読み込まれたか確認します。
詳細
Jadx - Android APK デコンパイラー
jadx を使用して Android APK ファイルをデコンパイルし、DEX バイトコードを読みやすい Java ソースコードに変換して、セキュリティ分析、脆弱性の発見、アプリ内部の仕組みの理解を支援します。
ツールの概要
Jadx は、Android APK ファイルから読みやすく整った Java ソースコードを生成する、DEX から Java へのデコンパイラーです。smali を生成する apktool とは異なり、jadx は実際の Java コードを生成するため、はるかに読みやすく、分析しやすくなっています。以下の用途に不可欠です。
- DEX バイトコードを読みやすい Java ソースに変換する
- アプリのロジックと制御フローを理解する
- コード内のセキュリティ脆弱性を見つける
- ハードコードされた認証情報、API キー、URL を発見する
- 暗号化や認証の実装を分析する
- 馴染みのある Java 構文でコードを検索する
前提条件
- jadx(および任意で jadx-gui)がインストールされている必要があります
- Java ランタイム環境(JRE)が必要です
- 十分なディスク容量が必要です(デコンパイル後の出力サイズは通常、APK の 3~10 倍です)
- 出力ディレクトリへの書き込み権限が必要です
GUI と CLI の比較
Jadx には 2 つのインターフェースがあります。
CLI(jadx):コマンドラインインターフェース
- 自動化やスクリプト作成に最適です
- 複数 APK の一括処理に対応します
- 他のツールと連携できます
- ヘッドレスサーバー環境で使用できます
GUI(jadx-gui):グラフィカルインターフェース
- 対話的にコードを閲覧できます
- 検索機能を内蔵しています
- 相互参照やナビゲーションに対応します
- 手動分析が容易です
- 構文をハイライト表示します
用途に応じた選択:
- 自動分析、スクリプト、CI/CD パイプラインには CLI を使用します
- 対話的な探索や詳細な分析には GUI を使用します
手順
1. APK の基本的なデコンパイル(最も一般的)
標準的なデコンパイルコマンド:
jadx <apk-file> -d <output-directory>
例:
jadx app.apk -d app-decompiled
難読化解除を有効にする場合(難読化されたアプリに推奨):
jadx --deobf app.apk -d app-decompiled
2. 出力構造を理解する
デコンパイル後、出力ディレクトリには以下の内容が含まれます。
app-decompiled/
├── sources/ # Java source code
│ └── com/company/app/ # Package structure
│ ├── MainActivity.java
│ ├── utils/
│ ├── network/
│ └── ...
└── resources/ # Decoded resources
├── AndroidManifest.xml # Readable manifest
├── res/ # Resources
│ ├── layout/ # XML layouts
│ ├── values/ # Strings, colors
│ ├── drawable/ # Images
│ └── ...
└── assets/ # App assets
3. デコンパイルのオプション
A. パフォーマンスオプション
マルチスレッドでのデコンパイル(高速化):
jadx -j 4 app.apk -d output
# -j specifies number of threads (default: CPU cores)
リソースをスキップ(コードのみ、高速化):
jadx --no-res app.apk -d output
ソースコードをスキップ(リソースのみ):
jadx --no-src app.apk -d output
B. 難読化解除オプション
難読化解除を有効にする:
jadx --deobf app.apk -d output
- 難読化されたクラスの名前を変更します(a.b.c → 意味のある名前)
- 元の名前の復元を試みます
- コードが大幅に読みやすくなります
- 難読化または縮小されたアプリには不可欠です
難読化解除マップの出力:
jadx --deobf --deobf-use-sourcename app.apk -d output
- より積極的に難読化を解除します
- 名前を変更した識別子のヒントとしてソースファイル名を使用します
C. 出力の制御
一貫性のないコードや不正なコードを表示する:
jadx --show-bad-code app.apk -d output
- 正しくデコンパイルできなかったコードを表示します
- 難読化やデコンパイル対策の手法を見つけるのに役立ちます
- 構文エラーを含む場合がありますが、構造を明らかにします
Gradle プロジェクトとしてエクスポートする:
jadx --export-gradle app.apk -d output
- ビルド可能な Gradle Android プロジェクトを作成します
- アプリの再ビルドや変更に役立ちます
- build.gradle ファイルが含まれます
フォールバックモード(デコンパイルに失敗する場合):
jadx --fallback app.apk -d output
- 別のデコンパイル方法を使用します
- 出力されるコードの整合性は低くなりますが、特殊なケースにも対応できます
4. よくある分析タスク
A. 機密情報の検索
デコンパイル後、よくあるセキュリティ上の問題を検索します。
# Search for API keys
grep -r "api.*key\|apikey\|API_KEY" app-decompiled/sources/
# Search for passwords and credentials
grep -r "password\|credential\|secret" app-decompiled/sources/
# Search for hardcoded URLs
grep -rE "https?://[^\"]+" app-decompiled/sources/
# Search for encryption keys
grep -r "AES\|DES\|RSA\|encryption.*key" app-decompiled/sources/
# Search for tokens
grep -r "token\|auth.*token\|bearer" app-decompiled/sources/
# Search for database passwords
grep -r "jdbc\|database\|db.*password" app-decompiled/sources/
B. セキュリティ脆弱性の発見
SQL インジェクション:
grep -r "SELECT.*FROM.*WHERE" app-decompiled/sources/ | grep -v "PreparedStatement"
grep -r "rawQuery\|execSQL" app-decompiled/sources/
安全でない暗号化:
grep -r "DES\|MD5\|SHA1" app-decompiled/sources/
grep -r "SecureRandom.*setSeed" app-decompiled/sources/
grep -r "Cipher.getInstance" app-decompiled/sources/ | grep -v "AES/GCM"
安全でないストレージ:
grep -r "SharedPreferences" app-decompiled/sources/
grep -r "MODE_WORLD_READABLE\|MODE_WORLD_WRITABLE" app-decompiled/sources/
grep -r "openFileOutput" app-decompiled/sources/
WebView の脆弱性:
grep -r "setJavaScriptEnabled.*true" app-decompiled/sources/
grep -r "addJavascriptInterface" app-decompiled/sources/
grep -r "WebView.*loadUrl" app-decompiled/sources/
証明書ピンニングの回避:
grep -r "TrustManager\|HostnameVerifier" app-decompiled/sources/
grep -r "checkServerTrusted" app-decompiled/sources/
C. アプリのロジックを理解する
エントリーポイントを見つける:
# Main activities
grep -r "extends Activity\|extends AppCompatActivity" app-decompiled/sources/
# Application class
grep -r "extends Application" app-decompiled/sources/
# Services
grep -r "extends Service" app-decompiled/sources/
# Broadcast receivers
grep -r "extends BroadcastReceiver" app-decompiled/sources/
ネットワーク通信を追跡する:
# Find HTTP client usage
grep -r "HttpURLConnection\|OkHttpClient\|Retrofit" app-decompiled/sources/
# Find API endpoints
grep -r "@GET\|@POST\|@PUT\|@DELETE" app-decompiled/sources/
# Find base URLs
grep -r "baseUrl\|BASE_URL\|API_URL" app-decompiled/sources/
認証ロジックを見つける:
grep -r "login\|Login\|authenticate\|Authorization" app-decompiled/sources/
grep -r "jwt\|JWT\|bearer\|Bearer" app-decompiled/sources/
D. 特定のクラスを分析する
興味深いクラスを特定した後、そのクラスを直接読みます。
# View specific class
cat app-decompiled/sources/com/example/app/LoginActivity.java
# Use less for pagination
less app-decompiled/sources/com/example/app/network/ApiClient.java
# Search within specific class
grep "password" app-decompiled/sources/com/example/app/LoginActivity.java
5. GUI モード(対話的な分析)
GUI の起動:
jadx-gui app.apk
GUI の機能:
- 全文検索:Ctrl+Shift+F(すべてのコードを検索)
- 使用箇所の検索:クラス/メソッドを右クリック →「使用箇所を検索」
- 宣言へ移動:任意のクラス/メソッドを Ctrl+クリック
- 逆コンパイル:任意のクラスをクリックして Java コードを表示
- 逆コンパイルしたコードを保存:File → Save all
- エクスポートオプション:File → Export as Gradle project
GUI のワークフロー:
- jadx-gui で APK を開きます
- 左側のパネルでパッケージ構造を参照します
- 検索(Ctrl+Shift+F)を使ってキーワードを検索します
- 検索結果をクリックして、コードを文脈の中で確認します
- Ctrl+クリックで相互参照をたどります
- 注目した内容を保存します
6. 他のツールとの連携
Jadx と Apktool の併用
どちらのツールも互いを補完します。
Jadx の強み:
- 読みやすい Java ソースコード
- ロジックを理解しやすい
- コード内をすばやく検索できる
Apktool の強み:
- リソースを正確に抽出できる
- Smali コード(元のコードに近い)
- APK を再ビルド/再パッケージ化できる
推奨ワークフロー:
# Use jadx for code analysis
jadx --deobf app.apk -d app-jadx
# Use apktool for resources and smali
apktool d app.apk -o app-apktool
# Analyze both outputs
grep -r "API_KEY" app-jadx/sources/
grep -r "api_key" app-apktool/res/
よくあるワークフロー
ワークフロー 1:セキュリティ評価
# 1. Decompile with deobfuscation
jadx --deobf app.apk -d app-decompiled
# 2. Search for hardcoded secrets
echo "[+] Searching for API keys..."
grep -ri "api.*key\|apikey" app-decompiled/sources/ | tee findings-apikeys.txt
echo "[+] Searching for passwords..."
grep -ri "password\|passwd\|pwd" app-decompiled/sources/ | tee findings-passwords.txt
echo "[+] Searching for URLs..."
grep -rE "https?://[^\"]+" app-decompiled/sources/ | tee findings-urls.txt
# 3. Check crypto usage
echo "[+] Checking crypto implementations..."
grep -r "Cipher\|SecretKey\|KeyStore" app-decompiled/sources/ | tee findings-crypto.txt
# 4. Check for insecure storage
echo "[+] Checking storage mechanisms..."
grep -r "SharedPreferences\|SQLite\|openFileOutput" app-decompiled/sources/ | tee findings-storage.txt
# 5. Summary
echo "[+] Analysis complete. Check findings-*.txt files"
ワークフロー 2:IoT アプリの分析
IoT コンパニオンアプリの場合は、デバイスとの通信を見つけます。
# 1. Decompile
jadx --deobf iot-app.apk -d iot-app-decompiled
# 2. Find device communication
echo "[+] Finding device endpoints..."
grep -rE "https?://[^\"]+" iot-app-decompiled/sources/ | \
grep -v "google\|android\|facebook" | \
tee device-endpoints.txt
# 3. Find API structure
echo "[+] Finding API definitions..."
grep -r "@GET\|@POST\|@PUT" iot-app-decompiled/sources/ | tee api-endpoints.txt
# 4. Find authentication
echo "[+] Finding auth mechanisms..."
grep -r "Authorization\|authentication\|apiKey" iot-app-decompiled/sources/ | tee auth-methods.txt
# 5. Find device discovery
echo "[+] Finding device discovery..."
grep -r "discover\|scan\|broadcast\|mdns" iot-app-decompiled/sources/ | tee device-discovery.txt
# 6. Check for certificate pinning
echo "[+] Checking certificate pinning..."
grep -r "CertificatePinner\|TrustManager" iot-app-decompiled/sources/ | tee cert-pinning.txt
ワークフロー 3:認証情報の簡易チェック
# Fast decompilation without resources
jadx --no-res --deobf app.apk -d app-code
# Search for common credential patterns
grep -r "username.*password\|user.*pass" app-code/sources/
grep -r "admin\|root\|default.*password" app-code/sources/
grep -r "hardcoded\|TODO.*password\|FIXME.*password" app-code/sources/
ワークフロー 4:API エンドポイントの特定
# Decompile
jadx app.apk -d app-decompiled
# Find Retrofit/REST API definitions
find app-decompiled/sources -name "*Api*.java" -o -name "*Service*.java" -o -name "*Client*.java"
# Extract all endpoints
grep -r "@GET\|@POST\|@PUT\|@DELETE\|@PATCH" app-decompiled/sources/ | \
sed 's/.*@\(GET\|POST\|PUT\|DELETE\|PATCH\)("\([^"]*\)".*/\1 \2/' | \
sort -u
# Find base URLs
grep -r "baseUrl\|BASE_URL\|API_BASE" app-decompiled/sources/
ワークフロー 5:複数の APK の一括処理
# Decompile multiple APKs
for apk in *.apk; do
name=$(basename "$apk" .apk)
echo "[+] Processing $apk..."
jadx --no-res --deobf "$apk" -d "decompiled-$name"
# Quick search for secrets
grep -r "api.*key\|password\|secret" "decompiled-$name/sources/" > "findings-$name.txt"
done
echo "[+] All APKs processed. Check findings-*.txt files"
ベストプラクティス
1. 本番アプリでは必ず難読化解除を使用する
# Most production apps are obfuscated
jadx --deobf app.apk -d output
--deobf を指定しないと、次のようなコードが表示されます。
public class a {
public void b(String c) { ... }
}
--deobf を指定すると、jadx は意味のある名前を付けようとします。
public class NetworkClient {
public void sendRequest(String url) { ... }
}
2. 大規模なアプリではマルチスレッドを使用する
# Faster decompilation
jadx -j 8 large-app.apk -d output
3. コードのみを分析する場合はリソースをスキップする
# 3-5x faster when you only need code
jadx --no-res app.apk -d output
4. 体系的に検索する
場当たり的に grep するのではなく、このスキルの最後にある「セキュリティ分析チェックリスト」に沿って作業してください。
5. 詳細な分析には GUI を使用する
複雑なアプリの場合:
- 最初の逆コンパイルには CLI を使用します
- 注目すべきパターンを検索します
- 詳細に調査するため、GUI で開きます
- 相互参照を使ってコードの流れをたどります
6. 実行時分析と組み合わせる
静的分析(jadx)+動的分析:
- jadx を使って API エンドポイントを見つけます
- curl/burp でエンドポイントをテストします
- jadx を使って認証フローを把握します
- 実行時の計測(Frida)で認証をテストします
トラブルシューティング
問題:逆コンパイルがエラーで失敗する
解決方法:フォールバックモードを使うか、不正なコードを表示します。
jadx --fallback --show-bad-code app.apk -d output
問題:コードが読み取れない(難読化されている)
解決方法:難読化解除を有効にします。
jadx --deobf app.apk -d output
問題:メモリ不足エラーが発生する
解決方法:jadx のランチャーが読み込む JVM オプション(JAVA_OPTS または JADX_OPTS)で Java ヒープサイズを増やします。
export JAVA_OPTS="-Xmx4096m"
jadx app.apk -d output
(jadx 自体に -Xmx 引数はありません。ヒープサイズは jadx ではなく JVM に渡す必要があります。)
問題:逆コンパイルに非常に時間がかかる
解決方法:リソースをスキップするか、スレッド数を増やします。
jadx --no-res -j 8 app.apk -d output
問題:一部のメソッドに「Can't load method」と表示される
解決方法:--show-bad-code を使って部分的に逆コンパイルされたコードを表示します。
jadx --show-bad-code app.apk -d output
問題:GUI で APK を開けない
解決方法:まず CLI を使ってエラーを確認します。
jadx app.apk -d test-output
# If successful, try GUI again
高度な機能
Gradle プロジェクトとしてエクスポートする
jadx --export-gradle app.apk -d app-project
cd app-project
./gradlew build
ビルド可能な Android Studio プロジェクトを作成します。
難読化解除マップを生成する
jadx --deobf --deobf-use-sourcename app.apk -d output
# Check output/mapping.txt for name mappings
カスタム逆コンパイルオプション
# All options combined
jadx \
--deobf \
--deobf-use-sourcename \
--show-bad-code \
--no-imports \
--no-inline-anonymous \
--no-replace-consts \
app.apk -d output
IoTHackBot ツールとの連携
Jadx は IoTHackBot のワークフローに組み込めます。
-
APK → API の特定:
- jadx で IoT アプリを逆コンパイルします
- API エンドポイントを抽出します
- ネットワークツールでエンドポイントをテストします
-
APK → 認証情報の抽出:
- ハードコードされた認証情報を見つけます
- IoT デバイスに対してテストします
- onvifscan、telnetshell と組み合わせて使用します
-
APK → プロトコル分析:
- デバイスの通信プロトコルを把握します
- iotnet でトラフィックをキャプチャします
- カスタムスクリプトでリプレイ/変更します
-
APK → デバイスの列挙:
- デバイスの検出メカニズムを見つけます
- ONVIF デバイスには wsdiscovery を使用します
- ネットワークスキャンには nmap を使用します
クイックリファレンス
# Basic decompilation
jadx <apk> -d <output-dir>
# With deobfuscation (recommended)
jadx --deobf <apk> -d <output-dir>
# Fast (no resources)
jadx --no-res <apk> -d <output-dir>
# Multi-threaded
jadx -j <threads> <apk> -d <output-dir>
# Show problematic code
jadx --show-bad-code <apk> -d <output-dir>
# Export as Gradle project
jadx --export-gradle <apk> -d <output-dir>
# GUI mode
jadx-gui <apk>
# Fallback mode
jadx --fallback <apk> -d <output-dir>
セキュリティ分析チェックリスト
jadx を使用して APK を分析する際は、このチェックリストを使用してください。
- 難読化解除を有効にして逆コンパイルする
- ハードコードされた API キーを検索する
- ハードコードされた認証情報を検索する
- すべての HTTP/HTTPS URL を見つける
- 暗号化の実装(アルゴリズム、鍵生成)を確認する
- 証明書ピンニングの実装を確認する
- SharedPreferences の使用箇所を見つける(ストレージのセキュリティ)
- WebView のセキュリティ設定を確認する
- データベース操作を見つける(SQL インジェクション)
- デバッグ/ログ出力コードを確認する
- エクスポートされたコンポーネントを見つける(マニフェストから)
- 認証/認可ロジックを確認する
- ファイル操作を見つける(パストラバーサル)
- ネイティブライブラリの読み込みを確認する
- すべての調査結果を記録する
重要な注意事項
- Jadx が生成する Java ソースは近似的なものであり、元のソースコードではありません
- 一部の最適化や難読化により、コンパイルできないコードが生成される場合があります
- 逆コンパイルされたコードは、元のソースコードとわずかに異なる場合があります
- 調査結果は必ず実行時分析と照合してください
- Jadx は標準的なツールでコンパイルされたアプリで最も効果を発揮します
- 高度に難読化または保護されたアプリでは、逆コンパイルが制限される場合があります
- 一部の改ざん防止機構は、逆コンパイルを検知します
セキュリティと倫理
重要:自分が所有している APK、または分析の許可を得ている APK のみを逆コンパイルしてください。
- 知的財産権とライセンスを尊重してください
- 脆弱性については、責任ある開示の手順に従ってください
- 逆コンパイルしたソースコードを配布しないでください
- 利用規約と EULA に注意してください
- 許可されたセキュリティテストと研究にのみ使用してください
- 法域によっては、リバースエンジニアリングが法律で禁止されている場合があります
成功基準
jadx による分析が成功した状態とは、次のとおりです。
- APK が読みやすい Java コードに正常に逆コンパイルされている
- (アプリが難読化されていた場合)難読化解除が適用されている
- すべてのソースコードを検索でき、読みやすい
- セキュリティに関する調査結果が記録されている
- API エンドポイントと URL が抽出されている
- 暗号化と認証のロジックが理解されている
- 他のシステムとの統合ポイントが特定されている
- 可能な場合、実行時テストで調査結果が検証されている