跳转至

注册表虚拟化

Sandboxie 不会维护宿主注册表的完整独立克隆。常规虚拟化把沙盒注册表更改与符合条件的宿主数据组合起来,利用注册表访问规则以及删除或重定位状态,构建应用程序所看到的视图。

SbieDll 负责主要的逻辑路径映射与受支持的合并操作。SbieDrv 提供独立的注册表过滤,并与 SbieSvc 一起管理沙盒配置单元的挂载生命周期。SandMan 负责配置这些机制;它本身不执行应用程序注册表合并。

注册表根与 RegHive

注册表挂载位置与其后备文件是两件不同的事:

位置 用途
KeyRootPath 挂载沙盒配置单元的注册表命名空间。
FileRootPath\RegHive 沙盒文件根之下的物理后备文件。

更改其中任一根本身不会自动迁移既有的沙盒内容。根配置与布局参见 沙盒根与卷布局。

由映像支撑的存储 可以改变承载沙盒文件根、因而也承载 RegHive 的物理存储,但 KeyRootPath 仍是配置单元被挂载到的注册表命名空间。

逻辑路径与沙盒注册表路径

应用程序继续使用逻辑的宿主风格注册表名称。Sandboxie 把对应的沙盒状态映射到已挂载的配置单元之下,例如:

\REGISTRY\MACHINE\Software\Vendor
    -> <KeyRootPath>\machine\Software\Vendor

HKLM 对应沙盒中的 machine 分支。对于 HKCU,宿主侧的当前用户 SID 对应沙盒中的 user\current 分支。文件系统里的 SeparateUserFolders 选项不会改变这一注册表映射。

HKCR 是 Windows 的 Classes 视图,并不是一个独立且统一的 Sandboxie 根。Windows 的 machine/每用户 Classes 合并,与 Sandboxie 沙盒侧的 Classes 映射,是两套不同的关系。沙盒自定义可以把沙盒配置单元内的 user\current\software\classes 链接到 user\current_classes。

读取与写入项

在常规虚拟化下,对仅存在于宿主的既有项的只读打开可以直接使用宿主项,而不必先创建对应的沙盒项。相反,创建操作即使请求的访问是读取导向的,也会创建沙盒侧的结构。

常规的创建与可写打开操作可以在沙盒配置单元内实体化相关层级,同时让宿主项保持不变。这不会克隆所有宿主值、整个宿主子树或完全相同的宿主安全描述符。宿主是否存在仍可能影响逻辑创建/打开的结果。

通过最初为读取宿主而打开的句柄写入一个值时,如果原生写入被拒绝,可以改为经沙盒的可写路径重试。这是有条件的处理,并不承诺每个失败的操作都会被重试。

合并的项与值

沙盒项可以只包含沙盒更改,而不是其宿主对应项的完整副本:

逻辑注册表项
    +-- 沙盒配置单元中的项与值
    +-- 符合条件的宿主项与值
    +-- 删除 / 重定位状态

这描述的是受支持的选定注册表数据操作,而不是所有注册表 API 共用的通用合成对象。

  • 仅存在于沙盒的值在沙盒视图中可见。
  • 仅存在于宿主、且符合条件、所选访问模式允许的值,仍然可见。
  • 合并结果中,同名的沙盒值优先。
  • 受支持的子项枚举可以合并宿主与沙盒的名称,并合并同名条目。
  • 可识别的删除状态可以抑制宿主项或值。

注册表查询取决于操作与信息类。有些返回已打开对象的原生信息,有些合成逻辑项名称,还有选定的完整/缓存信息由合并视图计算得出。枚举不是两层的一次原子快照,元数据也并非在每个 API 上都一致。

删除与重命名状态

注册表 V1 把删除标记存放在 RegHive 内部,项与值使用不同的标记。注册表 V2 使用沙盒文件根下的 RegPaths.dat,在常规沙盒注册表数据之外记录逻辑项/值的删除与项重定位状态。参见 虚拟化方案 V1 与 V2。

注册表 V2 提供了 Sandboxie 处理沙盒内项重命名所用的路径状态/重定位机制。这并不保证每次重命名都成功或具有原子性。V1 缺少该重定位机制,但这并不意味着每次原生重命名都会失败。

重建注册表内容可以让新的沙盒数据重新可见,但删除状态与元数据处理取决于 API,在 V2 下尤其如此。不要把重建当作对先前宿主视图的精确还原。

沙盒进程会加载 V2 的路径状态数据,并能检测到 RegPaths.dat 的部分后续更改。这些更新不应被视为事务性的、在所有进程间立即一致的或持久原子的。该文件是沙盒内容,不是供手工编辑的配置文件。

注册表访问模式

以下描述的是普通被挂钩访问所选择的模式:

生效模式 高层行为
标准 使用常规的沙盒注册表虚拟化与受支持的合并行为。
开放 对选定的规则直接使用宿主注册表。
对所有程序开放 使用同样的直连宿主模型,同时把沙盒内可执行文件也纳入适用范围。
封闭 当该模式获胜时,拒绝新的被挂钩注册表打开/创建。
读取 直接使用宿主注册表,同时生效的注册表过滤通常阻止修改宿主。
只写 / 仅沙盒内 隐藏常规的宿主数据,使用沙盒侧注册表状态。
标准覆盖 当标准规则获胜时,恢复正常虚拟化。

获胜的模式取决于进程选择器与资源规则匹配;参见 规则特异性。

普通的开放条目通常受“沙盒内可执行文件”资格限制。对所有程序开放会在该常规门之外加载,但它不会自动胜过其他规则,也不会绕过 Windows 权限。

对于新的被挂钩打开/创建,封闭会在常规沙盒复制路径之前被检查。因此沙盒副本不会自动使该打开免于封闭。已打开的句柄是另外一回事。

读取在 SbieDll 中选择直连宿主路径。在启用注册表过滤的标准沙盒中,其只读限制通常依赖驱动。禁用相关过滤会改变这一强制执行假设;原生 Windows 权限仍然适用。

只写 / 仅沙盒内并不意味着应用程序无法读取自己的沙盒侧数据。更具体的可访问后代仍可能依据规则匹配影响可见结构。

WOW64 注册表视图

Sandboxie 在构建沙盒对应项之前,先解析所选的 Windows 32/64 位注册表视图。规范路径可能包含 Wow6432Node,因此在适当的情况下它也会出现在沙盒侧路径中。并非每个注册表位置都有独立的 32 位与 64 位存储。

配置单元生命周期

在沙盒进程初始化期间,Sandboxie 会准备或访问 RegHive,把它挂载到 KeyRootPath,并把该进程与共享挂载关联。多个沙盒进程可以共享同一个配置单元。随着进程结束,引用被释放;当配置单元符合条件时,会协调卸载。

卸载不一定在最后一个进程退出后立即发生。忙状态、残留句柄、失败与生命周期选项都会影响它。损坏或无法加载的配置单元、根/后备关联冲突,或存储故障,都可能使注册表初始化失败或影响后续操作。挂载诊断参见 SBIE1241。

RegHive 与可用的 RegPaths.dat 作为沙盒注册表数据参与快照工作流。这与应用程序注册表操作所用的逻辑宿主/沙盒合并是分开的。

应用配置更改

  • 注册表访问规则列表按进程初始化。请重启受影响的沙盒进程树,以可靠地应用规则更改。
  • UseRegDeleteV2 在进程初始化时选定。更改后请重启受影响的进程;更改该设置并不是对已填充沙盒删除状态的就地转换。
  • KeyRootPath 作为沙盒/挂载上下文的一部分建立。更改前请停止受影响的沙盒进程;更改路径不会迁移 RegHive 或其内容。
  • 检测到后备文件变更后,RegPaths.dat 可能被重新加载,但不提供即时或有界的同步保证。

既有的注册表句柄继续引用它已经打开的对象和访问。配置更改不会普遍地重新定向或撤销它们。这些更改并不普遍要求重启 Windows、重启 SandMan 或重启服务。

安全边界

注册表虚拟化决定数据的呈现与存储。注册表规则选择、SbieDrv 过滤、Windows 安全描述符与进程令牌隔离是彼此独立的机制。合并视图本身并不是完整的宿主保护边界,RegHive 也不取代 Windows 访问检查。

应用程序隔离 可以保留注册表虚拟化而改变安全隔离。在该模式下,NoSecurityFiltering 可以禁用驱动的注册表过滤器;DisableKeyFilter 也可能影响该层。这不应被理解为禁用了所有 SbieDll 注册表挂钩。

开放规则有意在原生权限允许的地方允许直连宿主注册表。不得把标准模式的隔离假设套用到那些直连访问规则,或套用到禁用相关强制执行的配置上。

相关页面