#!/bin/bash

# =============================================
# 判官标准版 - Manifest随机属性注入工具
# 在AndroidManifest.xml中注入无害随机属性干扰检测
# =============================================

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# 输出目录
OUTPUT_DIR="./output"
TEMP_DIR="./temp_manifest"
mkdir -p "$OUTPUT_DIR"

# 随机字符串生成
generate_random_string() {
    local length=$1
    cat /dev/urandom | tr -dc 'a-zA-Z' | fold -w $length | head -n 1
}

# 随机数字生成
generate_random_number() {
    local min=$1
    local max=$2
    echo $((RANDOM % (max - min + 1) + min))
}

# 生成随机属性名
generate_random_attr_name() {
    local prefixes=("custom" "app" "config" "setting" "param" "data" "info" "meta" "flag" "opt")
    local suffixes=("Value" "Mode" "Type" "Level" "Status" "Code" "Key" "Id" "Tag" "Ref")
    local prefix=${prefixes[$RANDOM % ${#prefixes[@]}]}
    local suffix=${suffixes[$RANDOM % ${#suffixes[@]}]}
    local random=$(generate_random_string 4)
    echo "${prefix}${random}${suffix}"
}

# 生成随机属性值
generate_random_attr_value() {
    local types=("string" "number" "boolean" "hex")
    local type=${types[$RANDOM % ${#types[@]}]}
    
    case $type in
        "string")
            echo "$(generate_random_string 8)"
            ;;
        "number")
            echo "$(generate_random_number 1000 9999)"
            ;;
        "boolean")
            local bools=("true" "false")
            echo "${bools[$RANDOM % 2]}"
            ;;
        "hex")
            echo "0x$(generate_random_string 4 | xxd -p | head -c 8)"
            ;;
    esac
}

# 生成随机meta-data
generate_random_metadata() {
    local name="com.$(generate_random_string 6).$(generate_random_string 4).$(generate_random_attr_name)"
    local value=$(generate_random_attr_value)
    echo "        <meta-data android:name=\"$name\" android:value=\"$value\" />"
}

# 生成随机uses-feature
generate_random_feature() {
    local features=(
        "android.hardware.sensor.accelerometer"
        "android.hardware.sensor.compass"
        "android.hardware.sensor.gyroscope"
        "android.hardware.sensor.light"
        "android.hardware.sensor.proximity"
        "android.hardware.sensor.barometer"
        "android.hardware.sensor.stepcounter"
        "android.hardware.sensor.stepdetector"
        "android.hardware.sensor.heartrate"
        "android.hardware.sensor.ambient_temperature"
    )
    local feature=${features[$RANDOM % ${#features[@]}]}
    echo "    <uses-feature android:name=\"$feature\" android:required=\"false\" />"
}

# 生成随机property
generate_random_property() {
    local name="$(generate_random_string 8)_$(generate_random_string 4)"
    local value=$(generate_random_attr_value)
    echo "        <property android:name=\"$name\" android:value=\"$value\" />"
}

# 清理临时文件
cleanup() {
    rm -rf "$TEMP_DIR" 2>/dev/null
}

# 注入Manifest属性
inject_manifest() {
    local input_apk=$1
    local injection_count=$2
    
    if [ ! -f "$input_apk" ]; then
        echo -e "${RED}错误: APK文件不存在: $input_apk${NC}"
        return 1
    fi
    
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}  判官标准版 - Manifest随机属性注入${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    echo -e "${CYAN}输入文件: ${GREEN}$input_apk${NC}"
    echo -e "${CYAN}注入数量: ${GREEN}$injection_count 个属性${NC}"
    echo ""
    
    # 清理并创建临时目录
    cleanup
    mkdir -p "$TEMP_DIR"
    
    # 使用apktool解包
    echo -e "${YELLOW}[1/5] 解包APK文件...${NC}"
    
    # 检查apktool是否存在
    if ! command -v apktool &> /dev/null; then
        # 尝试使用java -jar方式
        if [ -f "./apktool.jar" ]; then
            java -jar ./apktool.jar d "$input_apk" -o "$TEMP_DIR/unpacked" -f 2>/dev/null
        else
            echo -e "${RED}错误: 未找到apktool，请确保apktool已安装${NC}"
            cleanup
            return 1
        fi
    else
        apktool d "$input_apk" -o "$TEMP_DIR/unpacked" -f 2>/dev/null
    fi
    
    if [ ! -d "$TEMP_DIR/unpacked" ]; then
        echo -e "${RED}解包失败${NC}"
        cleanup
        return 1
    fi
    
    local manifest="$TEMP_DIR/unpacked/AndroidManifest.xml"
    if [ ! -f "$manifest" ]; then
        echo -e "${RED}未找到AndroidManifest.xml${NC}"
        cleanup
        return 1
    fi
    
    echo -e "  ${GREEN}✓${NC} 解包成功"
    
    # 生成随机属性
    echo -e "${YELLOW}[2/5] 生成随机属性...${NC}"
    
    local inject_content=""
    local meta_count=$((injection_count / 3))
    local feature_count=$((injection_count / 3))
    local property_count=$((injection_count - meta_count - feature_count))
    
    # 生成meta-data
    for i in $(seq 1 $meta_count); do
        local metadata=$(generate_random_metadata)
        echo -e "  ${GREEN}+${NC} meta-data: $(echo $metadata | grep -o 'android:name="[^"]*"' | head -1)"
        inject_content="$inject_content\n$metadata"
    done
    
    # 生成uses-feature
    for i in $(seq 1 $feature_count); do
        local feature=$(generate_random_feature)
        echo -e "  ${GREEN}+${NC} uses-feature: $(echo $feature | grep -o 'android:name="[^"]*"' | head -1)"
        inject_content="$inject_content\n$feature"
    done
    
    # 注入到Manifest
    echo -e "${YELLOW}[3/5] 注入属性到Manifest...${NC}"
    
    # 在</application>前注入meta-data
    local meta_inject=""
    for i in $(seq 1 $meta_count); do
        meta_inject="$meta_inject$(generate_random_metadata)\n"
    done
    
    # 使用sed在</application>前插入
    sed -i "s|</application>|$meta_inject    </application>|" "$manifest"
    
    # 在<application前插入uses-feature
    local feature_inject=""
    for i in $(seq 1 $feature_count); do
        feature_inject="$feature_inject$(generate_random_feature)\n"
    done
    
    # 在<application之前插入
    sed -i "s|<application|$feature_inject\n    <application|" "$manifest"
    
    # 添加随机XML注释
    local comments_count=$((RANDOM % 5 + 3))
    for i in $(seq 1 $comments_count); do
        local comment="<!-- $(generate_random_string 32) -->"
        sed -i "1a$comment" "$manifest"
    done
    
    echo -e "  ${GREEN}✓${NC} 属性注入成功"
    
    # 重新打包
    echo -e "${YELLOW}[4/5] 重新打包APK...${NC}"
    
    local output_name=$(basename "$input_apk" .apk)
    local timestamp=$(date +%Y%m%d_%H%M%S)
    local output_apk="$OUTPUT_DIR/${output_name}_injected_${timestamp}.apk"
    
    if ! command -v apktool &> /dev/null; then
        if [ -f "./apktool.jar" ]; then
            java -jar ./apktool.jar b "$TEMP_DIR/unpacked" -o "$output_apk" 2>/dev/null
        fi
    else
        apktool b "$TEMP_DIR/unpacked" -o "$output_apk" 2>/dev/null
    fi
    
    if [ ! -f "$output_apk" ]; then
        echo -e "${RED}打包失败${NC}"
        cleanup
        return 1
    fi
    
    echo -e "  ${GREEN}✓${NC} 打包成功"
    
    # 显示结果
    echo -e "${YELLOW}[5/5] 处理完成!${NC}"
    echo ""
    echo -e "${BLUE}========================================${NC}"
    echo -e "${GREEN}✓ Manifest属性注入成功!${NC}"
    echo -e "  注入meta-data: ${CYAN}$meta_count 个${NC}"
    echo -e "  注入uses-feature: ${CYAN}$feature_count 个${NC}"
    echo -e "  注入XML注释: ${CYAN}$comments_count 个${NC}"
    echo -e "  输出文件: ${CYAN}$output_apk${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    echo -e "${YELLOW}注意: 输出的APK需要重新签名后才能安装${NC}"
    
    # 清理
    cleanup
    return 0
}

# 主菜单
show_menu() {
    echo -e "${BLUE}========================================${NC}"
    echo -e "${BLUE}  判官标准版 - Manifest随机属性注入${NC}"
    echo -e "${BLUE}========================================${NC}"
    echo ""
    echo -e "请选择操作:"
    echo -e "  ${GREEN}1.${NC} 注入少量属性 (5-10个)"
    echo -e "  ${GREEN}2.${NC} 注入中量属性 (15-20个)"
    echo -e "  ${GREEN}3.${NC} 注入大量属性 (30-50个)"
    echo -e "  ${GREEN}4.${NC} 自定义注入数量"
    echo -e "  ${GREEN}5.${NC} 查看输出目录"
    echo -e "  ${GREEN}0.${NC} 退出"
    echo ""
    echo -n "请输入选项 [0-5]: "
}

# 主函数
main() {
    while true; do
        show_menu
        read -r option
        case $option in
            1)
                echo -n "请输入APK文件路径: "
                read -r apk_path
                inject_manifest "$apk_path" $(generate_random_number 5 10)
                ;;
            2)
                echo -n "请输入APK文件路径: "
                read -r apk_path
                inject_manifest "$apk_path" $(generate_random_number 15 20)
                ;;
            3)
                echo -n "请输入APK文件路径: "
                read -r apk_path
                inject_manifest "$apk_path" $(generate_random_number 30 50)
                ;;
            4)
                echo -n "请输入APK文件路径: "
                read -r apk_path
                echo -n "请输入注入数量: "
                read -r count
                inject_manifest "$apk_path" $count
                ;;
            5)
                echo -e "${CYAN}输出目录内容:${NC}"
                ls -la "$OUTPUT_DIR"/*.apk 2>/dev/null || echo "暂无输出文件"
                ;;
            0)
                cleanup
                echo -e "${GREEN}再见!${NC}"
                exit 0
                ;;
            *)
                echo -e "${RED}无效选项${NC}"
                ;;
        esac
        echo ""
        echo -n "按回车继续..."
        read
        clear
    done
}

# 运行
main
