使用 WMI 查询安全软件信息

在这篇文章中,我们将详细介绍如何使用 Windows Management Instrumentation (WMI) API 来查询当前计算机上安装的安全软件的基本信息。我们将分析代码的各个部分,并解释每个步骤所涉及的技术和原理。

一、什么是 WMI?

WMI 是 Windows Management Instrumentation 的缩写,是微软提供的用于管理 Windows 系统的一种技术。它提供了一种标准的接口,允许开发者通过编程方式获取和操作 Windows 操作系统的各种信息,包括硬件、软件、网络配置等。WMI 是基于 CIM(Common Information Model)标准的实现,它使用了面向对象的方式来组织和表示系统的信息。

二、相关函数解释

以下是代码中使用的一些函数以及它们的参数的解释,摘抄了 MSDN 文档的相关内容:

CoInitializeEx

HRESULT CoInitializeEx(
  LPVOID pvReserved,
  DWORD  dwCoInit
);
  • pvReserved:保留参数,必须为 NULL
  • dwCoInit:初始化标志,指定了线程的并发模型。

 详情请参阅:CoInitializeEx function (combaseapi.h)

CoCreateInstance

HRESULT CoCreateInstance(
  REFCLSID  rclsid,
  LPUNKNOWN pUnkOuter,
  DWORD     dwClsContext,
  REFIID    riid,
  LPVOID    *ppv
);
  • rclsid:类标识符(CLSID)。
  • pUnkOuter:用于控制对象的外部创建的指针。通常为 NULL
  • dwClsContext:指定服务器的执行环境。
  • riid:接口标识符(IID)。
  • ppv:接收指向所请求接口的指针的地址。

详情请参阅:CoCreateInstance function (combaseapi.h)

CoSetProxyBlanket

HRESULT CoSetProxyBlanket(
  IUnknown                 *pProxy,
  DWORD                    dwAuthnSvc,
  DWORD                    dwAuthzSvc,
  OLECHAR                  *pServerPrincName,
  DWORD                    dwAuthnLevel,
  DWORD                    dwImpLevel,
  RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
  DWORD                    dwCapabilities
);
  • pProxy:指向要设置代理参数的接口指针的指针。
  • dwAuthnSvc:身份验证服务。
  • dwAuthzSvc:授权服务。
  • pServerPrincName:服务器的主体名称。
  • dwAuthnLevel:身份验证级别。
  • dwImpLevel:实现级别。
  • pAuthInfo:身份验证信息。
  • dwCapabilities:代理的功能标志。

 详情请参阅:CoSetProxyBlanket function (combaseapi.h)

IWbemServices::ExecQuery

HRESULT ExecQuery(
  [in]          const BSTR   strQueryLanguage,
  [in]          const BSTR   strQuery,
  [in]          long         lFlags,
  [in]          IWbemContext *pCtx,
  [out]         IEnumWbemClassObject **ppEnum
);
  • strQueryLanguage:查询语言,例如 "WQL"。
  • strQuery:查询字符串。
  • lFlags:标志,指定查询的行为。
  • pCtx:指向 WMI 上下文对象的指针。
  • ppEnum:接收指向查询结果集的指针的地址。

 详情请参阅:IWbemServices::ExecQuery method (wbemcli.h)

IEnumWbemClassObject::Next

HRESULT Next(
  [in]  LONG            lTimeout,
  [in]  ULONG           uCount,
  [out] IWbemClassObject **apObj,
  [out] ULONG           *puReturned
);
  • lTimeout:超时值,以毫秒为单位,或者可以指定为 WBEM_INFINITE 以表示无限超时。
  • uCount:要检索的对象数。
  • apObj:接收对象的数组。
  • puReturned:实际返回的对象数。

 详情请参阅:IEnumWbemClassObject::Next method (wbemcli.h)

这些函数和参数提供了在代码中使用 WMI API 时的基本操作和配置。通过了解这些函数的作用和参数的含义,可以更好地理解代码的功能和实现原理。

三、代码解析

让我们逐步分析代码并解释其中的各个部分。

3.1 初始化 COM

HRESULT hres = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

这一行代码初始化了 COM(Component Object Model)库,COM 是一种微软提供的用于组件化软件的技术,它允许不同的组件通过接口进行通信和交互。

3.2 创建 WMI Locator

IWbemLocator* pLoc = NULL;
hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);

这段代码创建了一个 WMI Locator 对象,它是用于定位和连接 WMI 服务的接口。 CLSID_WbemLocator 是 WMI Locator 的类标识符,IID_IWbemLocator 是 WMI Locator 的接口标识符。

3.3 连接 WMI 服务

IWbemServices* pSvc = NULL;
hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\SecurityCenter2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);

这段代码连接到了 WMI 服务,并指定了要连接的命名空间为 ROOT\SecurityCenter2。在这个命名空间中,我们可以查询关于安全中心的信息,包括安装的安全软件信息。

3.4 设置代理参数

hres = CoSetProxyBlanket(
    pSvc,                        
    RPC_C_AUTHN_WINNT,           
    RPC_C_AUTHZ_NONE,            
    NULL,                        
    RPC_C_AUTHN_LEVEL_CALL,      
    RPC_C_IMP_LEVEL_IMPERSONATE, 
    NULL,                        
    EOAC_NONE                    
);

这段代码设置了用于 WMI 服务的代理参数,包括身份验证方式、权限级别等。

3.5 执行查询

hres = pSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT * FROM AntiVirusProduct"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &pEnumerator
);

这段代码执行了一个 WMI 查询,查询的语句是 “SELECT * FROM AntiVirusProduct”,表示查询 AntiVirusProduct 类的所有实例。

3.6 处理查询结果

while (pEnumerator)
{
    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
    if (0 == uReturn)
    {
        break;
    }

    // 获取属性值并输出
    // ...
}

这段代码处理了查询结果,逐个获取实例的属性值并输出。

四、完整代码和测试

完整代码如下所示:

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>

# pragma comment(lib, "wbemuuid.lib")

using namespace std;

int main(int argc, char** argv)
{
    setlocale(LC_ALL, ".utf8");

    // Initialize COM. ------------------------------------------ 
        HRESULT hres = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (FAILED(hres))
    {
        wcout << "CoInitializeEx() failure:" << hex << (unsigned long)hres;
        return 0;
    }

    // Obtain the initial locator to Windows Management 
    // on a particular host computer. 
    IWbemLocator* pLoc = NULL;
    hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc);
    if (FAILED(hres))
    {
        CoUninitialize();
        wcout << "CreateInstance failure:" << hex << (unsigned long)hres;
        return 0;
    }

    // Connect to WMI through the IWbemLocator::ConnectServer method 
    // Connect to the local ROOT\CIMV2 namespace 
    // and obtain pointer pSvc to make IWbemServices calls. 
    IWbemServices* pSvc = NULL;
    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\SecurityCenter2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);

    if (FAILED(hres))
    {
        pLoc->Release();
        CoUninitialize();
        wcout << "ConnectServer() failure:" << hex << (unsigned long)hres;
        return 0;
    }

    cout << "Connected to ROOT//SecurityCenter2 WMI namespace" << endl;

    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
        pSvc,                        // Indicates the proxy to set
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
        NULL,                        // Server principal name 
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // client identity
        EOAC_NONE                    // proxy capabilities 
    );


    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        cin.get();
        return 1;               // Program has failed.
    }

    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----

    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;

    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("SELECT * FROM AntiVirusProduct"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);

    if (FAILED(hres))
    {
        cout << "Query for operating system name failed."
            << " Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        cin.get();
        return 1;               // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------

    IWbemClassObject* pclsObj;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
            &pclsObj, &uReturn);
        if (0 == uReturn)
        {
            break;
        }


        VARIANT vtProp{};
        // Get the value of the Name property
        hr = pclsObj->Get(L"displayName", 0, &vtProp, 0, 0);
        wcout << "AntiVirus  Product displayName : " << vtProp.bstrVal << endl;
        hr = pclsObj->Get(L"companyName", 0, &vtProp, 0, 0);
        wcout << "AntiVirus  Product companyName : " << vtProp.bstrVal << endl;
        hr = pclsObj->Get(L"pathToSignedProductExe", 0, &vtProp, 0, 0);
        wcout << "AntiVirus  Product pathToSignedProductExe : " << vtProp.bstrVal << endl;
        hr = pclsObj->Get(L"versionNumber", 0, &vtProp, 0, 0);
        wcout << "AntiVirus  Product versionNumber : " << vtProp.bstrVal << endl;
        VariantClear(&vtProp);
        pclsObj->Release();
    }


    // Cleanup
    // ========
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    //pclsObj->Release();
    CoUninitialize();
    cin.get();
    return 0;   // Program successfully completed.
}

测试过程的截图如下所示:

测试结果截图

总结

通过使用 WMI API,我们可以方便地查询和管理 Windows 系统的各种信息。在本文中,我们介绍了如何使用 WMI 查询当前计算机上安装的安全软件的基本信息,包括初始化 COM、连接 WMI 服务、执行查询以及处理查询结果等步骤。通过深入了解 WMI API 的使用,我们可以更好地理解和利用 Windows 系统的管理功能。


发布于:2024.02.07,更新于:2024.02.07

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/378544.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BlueLotus 下载安装使用

说明 蓝莲花平台BlueLotus&#xff0c;是清华大学曾经的蓝莲花战队搭建的平台&#xff0c;该平台用于接收xss返回数据。 正常执行反射型xss和存储型xss&#xff1a; 反射型在执行poc时&#xff0c;会直接在页面弹出执行注入的poc代码&#xff1b;存储型则是在将poc代码注入用…

基于51 单片机的交通灯系统 源码+仿真+ppt

主要内容&#xff1a; 1&#xff09;南北方向的绿灯、东西方向的红灯同时亮40秒。 2&#xff09;南北方向的绿灯灭、黄灯亮5秒&#xff0c;同时东西方向的红灯继续亮。 3&#xff09;南北方向的黄灯灭、左转绿灯亮&#xff0c;持续20秒&#xff0c;同时东西方向的红灯继续…

Spinnaker多云持续交付平台: 部署Minio存储服务

目录 一、实验 1.环境 2.K8S storage节点部署NFS 3.K8S 动态创建PV 4.K8S master节点部署HELM3 4.K8S master节点部署Minio存储服务&#xff08;第一种方式安装&#xff09; 5.Minio客户端安装MC命令 6.K8S master节点使用Docker 部署Minio存储服务&#xff08;第二种方…

设计模式学习笔记05(小滴课堂)

讲解Adapeter设计模式和应用场景 接口的适配器案例实战 代码&#xff1a; 定义一个接口&#xff1a; 编写适配器&#xff1a; 写我们的商品类&#xff1a; 会员类&#xff1a; 这样我们不同的需求可以根据需要去实现不同的接口方法&#xff0c;而不用实现全部接口方法。 适配…

elasticsearch重置密码操作

安装es的时候需要测试这个url&#xff1a;http://127.0.0.1:9200/ 出现弹窗让我输入账号和密码。我第一次登录&#xff0c;没有设置过账号和密码&#xff0c; 解决方法是&#xff1a;在es的bin目录下打开cmd窗口&#xff0c;敲命令&#xff1a;.\elasticsearch-reset-password…

移动Web——Bootstrap

1、Bootstrap-简介 Bootstrap是由Twitter公司开发维护的前端UI框架&#xff0c;它提供了大量编写好的CSS样式&#xff0c;允许开发者结合一定HTML结构及JavaScript&#xff0c;快速编写功能完善的网页及常见交互效果 <!DOCTYPE html> <html lang"en"> &…

上海亚商投顾:成交量突破万亿 沪指重回2800

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 昨日A股三大指数延续上涨&#xff0c;深成指领涨&#xff0c;沪指重新站上2800点。不过&#xff0c;指数黄白分…

MATLAB环境下基于深层小波时间散射网络的ECG信号分类

2012年&#xff0c;法国工程学院院士Mallat教授深受深度学习结构框架思想的启发&#xff0c;提出了基于小波变换的小波时间散射网络&#xff0c;并以此构造了小波时间散射网络。 小波时间散射网络的结构类似于深度卷积神经网络&#xff0c;不同的是其滤波器是预先确定好的小波…

从源码学习访问控制符使用

从源码学习访问控制符使用 Java中的访问控制符 ​ 在Java中&#xff0c;有四个访问控制符&#xff1a;public、protected、default&#xff08;默认或缺省&#xff0c;不使用关键字&#xff09;和private。 ​ 它们的访问范围如下&#xff1a; public&#xff1a;公共访问权…

【人工智能】人工智能 – 引领未来科技的潮流

写在前面 引言红利挑战结论 引言 人工智能是指使计算机系统表现出类似于人类智能的能力。其目标是实现机器具备感知、理解、学习、推理和决策等智能行为。人工智能的发展可以追溯到上世纪50年代&#xff0c;随着计算机技术和算法的不断进步&#xff0c;人工智能得以实现。 今天…

『运维备忘录』之 Kubernetes(K8S) 常用命令速查

一、简介 kubernetes&#xff0c;简称K8s&#xff0c;是用8代替名字中间的8个字符“ubernete”而成的缩写&#xff0c;是一个开源的&#xff0c;用于管理云平台中多个主机上的容器化的应用。kubernetes是基于容器技术的分布式架构解决方案&#xff0c;具有完备的集群管理能力&a…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月8日,星期四

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月8日 星期四 农历腊月廿九 1、 气象局&#xff1a;南方地区雨雪冰冻天气趋于结束&#xff0c;需警惕融雪融冰引发的次生灾害。 2、 应急管理部&#xff1a;1月各种自然灾害共造成228.9万人次不同程度受灾&#xff0c;直…

网络套件字(理论知识)

一、源IP地址和目的IP地址 上次说到IP地址是为了是为了让信息正确的从原主机传送到目的主机&#xff0c;而原IP地址和目的IP地址就是用于标识两个主机的&#xff0c;既然叫做地址必然有着路径规划的作用&#xff0c;而路径规划最重要的就是&#xff0c;从哪来到哪去&#xff0…

计算机毕业设计 | SSM超市进销存管理系统(附源码)

1&#xff0c;绪论 1.1 开发背景 世界上第一个购物中心诞生于美国纽约&#xff0c;外国人迈克尔库伦开设了第一家合作商店&#xff0c;为了更好地吸引大量客流量&#xff0c;迈克尔库伦精心设计了低价策略&#xff0c;通过大量进货把商品价格压低&#xff0c;通过商店一次性集…

论文封面下划线总是对不齐,这3步你肯定没做!

论文封面 在写论文时&#xff0c;总会遇到论文封面下划线对不齐&#xff0c;学会下面这三招轻松搞定封面。 解决方法 ①选中文字&#xff0c;点击“插入”&#xff0c;选择“表格”&#xff0c;找到“文本转化为表格”。列数为2&#xff0c;文字分割位置选空格&#xff0c;设置…

路由器如何映射端口映射?

在现代互联网中&#xff0c;随着网络应用的不断发展&#xff0c;很多用户需要进行远程访问或搭建服务器来满足自己的需求。由于网络安全的原因&#xff0c;直接将内网设备暴露在公网中是非常危险的。为了解决这个问题&#xff0c;路由器映射端口映射技术应运而生。本文将介绍什…

Python进阶--爬取美女图片壁纸(基于回车桌面网的爬虫程序)

目录 一、前言 二、爬取下载美女图片 1、抓包分析 a、分析页面 b、明确需求 c、抓包搜寻 d、总结特点 2、编写爬虫代码 a、获取图片页网页源代码 b、提取所有图片的链接和标题 c、下载并保存这组图片 d、 爬取目录页的各种类型美女图片的链接 e、实现翻页 三、各…

HACKTHEBOX通关笔记——mango(退役)

信息收集 端口扫描 ┌──(root㉿kali)-[~] └─# nmap -sC -sV -A -p- --min-rate10000 10.129.229.185 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-01-31 20:44 EST Warning: 10.129.229.185 giving up on port because retransmission cap hit (10). Nmap scan …

秘塔科技推出AI搜索产品「秘塔AI搜索」

近日&#xff0c;国内一家人工智能科技公司&#xff08;秘塔科技&#xff09;推出了一款AI搜索产品——秘塔AI搜索&#xff0c;能够大幅提升搜索效率&#xff0c;解决日常生活、工作学习等场景中遇到的各类搜索需求。 秘塔AI搜索官网&#xff1a;https://metaso.cn/ 相较于传统…

《小狗钱钱2》读书笔记

目录 前言 作者简介 经典语句摘录 前言 尽管[ 智慧是无法传授的], 但读书可以启发思路&#xff0c;开拓解题方法。 《小狗钱钱2》这本书是在《小狗钱钱》的基础上&#xff0c;作业进一步阐述了关于人生出生的智慧。 当然了&#xff0c;这本书感觉更适合成年人来看&#xff0…