VMP有个检测虚拟机的选项,这里只说过vmware检测的方法。
下面就来说下过这个检测的方法:
1.在VM_Retn 末尾处下好断,如下:
//VM_Retn
010536CC Main retn 50 //这里下好断
2.断下后,F7后,看代码,一直到出口处的指令为
0102F393 ED in eax,dx
0102F394 9C pushfd
0102F395 57 push edi
0102F396 C74424 04 FEFCF284 mov dword ptr ss:[esp+4],84F2FCFE
0102F39E 60 pushad
0102F39F C74424 20 72265BE7 mov dword ptr ss:[esp+20],E75B2672
3.F7步过0102F393 ED in eax,dx后,把edx,ebx寄存器的值清0
4.F9运行,发现可以正常运行了。
很简单,方法也是很老的东西了。原理就是:
in eax,dx这条指令在R3下会产生异常,而VMP在SEH里重新设置了新的EIP,初始化了新的VMContext,而在虚拟机里,这个异常不会触发。
简单的代码如下(摘自shellwolf在反调试文章的代码):
bool IsInsideVMWare_()
{
bool r;
_asm
{
push edx
push ecx
push ebx
mov eax, 'VMXh'
mov ebx, 0 // any value but MAGIC VALUE
mov ecx, 10 // get VMWare version
mov edx, 'VX' // port number
in eax, dx // read port
// on return EAX returns the VERSION
cmp ebx, 'VMXh' // is it a reply from VMWare?
setz [r] // set return value
pop ebx
pop ecx
pop edx
}
return r;
}
bool FV_VMWare_VMX()
{
__try
{
return IsInsideVMWare_();
}
__except(1) // 1 = EXCEPTION_EXECUTE_HANDLER
{
return false;
}
}
补充下:如果不懂分析VM的handler,不懂哪条是VM_Retn的话,那就CTRL+F,搜in eax,dx指令下断吧!