news 2026/11/3 10:22:43

Playport安全边界设计揭秘:宿主Steam会话与游戏内会话如何彻底隔离

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Playport安全边界设计揭秘:宿主Steam会话与游戏内会话如何彻底隔离

【免费下载链接】playport

Playport runs Windows games, 64-bit and now 32-bit, on a stock, non-jailbroken iPhone. Install a game from your library onto the phone, pick up a controller and press Play. The game runs on the phone's own CPU and GPU: no PC, no cloud, no stream.

项目地址:https://gitcode.com/gh_mirrors/pl/playport
点击查看免费下载

Playport 是一款让 Windows 游戏(64 位与 32 位)原生运行在普通 iPhone 上的工具:无需电脑、云端或串流,游戏直接跑在手机自己的 CPU 和 GPU 上。而在它的设计里,安全边界是核心关键词之一——Playport 的宿主 Steam 会话(你在手机上登录的那个 Steam 账号)与游戏内会话(Guest 中 Windows 客户端的会话)被刻意设计成两个彼此隔离的世界:宿主的任何 Steam 凭据默认都永远不会进入游戏。

为什么隔离是Playport安全设计的难题

先理解一个前提:Playport 里"宿主"和"游戏"并不是两堵墙隔开的两个世界。

按照 ARCHITECTURE.md 的描述,宿主 App、运行时(Wine + FEX 翻译器)和每一个 Guest 二进制文件运行在同一个进程里,共享同一个地址空间、同一个容器、同一组 Keychain 权限。这意味着进程内不存在传统的"边界",任何 Guest 侧代码理论上都能读到进程内存里的任何东西。

正是这个现实,逼出了 0004: Steam session boundary 这条最硬的设计决策:

  • 宿主的 native Steam 客户端(app/SteamClient/)与 Guest 里运行的任何 Steam 客户端,是两个互不相通的会话;
  • 没有任何宿主 Steam 秘密会被传进 Guest:refresh token、access token、QR 登录素材、机器/会话绑定、CDN token、depot key,都不行;
  • 堵住的通道也是全的:prefix 文件、环境变量、注册表、命令行参数、IPC、共享内存,乃至 wine_host 的 C ABI 接口——这个 ABI 里根本没有"携带凭据"的参数。

一句话概括:Guest 客户端要玩,请自己登录;拿宿主账号的钥匙去开门,这条路从设计上就不存在。

宿主一侧如何守住秘密:5条基线

0004 不只说"不传",还把"宿主自己怎么防漏"写成了可检查的规则:

防线做法
存储位置宿主秘密只存 Keychain:generic-password 条目、ThisDeviceOnly、不可同步;App 容器里一个字节都没有
内存形态秘密以Secret<T>持有,打印出来是<redacted>
日志脱敏每行日志都过一遍 scrubber,过滤 JWT、QR URL、query string、bearer 值和主目录路径
启动模式传递 Steam 命令的启动方式不在环境里放任何秘密,设备驱动会逐条检查日志转录
登出向 Steam 撤销 token,删除 Keychain 条目和缓存账号数据,游戏与存档保留

同时还有一个"休眠规则":游戏运行期间,宿主的 Steam 会话不做任何 Steam 工作——CM(Game Coordinator)连接在运行时启动前就关闭,唯一的例外见下一节。

三条受控通道:哪些"凭据"可以进游戏

绝对隔离会让在线游戏没法登录自家服务器。所以 Playport 为"游戏应该从商店拿到什么"开了三条受控例外,每一条都有独立的决策记录,并必须回答同一个五问:针对哪个秘密、唯一通道是什么、Guest 侧存储量是否实测、登出是否清除所有副本、撤销是否让 Guest 拿到的也失效。

1)加密 App Ticket:一条会自己消失的 ini 行

见 0017: An encrypted app ticket enters the guest。

  • 点击 Play 后,宿主为即将启动的那一款游戏向 Steam 申请一张加密 App Ticket,写入游戏配置steam_settings/configs.user.ini的ticket=<base64>一行;游戏退出(或下次启动、下次 App 启动、登出时)该行即被删除。
  • 这张票用发行商的密钥加密,Playport 自己都读不懂;游戏把它发给自家服务器,用于在线账号、跨平台登录与防盗版校验。
  • 小偷最多能做到的,是拿这张票冒充"你玩这一款游戏",直到服务器不再接受它;拿不到 Steam 账号本身。
  • 真机实测(证据):玩完两轮后搜索整个容器,除 ini 那一行外没有任何文件留下 ticket 的痕迹。

2)游戏运行中的"活着的"Steam 会话:只发 ticket,别的都拒绝

见 0062: A live Steam session during play,这是 0004 休眠规则的唯一口子。

游戏运行期间,宿主保持登录的 CM 连接只为一件事:像 Steam 客户端那样替游戏制作两类票据——auth session ticket(GetAuthSessionTicket)和 web API ticket(GetAuthTicketForWebApi)。除此之外,安装、PICS、资料、云存档、登录等一切 Steam 调用在游戏运行期间全部拒绝。

跨进 Guest 的只有:票据的字节、一个句柄和一个状态。不是 token,不是 SteamID,也不是别款游戏的票据。

这条通道的工程细节很能说明"最小化"的思路:

  • 唯一通道:一张 Wine unix call table playport_steam_unix_call_funcs(协议定义见 steam_ticket_protocol.h),由 steam_ticket_provider 挂在 ABI 上,Steam API 模拟器(gbe 补丁 0006)通过它请求。数据块定长、无指针、逐个校验 magic 与 size。
  • 配额由宿主定死:仅限被启动的那款 App;最多 8 张存活票据;每张间隔至少 2 秒、同时 4 张;Steam 自身的 token 供给上限再兜一层底。
  • 收尾:CancelAuthTicket可单独取消;一局结束时(1 秒内)发送空票据列表和空ClientGamesPlayed;崩溃或进程被杀,socket 随进程一起消亡。
  • 日志只记句柄、类型和大小,永不记录票据字节、token、identity 或 SteamID。

对照 0004 的五问,0062 逐条作答:威胁模型✅、单一通道✅、Guest 侧存储实测✅(票据只活在游戏内存,容器里搜不到票据头)、登出清副本✅(宿主只在内存持有票据,游戏结束后进程重启)、撤销同样作废 Guest 的✅(取消、局终、会话终止都会结束票据)。

3)GOG 与 Epic 游戏的同构例外

Steam 之外,Playport 为其他商店开了结构相同、范围同样收紧的例外:

  • GOG(0063):宿主在游戏运行期间扮演"本地 Galaxy 服务",监听127.0.0.1:9977,只签发限定在该游戏 client ID 范围内的 refresh token;成就、统计、排行榜由宿主代答。跨界的秘密仅此一项,游戏结束监听即停。
  • Epic(0059):宿主在 Play 后换取一个一次性、5 分钟有效的 exchange code(以及需要时的 ownership token),像 Epic 启动器一样放在游戏命令行旁。任何 Epic token(eg1)都不进 Guest。

清理与撤销:让秘密"活不过一局"

隔离不只是"少给",还包括"给过的要收回来"。Playport 的清理策略可以总结为四条:

  1. 行级清除:加密 App Ticket 的 ini 行在游戏退出、下次启动、下次 App 启动、登出时删除;
  2. 内存即终点:0062 的票据宿主侧只在内存持有,不落盘、不进 Keychain;
  3. 进程即墓碑:一局游戏结束后 Playport 会重启运行时进程(0029: restart after each game),崩溃或被杀同样让 socket 与内存票据一起消亡;
  4. 日志即审计:票据的字节、token、SteamID 永不入日志,Redactor会连日志里残留的ticket=值一起抹掉,pp secrets检查还能拦截提交中"长得像真票据"的行。

残余风险:设计者自己承认了什么

诚实的安全文档不假装没有洞。0004 明确写下:一个敌意的 Guest 二进制可以读到进程能读的一切,包括内存中正在使用的宿主 token。0062 进一步指出,存活的 CM 连接意味着理论上 Guest 里的原生代码可以"驱动"这条已登录连接。

缓解方式不是假装边界存在,而是收窄范围:

  • 只运行你拥有的游戏与真正的客户端(正版库 + 商店登录本身就是筛选器);
  • 宿主 token 只在"使用中"的短暂窗口里存在于内存;
  • 每条例外通道的爆炸半径都被压到最小——一张票只对应一款游戏、一个玩家、有限寿命。

换句话说:Playport 的安全模型不是"把恶客关在门外",而是"门外根本不放值得偷的东西"。

延伸阅读:决策记录与源码路径

Playport 把这类安全决策都沉淀为编号的 decision record(docs/decisions/),新手可以从这几份入手:

主题文档
会话隔离总纲0004-steam-session-boundary.md
加密 App Ticket0017-encrypted-app-ticket.md
局中活会话与票据0062-steam-live-session.md
GOG Galaxy 登录0063-gog-galaxy-sign-in.md
Epic 交换码0059-epic-exchange-code.md
每局之后重启0029-restart-after-each-game.md

关键源码:票据宿主侧实现 steam_ticket.c、协议 steam_ticket_protocol.h、宿主 ABI 声明 wine_host.h、宿主 Steam 客户端 app/SteamClient/(Kit 位于 app/SteamClient/)。

总结

  • Playport 用"一个进程、没有进程内边界"的现实,倒逼出"宿主秘密永不进 Guest"的硬规则,并从 Keychain 存储、日志脱敏到 ABI 设计逐层落实;
  • 三条受控例外(加密 App Ticket、局中票据、GOG/Epic 登录)各自有独立威胁模型、单一通道和清理路径,爆炸半径压到"一款游戏、一局游戏";
  • 票据类秘密"活不过一局":ini 行会删、内存票据随进程重启消亡、日志只留句柄;
  • 残余风险被如实记录,缓解手段是范围控制而非虚构的墙。

【免费下载链接】playport

Playport runs Windows games, 64-bit and now 32-bit, on a stock, non-jailbroken iPhone. Install a game from your library onto the phone, pick up a controller and press Play. The game runs on the phone's own CPU and GPU: no PC, no cloud, no stream.

项目地址:https://gitcode.com/gh_mirrors/pl/playport
点击查看免费下载

相关推荐

上一篇:郑希vs葛兰:用zhengxi-views对比全市场2.7万只基金的实战教程
下一篇:labelme 图像标注工具:快速完成目标检测、语义分割与图像级打标

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/3 10:21:55

grpcurl 命令行工具快速上手:gRPC 接口测试与调试实用指南

grpcurl 命令行工具快速上手&#xff1a;gRPC 接口测试与调试实用指南 【免费下载链接】grpcurl Like cURL, but for gRPC: Command-line tool for interacting with gRPC servers 项目地址: https://gitcode.com/gh_mirrors/gr/grpcurl gRPC 服务在网络上使用 protobuf…

作者头像 李华
网站建设 2026/11/3 10:19:06

3 步快速显示鼠标坐标:AutoHotkey 热键获取指南

3 步快速显示鼠标坐标&#xff1a;AutoHotkey 热键获取指南 【免费下载链接】AutoHotkey AutoHotkey - macro-creation and automation-oriented scripting utility for Windows. 项目地址: https://gitcode.com/gh_mirrors/au/AutoHotkey 需要精确记录屏幕上某一点的坐…

作者头像 李华
网站建设 2026/11/3 10:16:26

常用虚机模式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/11/3 10:10:49

告别ROS的繁琐, 易用易学的机器人学习系统: 华为诺亚面向机器人学习的开源Python框架

在近些年之中, 机器人技术于硬件范畴达成了显著的突破, 不管是DARPA机器人挑战赛, 又或是首届人形机器人自由搏击表演&#xff0c;均呈现出了令人刮目相看的进展。然而, 机器人的自主能力依旧明显地落后于机器学习的发展脚步。造成这一差距的关键瓶颈处于软件层面, 现有机器人技…

作者头像 李华