如何在云电脑实现虚拟应用—数据分层(应用分层)技术简介

如何在云电脑实现虚拟应用—数据分层(应用分层)技术简介

近几年虚拟化市场实现了非常大的发展,桌面虚拟化在企业中应用越来越广泛,其拥有的如下优点得到大量企业的青睐:

  1. 数据安全不落地。在虚拟化环境下面数据保存在中心服务器上面,只要保障中心服务器的安全,那么就能保障数据的绝对安全。
  2. 高扩展性。与普通的硬件PC相比,桌面虚拟化具有高扩展性,可以随时将虚拟化资源归还给虚拟化主机以及分配给其他虚拟化主机使用。
  3. 容易部署。桌面虚拟化一般可以通过模板话部署,将应用(数据)一键部署到新的虚拟机上。
  4. 统一化资产管理。资产管理一直是企业管理的难点,市面上有许多公司的管理软件都包括了资产管理这一环;在桌面虚拟化下面,资产管理得到了很好的解决。

通常情况下的虚拟化架构如下:
在这里插入图片描述

在上述架构中,我们可以安装层级来划分:

  1. 硬件层:主要是我们的实体硬件,包括内存,CPU,存储。
  2. 主机层:主要是我们的Host主机操作系统,一般来说以Linux居多。
  3. 客户机层:主要是我们的虚拟机操作系统,在这一层上面实现我们的具体应用(办公,开发,娱乐等)。

那么能否对客户机(Guest)这一层继续进行细化分层呢?例如我们实现:

  1. 我们将个人数据存放在一个单独层级。
  2. 无论我们使用虚拟机的还原系统,还是登录一台全新的虚拟机,我们将数据层进行合并,让我们个人数据和应用不会丢失。

本文来介绍一种在虚拟机中数据分层的技术,下面我们详细看一下其技术原理和实现。

1. 简介

数据分层是针对虚拟机来说的,以Windows系统为例,从下到上,我们可以将其分为三层:

  1. 系统OS层,该层表示Windows系统镜像安装的原始OS层,代表这一个可正常运行的OS。
  2. 应用层,该层表示各种应用程序组成的层,例如Chrome浏览器,微信,QQ等各种应用程序。
  3. 数据层,该层表示应用程序运行时候生成的各种文件数据,例如浏览器的记录,收藏夹;QQ微信的聊天数据。

其示意图大致如下:
在这里插入图片描述

一般来说,每个层都是一个独立的磁盘,将每个磁盘通过分层技术合并成一个整体可以正常使用运行的磁盘,如下:
在这里插入图片描述

对于各层来说,一般有如下特征:

  1. 操作系统层,只有一个数据磁盘表示该层,表示运行的系统。
  2. 应用程序层,该层是一个集合层,多个应用程序层元素组成该层,表示通常情况下我们需要的应用程序。
  3. 个人数据层,该层可以由一个或者多个磁盘组成,不过大部分情况下,我们只需要一个磁盘层即可。

对于上面这种情况,在实际的使用场景下可以进一步简化,将操作系统层和引用程序层合并成一个层,大致如下:
在这里插入图片描述

对于通常场景,我们可以将操作系统层和应用程序层合并成一个层到操作系统层;也就是说,我们在安装操作系统的时候,就将我们需要的应用软件安装好;后面使用过程中我们只需要弹性使用个人数据层即可。

我们的数据分层主要是针对这种简化的分层,对于应用分层可以参考我们的文章Windows内核沙盒原理详解。

对于数据分层我们的应用有:

  1. 还原系统下面,我们可以将自己程序的各种数据存放到自己的磁盘(或者云盘上面),这样我们虚拟主机是还原系统,但是数据是个人的数据,可以达到虚拟机重复利用的目的;例如我们10台主机可以分时间段给100个人(甚至更多人)使用,只要拥有个人数据磁盘就行。
  2. 数据上云,比如我们可以将个人数据层同步到自己的云盘;无论我们使用哪个电脑(虚拟机或者物理主机),可以将数据层进行合并,使得每台电脑使用的数据完全一致。

针对数据分层,我们主要的技术在于分层数据的合并,对于这个合并,有两个点:

  1. 注册表数据的合并。
  2. 文件数据的合并。

2. 注册表数据分层

注册表数据的分层需要对注册表的各种查询进行HOOK,然后将数据查询进行合并,将数据写入进行分发;注册表的HOOK技术有两种:

  1. 基于用户层API HOOK技术。
  2. 基于内核回调函数的HOOK技术。

这里我们使用内核回调函数的实现方式,使用CmRegisterCallbackEx来注册注册表的各种回调函数:

NTSTATUS CmRegisterCallbackEx(PEX_CALLBACK_FUNCTION Function,PCUNICODE_STRING      Altitude,PVOID                 Driver,PVOID                 Context,PLARGE_INTEGER        Cookie,PVOID                 Reserved
);

注册表的各种回调函数有如下:

typedef enum _REG_NOTIFY_CLASS {RegNtDeleteKey,RegNtPreDeleteKey,RegNtSetValueKey,RegNtPreSetValueKey,RegNtDeleteValueKey,RegNtPreDeleteValueKey,RegNtSetInformationKey,RegNtPreSetInformationKey,RegNtRenameKey,//...
} REG_NOTIFY_CLASS;

理论上我们需要对所有函数进行处理,主要的操作有:

  • RegNtPreCreateKeyEx对注册表的打开做处理(打开操作系统层的注册表还是打开数据层的注册表)。
  • RegNtPreQueryValueKey对注册表值得查询做处理,一般来说我们需要对注册表得值进行合并(选择的方式是将数据层覆盖操作系统层的注册表值,当然还需要做很多情况的处理)。
  • RegNtPreEnumerateKey枚举注册表项,这个函数也是最复杂的实现函数,因为我们需要对操作系统层和数据层的注册表项进行合并,去重等。
  • RegNtPreDeleteKeyRegNtPreDeleteValueKey注册表的删除,也是非常麻烦的操作,因为我们需要对注册表进行标记处理(不能将操作系统层的数据真实删除)。

上面这些接口只是示例,实际的实现要复杂很多,大致例如如下:

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;

完成上述注册表的函数之后,我们就完成了注册表的分层合并和写入的功能了。

3. 文件分层

文件分层来说和注册表类似也可以使用两种方式来实现:

  1. 基于用户层API HOOK技术。
  2. 基于文件过滤驱动来实现。

这里我们使用基于Minifilter的文件系统过滤驱动来实现,Minfilter基本框架如下:
在这里插入图片描述

我们使用FltRegisterFilter来注册文件系统过滤驱动,如下:

NTSTATUS FLTAPI FltRegisterFilter(PDRIVER_OBJECT         Driver,const FLT_REGISTRATION *Registration,PFLT_FILTER            *RetFilter
);

该函数需要我们提供各种文件系统的回调函数,如下:

typedef struct _FLT_REGISTRATION {USHORT                                      Size;USHORT                                      Version;FLT_REGISTRATION_FLAGS                      Flags;const FLT_CONTEXT_REGISTRATION              *ContextRegistration;const FLT_OPERATION_REGISTRATION            *OperationRegistration;PFLT_FILTER_UNLOAD_CALLBACK                 FilterUnloadCallback;PFLT_INSTANCE_SETUP_CALLBACK                InstanceSetupCallback;PFLT_INSTANCE_QUERY_TEARDOWN_CALLBACK       InstanceQueryTeardownCallback;PFLT_INSTANCE_TEARDOWN_CALLBACK             InstanceTeardownStartCallback;PFLT_INSTANCE_TEARDOWN_CALLBACK             InstanceTeardownCompleteCallback;PFLT_GENERATE_FILE_NAME                     GenerateFileNameCallback;PFLT_NORMALIZE_NAME_COMPONENT               NormalizeNameComponentCallback;PFLT_NORMALIZE_CONTEXT_CLEANUP              NormalizeContextCleanupCallback;PFLT_TRANSACTION_NOTIFICATION_CALLBACK      TransactionNotificationCallback;PFLT_NORMALIZE_NAME_COMPONENT_EX            NormalizeNameComponentExCallback;PFLT_SECTION_CONFLICT_NOTIFICATION_CALLBACK SectionNotificationCallback;
} FLT_REGISTRATION, *PFLT_REGISTRATION;

同样对于上述文件过滤驱动我们需要实现其所有回调函数,这里我们简要介绍几个功能:

  • IRP_MJ_CREATE是文件创建的回调函数,在该函数中,我们需要实现文件的重查询,文件的写时拷贝,文件安装属性等功能。
  • IRP_MJ_SET_INFORMATION文件设置,这里有两个重要的流程需要处理就是删除和重命名,对于操作系统层的文件,需要对其进行虚拟删除(一般是通过标记法来标记文件的删除)。
  • IRP_MJ_DIRECTORY_CONTROL这个是目录文件的查询,这个函数也是非常复杂的一个函数,主要需要对操作系统层和数据层的数据进行查询合并。

我们对IRP_MJ_CREATE重查询的关键代码做分析,大致如下实现对文件的重查询:

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请求。//...
}

4. 实现效果

通过上面的文件和注册表分层实现之后,我们就可以完成对数据的分层实现了;一般来说为例不影响用户的体验,对于分层数据磁盘我们是隐藏起来;因此在使用的时候,我们并无法看到该磁盘的存在;该磁盘被合并到了整个操作系统层,实现如下:

首先我们将分层驱动停用,查看操作系统盘和数据盘数据,如下:
在这里插入图片描述

启用我们数据分层驱动之后,我们可以看到数据盘的数据已经合并到了操作系统盘C盘,如下:
在这里插入图片描述

可以查看具体数据如下:
在这里插入图片描述

至此,我们完成了操作系统和整个数据盘的合并(或者换一种说法我们将操作系统和数据层分开存储,但是合并显示了)。

和数据分层类似,我们可以对整个应用程序进行分层,可以参考https://blog.csdn.net/tianxilink/article/details/132612811?spm=1001.2014.3001.5502的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/12455.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

STL库简介

一、STL库的概念 STL&#xff1a;是C标准库的重要追组成部分&#xff0c;不仅是一个可以复用的组件库&#xff0c;而且还是一个包含了数据结构和算法的软件框架。 二、STL的版本 原始版本 Alexander Stepanov、 Meng Lee 在惠普实验室完成的原始版本&#xff0c; 是一个开源…

JVM 双亲委派机制详解

文章目录 1. 双亲委派机制2. 证明3. 优势与劣势 1. 双亲委派机制 类加载器用来把类加载到 Java 虚拟机中。从JDK1.2版本开始&#xff0c;类的加载过程采用双亲委派机制&#xff0c;这种机制能更好地保证 Java 平台的安全。 1.定义 如果一个类加载器在接到加载类的请求时&…

(done) NLP+HMM 协作,还有维特比算法

参考视频&#xff1a;https://www.bilibili.com/video/BV1aP4y147gA/?p2&spm_id_frompageDriver&vd_source7a1a0bc74158c6993c7355c5490fc600 &#xff08;这实际上是 “序列标注任务”&#xff09; HMM 的训练和预测如下图 训练过程&#xff1a;我们首先先给出一个语…

web学习记录--(5.14)

1.Sublime安装与汉化 直接点击windows即可下载&#xff0c;安装即可 Thank You - Sublime Text 汉化 Install Package ChineseLocalzation 2.PHPstorm下载以及激活,汉化 直接下载&#xff0c;然后找激活码激活即可 汉化 plugins&#xff08;插件&#xff09;/chinese&…

SpringBoot接收参数的19种方式

https://juejin.cn/post/7343243744479625267?share_token6D3AD82C-0404-47A7-949C-CA71F9BC9583

未授权访问:ZooKeeper 未授权访问漏洞

目录 1、漏洞原理 2、环境搭建 3、未授权访问 防御手段 今天继续学习各种未授权访问的知识和相关的实操实验&#xff0c;一共有好多篇&#xff0c;内容主要是参考先知社区的一位大佬的关于未授权访问的好文章&#xff0c;还有其他大佬总结好的文章&#xff1a; 这里附上大…

2025年第十一届北京国际印刷技术展览会

2025年第十一届北京国际印刷技术展览会 展览时间&#xff1a;2025年5月15-19日 展览地点&#xff1a;北京中国国际展览中心&#xff08;顺义馆&#xff09; 主办单位&#xff1a;中国印刷及设备器材工业协会中国国际展览中心集团有限公司 承办单位&#xff1a;北京中印协华港国…

海思Hi3065H 200MHz 高性能 RISCV32 A² MCU

这是一款海思自研的RISCV32内核的高性能实时控制专用MCU&#xff0c; 具有高性能、高集成度、高可靠性、易开发的特点&#xff0c;同时还有嵌入式AI能力。 CPU • RISC-V200MHzFPU 存储 • Up to 152KB Code Flash • 8KB Data Flash • 16KB SRAM 个人认为这是MCU梯队非常…

【PB案例学习笔记】-02 目录浏览器

写在前面 这是PB案例学习笔记系列文章的第二篇&#xff0c;该系列文章适合具有一定PB基础的读者&#xff0c; 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码&#xff0c;小凡都上…

基于Django实现的(bert)深度学习文本相似度检测系统设计

基于Django实现的&#xff08;bert&#xff09;深度学习文本相似度检测系统设计 开发语言:Python 数据库&#xff1a;MySQL所用到的知识&#xff1a;Django框架工具&#xff1a;pycharm、Navicat、Maven 系统功能实现 登录页面 注册页面&#xff1a;用户账号&#xff0c;密码…

05-14 周二 PyTorch动态量化和静态量化理解

05-14 周二 PyTorch动态量化和静态量化理解 时间版本修改人描述2024年5月14日10:44:30V0.1宋全恒新建文档2024年5月14日16:28:16V1.0宋全恒填充了PyTorch对于两种量化方式的内容 简介 Pytorch动态量化 设计神经网络时&#xff0c;可以进行许多权衡。在模型开发和训练期间&…

Dilworth定理:最少的下降序列个数就等于整个序列最长上升子序列的长度

概念如下&#xff1a; 狄尔沃斯定理_百度百科 (baidu.com) 本质就是找要求序列中最长的单调的子序列&#xff08;不一定连续&#xff09;的长度。 模板如下&#xff1a; 时间复杂度为O&#xff08;N^2&#xff09; #include<iostream>using namespace std;int dp[100…

RK3568平台开发系列讲解(SPI篇)SPI数据的传输

🚀返回专栏总目录 文章目录 一、数据结构1.1、spi_transfer 结构体1.2、spi_message二、数据发送程序分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 参考资料: spi_transferspi_message一、数据结构 spi 数据传输主要使用了 spi_message 和 spi_transfer 结构…

二叉树的前序遍历(leetcode)

144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 这道题的启发性真的很强 &#xff0c;这里必须传入i的指针进去&#xff0c;下一次栈帧i&#xff0c;但回到了上一层i又变回到了原来的i&#…

docker network ls(用于列出 Docker 主机上的所有网络)

docker network ls 是一个 Docker 命令&#xff0c;用于列出 Docker 主机上的所有网络。Docker 允许你创建自定义的网络&#xff0c;以便更好地控制容器之间的通信。 当你运行 docker network ls 命令时&#xff0c;你可能会看到如下类似的输出&#xff08;输出可能会根据你的…

每日一题12:Pandas:数据重塑-融合

一、每日一题 解答&#xff1a; import pandas as pddef meltTable(report: pd.DataFrame) -> pd.DataFrame:reshaped_report report.melt(id_varsproduct, var_namequarter, value_namesales)return reshaped_report 题源&#xff1a;Leetcode 二、总结 melt()函数是Pa…

Nginx生产环境最佳实践之配置灰度环境

你好呀&#xff0c;我是赵兴晨&#xff0c;文科程序员。 下面的内容可以说是干货满满建议先收藏再慢慢细品。 今天&#xff0c;我想与大家深入探讨一个我们日常工作中不可或缺的话题——灰度环境。你是否在工作中使用过灰度环境&#xff1f;如果是&#xff0c;你的使用体验如…

AI图像生成-基本步骤

模型板块 1、新建采样器&#xff1a;新建节点-》采样器-》K采样器 2、拖动模型节点后放开&#xff0c;选择checkpoint加载器&#xff08;简易&#xff09;&#xff0c;模型新建成功 提示词板块 1、拖动正面条件节点后放开&#xff0c;选择CLIP文本编码器&#xff0c;模型新建…

mysql 一次删除多个备份表

show tables时&#xff0c;发现备份的表有点多&#xff0c;想要一个sql就删除 总不能drop table xx ; 写多次吧。 方式一 1.生成删除某个数据库下所有的表SQL -- 查询构建批量删除表语句&#xff08;根据数据库名称&#xff09; select concat(drop table , TABLE_NAME, ;)…

FSMC的NOR Flash/PSRAM 控制器功能介绍(STM32F4)

目录 概述 1 FSMC支持的类型 1.1 信号类型概述 1.2 FSMC的应用 2 外部存储器接口信号 2.1 I/O NOR Flash 2.2 PSRAM/SRAM 3 支持的存储器和事务 4 通用时序规则 5 NOR Flash/PSRAM 控制器异步事务 5.1 模式 1 - SRAM/PSRAM (CRAM) 5.2 模式 A - SRAM/PSRAM (CRAM…