From d3591488418e9d31d5ffa2501fe3e56ab7db6ea9 Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Fri, 21 Aug 2026 12:30:31 +0200 Subject: [PATCH] doc: Add the "docs\macOS_Support_Design.md" to git --- docs/macOS_Support_Design.md | 576 +++++++++++++++++++++++++++++++++++ 1 file changed, 576 insertions(+) create mode 100644 docs/macOS_Support_Design.md diff --git a/docs/macOS_Support_Design.md b/docs/macOS_Support_Design.md new file mode 100644 index 0000000..db357de --- /dev/null +++ b/docs/macOS_Support_Design.md @@ -0,0 +1,576 @@ +# macOS 远程桌面客户端设计文档 + +## 1. 概述 + +### 1.1 目标 + +在不影响现有 Windows/Linux 功能的基础上,为 YAMA 项目添加 macOS 客户端支持,前期实现远程桌面控制功能。 + +### 1.2 功能范围(Phase 1) + +| 功能 | 优先级 | 状态 | 说明 | +|-----|--------|------|------| +| 连接服务器 | P0 | ⏳ Stub | 复用现有网络协议 | +| 屏幕捕获 | P0 | ✅ 完成 | CGDisplayCreateImage 实现 | +| 鼠标控制 | P0 | ✅ 完成 | CGEvent 实现 | +| 键盘控制 | P0 | ✅ 完成 | CGEvent + VK映射 | +| 光标同步 | P1 | ⏳ 待实现 | 显示当前光标类型 | +| 多显示器 | P2 | ⏳ 待实现 | 支持多屏幕选择 | + +### 1.3 参考实现 + +- **Linux 客户端** (`linux/`): 架构相似,协议兼容 +- **RustDesk**: 成熟的跨平台远程桌面开源项目 +- **Sunshine**: 高性能游戏串流项目 + +--- + +## 2. 架构设计 + +### 2.1 目录结构(已实现) + +``` +YAMA/ +├── common/ # 跨平台共享(已有) +│ ├── commands.h # 协议定义 +│ └── ... +├── client/ # Windows 客户端(不动) +├── linux/ # Linux 客户端(不动) +└── macos/ # macOS 客户端(Phase 1 完成) + ├── CMakeLists.txt # 构建配置 + ├── build.sh # 一键编译脚本 + ├── README.txt # 使用说明 + ├── IOCPClient.h # 网络客户端 stub + ├── main.mm # 入口点 + 系统信息 + ├── Permissions.h # 权限检查声明 + ├── Permissions.mm # 权限检查实现 + ├── ScreenHandler.h # 屏幕捕获声明 + ├── ScreenHandler.mm # 屏幕捕获实现 + ├── InputHandler.h # 输入模拟声明 + ├── InputHandler.mm # 输入模拟实现 + ├── SystemManager.h # 进程管理声明 + └── SystemManager.mm # 进程管理实现 +``` + +### 2.2 模块依赖关系 + +``` +┌─────────────────────────────────────────────────┐ +│ main.mm │ +│ (入口、权限检查、系统信息收集) │ +└─────────────┬───────────────────────────────────┘ + │ + ┌─────────┼─────────┬─────────────┐ + ▼ ▼ ▼ ▼ +┌───────┐ ┌───────┐ ┌───────┐ ┌────────────┐ +│Screen │ │Input │ │System │ │IOCPClient │ +│Handler│ │Handler│ │Manager│ │(网络 stub) │ +└───┬───┘ └───┬───┘ └───────┘ └────────────┘ + │ │ + ▼ ▼ +┌─────────────────────────────────┐ +│ macOS 系统框架 │ +│ CoreGraphics (截屏) │ +│ Carbon (键码定义) │ +│ ApplicationServices (权限) │ +└─────────────────────────────────┘ +``` + +--- + +## 3. 技术选型 + +### 3.1 屏幕捕获方案(已选定) + +| 方案 | 最低版本 | 性能 | 复杂度 | 选择 | +|-----|---------|------|--------|-----| +| `CGDisplayCreateImage` | 10.5 | 中 | 低 | **✅ 已采用** | +| `CGDisplayStream` | 10.8 | 中 | 中 | 备选 | +| `ScreenCaptureKit` | 12.3 | 高 | 高 | 未来考虑 | + +**选择 CGDisplayCreateImage**: +- 实现简单,兼容性好 +- 与 Linux 端 `XGetImage` 方案一致 +- 足以支持 10-30 FPS 传输 + +### 3.2 输入模拟方案(已实现) + +| 功能 | API | 实现状态 | +|-----|-----|---------| +| 鼠标移动 | `CGEventCreateMouseEvent` | ✅ 完成 | +| 鼠标点击 | `CGEventCreateMouseEvent` | ✅ 完成 | +| 鼠标拖动 | `kCGEventLeftMouseDragged` | ✅ 完成 | +| 鼠标滚轮 | `CGEventCreateScrollWheelEvent` | ✅ 完成 | +| 键盘输入 | `CGEventCreateKeyboardEvent` | ✅ 完成 | +| 事件发送 | `CGEventPost(kCGHIDEventTap)` | ✅ 完成 | + +### 3.3 VK 键码映射(已实现) + +Windows VK 码到 macOS CGKeyCode 的完整映射: + +| 按键类型 | VK 范围 | macOS 映射 | +|---------|---------|-----------| +| 字母 A-Z | 0x41-0x5A | kVK_ANSI_A - kVK_ANSI_Z | +| 数字 0-9 | 0x30-0x39 | kVK_ANSI_0 - kVK_ANSI_9 | +| 小键盘 | 0x60-0x69 | kVK_ANSI_Keypad0 - 9 | +| F1-F12 | 0x70-0x7B | kVK_F1 - kVK_F12 | +| 方向键 | 0x25-0x28 | kVK_LeftArrow 等 | +| 修饰键 | 0x10-0x12 | kVK_Shift/Control/Option | +| Win 键 | 0x5B-0x5C | kVK_Command | + +### 3.4 差分算法(与 Linux 一致) + +| 算法 | ID | 说明 | +|-----|-----|------| +| ALGORITHM_GRAY | 0 | 灰度压缩 | +| ALGORITHM_DIFF | 1 | BGRA 差分 | +| ALGORITHM_H264 | 2 | 硬件编码(未实现)| +| ALGORITHM_RGB565 | 3 | RGB565 压缩 | + +### 3.5 macOS 版本支持 + +| 版本 | 代号 | 发布年份 | 支持状态 | +|-----|------|---------|---------| +| 10.13 | High Sierra | 2017 | ✅ 目标最低版本 | +| 10.14 | Mojave | 2018 | ✅ 支持 | +| 10.15 | Catalina | 2019 | ✅ 支持(需权限) | +| 11.x | Big Sur | 2020 | ✅ 支持 | +| 12.x | Monterey | 2021 | ✅ 支持 | +| 13.x | Ventura | 2022 | ✅ 支持 | +| 14.x | Sonoma | 2023 | ✅ 支持 | + +**注意**:macOS 10.15+ 需要用户授予屏幕录制权限。 + +--- + +## 4. 权限处理 + +### 4.1 所需权限 + +| 权限 | 用途 | 最低要求版本 | 授权方式 | +|-----|------|------------|---------| +| **屏幕录制** | 捕获屏幕内容 | 10.15 | 系统偏好设置 > 隐私 > 屏幕录制 | +| **辅助功能** | 模拟键盘/鼠标输入 | 所有版本 | 系统偏好设置 > 隐私 > 辅助功能 | + +### 4.2 权限检查实现(Permissions.mm) + +```objc +// 检查屏幕录制权限 +bool Permissions::checkScreenCapture() { + if (@available(macOS 10.15, *)) { + CGImageRef image = CGWindowListCreateImage( + CGRectMake(0, 0, 1, 1), + kCGWindowListOptionOnScreenOnly, + kCGNullWindowID, + kCGWindowImageDefault + ); + if (image == nil) return false; + CGImageRelease(image); + return true; + } + return true; // 10.15 之前不需要权限 +} + +// 检查辅助功能权限 +bool Permissions::checkAccessibility() { + return AXIsProcessTrusted(); +} + +// 请求辅助功能权限(弹出系统对话框) +void Permissions::requestAccessibility() { + NSDictionary *options = @{ + (__bridge id)kAXTrustedCheckOptionPrompt: @YES + }; + AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef)options); +} +``` + +### 4.3 权限引导流程 + +``` +程序启动 + │ + ▼ +检查屏幕录制权限 ──否──▶ 打开系统偏好设置 + │ + 是 + │ + ▼ +检查辅助功能权限 ──否──▶ 弹出授权对话框 + │ + 是 + │ + ▼ +正常运行 +``` + +--- + +## 5. 核心代码实现 + +### 5.1 ScreenHandler(已实现) + +```objc +// ScreenHandler.h +class ScreenHandler { +public: + ScreenHandler(); + ~ScreenHandler(); + + bool init(); // 初始化 + void start(IOCPClient* client, uint64_t id); // 开始捕获 + void stop(); // 停止捕获 + + int getWidth() const; + int getHeight() const; + + void sendBitmapInfo(); // 发送屏幕信息 + void onReceive(const uint8_t* data, size_t size); + void applyQualityLevel(int8_t level, bool persist); + +private: + bool captureScreen(std::vector& buffer); // 截屏 + void sendFirstScreen(); // 发送首帧 + void sendDiffFrame(); // 发送差分帧 + uint32_t compareBitmap(...); // 差分计算 + void convertBGRAtoGray(...); // 灰度转换 + void convertBGRAtoRGB565(...); // RGB565转换 + void captureLoop(); // 捕获循环 + + // 成员变量 + IOCPClient* m_client; + CGDirectDisplayID m_displayID; + BITMAPINFOHEADER_MAC m_bmpHeader; + std::vector m_prevFrame, m_currFrame; + std::atomic m_running; + std::atomic m_algorithm; + std::atomic m_maxFPS; +}; +``` + +### 5.2 InputHandler(已实现) + +```objc +// InputHandler.h +class InputHandler { +public: + InputHandler(); + ~InputHandler(); + + bool init(); // 初始化(检查权限) + void handleInputEvent(const MSG64_MAC* msg); // 处理输入事件 + bool hasAccessibilityPermission() const; + +private: + void handleMouseMove(int x, int y); + void handleMouseButton(CGMouseButton button, bool down, int x, int y); + void handleMouseDoubleClick(CGMouseButton button, int x, int y); + void handleMouseWheel(int delta); + void handleKeyEvent(uint32_t vkCode, bool down); + + static CGKeyCode vkToMacKeyCode(uint32_t vk); // VK 到 macOS 键码映射 + + bool m_hasPermission; + CGPoint m_lastMousePos; + bool m_leftButtonDown, m_rightButtonDown, m_middleButtonDown; +}; +``` + +### 5.3 SystemManager(已实现) + +```objc +// SystemManager.h +class SystemManager { +public: + SystemManager(IOCPClient* client, uint64_t clientID); + ~SystemManager(); + + void onReceive(const uint8_t* data, size_t size); + +private: + void sendProcessList(); // 进程列表 + void killProcesses(const uint8_t* data, size_t size); + void sendWindowsList(); // 窗口列表 + + static std::vector getAllPids(); // 枚举进程 + static std::string getProcessName(pid_t pid); + static std::string getProcessPath(pid_t pid); +}; +``` + +### 5.4 main.mm(已实现) + +主要功能: +- 命令行参数解析 +- 权限检查和引导 +- 系统信息收集(主机名、OS版本、CPU、内存等) +- 初始化各处理器 +- 主事件循环 + +```objc +int main(int argc, const char* argv[]) { + @autoreleasepool { + // 1. 解析命令行参数 + // 2. 检查权限 + // 3. 收集系统信息 + // 4. 初始化 ScreenHandler, InputHandler + // 5. 主循环 + } + return 0; +} +``` + +--- + +## 6. 构建配置 + +### 6.1 CMakeLists.txt + +```cmake +cmake_minimum_required(VERSION 3.15) +project(ghost_macos) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13") +set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64") # Universal Binary + +set(SOURCES + main.mm + ScreenHandler.mm + InputHandler.mm + SystemManager.mm + Permissions.mm +) + +add_executable(ghost ${SOURCES}) + +target_include_directories(ghost PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + +# 链接 macOS 框架 +find_library(COCOA_FRAMEWORK Cocoa REQUIRED) +find_library(COREGRAPHICS_FRAMEWORK CoreGraphics REQUIRED) +find_library(IOKIT_FRAMEWORK IOKit REQUIRED) +find_library(IOSURFACE_FRAMEWORK IOSurface REQUIRED) +find_library(APPLICATIONSERVICES_FRAMEWORK ApplicationServices REQUIRED) +find_library(SECURITY_FRAMEWORK Security REQUIRED) +find_library(CARBON_FRAMEWORK Carbon REQUIRED) + +target_link_libraries(ghost PRIVATE + ${COCOA_FRAMEWORK} + ${COREGRAPHICS_FRAMEWORK} + ${IOKIT_FRAMEWORK} + ${IOSURFACE_FRAMEWORK} + ${APPLICATIONSERVICES_FRAMEWORK} + ${SECURITY_FRAMEWORK} + ${CARBON_FRAMEWORK} +) + +target_compile_options(ghost PRIVATE -Wall -Wextra -fobjc-arc) +``` + +### 6.2 编译命令 + +```bash +# 方式 1: 使用脚本 +chmod +x build.sh +./build.sh + +# 方式 2: 手动编译 +mkdir build && cd build +cmake .. +make -j$(sysctl -n hw.ncpu) + +# 输出: build/bin/ghost +``` + +--- + +## 7. 实现进度 + +### Phase 1: 基础框架 ✅ 完成 + +| 任务 | 状态 | 产出 | +|-----|------|------| +| 创建目录结构 | ✅ | `macos/` 目录 | +| CMakeLists.txt | ✅ | 构建配置 | +| Permissions.h/mm | ✅ | 权限检查 | +| ScreenHandler.h/mm | ✅ | 屏幕捕获 | +| InputHandler.h/mm | ✅ | 输入模拟 | +| SystemManager.h/mm | ✅ | 进程管理 | +| main.mm | ✅ | 入口点 | +| IOCPClient.h | ✅ | 网络 stub | + +### Phase 2: 网络集成 ⏳ 待实现 + +| 任务 | 状态 | 说明 | +|-----|------|------| +| IOCPClient 实现 | ⏳ | 复用 client/IOCPClient | +| 登录信息发送 | ⏳ | LOGIN_INFOR 结构 | +| 心跳保活 | ⏳ | Heartbeat 机制 | +| 命令分发 | ⏳ | DataProcess 回调 | + +### Phase 3: 功能完善 ⏳ 待实现 + +| 任务 | 状态 | +|-----|------| +| 光标类型同步 | ⏳ | +| 多显示器支持 | ⏳ | +| 文件传输 | ⏳ | +| 剪贴板同步 | ⏳ | + +### Phase 4: 代码保护 ⏳ 待实现 + +| 任务 | 状态 | +|-----|------| +| 服务端密钥对生成 | ⏳ | +| 服务端签名逻辑 | ⏳ | +| 闭源库 libYamaCore | ⏳ | +| 客户端绑定验证 | ⏳ | + +--- + +## 8. 测试指南 + +### 8.1 编译前准备 + +```bash +# 安装 Xcode Command Line Tools +xcode-select --install + +# 安装 CMake (通过 Homebrew) +brew install cmake +``` + +### 8.2 编译运行 + +```bash +# 获取代码 +git clone +cd YAMA/macos + +# 编译 +./build.sh + +# 运行 +./build/bin/ghost [server_ip] [port] +``` + +### 8.3 首次运行权限授予 + +1. **屏幕录制权限**: + - 系统偏好设置 > 隐私与安全性 > 屏幕录制 + - 添加 `ghost` 可执行文件 + +2. **辅助功能权限**: + - 系统偏好设置 > 隐私与安全性 > 辅助功能 + - 添加 `ghost` 可执行文件 + +### 8.4 预期输出 + +``` +=== macOS Ghost Client (Phase 1) === +Server: 192.168.0.55:6543 +Checking permissions... +Collecting system information... +Hostname: MacBook-Pro.local +OS: macOS 14.0.0 +CPU: Apple M1 (0 MHz, 8 cores) +Memory: 16.0 GB +User: username +Resolution: 1:2560x1600 +Executable: /path/to/ghost +Start Time: 2024-04-29 12:00:00 +Initializing handlers... +Screen handler initialized: 2560x1600 +Input handler initialized +=== Phase 1 Status === +Screen Capture: READY +Input Control: READY +Network: STUB (Phase 2) +====================== +Starting main loop (Ctrl+C to exit)... +``` + +--- + +## 9. 常见问题 + +### 9.1 编译问题 + +| 问题 | 原因 | 解决方案 | +|-----|------|---------| +| 找不到 Foundation.h | 缺少 Xcode CLT | `xcode-select --install` | +| CMake 找不到 | 未安装 CMake | `brew install cmake` | +| 架构不匹配 | Universal Binary 问题 | 检查 CMAKE_OSX_ARCHITECTURES | + +### 9.2 运行时问题 + +| 问题 | 原因 | 解决方案 | +|-----|------|---------| +| 程序无法打开 | 未签名 | `xattr -d com.apple.quarantine ghost` | +| Screen Capture: NEED PERMISSION | 无录屏权限 | 系统偏好设置授权 | +| Input Control: NEED PERMISSION | 无辅助功能权限 | 系统偏好设置授权 | + +### 9.3 权限重置 + +```bash +# 如果权限状态混乱,可重置 +tccutil reset ScreenCapture +tccutil reset Accessibility +``` + +--- + +## 10. 代码保护机制(待实现) + +### 10.1 保护策略 + +核心思路:客户端内嵌服务端公钥,连接时验证服务端身份。 + +``` +┌─────────────────────┐ ┌─────────────────────┐ +│ macOS Client │ │ Your Server │ +│ │ 1. 挑战请求 │ │ +│ ┌─────────────────┐ │ ─────────────────▶ │ ┌─────────────────┐ │ +│ │ libYamaCore.a │ │ │ │ 服务端私钥 │ │ +│ │ (闭源) │ │ ◀───────────────── │ │ │ │ +│ │ 内嵌服务端公钥 │ │ 2. 签名响应 │ └─────────────────┘ │ +│ │ │ │ │ │ +│ │ 验证签名 ─────▶ 匹配 ──▶ 正常工作 │ +│ │ ─────▶ 不匹配 ──▶ 拒绝连接 │ +│ └─────────────────┘ │ │ │ +└─────────────────────┘ └─────────────────────┘ +``` + +### 10.2 实施步骤 + +1. 生成服务端密钥对 +2. 服务端添加签名逻辑 +3. 创建闭源库 libYamaCore +4. 嵌入公钥编译 +5. 客户端集成验证 + +--- + +## 11. 参考资料 + +### 11.1 官方文档 + +- [CGDisplayCreateImage](https://developer.apple.com/documentation/coregraphics/1454434-cgdisplaycreateimage) +- [CGEvent Reference](https://developer.apple.com/documentation/coregraphics/cgevent) +- [Carbon Events.h](https://developer.apple.com/documentation/carbon/events_h) +- [Accessibility API](https://developer.apple.com/documentation/applicationservices/axuielement_h) + +### 11.2 开源项目参考 + +- [RustDesk macOS](https://github.com/rustdesk/rustdesk/tree/master/src/platform/macos) +- [Sunshine Screen Capture](https://github.com/LizardByte/Sunshine/tree/master/src/platform/macos) + +--- + +## 12. 修订历史 + +| 日期 | 版本 | 修改内容 | +|-----|------|---------| +| 2026-04-28 | 1.0 | 初始版本(设计文档) | +| 2026-04-29 | 1.1 | 更新为实现文档,Phase 1 完成 |