当前位置: 首页 > news >正文

写时复制,读时加载

实现写时复制,读时加载,原理为,申请内存时,只给一段线性地址空间,并不分配物理内存,当cpu读、写该内存时,发生缺页中,或者写错误,中断处理程序根据前面设置的内容,决写分配物理内存,或者是共享内存,如果需要读取文件时,则根据需要读取相应的文件数据。

主要代码如下:

LPPE_FILE_ELEM load_pe_dll(char * lpFileName) {LPPE_FILE_ELEM lpSysFE, lpUserFE; //文件列表中的元素,保存文件信息//文件加载内存的默认地址//PIMAGE_DOS_HEADER pdh; //dos头PIMAGE_NT_HEADERS pnh; 	//pe文件头LPVOID pfile, pKrFile;PMEMORY_BASIC_INFORMATION pmbi;BYTE buf[512]; 		//临时块//补全文件目录路径add_patch((char *) buf, lpFileName);//1、从系统进程中查找是否已经加载lpSysFE = pe_find_file((char*) buf, get_sys_files_list());if (lpSysFE) {//系统中已经加载,进入下一步pKrFile = (LPVOID) lpSysFE->hModule;DbgPrint("dll已读入内存 : %s ,%x\n", lpSysFE->strFilePath,lpSysFE->dwNumberOfShares);//return lpFE->hModule;} else {//将文件加入系统文件列表中lpSysFE = kr_malloc(sizeof(PE_FILE_ELEM) + strlen((char*) buf) + 1);strcpy(lpSysFE->strFilePath, (char*) buf);if (load_file(lpSysFE->strFilePath, 0, 512, buf)) {//新exe头部的文件地址 指向PEpnh = (PIMAGE_NT_HEADERS) ((DWORD) buf+ ((PIMAGE_DOS_HEADER) buf)->e_lfanew);//系统进程中仅申请空间,读时加载pmbi = mem_virtual_alloc(&stMbiSys, 0,pnh->OptionalHeader.SizeOfImage, MEM_COMMIT,PAGE_READWRITE,MEM_IMAGE);pKrFile = (PBYTE) pmbi->BaseAddress;lpSysFE->hModule = (DWORD) pKrFile;lpSysFE->dwImgsize = pnh->OptionalHeader.SizeOfImage;lpSysFE->dwNumberOfShares = 0;list_push(get_sys_files_list(), (PLIST_ELEM) lpSysFE);load_pe_text((PIMAGE_DOS_HEADER) buf, (DWORD) lpSysFE->hModule,lpSysFE->strFilePath);if (!pKrFile) {//失败//DbgPrint("dll已读入内存 : %s ,%x\n");} else {//初始化时设置文件共享的次数为0,加入系统加载文件队列。}}}		//	if (lpFE)//2、检查用户空间 当前文件是否已经加载lpUserFE = pe_find_file(lpSysFE->strFilePath, get_current_file_list());if (lpUserFE) {//2、已经加载 直接返回return lpUserFE;} else {//第一次加入进程,将pKrfile的物理地址映射到 pfilepnh = (PIMAGE_NT_HEADERS) ((((PIMAGE_DOS_HEADER) pKrFile)->e_lfanew)+ (DWORD) pKrFile);pmbi = mem_virtual_alloc(MBI_USER_BASE, (LPVOID) pnh->OptionalHeader.ImageBase,pnh->OptionalHeader.SizeOfImage,MEM_COMMIT, PAGE_READWRITE, MEM_IMAGE);pfile = (PBYTE) pmbi->BaseAddress;DbgPrint("共享 dll: %s,%x,%x,%x,%x\n", lpSysFE->strFilePath, pfile,pKrFile, pnh->OptionalHeader.ImageBase);lpUserFE = kr_malloc(strlen((char*) lpSysFE->strFilePath) + sizeof(PE_FILE_ELEM)+ 1);strcpy(lpUserFE->strFilePath, lpSysFE->strFilePath);lpUserFE->hModule = (DWORD) pfile;lpUserFE->dwImgsize = lpSysFE->dwImgsize;lpUserFE->hSysModule = pKrFile;list_push(get_current_file_list(), (PLIST_ELEM) lpUserFE);lpSysFE->dwNumberOfShares++;DoRelocationTable(pfile);link_import(pfile);//文件头映射//	mem_map_demand(pKrFile, pfile,//		_ALIGN(	pdh->e_lfanew + sizeof(IMAGE_NT_HEADERS32)//					+ pnh->FileHeader.NumberOfSections//								* sizeof(IMAGE_SECTION_HEADER), 4096),//		PG_USER_R_P);}return lpUserFE;
}
BOOL mem_fail_sys(DWORD code, DWORD addr) {DWORD temp;LPPE_FILE_ELEM fe;PMEMORY_BASIC_INFORMATION pmbi =mem_find_mbi(&stMbiSys,addr);//DbgPrint("内核%s错误  0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n",(code&2?"写":"读"), addr, code,//		pmbi->BaseAddress, pmbi->RegionSize, pmbi->State, pmbi->Type);if (!pmbi) {return FALSE;}//如果是映射if (pmbi->State == MEM_COMMIT) {//分配物理内存,以4K为单位,if (pmbi->Type == MEM_IMAGE) {mem_physics(addr, 4096, PGE_SYS_RW_P);fe = (LPPE_FILE_ELEM) pe_find_from_addr(get_sys_files_list(), addr);if (fe->dwNumberOfShares != 0) {//直接分配内存,再读取文件//200对齐load_file_4k(fe, addr);} else {//正在读文件头}} else if (pmbi->Type == MEM_4MB_PAGES) {// MEM_4MB_PAGES://二级目录//	DbgPrint("二级页表%x,%x\n", addr, (DWORD *) MiGetPteAddress(addr));mem_physics(addr, 4096, PG_USER_RW_P);//*(DWORD *) MiGetPteAddress(addr) =//		get_freed_physics() + PG_USER_RW_P;} else {mem_physics(addr, 4096, PGE_SYS_RW_P);}//直接分配内存}	//if (pmbi->State == MEM_COMMIT)else {return FALSE;}return TRUE;
}
BOOL mem_fail_user(DWORD code, DWORD addr) {DWORD temp;LPPE_FILE_ELEM fe;PMEMORY_BASIC_INFORMATION pmbi =mem_find_mbi(MBI_USER_BASE, addr);//DbgPrint("用户%s错误  0x%x,0x%x,0x%x,0x%x,0x%x,0x%x\n", (code&2?"写":"读"),addr, code,//		pmbi->BaseAddress, pmbi->RegionSize, pmbi->State, pmbi->Type);if (!pmbi) {
//找不分配的段。return FALSE;}
//状态是不是已经提交
//只读,读写,还共享的读写
//如果是map类,分配内存,如果Image类,则读时加载,写时复制if (pmbi->State == MEM_COMMIT) {if (pmbi->Type == MEM_IMAGE) {fe = (LPPE_FILE_ELEM) pe_find_from_addr(get_current_file_list(),addr);if (fe->hSysModule == 0) {//说明是不是共享文件//DbgPrint("用户内存错误  0x%x , 0x%x , 0x%x , 0x%x \n", addr, code,//			pmbi->BaseAddress, pmbi->State);mem_physics(addr, 4096, PG_USER_RW_P);load_file_4k(fe, addr);//break;} else {//DbgPrint("用户内存错误 %x,%x\n",addr,fe);//先读取系统内存,如果出错则会中断到mem_fail_sys,加载文件//如果是读取,则映射,如果是写则分配内存再复制if (code & 2) {//重新申请物理内,再复制//DbgPrint("用户写错误%x\n", addr);mem_physics(addr, 4096, PG_USER_RW_P);memcpy((PVOID) (addr & 0xFFFFF000),(PVOID) ((fe->hSysModule + (addr - fe->hModule))& 0xFFFFF000), 4096);} else {//DbgPrint("用户读错误%x\n", addr);//说明可能内核没有读取文件,也可能没有映射//先试读下,没有读取文件会中断后读取,再映射//mem_fail_sys(0,fe->hSysModule+addr-fe->hModule);temp = *(PDWORD) (fe->hSysModule + addr - fe->hModule);//函数自己内部齐,size=1~4096效果应是一样mem_map_demand(fe->hSysModule + addr - fe->hModule, addr,4096, PG_USER_R_P);}//直接分配内存,再读取文件//addr-pmbi->BaseAddressg}} else if ((pmbi->Type == MEM_PRIVATE)) {//if (pmbi->Type == MEM_IMAGE)mem_physics(addr, 4096, PG_USER_RW_P);}}		//	if (pmbi->State == MEM_COMMIT)else {return FALSE;}return TRUE;
}

相关文章:

写时复制,读时加载

实现写时复制,读时加载,原理为,申请内存时,只给一段线性地址空间,并不分配物理内存,当cpu读、写该内存时,发生缺页中,或者写错误,中断处理程序根据前面设置的内容&#x…...

Python和R基因组及蛋白质组学和代谢组学

🌵Python片段 1. 数据处理与清理 基因组病理学的数据通常非常庞大,且可能包括 DNA 或 RNA 测序结果、基因表达数据等。Python 提供了高效的数据处理工具。 工具和库 Pandas: 用于加载、清理和操作数据。Numpy: 用于高效的数值计算。Dask: 用于大规模数…...

selenium环境搭建详细过程

一、准备工作 在开始搭建 Selenium 环境之前,确保具备以下条件: 1.稳定的网络连接: 以便能够下载所需的软件和驱动程序。 2.操作系统基础: 对您的操作系统(如 Windows、Mac 或 Linux)有基本的了解和操…...

Linux知识 - VIM

VI于VIM linux系统里边内置了一个编辑器就叫做vi(visual editor),但vi的功能非常有限,所以一般Linux的使用人员会选择一个比vi更强大的编辑器vim Vim的三种工作模式 输入模式 在正常模式中按下别字母键,会进入插入模式…...

【数据结构】链表重难点突破

目录 一、链表的概念 二、链表的实现 2.1 链表的构建 2.2 从链表头部添加元素 2.3 从链表尾部添加元素 2.4 链表任意位置添加元素 2.5 常规方法实现 2.6 获取指定位置的元素 2.7 获取指定元素的位置 2.8 修改链表中某一节点 2.9 删除链表的头结点 2.10 删除链表的尾…...

大宗商品行业区块链应用

应用场景 区块链技术具有透明性、去中心化、不可篡改等特点,因此可以在大宗商品定价方面得到应用。通过区块链技术,相关交易的各方可以在无需依赖中心化第三方的情况下,实时、准确地获取定价信息。这种技术的应用能够提高效率、降低成本、提…...

Varjo:垂直起降机混合现实培训解决方案

混合电动垂直起降机(VTOL)作为一种新型的航空运输机具有超越传统汽车的安全性、与飞机相当的速度以及无与伦比的灵活起降功能。电动垂直起降机能够在建筑顶部、直升机场或是没有跑道的地区起飞或降落,且排放要远远低于由航空汽油驱动的传统飞…...

sqlite-vec一个SQLite3高效向量搜索扩展--JDBC环境使用

最近要用SQLite3,之前放出来了SQLiteUtile工具,方便操作。今天发现AIGC方面,RAG知识库需要使用向量数据库,来存储知识信息。一般呢都是用mysql,但无奈的是mysql就是不让用。突然又发现SQLite3有向量库扩展组件&#xf…...

10 基于深度学习的目标检测

首次完成时间:2024 年 11月 20 日 1. 使用OpenCV的dnn模块实现图像分类。 1)程序代码: import numpy as np import cv2# 解析标签文件 row open("model1/synset_words.txt").read().strip().split("\n") class_label …...

leetcode top100中的30道递归和贪心

21到30题,递归和贪心...

非常简单实用的前后端分离项目-仓库管理系统(Springboot+Vue)part 2

七、创建前端项目 你下载了nodejs吗?从cn官网下载:http://nodejs.cn/download/,或者从一个国外org网站下载,选择自己想要的版本https://nodejs.org/download/release/,双击下载好的安装文件,选择安装路径安…...

shell脚本(完)—脚本互调重定向的学习

免责声明 学习视频来自B 站up主泷羽sec,如涉及侵权马上删除文章。 笔记的只是方便各位师傅学习知识,以下代码、网站只涉及学习内容,其他的都与本人无关,切莫逾越法律红线,否则后果自负。 脚本互调 在Shell脚本中&a…...

ant-design-vue中table某一列进行合并

ant-design-vue中table某一列进行合并 1、在colums中配置自定义渲染 {title: 区域,dataIndex: cityName,key: cityName,align: center,width: 120,customCell: (record, rowIndex, column) > {return {rowSpan: record.rowSpan}} },2、处理请求来的数据 tableData.dataSo…...

基于Springboot+Vue社区养老服务管理系统(源码+lw+讲解部署+PPT)

前言 详细视频演示 论文参考 系统介绍 系统概述 核心功能 用户角色与功能 具体实现截图 1. 服务信息查看功能 主要代码实现 截图: 2. 服务申请功能 主要代码实现 截图: 3. 公告信息查看功能 主要代码实现 截图: 4. 服务信息…...

大数据调度组件之Apache DolphinScheduler

Apache DolphinScheduler 是一个分布式易扩展的可视化 DAG 工作流任务调度系统。致力于解决数据处理流程中错综复杂的依赖关系,使调度系统在数据处理流程中开箱即用。 主要特性 易于部署,提供四种部署方式,包括Standalone、Cluster、Docker和…...

介绍一下strlwr(arr);(c基础)

hi , I am 36 适合对象c语言初学者 strlwr(arr)&#xff1b;函数是把arr数组变为小写字母 格式 #include<string.h> strlwr(arr); 返回值为arr 链接分享一下arr的意义(c基础)(必看)(牢记)-CSDN博客 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #incl…...

meterpreter常用命令 上

Meterpreter 是 Metasploit 框架中的一个高级 Payload&#xff0c;广泛用于渗透测试和攻击模拟。以下是一些常用的 Meterpreter 命令&#xff1a; 1. 基本命令 sysinfo 显示目标系统的基本信息&#xff08;操作系统、架构等&#xff09;。 getuid 获取当前用户的身份信息。…...

【kubernetes】kubernetes各组件的调用关系

目录 1. 说明2. Kubernetes组件概述2.1 控制平面组件2.2 节点组件 3. Kubernetes组件调用关系4. 示例说明 1. 说明 1.Kubernetes是一个开源的容器编排工具&#xff0c;其各个组件之间存在着复杂的调用关系&#xff0c;共同构建起一个完整的容器编排系统。2.Kubernetes集群主要…...

Java-08 深入浅出 MyBatis - 多对多模型 SqlMapConfig 与 Mapper 详细讲解测试

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…...

Vue.js修饰符

Vue.js 是一个渐进式JavaScript框架&#xff0c;用于构建用户界面。在Vue.js中&#xff0c;修饰符&#xff08;Modifiers&#xff09;是一种增强指令行为的工具&#xff0c;它们可以改变指令的默认行为。本文将详细讲解Vue.js中的修饰符&#xff0c;并提供实际示例&#xff0c;…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...