diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 2929204..013918a 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,26 +1,26 @@ { "$schema": "https://anthropic.com/claude-code/marketplace.schema.json", "name": "android-reverse-engineering-skill", - "description": "Claude Code plugins for Android reverse engineering, tracker detection, and ad SDK analysis", + "description": "Claude Code plugins for Android reverse engineering, tracker detection, ad SDK analysis, and SDK neutralization for enterprise deployment", "owner": { "name": "Simone Avogadro" }, "metadata": { - "description": "Claude Code plugins for Android reverse engineering, tracker detection, and ad SDK analysis", - "version": "1.1.0" + "description": "Claude Code plugins for Android reverse engineering, tracker detection, ad SDK analysis, and SDK neutralization for enterprise deployment", + "version": "1.2.0" }, "plugins": [ { "name": "android-reverse-engineering", "source": "./plugins/android-reverse-engineering", - "description": "Decompile Android APK/JAR/AAR with jadx, trace call flows, extract APIs, and analyze tracker/ad SDKs for privacy auditing.", - "version": "1.1.0", + "description": "Decompile Android APK/JAR/AAR with jadx, trace call flows, extract APIs, analyze tracker/ad SDKs for privacy auditing, and neutralize SDK entry points for enterprise deployment.", + "version": "1.2.0", "author": { "name": "Simone Avogadro" }, "repository": "https://github.com/SimoneAvogadro/android-reverse-engineering-skill", "license": "Apache-2.0", - "keywords": ["android", "reverse-engineering", "apk", "jadx", "decompile", "api-extraction", "tracker-analysis", "ad-analysis", "privacy"], + "keywords": ["android", "reverse-engineering", "apk", "jadx", "decompile", "api-extraction", "tracker-analysis", "ad-analysis", "privacy", "sdk-neutralizer", "enterprise"], "category": "security" } ] diff --git a/plugins/android-reverse-engineering/.claude-plugin/plugin.json b/plugins/android-reverse-engineering/.claude-plugin/plugin.json index 3e19321..720653c 100644 --- a/plugins/android-reverse-engineering/.claude-plugin/plugin.json +++ b/plugins/android-reverse-engineering/.claude-plugin/plugin.json @@ -1,13 +1,13 @@ { "name": "android-reverse-engineering", "version": "1.0.0", - "description": "Decompile Android APK/JAR/AAR with jadx, trace call flows, extract APIs, and analyze tracker/ad SDKs for privacy auditing.", + "description": "Decompile Android APK/JAR/AAR with jadx, trace call flows, extract APIs, analyze tracker/ad SDKs for privacy auditing, and neutralize SDK entry points for enterprise deployment.", "author": { "name": "Simone Avogadro" }, "repository": "https://github.com/SimoneAvogadro/android-reverse-engineering-skill", "license": "Apache-2.0", - "keywords": ["android", "reverse-engineering", "apk", "jadx", "decompile", "api-extraction", "tracker-analysis", "ad-analysis", "privacy"], + "keywords": ["android", "reverse-engineering", "apk", "jadx", "decompile", "api-extraction", "tracker-analysis", "ad-analysis", "privacy", "sdk-neutralizer", "enterprise"], "skills": "./skills/", "commands": "./commands/" } diff --git a/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh b/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh index b4f37a4..1c16b30 100755 --- a/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh +++ b/plugins/android-reverse-engineering/skills/android-reverse-engineering/scripts/install-dep.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # install-dep.sh — Install a single dependency for Android reverse engineering # Usage: install-dep.sh -# Dependencies: java, jadx, vineflower, dex2jar, apktool, adb +# Dependencies: java, jadx, vineflower, dex2jar, apktool, adb, smali, apksigner # # Exit codes: # 0 — installed successfully @@ -22,6 +22,8 @@ Available dependencies: dex2jar DEX to JAR converter apktool Android resource decoder adb Android Debug Bridge + smali Smali/baksmali assembler/disassembler + apksigner Android APK signing tool The script detects your OS and package manager, then: - Installs directly if possible (brew, or user-local install) @@ -473,6 +475,187 @@ install_adb() { fi } +install_smali() { + if command -v smali &>/dev/null || command -v baksmali &>/dev/null; then + ok "smali/baksmali already installed" + return 0 + fi + + # Check prerequisites for download-based install + require_tool "unzip" + + # Try brew first + if [[ "$PKG_MANAGER" == "brew" ]]; then + info "Installing smali via Homebrew..." + if brew install smali 2>/dev/null; then + ok "smali installed via Homebrew" + return 0 + fi + info "Homebrew formula not available, falling back to direct download." + fi + + # Download from GitHub releases (no sudo needed) + info "Installing smali from GitHub releases..." + local tag + tag=$(gh_latest_tag "google/smali") + if [[ -z "$tag" ]]; then + tag="v3.0.8" + fi + + local version="${tag#v}" + local url="https://github.com/google/smali/releases/download/${tag}/smali-${version}.zip" + local tmp_zip + tmp_zip=$(mktemp /tmp/smali-XXXXXX.zip) + + info "Downloading smali $version..." + if ! download "$url" "$tmp_zip"; then + # Try alternate naming with baksmali + url="https://github.com/google/smali/releases/download/${tag}/smali-${version}-fat.jar" + local install_dir="$HOME/.local/share/smali" + mkdir -p "$install_dir" + if download "$url" "$install_dir/smali.jar"; then + # Single JAR install — create wrapper + mkdir -p "$HOME/.local/bin" + cat > "$HOME/.local/bin/smali" <<'WRAPPER' +#!/usr/bin/env bash +exec java -jar "$HOME/.local/share/smali/smali.jar" assemble "$@" +WRAPPER + cat > "$HOME/.local/bin/baksmali" <<'WRAPPER' +#!/usr/bin/env bash +exec java -jar "$HOME/.local/share/smali/smali.jar" disassemble "$@" +WRAPPER + chmod +x "$HOME/.local/bin/smali" "$HOME/.local/bin/baksmali" + export PATH="$HOME/.local/bin:$PATH" + add_to_profile 'export PATH="$HOME/.local/bin:$PATH"' + ok "smali $version installed to $install_dir" + rm -f "$tmp_zip" + return 0 + fi + fail "Download failed." + rm -f "$tmp_zip" + manual "Download from https://github.com/google/smali/releases/latest" + fi + + local install_dir="$HOME/.local/share/smali" + rm -rf "$install_dir" + mkdir -p "$install_dir" + unzip -qo "$tmp_zip" -d "$install_dir" + rm -f "$tmp_zip" + + # Create wrapper scripts + mkdir -p "$HOME/.local/bin" + + # Look for the smali JAR + local smali_jar + smali_jar=$(find "$install_dir" -name "smali*.jar" -not -name "*baksmali*" | head -1) + local baksmali_jar + baksmali_jar=$(find "$install_dir" -name "baksmali*.jar" | head -1) + + if [[ -n "$smali_jar" ]]; then + cat > "$HOME/.local/bin/smali" < "$HOME/.local/bin/baksmali" </dev/null; then + ok "apksigner already installed" + return 0 + fi + + # Check if Android SDK build-tools has apksigner + if [[ -n "${ANDROID_HOME:-}" ]]; then + local bt_dir="$ANDROID_HOME/build-tools" + if [[ -d "$bt_dir" ]]; then + local latest_bt + latest_bt=$(ls -1 "$bt_dir" 2>/dev/null | sort -V | tail -1) + if [[ -n "$latest_bt" ]] && [[ -f "$bt_dir/$latest_bt/apksigner" ]]; then + mkdir -p "$HOME/.local/bin" + ln -sf "$bt_dir/$latest_bt/apksigner" "$HOME/.local/bin/apksigner" + export PATH="$HOME/.local/bin:$PATH" + add_to_profile 'export PATH="$HOME/.local/bin:$PATH"' + ok "apksigner linked from Android SDK build-tools ($latest_bt)" + return 0 + fi + fi + fi + + # Also check ANDROID_SDK_ROOT + if [[ -n "${ANDROID_SDK_ROOT:-}" ]] && [[ "$ANDROID_SDK_ROOT" != "${ANDROID_HOME:-}" ]]; then + local bt_dir="$ANDROID_SDK_ROOT/build-tools" + if [[ -d "$bt_dir" ]]; then + local latest_bt + latest_bt=$(ls -1 "$bt_dir" 2>/dev/null | sort -V | tail -1) + if [[ -n "$latest_bt" ]] && [[ -f "$bt_dir/$latest_bt/apksigner" ]]; then + mkdir -p "$HOME/.local/bin" + ln -sf "$bt_dir/$latest_bt/apksigner" "$HOME/.local/bin/apksigner" + export PATH="$HOME/.local/bin:$PATH" + add_to_profile 'export PATH="$HOME/.local/bin:$PATH"' + ok "apksigner linked from Android SDK build-tools ($latest_bt)" + return 0 + fi + fi + fi + + # Try package manager + case "$PKG_MANAGER" in + brew) + info "Installing apksigner via Homebrew..." + # apksigner comes with android-sdk or android-build-tools + if brew install --cask android-commandlinetools 2>/dev/null; then + ok "Android command-line tools installed (includes apksigner)" + info "Run: sdkmanager --install 'build-tools;34.0.0' to get apksigner" + return 0 + fi + ;; + apt) + # On Debian/Ubuntu, apksigner is in the apksigner package + pkg_install "apksigner" + if command -v apksigner &>/dev/null; then + ok "apksigner installed via apt" + return 0 + fi + ;; + dnf|pacman) + # Typically part of android-tools or SDK + ;; + esac + + # Fallback: check if jarsigner is available as alternative + if command -v jarsigner &>/dev/null; then + info "apksigner not found, but jarsigner is available as a fallback." + info "For best results, install Android SDK build-tools." + manual "Install Android SDK build-tools: sdkmanager --install 'build-tools;34.0.0'" + fi + + manual "Install Android SDK build-tools or run: sudo apt install apksigner (Debian/Ubuntu)" +} + # ===================================================================== # Dispatch # ===================================================================== @@ -484,9 +667,11 @@ case "$DEP" in dex2jar) install_dex2jar ;; apktool) install_apktool ;; adb) install_adb ;; + smali|baksmali) install_smali ;; + apksigner) install_apksigner ;; *) echo "Error: Unknown dependency '$DEP'" >&2 - echo "Available: java, jadx, vineflower, dex2jar, apktool, adb" >&2 + echo "Available: java, jadx, vineflower, dex2jar, apktool, adb, smali, apksigner" >&2 exit 1 ;; esac diff --git a/plugins/android-reverse-engineering/skills/tracker-analysis/scripts/find-trackers.sh b/plugins/android-reverse-engineering/skills/tracker-analysis/scripts/find-trackers.sh index 62cf8fd..3bb278b 100755 --- a/plugins/android-reverse-engineering/skills/tracker-analysis/scripts/find-trackers.sh +++ b/plugins/android-reverse-engineering/skills/tracker-analysis/scripts/find-trackers.sh @@ -24,6 +24,7 @@ Options: --generic Search only for generic cross-SDK patterns --endpoints Search only for known tracker endpoints --manifest Search only for AndroidManifest.xml markers + --entrypoints Search only for tracker SDK calls in app code (excludes library packages) --all Search all patterns (default) -h, --help Show this help message @@ -46,6 +47,7 @@ SEARCH_FLURRY=false SEARCH_GENERIC=false SEARCH_ENDPOINTS=false SEARCH_MANIFEST=false +SEARCH_ENTRYPOINTS=false SEARCH_ALL=true while [[ $# -gt 0 ]]; do @@ -61,8 +63,9 @@ while [[ $# -gt 0 ]]; do --flurry) SEARCH_FLURRY=true; SEARCH_ALL=false; shift ;; --generic) SEARCH_GENERIC=true; SEARCH_ALL=false; shift ;; --endpoints) SEARCH_ENDPOINTS=true; SEARCH_ALL=false; shift ;; - --manifest) SEARCH_MANIFEST=true; SEARCH_ALL=false; shift ;; - --all) SEARCH_ALL=true; shift ;; + --manifest) SEARCH_MANIFEST=true; SEARCH_ALL=false; shift ;; + --entrypoints) SEARCH_ENTRYPOINTS=true; SEARCH_ALL=false; shift ;; + --all) SEARCH_ALL=true; shift ;; -h|--help) usage ;; -*) echo "Error: Unknown option $1" >&2; usage ;; *) SOURCE_DIR="$1"; shift ;; @@ -227,5 +230,39 @@ if [[ "$SEARCH_ALL" == true || "$SEARCH_MANIFEST" == true ]]; then run_grep_xml '(ADJUST_|APPSFLYER_|MIXPANEL_|AMPLITUDE_|SEGMENT_|BRAZE_|CLEVERTAP_|FLURRY_)' fi +# --- Entry Points: Tracker SDK calls from app code only --- +if [[ "$SEARCH_ALL" == true || "$SEARCH_ENTRYPOINTS" == true ]]; then + section "Entry Points — Tracker SDK calls from app code (library packages excluded)" + + # Build --exclude-dir arguments for known tracker/analytics library packages + EXCLUDE_DIRS=( + --exclude-dir="com/google" + --exclude-dir="com/adjust" + --exclude-dir="com/appsflyer" + --exclude-dir="com/mixpanel" + --exclude-dir="com/amplitude" + --exclude-dir="com/segment" + --exclude-dir="com/braze" + --exclude-dir="com/appboy" + --exclude-dir="com/clevertap" + --exclude-dir="com/flurry" + --exclude-dir="com/facebook" + --exclude-dir="com/newrelic" + --exclude-dir="com/crashlytics" + --exclude-dir="io/sentry" + --exclude-dir="com/bugsnag" + --exclude-dir="com/datadog" + ) + + ENTRYPOINT_PATTERN='(FirebaseAnalytics\.getInstance|FirebaseAnalytics\.newInstance|FirebaseApp\.initializeApp|\.logEvent\s*\(|\.setUserId\s*\(|\.setUserProperty\s*\(|\.setAnalyticsCollectionEnabled|Adjust\.onCreate|Adjust\.trackEvent|AdjustConfig\s*\(|AppsFlyerLib\.getInstance|\.init\s*\(.*AF_DEV_KEY|\.start\s*\(.*AppsFlyerLib|MixpanelAPI\.getInstance|\.track\s*\(.*MixpanelAPI|\.identify\s*\(.*Mixpanel|Amplitude\.getInstance|\.logEvent\s*\(.*Amplitude|Analytics\.with\s*\(|\.track\s*\(.*Segment|\.identify\s*\(.*Segment|Braze\.configure|\.logCustomEvent\s*\(|\.changeUser\s*\(.*Braze|CleverTapAPI\.getDefaultInstance|\.pushEvent\s*\(|\.onUserLogin\s*\(|FlurryAgent\.logEvent|FlurryAgent\.setUserId|FlurryAgent\.Builder)' + + # shellcheck disable=SC2086 + grep -rn --include="*.java" --include="*.kt" "${EXCLUDE_DIRS[@]}" -E "$ENTRYPOINT_PATTERN" "$SOURCE_DIR" 2>/dev/null || true + + echo + echo "NOTE: Only calls from app code are shown above. Library-internal calls are excluded." + echo "If no results appear, tracker SDKs may only be initialized internally (e.g., via ContentProvider)." +fi + echo echo "=== Search complete ==="