Anti-VM——换种思路检测程序是否处于虚拟机环境中

       前几天看到两篇文章,内容是介绍老外(应用于病毒的自身防护)使用的用于检测虚拟机的特殊手段。文中提到的方法莫不令人感到惊奇:第一种是通过检测当前系统中最近打开的word文档数量,若不大于2次则报异常退出程序。另一种是判断当前系统的IP所属的机构名称,若处于黑名单内则报异常退出。与以前看到的特权指令检测、VMTools检测、服务检测、注册表检测等基于技术原理的检测手段不同,这两种方式是基于经验总结、结合反向思考得出来的奇淫技巧。相对于传统的检测手段,这两种方法的优势在于出其不意,同时准确性也并没有降低很多——事实上因为频繁还原系统环境,用于病毒分析的虚拟机打开word文档的次数确实往往少于3次,而且自身的IP信息也不会处理(这两个办法被应用于病毒的自身保护中,其他需求的反虚拟机应用此方法时不一定奏效)。

        看完上述方法,我也陷入了思考,是否有什么通用特征,是99%的虚拟机都具备而普通人用的主机是几乎不可能出现的。稍加思考就能想出一些,例如安装的日常软件少、硬盘不分区、硬盘总大小特别小等,但是为了确保准确性,要将判断标准的值设置得尽可能的极限,超过这个阈值基本可以确定虚拟机环境。个人倾向于判断硬盘数量和硬盘总大小。因为虚拟机一般用于实现某一或特定极少种环境需求,很少有用户将虚拟机作为主要机器使用,而极少的这一部分用户又几乎不会是软件分析人员、驱动调试人员或程序非法多开人员,因此不会专门为虚拟机的磁盘分区,而且一般磁盘分配得特别小。我记得VMWARE的默认磁盘分配大小为20G。

       我设定的判定标准为当前系统的硬盘盘符数量小于3且总大小小于256G,则判定为当前处于虚拟机环境中。Demo代码如下:

#include 
#include 

using namespace std;

//通过检测硬盘数量、大小特征判断虚拟机
BOOL AntiVMByCheckHD();


int main()
{
	if (AntiVMByCheckHD())
	{
		cout << "处于虚拟机中" << endl;
	}
	else
	{
		cout << "非虚拟机" << endl;
	}
	getchar();
	return 0;
}


BOOL AntiVMByCheckHD()
{
	ULONG     uHDsize = 0;  //硬盘总大小
	ULONG 	  uHDcount = 0; //硬盘数量

	DWORD dwLen = GetLogicalDriveStrings(0, NULL); //获取盘符字符串长度
	TCHAR * pszDriver = new TCHAR[dwLen];
	GetLogicalDriveStrings(dwLen, pszDriver); //获取盘符字符串


	unsigned long long ullFreeBytesToCaller;
	unsigned long long ullTotalBytes;
	unsigned long long ullFreeBytes;

	DWORD dwMoveLen = 0;
	while (dwMoveLen

       方法很容易实现,希望能想到更多思路。也欢迎有其他思路的朋友留言交流。

你可能感兴趣的:(免杀攻防,软件保护,奇淫技巧)