Windows内核沙盒原理详解

1、什么是沙盒——sandbox介绍

沙盒也叫沙箱,英文sandbox,顾名思义可以看做是一种容器,里面所做的一切都可以推倒重来,军事上常用沙盒来进行一些战争区域的地形模拟在计算机领域指一种虚拟技术,它实际上是一种安全体系,且多用于计算机安全技术。其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中。当某个程序试图发挥作用时,安全软件可以先让它在沙盒中运行,如果含有恶意行为,则禁止程序的进一步运行,而这不会对系统造成任何危害。它也可以让进程之间被逻辑隔离,在沙盒中执行的程序不实际修改或防止被修改系统的数据内容,如注册表、硬盘数据等。通常这种技术被计算机技术人员广泛使用,尤其是计算机反病毒行业,沙盒是一个观察计算机病毒的重要环境。

现在沙盒一般都有部分或完整的类似HIPS的程序控制功能,程序的一些高危活动会被禁止,如安装驱动,底层磁盘操作等。目前沙盒主要有两大类,一是采用虚拟技术的传统沙盒,另一个就是采用策略限制的沙盒。

传统沙盒的典型代表之一就是sandboxie。看看它是怎么描述自己的,你就知道什么是沙盒了。

1.1sandboxie

当你运行一个程序时,程序会读取硬盘上的数据,这时数据由硬盘流向程序然后数据经过处理很显示后再由程序写回到硬盘中。

  如果你运行一个游戏程序,它会先读取保存在硬盘中的数据记录,然后在你玩游戏的过程中显示出来,最后再写回硬盘以待下次使用。

sandboxie的作用就是改变了程序写入数据的地点,不让它写回到硬盘中,而是写到由sandboxie创造的一个虚拟区域。

上图展示了sandboxie的关键特性:一个虚拟的存储区域,或者称为沙盒。在读取数据时,数据由硬盘穿过沙盒到达程序,这个不受影响。但是在程序写入数据时,这些数据都被保存在沙盒中而不会写入到硬盘。

如果你在沙盒环境下运行一个游戏,sandboxie会从硬盘读取数据并保存,然后游戏读取沙盒中的数据来满足它的需要。但是当游戏想写入数据时,sandboxie会拦截写入并把数据转移到沙盒中。

sandboxie会在一个被称为sandbox(沙盒)的隔离的虚拟区域运行程序。程序在此区域内运行不会受到影响,但是不能对系统做出永久的实际改变,程序所做的所有对文件和注册表的改动都仅仅在沙盒中有效。

除了sandboxie这种利用虚拟技术的沙盒,还有另外一种采用策略限制的软件也可以称之为沙盒,因为它也具有可以恢复所有程序所生成的文件和注册表键值的功能,称之为ROLLBACK(回滚),而对于修改和删除操作和传统沙盒不同的是采用的是策略限制。典型代表有DefenseWall。

1.2、DefenseWall

DefenseWall(DW)与sandboxie不同,它没有采用虚拟技术,所以在DW中运行的程序所生成的文件和注册表键值都是实机生成,DW会对它们进行追踪,所有这些生成的东西都受到策略限制。如在DW内的一个程序生成了一个可执行文件,当运行这个可执行文件时,这个文件会被DW追踪到自动加入非信任区,受到策略限制,这样一来确保了该文件不会对你的系统造成损害。而对系统重要文件和注册表键值的修改和删除同样会受到策略限制,禁止非信任程序进行操作。而传统沙盒对修改删除的操作是采用的虚拟化重定向技术,也就是说所有的修改删除操作都是在虚拟区域中完成,真正的文件和注册表是没有被修改或删除的。从技术上说DW更接近于传统HIPS,只是增加了对生成项的追踪限制功能,所以它是一个比较另类的沙盒。

1.3、AppVolumes

AppVolumes是沙盒的另一种扩展应用,它和sandboixe一样采用虚拟技术,但与之有着截然相反的应用方式,sandboxie的作用域是用户指定的程序,以及它创建的子程序,而AppVolumes的作用域是整个系统,它采用了一种很有意思用法,预先在一个Windows环境中开启沙盒模式,在沙盒中安装各种应用程序,再把重定向生成的数据打包起来,分发到其他Windows系统中,这样达到的效果就是其他Windows系统可以免安装就可以使用预先记录的软件,是一种全新的软件批量部署的技术手段。

2、沙盒实现原理

本文重点讲解Windows内核级虚拟技术沙盒的实现原理,其他平台的原理也大致相同,只是使用的实现方法有所差异。

2.1文件重定向

Windows系统提供两种方式来实现文件重定向:

2.1.1 方式1: File System Filter Drivers 

文件系统过滤驱动程序是一个可选的驱动程序,该驱动程序将增加或修改文件系统的行为。它是一个内核模式组件,作为内核执行的一部分运行,可以改变文件系统的I/O操作。设定相关的属性,过滤驱动可以记录日志,监视,修改,甚至可以防止文件操作。典型的应用程序的文件系统过滤器的驱动程序,包括防病毒程序,加密程序和分层存储管理系统

2.1.2 方式2: File System Minifilter Drivers

由系统提供的Filter manager内核模式驱动程序,符合传统的文件系统过滤驱动模型,并公开了文件系统过滤驱动程序所需的功能。利用这一功能,第三方开发者可以编写微过滤驱动的开发,这是比传统的文件系统过滤驱动程序更简单,从而缩短开发过程而生产更高质量、更强大的驱动程序。

本文只着重介绍Minifilter的原理。

2.2 Minifilter介绍:

由过滤管理器安装Windows中,加载并激活。过滤器管理器将微过滤驱动附加到目标卷的文件系统堆栈。系统中可同时有多个微过滤驱动共存,通过设定加载顺序来现实不同的功能。例如,一个防病毒过滤器的驱动程序应该比一个其他过滤器驱动程序更早加载, 所以它可以检测到病毒和消毒文件。系统为不同的功能类型定义了相应的加载顺序(altitude 属性)。

下图显示了一个简化的I/O堆栈与过滤管理器和三个微过滤驱动。

过滤管理器还提供了一系列FltXxx功能接口,简化了微过滤驱动程序的代码编写。

FltCreateFile

FltReadFile

FltWriteFile

...

2.3 微过滤器管理器模型的优点

  • 更好地控制过滤波器的加载顺序
  • 不像传统的过滤驱动程序,微过滤驱动可以在任何时间加载,并加载到在适当的位置。
  • 动态卸载的能力
  • 不像传统的过滤驱动程序,无法动态卸载,微过滤驱动可随时卸下,同时如果需要的话,也可以防止自己被卸载。
  • 只响应有必要的操作
  • 过滤管理器使用一种微过滤驱动可以选择哪些类型的I/O操作回调模型(基于IRP,快速I/O,或fsfilter)过滤。微过滤驱动只需要接收已注册的回调例程I/O请求。可以忽略某些类型的操作,例如分页I/O和缓存I/O。
  • 更高效的使用内核堆栈
  • 过滤器管理器进行了优化以减少内核堆栈使用量,采用回调模型大大降低了堆栈上的微过滤驱动的影响,同时减少了递归I/O的影响。
  • 减少冗余代码
  • 过滤器管理器优化了文件名的处理,以及多处理器的支持,这使得锁定更高效,更不容易出错。
  • 降低复杂度
  • 该过滤器管理器简化了过滤I/O请求,通过提供常用功能的支持例程,例如命名、上下文管理、用户模式和内核模式之间的通信以及文件系统之间的区别。并且自动帮助微过虑驱动完成某些工作,如待它列举和附加到文件系统栈。
  • 更好的易扩展性
  • 因为微过滤驱动只登记需要处理的I/O操作,对新业务的支持可以添加到过滤管理器而不影响现有微过滤驱动。
  • 支持多平台
  • 一个微过滤驱动可以运行在任何版本的Windows,支持过滤管理器。
  • 更好的支持用户模式应用程序
  • 过滤器管理器提供了常用的功能对用户的服务模式和控制微过滤驱动的工作程序。过滤器管理器用户模式库,filterlib.dll,使得用户模式服务或控制程序和微过滤驱动之间的通讯。filterlib.dll还提供了管理工具界面。
  • 2.4 文件重定向现实

通过调用FltRegisterFilter来注册Minifilter驱动,以下是注册时需要输入的主要参数信息

FltRegisterFilter(driverObject, &fltRegistration, &SnapFltFilter);

2.4.1 需要处理的管理例程

NanosFilterUnload卸载例程

NanosFilterInstanceSetup新卷到达例程

NanosFilterInstanceQueryTeardown卷拆卸询问例程

NanosFilterInstanceTeardownStart卷开始拆卸例程

NanosFilterInstanceTeardownComplete卷完成拆卸例程

NanosFilterGenerateFileName文件名缓存生成例程

NanosNormalizeNameComponentCallback文件名标准化例程

NanosTxNotificationCallback事务处理提示例程

NansNormalizeNameComponentExCallback文件名标准化附加例程

2.4.2 需要处理的IRP

  • IRP_MJ_SHUTDOWN系统关机命令
  • IRP_MJ_CREATE:文件创建或打开命令,文件的任何操作,都是从这里开始的。

NanosFileCreatePreCallback:文件创建或打开之前将调用此例程,文件重定向的关键代码片断如下

FLT_PREOP_CALLBACK_STATUS NanosFileCreatePreCallback(PFLT_CALLBACK_DATA Cbd, PCFLT_RELATED_OBJECTS FltObjects, PVOID *CompletionContext)
{	
UNICODE_SIRING NewFileName; 				//将要重定向的目标文件路径
...											
FileObject = Cbd->Iopb->TargetFileObject;
status = IoReplaceFileObjectName(
	FileObject ,
	NewFileName.Buffer,
	NewFileName.Length); 				//替换文件对象的名称
if (status < 0)
{
	FileObject->FileName = NewFileName;
	NewFileName.Length = 0;
NewFileName.MaximumLength = 0;
	NewFileName.Buffer = 0;
}
Cbd->IoStatus.Status = STATUS_REPARSE;		//告诉系统重新分析文件对象的名称,将对新文件名发起一个新的I/O请求。

当原始文件存在时,如果需要修改,则需要把原始文件复制到重定向路径。

NanosFileCreatePostCallback

系统操作完成文件创建或打开后回调此例程,其中主要是处理各种文件错误信息,以及正常完成时可创建上下文以供下面文件相关的例程使用。

  • IRP_MJ_NETWORK_QUERY_OPEN:打开网络路径
  • IRP_MJ_SET_INFORMATION:设置文件信息,比如删除文件,重命名文件,更改文件大小等

NanosFileSetInformationPreCallback

在实现文件重定向功能时,这里主要处理文件的删除及重命名。

删除文件时,如果删除的文件不是重定向创建的或修改过,此时不能删除真实的文件,而是设置一个标识,说明此文件已经被用户删除,在列举文件时,检查到此标识的文件就从列举结果中去除。

当删除目录时要组合真实目录和重定向后的目录,只要其中一方有文件存在,就不允许删除目录。

当重命名文件时,除了判断原始路径是不否有同名文件,同时还要判断重定向后的目录中是否有同名文件。

NanosFileSetInformationPostCallback

当系统实际操作完成后将调用此例程,如果是重命名文件,则需要更新上下文中的数据以匹配新路径。

  • IRP_MJ_DIRECTORY_CONTROL:目录操作命令,列举子目录及文件
  • NanosDirectoryControlPreCallback
  • 列举目录时要组合原始路径和重定向路径中的全部内容。
  • IRP_MJ_QUERY_VOLUME_INFORMATION:卷信息查询命令

NanosQueryVolumeInfoPreCallback

在查询卷的可用空间时,要根据重定向的目标目录的剩余空间大小来提供正常的卷空间。

  • IRP_MJ_QUERY_INFORMATION:文件信息查询命令,比如文件创建修改时间,文件大小等

NanosQueryFileInfoPreCallback

2.4.3 上下文回调例程

FLT_CONTEXT_REGISTRATION ContextRegistration[] = {
	{ FLT_STREAMHANDLE_CONTEXT/*0x10*/,	0, NanosContextCleanup, sizeof(SNAP_STREAM_HANDLE_CONTEXT),	'rdvS', 0, 0, 0 },
	{ FLT_STREAM_CONTEXT/*8*/,			0, NanosContextCleanup, sizeof(SNAP_STREAM_CONTEXT),	'rdvS', 0, 0, 0 },
	{ FLT_VOLUME_CONTEXT/*1*/,			0, NanosContextCleanup, sizeof(SNAP_VOLUME_CONTEXT),	'rdvS', 0, 0, 0 },
	{ FLT_INSTANCE_CONTEXT/*2*/,			0, NanosContextCleanup, 4,		'rdvS', 0, 0, 0	},
	{ FLT_CONTEXT_END/*0xFFFF*/,			0, 0, 0, 0, 0, 0, 0 },
};
  • FLT_STREAMHANDLE_CONTEXT
  •  流句柄上下文,也就是大家常见的FO(File Object)的上下文,一个文件可以对应多个FO,属一对多的关系,每个FO对就指定的权限等。
  • 在文件重定向的实现中,可以用此上下文来保存真实文件和重定向文件的句柄。
  • FLT_STREAM_CONTEXT
  • 流上下文,也就是大家常用的FCB(File Control Block)的上下文, 文件和FCB是一对一的关系。在此上下文中我们可以保存原始路径及重定向的路径信息。
  • FLT_VOLUME_CONTEXT
  • 卷上下文,卷就是大家通常看的C、D、E盘以及网络路径,一般情况下一个卷对应一个微过滤驱动实例对象, 在实际应用中经常用Instance Context来代替Volume Context。
  • FLT_INSTANCE_CONTEXT

实例上下文,也就是微过滤驱动在文件系统的设备堆栈上创建的一个过滤器实例。

三、注册表重定向

从WindowsXP开始,系统就提供了注册表过滤驱动的框架,从Vista开始此框架功能更加强大,足以完成注册表重定向的功能。

3.1 注册过滤驱动CmRegisterCallbackEx

注册表过滤驱动程序是内核模式驱动程序,用来过滤注册表调用,如反病毒软件的驱动组件。通过注册CmRegisterCallbackEx允许注册表过滤驱动程序来过滤任何线程调用注册表的功能。通过回调例程接收每个注册表操作通知在系统操作之前。reg_ xxx_key_information数据结构包含有关每个注册表操作信息。回调例程也能够阻止注册表操作。当系统完成操作后,回调例程也会收到通知。

系统中可注册多个滤驱动程序,按照注册时的输入的加载顺序,每个驱动程序都可以过滤注册表操作。

驱动程序可以完全处理注册表操作(或将请求的操作重定向到一个不同的操作),并可以防止系统操作。

驱动程序可以将上下文信息分配给单独的注册表操作或键值对象。

驱动可以修改注册表操作的输出参数和返回值。

reg_ xxx_key_information数据结构为每个不同的操作提供额外的成员。

3.2 需要处理的回调例程

regRoutineTable[RegNtPreQueryValueKey] = NanosRegNtPreQueryValueKeyCallback;
	regRoutineTable[RegNtPreEnumerateValueKey] = NanosRegNtPreEnumerateValueKeyCallback;
	regRoutineTable[RegNtPreQueryMultipleValueKey] = NanosRegNtPreQueryMultipleValueKeyCallback;
	regRoutineTable[RegNtPreDeleteValueKey] = NanosRegNtPreDeleteValueKeyCallback;
	regRoutineTable[RegNtPreDeleteKey] = NanosRegNtPreDeleteKeyCallback;
	regRoutineTable[RegNtPreRenameKey] = NanosRegNtPreRenameKeyCallback;
	regRoutineTable[RegNtPostRenameKey] = NanosRegNtPostRenameKeyCallback;
	regRoutineTable[RegNtPreEnumerateKey] = NanosRegNtPreEnumerateKeyCallback;
	regRoutineTable[RegNtPreQueryKey] = NanosRegNtPreQueryKeyCallback;
	regRoutineTable[RegNtPostQueryKey] = NanosRegNtPostQueryKeyCallback;
	regRoutineTable[RegNtPreSetValueKey] = NanosRegNtPreSetValueKeyCallback;
	regRoutineTable[RegNtPreCreateKeyEx] = NanosRegNtPreCreateKeyExCallback;
	regRoutineTable[RegNtPreOpenKeyEx] = NanosRegNtPreOpenKeyExCallback;
	regRoutineTable[RegNtCallbackObjectContextCleanup] = NanosRegNtCallbackObjectContextCleanupCallback;
	regRoutineTable[RegNtPreQueryKeySecurity] = NanosRegNtPreQueryKeySecurityCallback;
	regRoutineTable[RegNtPreSetKeySecurity] = NanosRegNtPreSetKeySecurityCallback;

如果回调例程返回STATUS_SUCCESS,配置管理器会继续处理注册表操作。

如果回调例程返回STATUS_CALLBACK_BYPASS,配置管理器停止处理注册表操作并返回到调用线程STATUS_SUCCESS。

如果回调例程返回一个状态值,NT_SUCCESS(status)为FALSE(除了STATUS_CALLBACK_BYPASS),配置管理器停止处理注册表操作并返回指定的值返回到调用线程。

  • RegNtPreQueryValueKey查询Value前回调
  • RegNtPreEnumerateValueKey列举Value前回调
  • 列举Value时需要组合原始路径和重定向路径的内容。
  • RegNtPreQueryMultipleValueKey列举多个Value前回调
  • 列举Value时需要组合原始路径和重定向路径的内容。
  • RegNtPreDeleteValueKey删除Value前回调
  • 删除Value时,如果是操作没有重定向的Value,则不能真正执行删除操作,而是设置一个标记,表示已经删除
  • RegNtPreDeleteKey删除Key前回调
  • 删除Key时,如果是操作没有重定向的Key,则不能真正执行删除操作,而是设置一个标记,表示已经删除。
  • RegNtPreRenameKey重命名Key前回调
  • RegNtPostRenameKey重命名Key后回调
  • 重命名后在此回调里更新上下文信息。
  • RegNtPreEnumerateKey列举Key前回调
  • 列举Key时需要组合原始路径和重定向路径的内容。
  • RegNtPreQueryKey查询Key前回调
  • RegNtPostQueryKey查询Key后回调
  • 系统实际查询过后,需要结合原始Key的数据和重定向后Key的数据来修正返回结果,
  • 比如获取KeyCachedInformation, KeyFullInformation类型的数据时。
  • RegNtPreSetValueKey修改Value前回调
  • 在修改Value时,需要把原始的Key的内容先得到重定向的Key中,再修改指定的Value的内容。

  • RegNtPreCreateKeyEx:创建Key前回调
typedef struct _REG_CREATE_KEY_INFORMATION_V1 {
  PUNICODE_STRING 	CompleteName;
  PVOID           		RootObject;
  PVOID           		ObjectType;
  ULONG           		Options;
  PUNICODE_STRING 	Class;
  PVOID           		SecurityDescriptor;
  PVOID           		SecurityQualityOfService;
  ACCESS_MASK     	DesiredAccess;
  ACCESS_MASK     	GrantedAccess;
  PULONG          		Disposition;
  PVOID           		*ResultObject;
  PVOID           		CallContext;
  PVOID           		RootObjectContext;
  PVOID           		Transaction;
  ULONG_PTR       		Version;
  PUNICODE_STRING 	RemainingName;
  ULONG           		Wow64Flags;
  ULONG           		Attributes;
  KPROCESSOR_MODE 	CheckAccessMode;
} REG_CREATE_KEY_INFORMATION_V1;

创建Key时首先调用到此例程,重定向时就创建到自定义的位置,并把Key对象保存到ResultObject中,然后返回STATUS_CALLBACK_BYPASS。

调用CmSetCallbackObjectContext来设置Key对象的上下文。

  1. RegNtPreOpenKeyEx打开Key前回调
  2. RegNtCallbackObjectContextCleanup上下文清理回调
  3. RegNtPreQueryKeySecurity查询Key安全信息前回调
  4. RegNtPreSetKeySecurity修改Key安全信息前回调

更完整的重定向也包括重定向安全信息的修改,在此接口中处理。

根据沙盒的特性,软件沙盒需要实现以下例主要逻辑

  1. 新建、修改及删除操作都是在特定的虚拟区域生效,原始数据不受任何影响。
  2. 数据的呈现是原始数据叠加上重定向后的数据的合集。
  3. 重命名、删除等操作需要考虑对原始数据和重定向数据的影响。
  4. 可以任意撤销重定向的修改内容。
  5. 文件操作和注册表操作的逻辑是一致

四、基于Windows沙箱的应用场景之一 App Volume(应用分层)

把任何正常安装的Windows应用打包成一个便携的虚拟磁盘。此后不再需要进一步的安装过程就可以将应用发布成百上千次到任何目标。应用更新、与其他应用组合、回滚操作以及弃用都一样的简便。应用分层最好的便捷的企业应用生命周期管理方式。

App Volume是沙盒的另一种扩展应用,它和sandboxie一样采用虚拟技术,但与之有着截然相反的应用方式,sandboxie的作用域是用户指定的程序,以及它创建的子程序,而AppVolumes的作用域是整个系统,它采用了一种很有意思用法,预先在一个Windows环境中开启沙盒模式,在沙盒中安装各种应用程序,再把重定向生成的数据打包起来,分发到其他Windows系统中,这样达到的效果就是其他Windows系统可以免安装就可以使用预先记录的软件,是一种全新的软件分发的技术手段,并且可以对用户数据采用同样的方式来采用数据漫游,系统、应用、用户数据分层处理,所以也叫做应用分层技术。

应用分成的技术在云桌面领域的用的场景相对的,除了批量软件分发之外,还有就是在还原模式虚拟环境中,怎么保留用户一些特殊文件或者注册表配置。 比如用户保存浏览器标签。打印机配置等等

市场上最好的应用分层工具有哪些? 应用分层市场有三款主要的产品:VMware App Volume、Liquidware Labs FlexApp以及Citrix提供的产品。Citrix正在使用今年早些时候收购的UniDesk的技术替代现有的AppDisk产品。

App Volume核心其就是在于前文所介绍的 文件重定向和注册表重定向技术

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值