反调试——8——虚拟机检测

发布时间:2022-07-03 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了反调试——8——虚拟机检测脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

反调试——8——虚拟机检测

其实虚拟机检测也无外乎就是检测一些虚拟机特有的特征,然后来判断是否是在虚拟机里面,比如说这里(查看系统中运行的服务):

反调试——8——虚拟机检测

 

 

但是不能直接盲目的通过VMware这六个关键字母就判断是在虚拟机里面了,因为你的脑如果开了虚拟机,也会有一些VMware开头的虚拟机服务:

反调试——8——虚拟机检测

 

 

所以我们必须要选取一些比较唯一的,比如说这里我们选这个VMware SVGA HelPEr Service这个把,大家可以自行选择。然后需要做的就是遍历系统中的服务,看看有没有这个东西就行了。

遍历系统中的服务:

这里会用到一个API:

EnumServicesstatusA function (winsvc.h) - Win32 apps | Microsoft Docs

BOOL EnumServicesStatusA(  SC_HANDLE              hSCManager,  DWORD                  dwServiceType,  DWORD                  dwServiceState,  LPENUM_SERVICE_STATUSA lpServices,  DWORD                  cbBufSize,  LPDWORD                pcbBytesNeeded,  LPDWORD                lpServicesReturned,  LPDWORD                lPResumeHandle);

然后这个API的第一个参数需要用OpenSCManager这个API来使用:OpenSCManagerA function (winsvc.h) - Win32 apps | Microsoft Docs

 

SC_HANDLE OpenSCManagerA(  LPCSTR lpMachineName,//如果值为0表示本机  LPCSTR lpDatabaseName,  DWORD  dwDesiredAccess);

然后这个服务数据库的句柄必须调用一个API来关闭:

CloseServiceHandle()

 

void testVirtual()
{
    auto hSCM = OpenSCManagerA(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
    /*
    第一个为NULL表示是本机,
    第二个参数是指定值,
    第三个参数表示权限,如果要调用枚举服务API就需要是这个权限。
    */
    if (hSCM == NULL)
    {
        cout << "打开系统服务数据库错误" << endl;
        return;
    }
    LPENUM_SERVICE_STATUSA lpServiceStatus = NULL;
    lpServiceStatus = (LPENUM_SERVICE_STATUSA)malloc(0x8000);
    DWORD servieceSize = 0;
    DWORD needSize = 0;
    DWORD resumeHandle = 0;
    auto ret = EnumServicesStatusA(hSCM, SERVICE_WIN32, SERVICE_STATE_ALL, lpServiceStatus, 0x8000, &needSize, &servieceSize, &resumeHandle);
    /*
    第一个参数:是服务数据库的句柄
    第二个参数:是要的服务的类型,这里不直到怎么查看我就全部加上了
    第三个参数:服务的状态,是否启动
    第四个参数:服务结构体的缓冲区
    第五个参数:缓冲区大小
    第六个参数:如果缓冲区大小不够,需要的剩下的大小是多少
    第七个参数:得到的服务的数量
    第八个参数:缓冲区不够的时候下一个服务的结构体指针
    */
    if(needSize>0x8000)
    {
        cout << "缓冲区过小" << endl;
        return;
    }
​
    for (int i = 0; i < servieceSize; i++)
    {
        if (strcmp(lpServiceStatus->lpDisplayName, "VMware SVGA Helper Service")==0)
        {
            cout<<"检测到了虚拟机"<<endl;
            return ;
        }
        lpServiceStatus++;
    }
    cout << "没有检测到虚拟机" << endl;
    CloseServiceHandle(hSCM);
}

 

反调试——8——虚拟机检测

 

 

还有很多方式,大家可以入手,只要是可以唯一标识虚拟机就好。

特殊的办法

这个办法我也不知道为什么。不是虚拟机的环境运行下面的代码会崩溃。是虚拟机则安然无恙。

            push   edx
            push   ecx
            push   ebx
            mov    eax, 'VMXh'
            mov    ebx, 0
            mov    ecx, 10 
            mov    edx, 'VX' 
            in     eax, dx 
            cmp    ebx, 'VMXh'
            pop    ebx
            pop    ecx
            pop edx

 

//代码实现:
void testAsSEMer()
{
    int FLAG = FALSE;
    __try
    {
        __asm
        {
            push   edx
            push   ecx
            push   ebx
            mov    eax, 'VMXh'
            mov    ebx, 0
            mov    ecx, 10
            mov    edx, 'VX'
            in     eax, dx
            cmp    ebx, 'VMXh'
            pop    ebx
            pop    ecx
            pop edx
        }
    }
    __except(1)
    {
        FLAG = TRUE;
    }
    if (FLAG == FALSE)
    {
        cout << "检测到了虚拟机" << endl;
    }
    else
    {
        cout << "未检测到虚拟机" << endl;
    }
}

 

反调试——8——虚拟机检测

 

 

小结

虚拟机和本机肯定是有一些不同的,抓住这些验证不同的办法就可以来检测是否是在虚拟机里了。

脚本宝典总结

以上是脚本宝典为你收集整理的反调试——8——虚拟机检测全部内容,希望文章能够帮你解决反调试——8——虚拟机检测所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。