超级兔子,鲁大师神马的软件检测硬件用到的主要技术手段就是WMI,上次被同事问到,抽空看了下,还不错,主要依赖com技术实现,客户端程序通过查询的方式向com服务器进行相关信息的询问。有以下一些概念要了解下:
1、WBEM - Web Based Enterprise Management的缩写,一种行业规范,建立了在企业网络中访问和共享管理信息的标准。
2、WMI - Windows Management Instrumentation的缩写,是WBEM在Windows下的实现。通过WMI,我们可以获取关于硬件/软件的数据,也可以提供关于硬件或软件服务的数据给WMI。
3、CIM - Common Information Model(公共信息模型)的缩写。在WMI架构中,CIM对象部件是结构的中心部件,控制着信息的流程。CIM把管理区域分为物理区域和逻辑区域,他们分别对应管理环境的物理和逻辑元素。而逻辑域又可进一步分为系统域、设备域、应用程序域和网络域。
WMI的核心就是一个CIM管理器,客户端程序直接向它进行信息查询和信息设置。
既然是基于com的,那就意味着,客户端程序是不限语言的,管你神马c++还是脚本,只要遵守它的调用规范,它都会来者不拒,告诉你想知道。
windows系统下带了一个wmi的测试器,直接在run下运行wbemtest即可调出来。可以通过这个玩意进行手工的查询和检测。可以摸索下怎么使用,不错的小工具。写wmi程序搜查必备啊。
放点源代码(其实网上这样代码很多,大同小异,因为调用规范已经给你限死了),检测本地安装安全软件,其实这个依赖于安全软件是否向wmi进行了注册,如果安全软件不向wmi注册自然是啥都查不到。不过令人高兴的是基本上正规的杀软都会向系统注册的。
// 初始化 …… HRESULT hRes; hRes = CoInitialize( NULL ); if ( FAILED(hRes) ) { return FALSE; } hRes = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0 ); if ( FAILED(hRes) && RPC_E_TOO_LATE != hRes ) { return FALSE; } hRes = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (LPVOID *)&m_pLocator ); if ( FAILED(hRes) ) { return FALSE; } return TRUE; …… // 查询 …… IWbemLocator * pWbemLocator = NULL; IWbemServices * pWbemServices = NULL; IEnumWbemClassObject * pEnumWbemClassObject = NULL; IWbemClassObject * pWbemClassObject = NULL; HRESULT hRes = S_OK; BOOL bRes = TRUE; ULONG ulReturn = 0; ANTIVIRUSPRODUCT product; VARIANT variant; _bstr_t bString; BSTR bStr = NULL; hRes = m_pLocator->ConnectServer( _T("root//SecurityCenter"), NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices ); if ( FAILED(hRes) ) { hRes = m_pLocator->ConnectServer( _T("root//SecurityCenter2"), NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices ); if ( FAILED(hRes) ) { return FALSE; } } hRes = pWbemServices->ExecQuery( _T("WQL"), _T("Select * from AntiVirusProduct"), WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumWbemClassObject ); if ( FAILED(hRes) ) { return FALSE; } hRes = pEnumWbemClassObject->Reset(); if ( FAILED(hRes) ) { return FALSE; } while( true ) { hRes = pEnumWbemClassObject->Next( WBEM_INFINITE, 1, &pWbemClassObject, &ulReturn ); if ( WBEM_S_FALSE == hRes ) { break; } else if ( FAILED(hRes) ) { return FALSE; } hRes = pWbemClassObject->Get( _T("displayName"), 0, &variant, NULL, NULL ); if ( WBEM_S_NO_ERROR == hRes ) { product.strProductName = variant; } else if ( WBEM_E_NOT_FOUND == hRes ) { product.strProductName = _T(""); } else { continue; } VariantClear( &variant ); hRes = pWbemClassObject->Get( _T("companyName"), 0, &variant, NULL, NULL ); if ( WBEM_S_NO_ERROR == hRes ) { product.strCompanyName = variant; } else if ( WBEM_E_NOT_FOUND == hRes ) { product.strCompanyName = _T(""); } else { continue; } hRes = pWbemClassObject->Get( _T("versionNumber"), 0, &variant, NULL, NULL ); if ( WBEM_S_NO_ERROR == hRes ) { product.strVersionNumber = variant; } else if ( WBEM_E_NOT_FOUND == hRes ) { product.strVersionNumber = _T(""); } else { continue; } hRes = pWbemClassObject->Get( _T("productUptoDate"), 0, &variant, NULL, NULL ); if ( WBEM_E_NOT_FOUND == hRes ) { product.bExpired = true; } else if ( WBEM_S_NO_ERROR == hRes ) { product.bExpired = !variant.boolVal; } else { continue; } m_productList.push_back( product ); } return TRUE; …… // 反初始化 …… if (m_pLocator) { m_pLocator->Release(); } CoUninitialize(); ……