恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Atmosphere sm 模块深度解析:Horizon 服务管理器的重实现与扩展 IPC 接口
首页
资讯中心
/
Atmosphere sm 模块深度解析:Horizon 服务管理器的重实现与扩展 IPC 接口
Atmosphere sm 模块深度解析:Horizon 服务管理器的重实现与扩展 IPC 接口
发布时间:2026/9/13 11:26:48
Atmosphere sm 模块深度解析Horizon 服务管理器的重实现与扩展 IPC 接口【免费下载链接】AtmosphereAtmosphère is a work-in-progress customized firmware for the Nintendo Switch.项目地址: https://gitcode.com/GitHub_Trending/at/Atmosphere导读smService Manager是 Horizon OS 中负责系统服务注册、查询与分发的核心系统模块——所有进程通过它获取服务句柄、注册新服务。Atmosphère 在 stratosphere/sm 下完整重实现了这一模块并在此基础上追加了调试监视接口sm:dmnt与三类扩展 IPC 命令sm:用户服务扩展、sm:m管理服务扩展其中 MitM中间人命令构成了整个 Atmosphère 系统模块拦截框架的基石。读完本文你将掌握sm模块的端口架构与内部状态机、每条扩展命令的语义与源码级实现、以及如何基于 libstratosphere 的客户端 API 编写自己的 MitM 模块。一、模块定位服务管理器做了什么在 Horizon 系统里sm扮演着服务注册中心的角色进程侧客户端调用GetServiceHandle按服务名ServiceName最长 8 字符见 sm_types.hpp拿到服务端口句柄服务侧宿主通过RegisterService把命名端口注册进系统供其他进程连接。Atmosphère 的 sm.md 明确将其定义为a reimplementation of the Horizon OSssmsystem module。作为系统模块其构建元数据在 sm.json 中体现得相当典型配置项值说明title_id0x0100000000000004系统模块固定 Title IDmain_thread_priority27主线程优先级process_category1系统进程类别immortaltrue不可退出进程见 sm_main.cppExit直接AMS_ABORTuse_secure_memorytrue使用安全内存handle_table_size512句柄表容量主循环出奇地精简——sm_main.cpp 只有三步设置线程名 →InitializeTipcServer()初始化服务器 →LoopProcessTipcServer()永久循环分发请求。真正的复杂度全部集中在服务管理器的内部实现中。二、端口架构sm:与sm:m双端口重实现通过TIPC轻量进程间通信服务器提供两个端口见 sm_tipc_server.cppenum PortIndex : size_t { PortIndex_Manager, PortIndex_User, PortIndex_Count, }; constexpr inline size_t MaxSessionsManager 1; constexpr inline size_t MaxSessionsUser 0x50 8 - MaxSessionsManager;端口服务接口会话上限分配策略sm:UserService0x5787 个SlabAllocatorslab 池sm:mManagerService1SingletonAllocator单例其中sm:通过svc::ManageNamedPort创建命名端口sm:m则由模块自己调用impl::RegisterServiceForSelf注册sm_tipc_server.cpp这样本模块也能作为普通服务被系统查询到。接口的 TIPC 定义宏分别位于 sm_user_interface.hpp 与 sm_manager_interface.hpp。值得注意的是由于官方 12.0.0 起sm改为多线程处理却缺乏互斥保护Atmosphère 的实现使用os::SdkRecursiveMutex g_mutex对所有全局状态访问加锁sm_service_manager.cpp避免并发访问竞态。三、内部状态四张表与容量上限服务管理器的全部状态集中在 sm_service_manager.cpp 的常量与全局表中全局表常量含义g_process_listProcessCountMax 0x50注册的进程信息进程 ID、程序 ID、Override 状态、访问控制 SACg_service_listServiceCountMax 0x180已注册服务名称、宿主进程、端口句柄、是否 light、会话数、MitM 索引g_future_mitm_listMitmCountMax 0x20“未来 MitM” 预声明g_mitm_listMitmCountMax 0x20已安装的 MitM端口、查询句柄、转发句柄、等待确认状态访问控制缓冲区AccessControlSizeMax 0x200每个进程 SAC 上限访问控制SAC校验是服务安全的根基每个非初始进程注册时必须提交acid_sac限制与aci_sac允许两份访问控制表RegisterProcess会校验aci_sac的每一项都被acid_sac允许sm_service_manager.cpp。条目编码支持精确匹配与通配符模糊匹配IsWildcard()检测尾部*并区分 host可注册服务与 client可获取服务权限ValidateAccessControl。获取/注册服务时非初始进程必须通过对应权限校验否则返回sm::ResultNotAllowed()。服务名本身也有合法性约束首字符非空、结尾之后必须全零见 ValidateServiceName。四、扩展 IPC 命令sm:用户服务接口原文档 sm.md 给出的sm:扩展 SwIPC 定义如下这是 Atmosphère 为所有用户态进程开放的扩展面interface ams::sm::UserService is sm: { ... [65000] AtmosphereInstallMitm(ServiceName service) - sf::OutMoveHandle srv_h, sf::OutMoveHandle qry_h; [65001] AtmosphereUninstallMitm(ServiceName service); [65002] Deprecated_AtmosphereAssociatePidTidForMitm(); [65003] AtmosphereAcknowledgeMitmSession(ServiceName service) - sf::OutMitmProcessInfo client_info, sf::OutMoveHandle fwd_h; [65004] AtmosphereHasMitm(ServiceName service) - sf::Outbool out; [65005] AtmosphereWaitMitm(ServiceName service); [65006] AtmosphereDeclareFutureMitm(ServiceName service); [65100] AtmosphereHasService(ServiceName service) - sf::Outbool out; [65101] AtmosphereWaitService(ServiceName service); }对应到 sm_user_service.hpp 中每个命令的处理函数命令号与 IUserInterface 宏一一对应。逐条语义如下4.1 MitM 生命周期命令65000–65006命令号命令行为65000AtmosphereInstallMitm为已存在的服务安装 MitM返回两个句柄srv_hMitM 服务端口截获新连接与qry_h查询会话用于询问“本次会话是否应被截获”。若目标服务尚未注册请求会被延迟返回tipc::ResultRequestDeferred直到服务出现65001AtmosphereUninstallMitm卸载 MitM仅允许 MitM 宿主进程操作校验mitm_info-process_id process_id65002Deprecated_AtmosphereAssociatePidTidForMitm已废弃占位命令TIPC 定义中未再出现见 sm_user_interface.hpp65003AtmosphereAcknowledgeMitmSession确认一次被截获的会话返回发起方进程的MitmProcessInfo与转发句柄fwd_h指向原服务的真实会话并解除对该服务的延迟65004AtmosphereHasMitm查询某服务当前是否安装有 MitM65005AtmosphereWaitMitm阻塞式等待服务尚无 MitM 时返回ResultRequestDeferred待安装完成后重试65006AtmosphereDeclareFutureMitm未来 MitM 预声明在目标服务注册之前就声明将拦截它服务一注册请求即被延迟等待 MitM 就位避免竞态MitmProcessInfo的结构定义在 sm_types.hpp包含process_id、program_id与cfg::OverrideStatus并被静态断言为 0x20 字节的平凡结构。4.2 服务查询命令65100–65101AtmosphereHasService65100查询服务是否已注册内部先做ValidateServiceName再查g_service_listsm_service_manager.cppAtmosphereWaitService65101服务未注册时返回ResultRequestDeferred注册后由TriggerResume唤醒重试sm_service_manager.cpp。这两个命令是 libstratosphere 中sm::WaitService一类同步原语的底层支撑常用于系统模块间启动顺序协调。五、扩展 IPC 命令sm:m管理服务接口sm:m由ManagerServicesm_manager_service.hpp实现仅向系统管理方开放 1 个会话。原文档给出的扩展定义interface ams::sm::ManagerService is sm:m { ... [65000] AtmosphereEndInitDefers(os::ProcessId process_id, sf::InBuffer acid_sac, sf::InBuffer aci_sac); [65001] AtmosphereHasMitm(ServiceName service) - sf::Outbool out; [65002] AtmosphereRegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, cfg::OverrideStatus override_status, sf::InBuffer acid_sac, sf::InBuffer aci_sac); }结合 sm_manager_interface.hpp 的 TIPC 定义逐条解析命令号命令行为65000AtmosphereEndInitDefers结束初始化延迟期。参见下文“延迟机制”65001AtmosphereHasMitm与sm:同名命令等价的管理侧查询65002AtmosphereRegisterProcess注册进程的增强版相比官方RegisterProcess仅进程 ID 两份 SAC额外携带ncm::ProgramId与cfg::OverrideStatus。这两份附加信息被存入ProcessInfo并在 MitM 会话确认时通过MitmProcessInfo回传给 MitM 模块sm_manager_service.hpp注意文档中sm:m的 65000 命令签名带参数而当前仓库 sm_manager_interface.hpp 中该命令已改为无参void AtmosphereEndInitDefers()实现sm_service_manager.cpp也只是翻转g_ended_initial_defers标志并刷新 hos 版本。这正是“实现随版本演进”的实例以仓库现状为准。六、MitM 机制的核心原理MitM 是 Atmosphère 系统模块框架ams_mitm、fs_mitm、dns_mitm等赖以工作的关键。以 InstallMitm 实现 为例完整流程如下校验服务必须已注册未被其他进程 MitMg_mitm_list中有空位预声明若尚无未来声明先AddFutureMitmDeclaration失败时回滚清理创建端口以原服务相同的max_sessions、is_light重新创建一对端口port_hnd归 MitM 使用hnd作为srv_h返回给调用方创建查询会话svc::CreateSession生成qry_hnd返回给 MitM 进程与mitm_qry_hnd服务管理器留存登记填充MitmInfo与ServiceInfo::mitm_indexTriggerResume唤醒可能被延迟的请求。此后当某客户端GetServiceHandle命中被 MitM 的服务且不是 MitM 宿主自身时GetServiceHandleImpl先通过查询会话向 MitM 发送命令65000serviceDispatchInOut(..., 65000, client_info, should_mitm)见 sm_service_manager.cpp询问“是否截获此客户端”若 MitM 回复“不截获”直接连接原服务端口若回复“截获”则同时建立转发会话连向原服务与MitM 会话连向 MitM 端口并置waiting_ack状态——此后对同一服务的连接请求会暂时延迟直到 MitM 调用AtmosphereAcknowledgeMitmSession取走fwd_h并解除延迟AcknowledgeMitmSession。被禁止 MitM 的程序实现中通过硬编码的IsMitmDisallowedsm_service_manager.cpp禁止对以下程序安装 MitM否则会阻碍启动流程Loader、Pm、Spl、Boot、Ncm、ams::Mitm、Creport源码注释也坦言该名单是“需要设计思考的硬编码方案”。客户端 APIlibstratosphere 为模块开发者封装了完整客户端接口见 sm_mitm_api.hpp仅在AMS_SF_MITM_SUPPORTED时可用实现位于 sm_mitm_api.cppnamespace ams::sm::mitm { Result InstallMitm(os::NativeHandle *out_port, os::NativeHandle *out_query, ServiceName name); Result UninstallMitm(ServiceName name); Result DeclareFutureMitm(ServiceName name); Result ClearFutureMitm(ServiceName name); Result AcknowledgeSession(Service *out_service, MitmProcessInfo *out_info, ServiceName name); Result HasMitm(bool *out, ServiceName name); Result WaitMitm(ServiceName name); }典型 MitM 模块的启动套路即为DeclareFutureMitm可选抢占竞态→InstallMitm获取端口与查询会话 → 循环WaitMitm/接收查询 → 对每个被截获会话AcknowledgeSession拿到转发句柄与原进程信息 → 在自己的Service上处理请求、必要时转发到fwd_h。七、初始化延迟机制规避 FS 启动缺陷AtmosphereEndInitDefers对应的内部机制定义在 sm_service_manager.cppconstexpr const sm::ServiceName InitiallyDeferredServices[] { ServiceName::Encode(fsp-srv) };在sm:m收到AtmosphereEndInitDefers之前GetServiceHandle对名单内的服务当前为fsp-srv一律返回ResultRequestDeferred延迟处理ShouldDeferForInit。EndInitialDefers在翻转标志后会为名单内所有服务调用TriggerResume并刷新 hos 版本sm_service_manager.cpp。源码注释说明这是works around FS bug——通过延迟对fsp-srv的访问规避 FS 模块初始化时序上的缺陷且该机制可随需求扩展更多服务。八、调试监视接口sm:dmnt原文档 sm.md 记载Atmosphère 重实现额外提供sm:dmnt接口供调试监视器debug monitor查询服务管理器的运行状态。其 SwIPC 定义interface ams::sm::DmntService is sm:dmnt { [65000] AtmosphereGetRecord(ServiceName service) - sf::OutServiceRecord record; [65001] AtmosphereListRecords(u64 offset) - sf::OutArrayServiceRecord records, sf::Outu64 out_count; [65002] AtmosphereGetRecordSize() - sf::Outu64 record_size; }三个命令分别实现按名称查询单条服务记录AtmosphereGetRecord、从指定偏移批量列出记录AtmosphereListRecords返回数组与写入条数out_count、获取单条记录大小以便分配缓冲区AtmosphereGetRecordSize。这与变更日志 changelog.md 中 “An extension was added to sm, adding a newsm:dmntservice” 的记载一致为调试工具提供了只读的、结构化的服务表快照能力。九、向后兼容官方命令的 TIPC 化与 CMIF shim官方sm的命令集本身也以0–4号命令的形式存在于IUserInterfaceRegisterClient、GetServiceHandle、RegisterService、UnregisterService、DetachClient其中GetServiceHandle的完整路径为校验客户端已初始化 → 检查初始化延迟/未来 MitM/等待确认等延迟条件 → 按访问控制放行 → 依 MitM 状态返回原端口或 MitM 端口句柄GetServiceHandle。为兼容老式CMIF客户端大量 homebrew 系统模块仍使用旧 IPC 协议UserService::ProcessDefaultServiceCommandsm_user_service.cpp提供了硬编码消息头的 shim识别RegisterClient、GetServiceHandle、RegisterService、UnregisterService、DetachClient的 CMIF 请求并翻译为 TIPC 处理同时支持QueryPointerBufferSize控制命令与强制处理器延迟响应。源码注释明确说明Atmosphère 扩展命令不做 CMIF shim——扩展命令本身不保证向旧式 CMIF 客户端提供兼容sm_user_service.cpp。十、总结与延伸阅读Atmosphère 的sm重实现以双端口 TIPC 服务器为骨架、四张全局表 递归互斥锁为内核完整复刻官方服务管理语义访问控制、命名校验、延迟分发并叠加了三个层面的扩展服务查询扩展sm:65100/65101HasService/WaitServiceMitM 框架扩展sm:65000–65006、sm:m65001/65002安装、卸载、确认、等待、未来声明与进程注册增强调试接口sm:dmnt记录查询、列表与尺寸查询。想继续深入推荐按以下路径阅读仓库源码模块入口与服务器初始化stratosphere/sm/source/sm_main.cpp、stratosphere/sm/source/sm_tipc_server.cpp核心实现stratosphere/sm/source/impl/sm_service_manager.cpp接口定义libraries/libstratosphere/include/stratosphere/sm/impl/sm_user_interface.hpp、libraries/libstratosphere/include/stratosphere/sm/impl/sm_manager_interface.hpp客户端 MitM APIlibraries/libstratosphere/source/sm/sm_mitm_api.cpp构建配置stratosphere/sm/sm.json模块文档docs/components/modules/sm.md结合 ams_mitm 下fs_mitm、dns_mitm等实际模块的源码即可把本文的命令级知识落成可运行的拦截服务。【免费下载链接】AtmosphereAtmosphère is a work-in-progress customized firmware for the Nintendo Switch.项目地址: https://gitcode.com/GitHub_Trending/at/Atmosphere创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考