123 lines
3.9 KiB
Bash
123 lines
3.9 KiB
Bash
#!/bin/bash
|
||
# macOS Ghost Client 安装脚本
|
||
# 用法: ./install.sh [ghost路径]
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
APP_DIR="/Applications/GhostClient.app"
|
||
APP_BIN="$APP_DIR/Contents/MacOS/ghost"
|
||
|
||
# 源 binary 优先级:
|
||
# 1) 命令行参数显式指定
|
||
# 2) 脚本同目录的 ghost(拷贝分发场景,不带源码/不重编)
|
||
# 3) build/bin/ghost(标准构建产物)
|
||
if [ -n "$1" ]; then
|
||
GHOST_SRC="$1"
|
||
elif [ -f "$SCRIPT_DIR/ghost" ]; then
|
||
GHOST_SRC="$SCRIPT_DIR/ghost"
|
||
else
|
||
GHOST_SRC="$SCRIPT_DIR/build/bin/ghost"
|
||
fi
|
||
|
||
echo "=== GhostClient 安装程序 ==="
|
||
echo ""
|
||
|
||
# 检查源文件
|
||
if [ ! -f "$GHOST_SRC" ]; then
|
||
echo "错误: 找不到 ghost 二进制"
|
||
echo " 尝试过: $SCRIPT_DIR/ghost"
|
||
echo " 尝试过: $SCRIPT_DIR/build/bin/ghost"
|
||
echo ""
|
||
echo "请先编译: ./build.sh"
|
||
echo "或将 ghost 二进制放到脚本同目录"
|
||
echo "或指定路径: $0 <ghost可执行文件路径>"
|
||
exit 1
|
||
fi
|
||
|
||
echo "源文件: $GHOST_SRC"
|
||
echo ""
|
||
|
||
set -e
|
||
|
||
# 1. 停止旧进程
|
||
echo "[1/7] 停止旧进程..."
|
||
pkill -9 -f "$APP_BIN" 2>/dev/null || true
|
||
|
||
# 2. 重置系统权限(关键步骤!避免权限缓存导致空白桌面)
|
||
echo "[2/7] 重置系统权限..."
|
||
echo " (这会清除屏幕录制和辅助功能的旧授权,需要重新授权)"
|
||
tccutil reset ScreenCapture 2>/dev/null || true
|
||
tccutil reset Accessibility 2>/dev/null || true
|
||
|
||
# 3. 创建应用程序包
|
||
echo "[3/7] 创建应用程序..."
|
||
sudo rm -rf "$APP_DIR"
|
||
sudo mkdir -p "$APP_DIR/Contents/MacOS"
|
||
sudo mkdir -p "$APP_DIR/Contents/Resources"
|
||
|
||
# 复制 ghost 到 app bundle 内部
|
||
sudo cp "$GHOST_SRC" "$APP_BIN"
|
||
sudo chmod +x "$APP_BIN"
|
||
|
||
# 创建 Info.plist
|
||
sudo tee "$APP_DIR/Contents/Info.plist" > /dev/null << 'EOF'
|
||
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||
<plist version="1.0">
|
||
<dict>
|
||
<key>CFBundleExecutable</key>
|
||
<string>ghost</string>
|
||
<key>CFBundleIdentifier</key>
|
||
<string>com.ghost.client</string>
|
||
<key>CFBundleName</key>
|
||
<string>GhostClient</string>
|
||
<key>CFBundleVersion</key>
|
||
<string>1.0</string>
|
||
<key>LSUIElement</key>
|
||
<true/>
|
||
</dict>
|
||
</plist>
|
||
EOF
|
||
|
||
# 4. 清除隔离属性
|
||
echo "[4/7] 清除隔离属性..."
|
||
sudo xattr -cr "$APP_DIR"
|
||
|
||
# 5. 签名应用(ad-hoc 重签)
|
||
# 必须步骤:Apple Silicon 上未签 / 签名失效的 binary 会被 AMFI 直接 SIGKILL。
|
||
# 常见破坏签名的场景:服务端 BuildDlg 在 Windows 端 patch 了 binary 里的服务器
|
||
# 地址 → 那一页的 SHA-256 hash 跟原签名块对不上 → AMFI 拒绝运行。
|
||
# --force 替换旧签名,--deep 覆盖 bundle 内所有可执行项,--sign - 是 ad-hoc。
|
||
echo "[5/7] 签名应用 (ad-hoc, 修复 binary 修改后的签名失效)..."
|
||
sudo codesign --force --deep --sign - "$APP_DIR"
|
||
|
||
# 6. 添加到登录项(开机自启)
|
||
echo "[6/7] 添加到登录项..."
|
||
osascript -e 'tell application "System Events" to delete login item "GhostClient"' 2>/dev/null || true
|
||
osascript -e 'tell application "System Events" to make login item at end with properties {path:"/Applications/GhostClient.app", hidden:true}' 2>/dev/null && echo " 已添加开机自启" || echo " 添加失败,请手动添加"
|
||
|
||
# 7. 完成
|
||
echo "[7/7] 安装完成!"
|
||
echo ""
|
||
echo "========================================"
|
||
echo " 下一步: 授权系统权限"
|
||
echo "========================================"
|
||
echo ""
|
||
echo "1. 启动应用 (会自动弹出权限请求):"
|
||
echo ""
|
||
echo " open /Applications/GhostClient.app"
|
||
echo ""
|
||
echo "2. 授权以下权限 (在系统设置中勾选 GhostClient):"
|
||
echo " - 屏幕录制: 允许捕获屏幕画面"
|
||
echo " - 辅助功能: 允许控制鼠标键盘"
|
||
echo ""
|
||
echo "3. 授权后重启应用:"
|
||
echo ""
|
||
echo " pkill -f GhostClient && open /Applications/GhostClient.app"
|
||
echo ""
|
||
echo "4. 查看日志确认运行状态:"
|
||
echo ""
|
||
echo " tail -f /tmp/ghost.log"
|
||
echo ""
|
||
echo "========================================"
|
||
echo ""
|