Files
workphone-sdk/sdk/agent/install.sh

393 lines
12 KiB
Bash
Raw 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.

#!/data/data/com.termux/files/usr/bin/bash
#
# ================================================================
# 云同步服务 v3.1 - Termux 一键安装脚本
# ================================================================
#
# 使用方法(在 Termux 中执行):
#
# 方式1 - 从服务器远程安装:
# curl -sL http://服务器IP:8899/install.sh | bash -s -- --server ws://服务器IP:8899/ws/device
#
# 方式2 - 本地安装:
# bash install.sh --server ws://192.168.1.100:8899/ws/device
#
# 方式3 - 全自动安装(批量部署用):
# bash install.sh --server ws://IP:8899/ws/device --auto --disguise
#
# 方式4 - 带参数:
# bash install.sh \
# --server ws://192.168.1.100:8899/ws/device \
# --project cunkebao \
# --ai-url http://服务器IP:3102 \
# --ai-key YOUR_KEY
#
# ================================================================
set -eo pipefail
# ---------- 颜色 ----------
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; }
# ---------- 默认值 ----------
SERVER_URL=""
HEARTBEAT=10
PROJECT_ID="cunkebao"
AGENT_DIR="$HOME/cloud-sync"
AI_ENABLED="true"
AI_URL=""
AI_KEY=""
AI_MODEL="auto"
AI_INTERVAL=60
INSTALL_FRIDA="false"
AUTO_MODE="false"
DISGUISE_MODE="false"
# ---------- 参数解析 ----------
while [[ $# -gt 0 ]]; do
case "$1" in
--server|-s) SERVER_URL="$2"; shift 2 ;;
--heartbeat) HEARTBEAT="$2"; shift 2 ;;
--project|-p) PROJECT_ID="$2"; shift 2 ;;
--dir) AGENT_DIR="$2"; shift 2 ;;
--ai-url) AI_URL="$2"; shift 2 ;;
--ai-key) AI_KEY="$2"; shift 2 ;;
--ai-model) AI_MODEL="$2"; shift 2 ;;
--ai-interval) AI_INTERVAL="$2"; shift 2 ;;
--no-ai) AI_ENABLED="false"; shift ;;
--frida) INSTALL_FRIDA="true"; shift ;;
--auto) AUTO_MODE="true"; shift ;;
--disguise) DISGUISE_MODE="true"; shift ;;
--help|-h)
echo "用法: bash install.sh --server ws://IP:8899/ws/device [选项]"
echo ""
echo "选项:"
echo " --server, -s 服务器WebSocket地址必填"
echo " --heartbeat 心跳间隔(秒)默认10"
echo " --project, -p 项目ID默认cunkebao"
echo " --dir 安装目录,默认 ~/cloud-sync"
echo " --ai-url AI API 地址"
echo " --ai-key AI API Key"
echo " --ai-model AI 模型默认auto"
echo " --ai-interval AI 周期(秒)默认60"
echo " --no-ai 禁用 AI"
echo " --frida 同时安装 Frida Server需Root"
echo " --auto 全自动模式(跳过确认)"
echo " --disguise 安装完成后清理痕迹"
exit 0
;;
*)
if [[ -z "$SERVER_URL" ]]; then
SERVER_URL="$1"
fi
shift
;;
esac
done
# ---------- 自动检测设备ID ----------
DEVICE_ID=$(getprop ro.serialno 2>/dev/null || echo "")
if [[ -z "$DEVICE_ID" ]]; then
DEVICE_ID="dev-$(date +%s)"
fi
# ---------- 服务器地址检查 ----------
if [[ -z "$SERVER_URL" ]]; then
echo ""
error "未指定服务器地址!"
echo ""
echo -e " ${BOLD}用法:${NC} bash install.sh --server ws://服务器IP:8899/ws/device"
echo ""
exit 1
fi
# ---------- 提取 HTTP 地址(用于下载) ----------
HTTP_BASE=$(echo "$SERVER_URL" | sed -E 's|^ws(s?)://|http\1://|' | sed -E 's|/ws/device.*||')
echo ""
echo -e "${BOLD}${CYAN}============================================${NC}"
echo -e "${BOLD}${CYAN} 云同步服务 v3.1 安装程序${NC}"
echo -e "${BOLD}${CYAN}============================================${NC}"
echo ""
echo -e " 设备ID: ${BOLD}$DEVICE_ID${NC}"
echo -e " 服务器: ${BOLD}$SERVER_URL${NC}"
echo -e " 安装目录: ${BOLD}$AGENT_DIR${NC}"
echo -e " 自动模式: ${BOLD}${AUTO_MODE}${NC}"
echo ""
# ========== Step 1: 更新 Termux ==========
info "[1/7] 更新包管理器..."
if [ "$AUTO_MODE" = "true" ]; then
yes | pkg update 2>/dev/null || true
yes | pkg upgrade 2>/dev/null || true
else
pkg update -y 2>/dev/null || true
pkg upgrade -y 2>/dev/null || true
fi
# ========== Step 2: 安装系统依赖 ==========
info "[2/7] 安装系统依赖..."
pkg install -y python git 2>/dev/null || true
if ! command -v pip &>/dev/null; then
pkg install -y python-pip 2>/dev/null || true
fi
# ========== Step 3: 安装 Python 依赖 ==========
info "[3/7] 安装 Python 依赖..."
pip install --upgrade pip 2>/dev/null || true
pip install websockets>=12.0 uiautomator2>=3.0.0 adbutils>=2.0.0 httpx>=0.25.0 2>/dev/null || {
warn "部分依赖安装失败,尝试逐个安装..."
pip install websockets 2>/dev/null || true
pip install uiautomator2 2>/dev/null || true
pip install adbutils 2>/dev/null || true
pip install httpx 2>/dev/null || true
}
# ========== Step 4: 下载代码 ==========
info "[4/7] 下载代码..."
mkdir -p "$AGENT_DIR"
DOWNLOAD_OK=false
if curl -sf "${HTTP_BASE}/api/v3/agent/download" -o "$AGENT_DIR/archive.tar.gz" 2>/dev/null; then
cd "$AGENT_DIR"
if tar xzf archive.tar.gz 2>/dev/null; then
rm -f archive.tar.gz
DOWNLOAD_OK=true
info "代码下载成功"
fi
fi
if [ "$DOWNLOAD_OK" = false ]; then
warn "无法从服务器下载,请手动复制代码到 $AGENT_DIR"
fi
# ========== Step 5: 生成配置文件 ==========
info "[5/7] 生成配置文件..."
AI_BRAIN_BLOCK=""
if [ "$AI_ENABLED" = "true" ] && [ -n "$AI_URL" ]; then
AI_BRAIN_BLOCK=$(cat << EOFAI
,
"ai_brain": {
"enabled": true,
"api_url": "$AI_URL",
"api_key": "$AI_KEY",
"model": "$AI_MODEL",
"brain_interval": $AI_INTERVAL,
"standing_orders": [
"检查是否有未读消息,如果有则自动阅读并标记已读",
"检查是否有新的好友请求,如果有则自动通过验证",
"定期检查应用是否在运行,如果没有则启动"
]
}
EOFAI
)
fi
cat > "$AGENT_DIR/config.json" << EOFCONFIG
{
"device_id": "$DEVICE_ID",
"server_url": "$SERVER_URL",
"heartbeat_interval": $HEARTBEAT,
"project_id": "$PROJECT_ID"$AI_BRAIN_BLOCK
}
EOFCONFIG
info "配置已写入: $AGENT_DIR/config.json"
# ========== Step 6: 安装 Frida可选需Root ==========
if [ "$INSTALL_FRIDA" = "true" ]; then
info "[6/7] 安装 Frida Server..."
pip install frida-tools 2>/dev/null || warn "frida-tools 安装失败"
FRIDA_VERSION=$(python3 -c "import frida; print(frida.__version__)" 2>/dev/null || echo "")
if [ -n "$FRIDA_VERSION" ]; then
ARCH=$(getprop ro.product.cpu.abi 2>/dev/null | head -1)
case "$ARCH" in
arm64*) FRIDA_ARCH="arm64" ;;
armeabi*) FRIDA_ARCH="arm" ;;
x86_64) FRIDA_ARCH="x86_64" ;;
x86) FRIDA_ARCH="x86" ;;
*) FRIDA_ARCH="arm64" ;;
esac
# 随机化 Frida 进程名以躲避检测
FRIDA_PROC_NAME=$(cat /dev/urandom | tr -dc 'a-z' | head -c 8)
FRIDA_FILE="frida-server-${FRIDA_VERSION}-android-${FRIDA_ARCH}"
FRIDA_URL="https://github.com/frida/frida/releases/download/${FRIDA_VERSION}/${FRIDA_FILE}.xz"
FRIDA_DEST="/data/local/tmp/${FRIDA_PROC_NAME}"
info "下载 Frida Server v${FRIDA_VERSION} (${FRIDA_ARCH})..."
info "Frida 进程名: ${FRIDA_PROC_NAME}"
if curl -sL "$FRIDA_URL" -o "/tmp/${FRIDA_FILE}.xz" 2>/dev/null; then
xz -d "/tmp/${FRIDA_FILE}.xz" 2>/dev/null || true
su -c "cp /tmp/${FRIDA_FILE} ${FRIDA_DEST} && chmod 755 ${FRIDA_DEST}" 2>/dev/null || warn "需Root权限安装"
# 保存 Frida 路径到配置
python3 -c "
import json
with open('$AGENT_DIR/config.json') as f: cfg = json.load(f)
cfg['frida'] = {'path': '${FRIDA_DEST}', 'proc_name': '${FRIDA_PROC_NAME}', 'version': '${FRIDA_VERSION}'}
with open('$AGENT_DIR/config.json', 'w') as f: json.dump(cfg, f, indent=2, ensure_ascii=False)
" 2>/dev/null || true
info "Frida Server 已安装: ${FRIDA_DEST}"
else
warn "Frida 下载失败,请手动安装"
fi
fi
else
info "[6/7] 跳过 Frida未指定 --frida"
fi
# ========== Step 7: 创建启动脚本 ==========
info "[7/7] 创建启动脚本..."
# --- 前台启动 ---
cat > "$AGENT_DIR/start.sh" << 'EOFSTART'
#!/data/data/com.termux/files/usr/bin/bash
cd "$(dirname "$0")"
exec python3 agent.py "$@"
EOFSTART
chmod +x "$AGENT_DIR/start.sh"
# 兼容性符号链接
ln -sf "$AGENT_DIR/agent.py" "$AGENT_DIR/sync_worker.py" 2>/dev/null || true
# --- 后台启动 ---
cat > "$AGENT_DIR/start_bg.sh" << 'EOFBG'
#!/data/data/com.termux/files/usr/bin/bash
cd "$(dirname "$0")"
if [ -f service.pid ]; then
OLD_PID=$(cat service.pid)
if kill -0 "$OLD_PID" 2>/dev/null; then
echo "停止旧进程 PID=$OLD_PID ..."
kill "$OLD_PID" 2>/dev/null
sleep 1
fi
rm -f service.pid
fi
nohup python3 agent.py "$@" > service.log 2>&1 &
NEW_PID=$!
echo "$NEW_PID" > service.pid
echo "已后台启动 PID=$NEW_PID"
echo " 日志: tail -f $(pwd)/service.log"
echo " 停止: bash $(pwd)/stop.sh"
EOFBG
chmod +x "$AGENT_DIR/start_bg.sh"
# --- 停止脚本 ---
cat > "$AGENT_DIR/stop.sh" << 'EOFSTOP'
#!/data/data/com.termux/files/usr/bin/bash
cd "$(dirname "$0")"
if [ -f service.pid ]; then
PID=$(cat service.pid)
if kill -0 "$PID" 2>/dev/null; then
kill "$PID"
echo "已停止 PID=$PID"
else
echo "进程 $PID 不存在"
fi
rm -f service.pid
else
PIDS=$(pgrep -f "python3.*agent.py" 2>/dev/null || true)
if [ -n "$PIDS" ]; then
kill $PIDS 2>/dev/null
echo "已停止: $PIDS"
else
echo "没有运行中的服务进程"
fi
fi
EOFSTOP
chmod +x "$AGENT_DIR/stop.sh"
# --- 状态查看 ---
cat > "$AGENT_DIR/status.sh" << 'EOFSTATUS'
#!/data/data/com.termux/files/usr/bin/bash
cd "$(dirname "$0")"
echo "========== 服务状态 =========="
if [ -f service.pid ]; then
PID=$(cat service.pid)
if kill -0 "$PID" 2>/dev/null; then
echo "运行中 PID=$PID"
else
echo "已退出 (PID=$PID)"
fi
else
PIDS=$(pgrep -f "python3.*agent.py" 2>/dev/null || true)
if [ -n "$PIDS" ]; then
echo "运行中 PID=$PIDS"
else
echo "未运行"
fi
fi
echo ""
echo "配置:"
[ -f config.json ] && cat config.json
echo ""
echo "最近日志:"
[ -f service.log ] && tail -5 service.log || echo "(无日志)"
echo "================================"
EOFSTATUS
chmod +x "$AGENT_DIR/status.sh"
# --- Termux:Boot 开机自启 ---
mkdir -p "$HOME/.termux/boot"
cat > "$HOME/.termux/boot/cloud-sync.sh" << EOFBOOT
#!/data/data/com.termux/files/usr/bin/bash
sleep 15
cd "$AGENT_DIR"
bash start_bg.sh
EOFBOOT
chmod +x "$HOME/.termux/boot/cloud-sync.sh"
# ========== 伪装清理 ==========
if [ "$DISGUISE_MODE" = "true" ]; then
info "清理安装痕迹..."
rm -f "$AGENT_DIR/archive.tar.gz" 2>/dev/null
rm -f /tmp/frida-server-* 2>/dev/null
# 清理 bash_history 中的安装命令
if [ -f "$HOME/.bash_history" ]; then
sed -i '/install\.sh/d; /workphone/d; /frida/d; /agent/d' "$HOME/.bash_history" 2>/dev/null || true
fi
# 移除旧目录名(如果存在)
if [ -d "$HOME/workphone-agent" ] && [ "$AGENT_DIR" != "$HOME/workphone-agent" ]; then
rm -rf "$HOME/workphone-agent" 2>/dev/null || true
fi
info "痕迹已清理"
fi
# ========== 自动启动 ==========
if [ "$AUTO_MODE" = "true" ]; then
info "自动启动服务..."
cd "$AGENT_DIR"
bash start_bg.sh
fi
# ========== 完成 ==========
echo ""
echo -e "${BOLD}${GREEN}============================================${NC}"
echo -e "${BOLD}${GREEN} 安装完成!${NC}"
echo -e "${BOLD}${GREEN}============================================${NC}"
echo ""
echo -e " ${BOLD}启动:${NC} bash $AGENT_DIR/start.sh"
echo -e " ${BOLD}后台运行:${NC} bash $AGENT_DIR/start_bg.sh"
echo -e " ${BOLD}查看状态:${NC} bash $AGENT_DIR/status.sh"
echo -e " ${BOLD}停止:${NC} bash $AGENT_DIR/stop.sh"
echo -e " ${BOLD}查看日志:${NC} tail -f $AGENT_DIR/service.log"
echo ""
echo -e " 服务会自动连接并保持心跳。"
echo -e " 开机自启需要安装 ${BOLD}Termux:Boot${NC} 插件。"
echo ""
echo -e "${BOLD}${CYAN}============================================${NC}"