相比反调试技术,反虚拟机技术相对而言简单些,本来想写反调试的,但是发现坛子反调试技术精华一大堆。逆向工程师遇到最多的应该是反调试技术,可能只有反病毒工程师会遇到反虚拟机技术。反虚拟机技术没有固定的方法,就像做饭一样,蒸着吃炸着吃烤着吃,怎么吃都能吃,怎么吃都好吃,没法总结,也不可能总结全面。虚拟机检测是一门艺术,没有固定的章法。这里只列举一些最常见的希望各路大佬多多补充。
安装了VMware Tools之后进程列表中会多出来三个进程: VMwareService.exe VMwareTray.exe VMwareUser.exe
注册表项包括虚拟机硬盘驱动器,适配器和虚拟鼠标
通常,MAC地址的前三个字节标识一个提供商,VMware对应的MAC地址开头为00:0C:29
内核模式下,VMWare使用二进制翻译技术进行模拟指令的操作,运行于内核态的某些特权指令被解释和模拟,也就是说他们不再物理处理器上运行。相反,在用户模式下,代码直接在处理器运行,几乎和所有硬件交互的指令,要么是特权之灵,要么就是会产生内核态陷阱指令或者是终端指令,vmware截获终端并处理他们,一遍虚拟机仍然认为我是一个真实的主机。
但是在x86架构上,一些指令在获取硬件信息的时候并不产生异常,比如说sldt、cpuid等。VMware为了正确模拟这些指令,就需要在所有指令上进行二进制翻译,这些指令包括但不限于特权指令。这么干的话由于进行了二进制翻译,所以会造成很大的性能损失。VMware的开发人员显然考虑到了这点,所以允许一些特定指令在没有正确虚拟化的前提下运行,这样的话会造成某些特定的指令在VMWare虚拟机会返回和物理机不一样的结果。
处理器使用某些关键的数据结构和表会被加载与真实系统不同的偏移量,也就是全虚拟化的一个副作用。中断描述表IDT是CPU里面的一个用来确保正确响应终端和异常的数据结构。在x86架构下,所有的内存获取要么是通过全局描述表GDT获得,要么就是通过本地描述表LDT获得。这些表中包含段描述符提供每一个端的详细储存信息,比如说段基址类型、长度以及权限等等。其实CPU内部有用来存放IDT、GDT和LDT表的基址和大小的寄存器,也就是IDTR、GDTR和LDTR。这里需要提醒一点,操作系统不需要使用这些表,比如说Windows的平面内存模型就是默认使用GDT不适用LDT。sidt、sgdt和sldt指令可以读取这些表的位置,并且将相应寄存器存入对应的内存地址。虽然说这些指令通常情况下是操作系统使用的,但是x86架构下这三个指令其实不是特权指令,换句话说就是,可以在用户态内存执行。
在x86架构下,IDTR\GDTR\LDTR的值必须对宿主机操作系统有效,同时,他们偏离了虚拟机操作系统的预期值,原因是sidt、sgdt和sldt可以随时被用户态的代码使用,而且不会产生陷阱,这样的话VMWare就不会正确虚拟化这些指令。
Red Pill通过运行sidt指令获取IDTR寄存器的值。虚拟机监视器必须重新定位Guest系统的IDTR,来避免与Host系统的IDTR冲突。因为在虚拟机中运行sidt指令时,虚拟机监视器不会得到通知,所以会返回虚拟机的IDTR。Red Pill通过测试这种差异来探测VMWare的使用。这种方法存在一个缺陷,由于IDT的值只针对处于正在运行的处理器而言,在单CPU中它是个常量,但当它处于多CPU时就可能会受到影响了,因为每个CPU都有其自己的IDT,这样问题就自然而然的产生了。
针对此问题,有一种方法就是利用Red Pill反复地在系统上循环执行任务,以此构造出一张当前系统的IDT值变化统计图,但这会增加CPU负担;另一种方法就是windows API函数SetThreadAffinityMask()将线程限制在单处理器上执行,当执行此测试时只能准确地将线程执行环境限制在本地处理器,而对于将线程限制在VM处理器上就可能行不通了,因为VM是计划在各处理器上运行的,VM线程在不同的处理器上执行时,IDT值将会发生变化,因此此方法也很少被使用。
需要注意的是Red Pill只在但处理器的主机上才能够有效,针对多核心和多处理器可能会出现是小的情况,因为每一个处理器都会有一个对应的IDT,所以sidt指令结果可能不唯一。
用sgdt和sldt指令去探测VMWare环境的技术叫做No Pill,No Pill实现的原理是:LDT数据结构由处理器分配而不是操作系统分配。正常情况下,Windows操作系统里面不会使用LDT数据结构,但是VMware却提供了LDT的虚拟化支持,在VMWare里面,LDT还和一般的LDT不太一样:宿主机系统中LDT位置的值是0,但是在虚拟机中不是0。
对于这种方法的话,我们可用NOP去替换in指令,或者修补条件跳转,这样的话不论比较结果如何都执行到位探测到虚拟机的程序分支。
VMware的安装目录C:\Program Files\VMware\VMware Tools也会留下恨及
在IDA中可以用如下脚本查找前面提到的指令
修改如下配置可用于伪装
除此之外,还建议卸载VMware Tools,禁用共享文件夹
BOOL
IsVMWarePre()
{
PROCESSENTRY32 pe32;
pe32.dwSize
=
sizeof(pe32);
HANDLE hProcessSnap
=
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
0
);
if
(hProcessSnap
=
=
INVALID_HANDLE_VALUE)
{
return
FALSE;
}
BOOL
bMore
=
Process32First(hProcessSnap, &pe32);
while
(bMore)
{
if
(strcmp(pe32.szExeFile,
"VMwareService.exe"
)
=
=
0
|| strcmp(pe32.szExeFile,
"VMwareTray.exe"
)
=
=
0
|| strcmp(pe32.szExeFile,
"VMwareUser.exe"
)
=
=
0
)
{
return
TRUE;
}
bMore
=
Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return
FALSE;
}
BOOL
IsVMWarePre()
{
PROCESSENTRY32 pe32;
pe32.dwSize
=
sizeof(pe32);
HANDLE hProcessSnap
=
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
0
);
if
(hProcessSnap
=
=
INVALID_HANDLE_VALUE)
{
return
FALSE;
}
BOOL
bMore
=
Process32First(hProcessSnap, &pe32);
while
(bMore)
{
if
(strcmp(pe32.szExeFile,
"VMwareService.exe"
)
=
=
0
|| strcmp(pe32.szExeFile,
"VMwareTray.exe"
)
=
=
0
|| strcmp(pe32.szExeFile,
"VMwareUser.exe"
)
=
=
0
)
{
return
TRUE;
}
bMore
=
Process32Next(hProcessSnap, &pe32);
}
CloseHandle(hProcessSnap);
return
FALSE;
}
[HKEY_LOCAL_MACHINE_HARDWARE\DEVICEMAP\Scsi\Scsi Port
0
\Scsi Bus
0
\Target
Id
0
\Logical Unit
Id
0
]
"Identifier"
=
"VMware Virtual IDE Hard Drive"
"Type"
=
"DiskPeripheral"
[HKEY_LOCAL_MACHINE_HARDWARE\SOFTWARE\Microsoft\Windows\CurrentVersion\Reinstall\
0000
]
"DeviceDesc"
=
"VMware Accelerated AMD PCNet Adapter"
"DisplayName"
=
"VMware Acceleeated AMD PCNet Adapter"
"Mfg"
=
"VMware,Inc."
"ProviderName"
=
"VMware,Inc."
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{
4D36E96F
-
E325
-
11CE
-
BFC1
-
08002BE10318
}\
0000
]
"LocationInformationOverride"
=
"plugged into PS/2 mouse port"
"InfPath"
=
"oem13.inf"
"InfSection"
=
"VMMouse"
"ProviderName"
=
"VMware,Inc."
[HKEY_LOCAL_MACHINE_HARDWARE\DEVICEMAP\Scsi\Scsi Port
0
\Scsi Bus
0
\Target
Id
0
\Logical Unit
Id
0
]
"Identifier"
=
"VMware Virtual IDE Hard Drive"
"Type"
=
"DiskPeripheral"
[HKEY_LOCAL_MACHINE_HARDWARE\SOFTWARE\Microsoft\Windows\CurrentVersion\Reinstall\
0000
]
"DeviceDesc"
=
"VMware Accelerated AMD PCNet Adapter"
"DisplayName"
=
"VMware Acceleeated AMD PCNet Adapter"
"Mfg"
=
"VMware,Inc."
"ProviderName"
=
"VMware,Inc."
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{
4D36E96F
-
E325
-
11CE
-
BFC1
-
08002BE10318
}\
0000
]
"LocationInformationOverride"
=
"plugged into PS/2 mouse port"
"InfPath"
=
"oem13.inf"
"InfSection"
=
"VMMouse"
"ProviderName"
=
"VMware,Inc."
string mac;
if
(mac
=
=
"00-0c-29"
)
{
return
TRUE;
}
else
return
FALSE;
string mac;
if
(mac
=
=
"00-0c-29"
)
{
return
TRUE;
}
else
return
FALSE;
虚拟机监视器VMM(Virtual Machine Monitor)是一个运行在宿主机系统,用来监视虚拟机状态的监视器。VMM为客户及操作系统提供一个完整的虚拟平台。但是VMM也存在一些可以被恶意代码探测到虚拟化的安全缺陷。
虚拟机监视器VMM(Virtual Machine Monitor)是一个运行在宿主机系统,用来监视虚拟机状态的监视器。VMM为客户及操作系统提供一个完整的虚拟平台。但是VMM也存在一些可以被恶意代码探测到虚拟化的安全缺陷。
BOOL
IsVMWarePre()
{
ULONG xdt
=
0
;
ULONG InVM
=
0
;
__asm
{
push edx
sidt [esp
-
2
]
pop edx
nop
mov xdt , edx
}
if
(xdt >
0xd0000000
)
{
InVM
=
1
;
}
else
{
InVM
=
0
;
}
__asm
{
push edx
sgdt [esp
-
2
]
pop edx
nop
mov xdt , edx
}
if
(xdt >
0xd0000000
)
{
InVM
+
=
1
;
}
if
(InVM
=
=
0
)
{
return
FALSE;
}
else
{
return
TRUE;
}
BOOL
IsVMWarePre()
{
ULONG xdt
=
0
;
ULONG InVM
=
0
;
__asm
{
push edx
sidt [esp
-
2
]
pop edx
nop
mov xdt , edx
}
if
(xdt >
0xd0000000
)
{
InVM
=
1
;
}
else
{
InVM
=
0
;
}
__asm
{
push edx
sgdt [esp
-
2
]
pop edx
nop
mov xdt , edx
}
if
(xdt >
0xd0000000
)
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2020-11-16 12:51
被Golden_Boy编辑
,原因: