在现代计算机系统中,虚拟机技术的应用越来越广泛。虚拟机提供了一种隔离环境,使得不同的程序可以在同一个物理机上独立运行而互不干扰。然而,有时候需要在虚拟机内部运行的程序与外部软件进行通信。本文将探讨实现这种通信的方法,并着重介绍一种难以被检测的内存通信技术。
实现虚拟机内外通信的常见方法包括网络连接、共享文件夹以及虚拟机软件提供的API。然而,这些方法存在一些局限性:
因此,需要一种新的通信方法,它不仅难以被检测,而且不依赖于任何特定的虚拟机产品。
设想是直接读取和写入虚拟机的内存。具体来说,就是在虚拟机内部预留一个内存区域,然后通过这个区域进行通信。在虚拟机内部,只需要预留内存区域并进行同步。最困难的部分是如何从主机访问这个内存区域,并实现适当的同步。
为了实现这种内存通信技术,需要了解以下知识点:
要实现内存通信,需要解决以下几个技术问题:
从进程的角度来看,许多桌面虚拟机解决方案(如VMWare Workstation、VirtualBox、VirtualPC、Parallels Desktop)的结构如下:
例如,VMWare中这个进程叫做“vmware-vmx.exe”。
虚拟机的物理内存存储在一个进程中,但其内部结构是未知的。因此,虚拟机内部程序不仅要预留通信内存,还要用一些标志来标记预留的内存。
可以使用以下两种常见的方法来读取和写入目标内存区域:
此外,还需要实现一些同步原语。同步方法基于这样一个假设:每个虚拟机实际上都在执行(而不是解释!)代码(至少是非特权指令)。这个假设对于上述提到的虚拟机(VMWare、VirtualBox等)是有效的。
结合以上所有内容,可以得到以下通信引擎的方案:
注入的代码应该定期扫描虚拟机内存,寻找用于通信的页面的标志。当这些页面被找到后,就可以进行通信,并使用基于InterlockedCompareExchange的互斥锁进行同步。