内存映射文件
什么是内存映射文件
内存映射文件是一种将磁盘文件直接映射到进程地址空间的技术,允许应用程序像访问内存一样访问文件内容。这种机制提供了高效的文件I/O操作方法
#include<windows.h>
#include<iostream>HANDLE hFile;
HANDLE hMapFile;
DWORD dwFileMapSize;
LPVOID lpAddr;LPVOID MappingFile(LPCWSTR lpcFileName) {// 得到文件句柄hFile = CreateFile(lpcFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hFile == INVALID_HANDLE_VALUE) {std::cout << "打开文件失败,错误码:" << GetLastError() << std::endl;return 0;}// 创建FileMapping 第一个参数如果为-1则表示只创建物理页,如果是一个文件句柄则表示创建文件映射区hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, L"映射文件");if (hMapFile == NULL) {std::cout << "创建映射文件失败,错误码:" << GetLastError() << std::endl;return 0;}// 映射到虚拟内存的起始地址lpAddr = MapViewOfFile(hMapFile, FILE_MAP_COPY, 0, 0, 0);if (lpAddr == NULL) {std::cout << "映射文件失败,错误码:" << GetLastError() << std::endl;return 0;}return lpAddr;
}int main() {LPVOID fileBuff = MappingFile(L"C:\\Users\\BananaLi\\Desktop\\mydll.dll");// 读取文件DWORD dwContentOne = *(DWORD*)fileBuff;std::cout << "文件内容:" << std::hex << dwContentOne << std::endl;// 加偏移读取文件DWORD dwContentTwo = (*(DWORD*)fileBuff) + 0x10; // 这里的0x10其实是16*4 = 64字节,DWORD4字节,+1相当于加4字节std::cout << "文件内容:" << std::hex << dwContentTwo << std::endl; 写文件//*(DWORD*)fileBuff = 0x12345678;// 强制更新缓存FlushViewOfFile(fileBuff, 4);// 释放资源UnmapViewOfFile(fileBuff);CloseHandle(hMapFile);CloseHandle(hFile);return 0;
}
映射系统文件
我们知道像是kernel32.dll,user32.dll,ntdll.dll这些文件在物理内存中只存在一份,那如果我在通过上面的方式,进行内存映射文件后,修改它里面的某个函数,那其它进程中使用到这个函数时,也是执行我们修改后的函数吗?
写时拷贝
在MapViewOfFile这个函数中的dwDesiredAccess参数,有一个参数值,是FILE_MAP_COPY,这个参数是当映射的文件发生写操作时,就拷贝一份物理内存中的映射文件数据