关于vmware 穿透读写的研究
- 未分类
- 2025-12-08
- 5热度
- 0评论
1765203475-VmWareThrough-main
通过研究这份代码发现,在VMware虚拟机内存大于2gb的时候,会出现一个问题就是找不到偏移,通过不断调试对比内存发现,在VMReadHostRegion读不到vmem中的数据。
这时候需要修改VMReadHostRegion函数,另外这份源码是不能运行在windows 11的系统中的,因为vmware选择win11安装后,在内存布局中是没有vmem内存名称的,需要搜索eprocess的特征来确定实际的vmem内存地址
BOOL VMReadHostRegion(PVOID buffer, ULONG64 addr, SIZE_T size) {
ReadProcessMemory(gVmWareProcessHandle,
(void*)((ULONG64)gMemBaseInfo.BaseAddress + addr),
buffer, size, NULL);
//读取在正常地址内读取不到需要的数据,就在减去0x40000000的位置再读取一次,这样就能读取到需要的数据了。也能在大于2GB内存的系统内读写内存
if (*(DWORD64*)buffer == 0)
{
ReadProcessMemory(gVmWareProcessHandle,
(void*)((ULONG64)gMemBaseInfo.BaseAddress + addr - 0x40000000),
buffer, size, NULL);
}
if (*(DWORD64*)buffer == 0)
{
return FALSE;
}
else
{
return TRUE;
}
}
# VMware内存操作工具原理文档
## 1. 项目概述
本项目是一个高级VMware虚拟机内存操作工具,用于从宿主机直接访问和操作虚拟机内存,实现内核模式注入和驱动加载等功能。该工具通过直接访问VMware进程映射的虚拟机物理内存,绕过了传统的虚拟机隔离机制,实现了对虚拟机内部系统的深度控制。
## 2. 核心组件
### 2.1 主应用程序(VmWareApp.c/h)
- **功能**:实现核心功能,包括内存初始化、内核数据获取、进程查找等
- **主要函数**:
- `VmWareThroughInit`:初始化整个系统
- `VMFindVmProcessData`:查找目标进程数据
- `VMReadVmVirtualAddr`/`VMWriteVmVirtualAddr`:读写虚拟机虚拟地址
- `VMTranslatePhyAddress`:虚拟地址转物理地址 (重点vmem地址+物理地址=虚拟机内地址)
### 2.2 内核模式注入(KernelModeInject.c/h)
- **功能**:实现内核模式代码注入
- **主要函数**:
- `KMIKernelInject`:执行内核注入
- `KMIGetWinModuleInfo`:获取Windows模块信息
### 2.3 VMware磁盘操作(VmWareDisk.c/h)
- **功能**:封装VMware VIX Disk Library,实现虚拟机磁盘操作
- **主要功能**:连接虚拟机、打开磁盘、读写磁盘等
### 2.4 内存操作(MemX64.c/h)
- **功能**:实现x64/IA32e模式下的内存管理
- **主要函数**:
- `MemX64Prototype`:处理原型页表项
- `MemX64TransitionPaged`:处理转换页表项
### 2.5 辅助组件
- **pe.c/h**:PE文件操作
- **vad.c/h**:虚拟地址描述符(VAD)操作
- **debug.c/h**:调试功能
- **misc.c/h**:杂项功能
## 3. 执行步骤
### 3.1 初始化阶段
1. **进程句柄获取**:
- 打开VMware进程,获取进程句柄
- 权限:需要`PROCESS_VM_READ`、`PROCESS_VM_WRITE`等权限
2. **内存映射查找**:
- 通过`VMFindMappedRegion`函数遍历VMware进程的内存映射
- 查找扩展名为`.vmem`的内存映射区域,这是虚拟机物理内存的映射
- 记录映射基址和大小
3. **内核数据初始化**:
- 通过`VMNtKernelDataInit`函数从物理内存中查找内核数据
- 扫描物理内存中的`PROCESSOR_START_BLOCK`结构
- 获取内核入口地址和DirectoryTableBase(CR3)
4. **进程偏移获取**:
- 通过`VMGetWinX64ProcessOffset`函数获取Windows内核结构偏移
- 查找`DirectoryTableBaseOffset`、`ActiveProcessLinksOffset`、`ImageFileNameOffset`等
- 通过特征值扫描定位VAD根节点偏移
### 3.2 进程查找阶段
1. **系统进程获取**:
- 从内核数据中获取System进程的EPROCESS地址
- 通过`ActiveProcessLinks`链表遍历所有进程
2. **目标进程定位**:
- 根据进程名(如"notepad.exe")查找目标进程
- 比较进程的`ImageFileName`字段
- 获取目标进程的EPROCESS结构和CR3值
3. **进程数据记录**:
- 将目标进程的EPROCESS地址、CR3、VAD根节点等信息保存到`VM_PROCESS_DATA`结构
### 3.3 内核注入阶段
1. **注入准备**:
- 准备注入代码和数据
- 初始化注入数据结构`KMJDATA`
2. **内核函数获取**:
- 通过`KMJInitializeVmKernelFunctions`函数获取内核函数地址
- 包括`PsCreateSystemThread`、`MmMapIoSpaceEx`等关键函数
3. **注入执行**:
- 通过`KMIKernelInject`函数执行内核注入
- 利用之前获取的内核数据和进程信息
- 执行阶段1、阶段2、阶段3注入代码
### 3.4 驱动加载阶段
1. **驱动路径处理**:
- 处理驱动路径,转换为NT路径格式(如"\\??\\c:\\test\\DriverTest.sys")
2. **驱动加载**:
- 通过`VMLoadDriver`函数加载驱动
- 利用之前的内核注入结果
- 调用内核函数加载驱动
## 4. 技术原理
### 4.1 VMware内存映射利用
- **原理**:VMware将虚拟机的物理内存以`.vmem`文件的形式映射到宿主机进程空间
- **实现**:通过`GetMappedFileNameA`函数查找`.vmem`映射区域
- **优势**:直接访问物理内存,绕过虚拟机监控器(VMM)的隔离
### 4.2 物理内存直接访问
- **原理**:利用VMware进程的内存映射,直接读写虚拟机物理内存
- **实现**:通过`ReadProcessMemory`和`WriteProcessMemory`函数访问映射区域
- **关键函数**:
- `VMReadHostRegion`:读取宿主机内存区域
- `VMWriteHostRegion`:写入宿主机内存区域
### 4.3 虚拟地址转换
- **原理**:实现x64/IA32e模式下的页表转换
- **步骤**:
1. 从虚拟地址中提取PML4、PDPT、PD、PT索引
2. 遍历页表,获取物理页框号
3. 组合物理页框号和页内偏移,得到物理地址
- **关键函数**:`VMTranslatePhyAddress`
### 4.4 内核数据结构解析
- **原理**:通过特征值扫描和结构分析,定位内核数据结构
- **主要结构**:
- `EPROCESS`:进程对象
- `KPROCESS`:内核进程对象
- `VAD`:虚拟地址描述符
- `LDR_DATA_TABLE_ENTRY`:模块加载信息
- **实现**:通过`VMGetWinX64ProcessOffset`函数动态查找结构偏移
### 4.5 内核模式注入
- **原理**:利用物理内存访问,修改内核数据和代码,实现无驱动内核注入
- **阶段**:
1. 阶段1:初始化和准备
2. 阶段2:代码注入和执行
3. 阶段3:后续处理和清理
- **关键技术**:直接修改内核内存、调用内核函数、创建系统线程
### 4.6 驱动加载
- **原理**:利用内核注入结果,调用内核函数加载驱动
- **优势**:绕过传统的驱动签名验证和加载机制
- **实现**:通过注入的代码调用`ZwSetSystemInformation`或直接操作驱动对象
## 5. 核心数据结构
### 5.1 NT_PROCESS_OFFSET
```c
typedef struct _NT_PROCESS_OFFSET {
DWORD DirectoryTableBaseOffset; // DirectoryTableBase偏移
DWORD ActiveProcessLinksOffset; // ActiveProcessLinks偏移
DWORD ImageFileNameOffset; // ImageFileName偏移
DWORD UniqueProcessId; // 唯一进程ID
DWORD VadRootOffset; // VAD根节点偏移
} NT_PROCESS_OFFSET, *PNT_PROCESS_OFFSET;
```
### 5.2 NT_PROCESS_DATA
```c
typedef struct _NT_PROCESS_DATA {
DWORD ProcessSize; // 进程大小
DWORD64 MemoryKernelDirbase; // 内核DirectoryTableBase
DWORD64 MemoryKernelEntry; // 内核入口地址
DWORD64 MemoryKernelBase; // 内核基地址
DWORD64 SystemProcessEprocess; // System进程EPROCESS地址
PVOID PsLoadedModuleListPtr; // 模块加载列表指针
} NT_PROCESS_DATA, *PNT_PROCESS_VERSION_DATA;
```
### 5.3 VM_PROCESS_DATA
```c
typedef struct _VM_PROCESS_DATA {
DWORD64 PEB; // PEB地址
DWORD PEB32; // 32位PEB(仅WoW64)
DWORD64 DestProcessEprocess; // 目标进程EPROCESS地址
ULONGLONG DestProcessCr3; // 目标进程CR3
DWORD64 VadRoot; // 目标进程VAD根节点
} VM_PROCESS_DATA, *PVM_PROCESS_DATA;
```
## 6. 安全考虑
### 6.1 风险
- **虚拟机逃逸风险**:直接访问物理内存可能导致虚拟机逃逸
- **系统稳定性风险**:错误的内存修改可能导致虚拟机崩溃
- **安全软件检测**:可能被安全软件检测为恶意行为
- **法律风险**:未经授权访问虚拟机内存可能违反法律法规
### 6.2 防护措施
- **权限控制**:仅在必要时使用高权限
- **内存验证**:修改内存前验证地址有效性
- **错误处理**:完善的错误处理机制
- **日志记录**:详细的操作日志,便于调试和审计
## 7. 应用场景
- **虚拟机调试**:深入调试虚拟机内核和驱动
- **安全研究**:研究虚拟机安全机制和漏洞
- **恶意软件分析**:在隔离环境中分析恶意软件
- **系统维护**:在虚拟机无法正常启动时进行修复
- **逆向工程**:分析虚拟机中的软件和驱动
## 8. 技术亮点
1. **直接物理内存访问**:绕过VMM隔离,实现高效内存访问
2. **动态偏移查找**:无需硬编码内核结构偏移,适应不同Windows版本
3. **无驱动内核注入**:不需要加载驱动即可实现内核模式操作
4. **跨版本兼容**:支持多种Windows版本
5. **模块化设计**:组件化设计,便于扩展和维护
## 9. 后续改进方向
1. **PDB支持**:通过PDB文件获取内核结构偏移,提高准确性和兼容性
2. **更多虚拟机支持**:支持VirtualBox、Hyper-V等其他虚拟机
3. **GUI界面**:开发图形用户界面,提高易用性
4. **更多注入方式**:支持更多内核注入技术
5. **自动化脚本**:支持脚本自动化操作
6. **安全增强**:添加更多安全检查和防护机制
