#!/usr/bin/env bash # 经 ADB 向 Termux 推送 config + 启动脚本,并在手机上拉起 Agent(无线主控 · 不依赖 Mac 侧 agent.py) # 用法: DEVICE_SERIAL=xgfe65eimrrofyws bash sdk/scripts/termux_push_and_start_agent.sh set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SDK_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" LAN_ENV="${SDK_ROOT}/config/lan.env" [[ -f "${LAN_ENV}" ]] && source "${LAN_ENV}" || true export ANDROID_ADB_SERVER_PORT="${ANDROID_ADB_SERVER_PORT:-5037}" ADB=(adb -P "${ANDROID_ADB_SERVER_PORT}") DEVICE_SERIAL="${DEVICE_SERIAL:-xgfe65eimrrofyws}" SDK_PORT="${WORKPHONE_SDK_PORT:-8899}" DEVICE_ID="${DEVICE_ID:-${DEVICE_SERIAL}}" FRIDA_PORT="$(python3 -c "import json; print(json.load(open('${SCRIPT_DIR}/anti_detect/phantom_frida_config.json'))['listen_port'])" 2>/dev/null || echo 38829)" pick_mac_lan_ip() { if [[ -n "${WORKPHONE_LAN_IP:-}" ]]; then echo "${WORKPHONE_LAN_IP}" return fi local ip for ip in $(ifconfig 2>/dev/null | awk '/inet /{print $2}' | grep -v '^127\.'); do [[ "$ip" == 198.18.* ]] && continue [[ "$ip" == 192.168.* || "$ip" == 10.* ]] && { echo "$ip"; return; } done echo "127.0.0.1" } MAC_IP="$(pick_mac_lan_ip)" TERMUX_HOME="/data/data/com.termux/files/home" REMOTE_DIR="${TERMUX_HOME}/workphone" REMOTE_AGENT="${REMOTE_DIR}/agent" REMOTE_CFG="${REMOTE_AGENT}/config.json" REMOTE_START="${REMOTE_DIR}/start_agent.sh" REMOTE_WATCH="${REMOTE_DIR}/agent_watchdog.sh" REMOTE_BOOT="${TERMUX_HOME}/.termux/boot/00-workphone-agent.sh" LOG="${SDK_ROOT}/logs/termux_agent_push.log" mkdir -p "${SDK_ROOT}/logs" log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; } if ! "${ADB[@]}" -s "${DEVICE_SERIAL}" get-state 2>/dev/null | grep -qx device; then log "FAIL: adb device not ready serial=${DEVICE_SERIAL}" exit 1 fi # ① NAS→Docker→frp 有序 config(与 BIND-03 一致,无 USB 后手机自主寻服) CFG_TMP="$(mktemp)" python3 "${SCRIPT_DIR}/build_agent_config.py" --device-id "${DEVICE_ID}" --for-phone --out "${CFG_TMP}" PRIMARY_WS="$(python3 "${SCRIPT_DIR}/build_agent_config.py" --for-phone --print-primary 2>/dev/null | head -1)" log "config primary=${PRIMARY_WS} (NAS优先,非 Mac 单点)" # ② 写 start_agent.sh START_TMP="$(mktemp)" cat > "${START_TMP}" </dev/null || cd "\${HOME}/storage/downloads/workphone/agent" 2>/dev/null || exit 1 pkill -f "python.*agent.py" 2>/dev/null || true sleep 1 nohup python agent.py --config config.json >> "\${HOME}/workphone/agent.log" 2>&1 & echo "agent_pid=\$!" >> "\${HOME}/workphone/agent.log" BOOT chmod +x "${START_TMP}" WATCH_TMP="$(mktemp)" cat > "${WATCH_TMP}" <<'WATCH' #!/data/data/com.termux/files/usr/bin/bash # 手机侧看门狗:无 USB 时 Agent 崩溃自动拉起(30s) export WP_AGENT_ON_DEVICE=1 export WP_FRIDA_MODE=remote AGENT_DIR="${HOME}/workphone/agent" LOG="${HOME}/workphone/watchdog.log" while true; do if ! pgrep -f "python.*agent.py" >/dev/null 2>&1; then echo "$(date '+%F %T') restart agent" >> "$LOG" cd "$AGENT_DIR" 2>/dev/null && \ nohup python agent.py --config config.json >> "${HOME}/workphone/agent.log" 2>&1 & fi sleep 30 done WATCH chmod +x "${WATCH_TMP}" BOOT_TMP="$(mktemp)" cat > "${BOOT_TMP}" <<'TBOOT' #!/data/data/com.termux/files/usr/bin/bash # Termux:Boot — 开机自动启动 Agent + 看门狗(无线主控 · 无 Mac USB) termux-wake-lock 2>/dev/null || true bash "${HOME}/workphone/start_agent.sh" >> "${HOME}/workphone/boot.log" 2>&1 & pgrep -f agent_watchdog.sh >/dev/null || \ nohup bash "${HOME}/workphone/agent_watchdog.sh" >> "${HOME}/workphone/watchdog.log" 2>&1 & TBOOT chmod +x "${BOOT_TMP}" log "push config → ${DEVICE_SERIAL} (${PRIMARY_WS}/${DEVICE_ID})" "${ADB[@]}" -s "${DEVICE_SERIAL}" shell "mkdir -p ${REMOTE_DIR}/agent ${TERMUX_HOME}/.termux/boot" 2>/dev/null || true "${ADB[@]}" -s "${DEVICE_SERIAL}" push "${CFG_TMP}" "${REMOTE_CFG}" >/dev/null 2>&1 || \ "${ADB[@]}" -s "${DEVICE_SERIAL}" push "${CFG_TMP}" "/sdcard/workphone_config.json" >/dev/null "${ADB[@]}" -s "${DEVICE_SERIAL}" push "${START_TMP}" "${REMOTE_START}" >/dev/null 2>&1 || \ "${ADB[@]}" -s "${DEVICE_SERIAL}" push "${START_TMP}" "/sdcard/start_agent.sh" >/dev/null "${ADB[@]}" -s "${DEVICE_SERIAL}" push "${WATCH_TMP}" "${REMOTE_WATCH}" >/dev/null 2>&1 || true "${ADB[@]}" -s "${DEVICE_SERIAL}" push "${BOOT_TMP}" "${REMOTE_BOOT}" >/dev/null 2>&1 || true rm -f "${CFG_TMP}" "${START_TMP}" "${WATCH_TMP}" "${BOOT_TMP}" # ③ 尝试 Termux RUN_COMMAND 启动(0.118+) log "termux RUN_COMMAND start_agent…" "${ADB[@]}" -s "${DEVICE_SERIAL}" shell am broadcast \ -a com.termux.RUN_COMMAND \ -n com.termux/com.termux.app.RunCommandService \ --es com.termux.RUN_COMMAND_PATH "${TERMUX_HOME}/usr/bin/bash" \ --esa com.termux.RUN_COMMAND_ARGUMENTS "-lc,${REMOTE_START}" \ --ez com.termux.RUN_COMMAND_BACKGROUND true 2>/dev/null || true # ④ 兼容旧版 RUN_SCRIPT "${ADB[@]}" -s "${DEVICE_SERIAL}" shell am broadcast \ -a com.termux.RUN_SCRIPT \ --es com.termux.RUN_SCRIPT_PATH "${REMOTE_START}" 2>/dev/null || true # ⑤ 启动手机看门狗(无 USB 时 Agent 崩溃自动拉起) "${ADB[@]}" -s "${DEVICE_SERIAL}" shell "nohup bash ${REMOTE_WATCH} >> ${TERMUX_HOME}/workphone/watchdog.log 2>&1 &" 2>/dev/null || true sleep 3 WS_COUNT=$(curl -s -m 5 "http://127.0.0.1:${SDK_PORT}/api/v3/connection/status" 2>/dev/null | \ python3 -c "import sys,json;d=json.load(sys.stdin).get('data',{});print(d.get('online_ws_count',0))" 2>/dev/null || echo 0) log "done ws_online=${WS_COUNT}" [[ "${WS_COUNT}" -ge 1 ]] && exit 0 # ⑤ 回退:Mac 侧 oneclick(USB + adb reverse) log "termux start pending → fallback oneclick" DEVICE_SERIAL="${DEVICE_SERIAL}" bash "${SCRIPT_DIR}/frida_workphone_oneclick.sh" -d "${DEVICE_SERIAL}" >>"$LOG" 2>&1 || true WS_COUNT=$(curl -s -m 5 "http://127.0.0.1:${SDK_PORT}/api/v3/connection/status" 2>/dev/null | \ python3 -c "import sys,json;d=json.load(sys.stdin).get('data',{});print(d.get('online_ws_count',0))" 2>/dev/null || echo 0) log "oneclick fallback ws_online=${WS_COUNT}" [[ "${WS_COUNT}" -ge 1 ]]