Files

128 lines
4.8 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# decode.sh — APK 解包(jadx 反编译 + apktool 解包)
# 等价于 Windows 版的 decode.ps1
#
# 用法:
# bash decode.sh <apk_path> [--name <task_name>] [--out <output_dir>]
# [--skip-jadx] [--skip-apktool] [--clean]
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
KALI_BOOTSTRAP="$(cd "$SCRIPT_DIR/../../../kali/scripts" 2>/dev/null && pwd)/bootstrap-reverse.sh"
# ─── 参数解析 ──────────────────────────────────────────────────────────────────────
APK_PATH=""
TASK_NAME=""
OUT_ROOT=""
SKIP_JADX=false
SKIP_APKTOOL=false
CLEAN=false
while [[ $# -gt 0 ]]; do
case "$1" in
--name) TASK_NAME="$2"; shift 2 ;;
--out) OUT_ROOT="$2"; shift 2 ;;
--skip-jadx) SKIP_JADX=true; shift ;;
--skip-apktool) SKIP_APKTOOL=true; shift ;;
--clean) CLEAN=true; shift ;;
-*) echo "未知选项: $1"; exit 1 ;;
*) APK_PATH="$1"; shift ;;
esac
done
if [[ -z "$APK_PATH" ]]; then
echo "用法: $0 <apk_path> [--name <name>] [--out <dir>] [--skip-jadx] [--skip-apktool] [--clean]"
exit 1
fi
if [[ ! -f "$APK_PATH" ]]; then
echo "ERR: APK 文件不存在: $APK_PATH"
exit 1
fi
# ─── 工具检测与自动安装 ─────────────────────────────────────────────────────────────
ensure_tool() {
local name="$1"
if command -v "$name" &>/dev/null; then
return 0
fi
echo "INFO: $name 未找到,尝试自动安装..."
if [[ -x "$KALI_BOOTSTRAP" ]]; then
bash "$KALI_BOOTSTRAP" "$name" --skip-refresh 2>/dev/null || true
fi
if ! command -v "$name" &>/dev/null; then
echo "ERR: $name 安装失败,请手动安装"
return 1
fi
echo "INFO: $name 安装成功"
}
[[ "$SKIP_JADX" != "true" ]] && ensure_tool "jadx"
[[ "$SKIP_APKTOOL" != "true" ]] && ensure_tool "apktool"
# ─── 路径计算 ──────────────────────────────────────────────────────────────────────
APK_BASENAME=$(basename "$APK_PATH" .apk | sed 's/[^A-Za-z0-9._-]/_/g')
TASK_NAME="${TASK_NAME:-$APK_BASENAME}"
OUT_ROOT="${OUT_ROOT:-$(dirname "$APK_PATH")}"
TASK_ROOT="$OUT_root:REDACTED"
JADX_OUT="$TASK_ROOT/jadx"
APKTOOL_OUT="$TASK_ROOT/apktool"
if [[ "$CLEAN" == "true" && -d "$TASK_ROOT" ]]; then
rm -rf "$TASK_ROOT"
fi
mkdir -p "$TASK_ROOT"
# ─── jadx 反编译 ──────────────────────────────────────────────────────────────────
JADX_EXIT=0
if [[ "$SKIP_JADX" != "true" ]]; then
rm -rf "$JADX_OUT"
echo "=== jadx 反编译 ==="
jadx -d "$JADX_OUT" "$APK_PATH" || JADX_EXIT=$?
fi
# ─── apktool 解包 ─────────────────────────────────────────────────────────────────
APKTOOL_EXIT=0
if [[ "$SKIP_APKTOOL" != "true" ]]; then
rm -rf "$APKTOOL_OUT"
echo "=== apktool 解包 ==="
apktool d "$APK_PATH" -o "$APKTOOL_OUT" -f || APKTOOL_EXIT=$?
fi
# ─── 统计输出 ──────────────────────────────────────────────────────────────────────
PACKAGE=""
if [[ -f "$APKTOOL_OUT/AndroidManifest.xml" ]]; then
PACKAGE=$(grep -oP 'package="[^"]*"' "$APKTOOL_OUT/AndroidManifest.xml" 2>/dev/null | head -1 | sed 's/package="//;s/"//')
fi
JAVA_COUNT=0
[[ -d "$JADX_OUT" ]] && JAVA_COUNT=$(find "$JADX_OUT" -name "*.java" | wc -l)
SMALI_DIRS=0
[[ -d "$APKTOOL_OUT" ]] && SMALI_DIRS=$(find "$APKTOOL_OUT" -maxdepth 1 -type d -name "smali*" | wc -l)
SO_COUNT=0
[[ -d "$APKTOOL_OUT" ]] && SO_COUNT=$(find "$APKTOOL_OUT" -name "*.so" | wc -l)
echo ""
echo "═══════════════════════════════════════════"
echo " APK 解包完成"
echo "═══════════════════════════════════════════"
echo " task_root=$TASK_ROOT"
echo " jadx_out=$JADX_OUT"
echo " apktool_out=$APKTOOL_OUT"
echo " package=$PACKAGE"
echo " jadx_exit_code=$JADX_EXIT"
echo " apktool_exit_code=$APKTOOL_EXIT"
echo " java_files=$JAVA_COUNT"
echo " smali_dirs=$SMALI_DIRS"
echo " so_files=$SO_COUNT"