使用 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 setRPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxxRPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxxNULL,                        // Server principal name RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxxNULL,                        // client identityEOAC_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 systemIEnumWbemClassObject* 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 propertyhr = 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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue安装与配置

写入借鉴网址&#xff1a;好细的Vue安装与配置_vue配置-CSDN博客 下载Vue安装地址&#xff1a; Node.js — Download 查看是否安装成功&#xff1a; node -v npm -v 配置全局模式及缓存 结果通过&#xff1a; C:\Windows\system32>npm install vue -g added 20 packages …

大学生活的“三角平衡”与“合法”偷懒艺术

在那个被称为大学的神奇乐园里&#xff0c;我终于找到了自我&#xff0c;或者说&#xff0c;我找到了一种平衡。这种平衡被我称为“三角平衡”&#xff0c;它是由懒觉、兴趣爱好和学习这三者构成的。在这个平衡中&#xff0c;我像一名杂技演员一样&#xff0c;稳稳地站在三个顶…

jsp商场会员卡管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 商场会员卡管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.…

python中sort()函数的详细使用方法

目录 使用reverse指定排序顺序 使用key指定排序规则 使用匿名函数制定规则 定义比较函数制定规则 制定多规则 多复杂规则排序 sort()是python非常好用的排序函数&#xff0c;可以对一个列表进行排序&#xff0c;这个排序只是会修改原列表&#xff0c;不会创建新的列表 使…

2024年 复习 HTML5+CSS3+移动web 笔记 之CSS遍 第6天

6.1 定位-相对和绝对和固定 6.2 相对和绝对和固定 6.3 堆叠顺序z-index 6.4 定位总结 6.5 CSS精灵 基本使用 6.6 案例 CSS精灵 京东服务 6.7 字体图标-下载和使用 6.8 字体图标-上传 6.9 垂直对齐方式vertical-align 6.10 过渡属性 6.11 修饰属性-透明度与光标类型 6.12 综合案…

2.8 数据类型与作用域练习

1、选择题 1.1、以下选项中,不能作为合法常量的是 ___B___ A&#xff09;1.234e04 B&#xff09;1.234e0.4 C&#xff09;1.234e4 D&#xff09;1.234e0 解析&#xff1a;在C语言中&#xff0c;合法的浮点常量形式通常遵循以下规则&#xff1a;1.可以有整数部分、小数部…

string容器

1. string基本概念 1.1 本质&#xff1a; string是C风格的字符串&#xff0c;而string本质上是一个类 string和char * 区别&#xff1a; char * 是一个指针 string是一个类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char*型的容器。 1.2 特点…

Unity类银河恶魔城学习记录5-1.5-2 P62-63 Creating Player Manager and Skill Manager源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili PlayerManager.cs using System.Collections; using System.Collections.G…

ClickHouse的优缺点和应用场景

当业务场景需要一个大批量、快速的、可支持聚合运算的数据库&#xff0c;那么可选择ClickHouse。 选择ClickHouse 的原因&#xff1a; 记录类型类似于LOG&#xff0c;读取、运算远远大于写入操作选取有限列&#xff0c;对近千万条数据&#xff0c;快算的运算出结果。数据批量…

内网穿透工具

1. nps-npc 1.1 简介 nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发&#xff0c;可支持任何tcp、udp上层协议&#xff08;访问内网网站、本地支付接口调试、ssh访问、远程桌面&#xff0c;内网dns解析等等……&#xff09;&#xff0c…

Golang数据库编程详解 | 深入浅出Go语言原生数据库编程

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。 Golang学习专栏&#xff1a;https://blog.csdn.net/qq_35716689/category_12575301.html 前言 对数据库…

OLED调试简介

文章目录 一、介绍调试方法介绍OLED简介硬件电路OLED驱动函数 二、操作连接线路使用驱动函数显示内容 OLED.c的内容 一、介绍 调试方法介绍 OLED简介 硬件电路 OLED驱动函数 二、操作 连接线路 因为这两个引脚不做配置是浮空状态&#xff0c;在这里直接用电源给OLED供电 使…

【leetcode热题100】搜索二维矩阵

给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…

python实现中国剩余定理

中国剩余定理又称孙子定理&#xff0c;是数论中一个重要定理。最早可见于我国的数学著作《孙子算经》卷下“物不知数”问题&#xff0c;原文如下&#xff1a; 有物不知其数&#xff0c;三三数之剩二&#xff0c;五五数之剩三&#xff0c;七七数之剩二。问物几何&#xff1f;即…

《向量数据库指南》——Milvus Cloud「删除」:眼见未必为实

“执行 Collection 中的 delete 操作后,再次调用 num_entities 检查集合中的数据的条数,和删除前一致, delete 不能从物理层面上删除数据吗?”“删除的数据还能被查到是为什么?”“请问下删除 collection 后,磁盘大小没有恢复,该怎么处理?”社区中关于“删除”讨论最多…

Allergo_17_4安装记录

习惯用Allergo软件中的Orcad组件来画原理图&#xff0c;画PCB用PADS PADS的安装记录参考&#xff1a;PADS VX 2.7安装记录-CSDN博客 一、资源&#xff1a; 资源&#xff1a;百度云安装包&#xff1a;Cadence SPB 17.4-2019 安装包 提取码&#xff1a;ajow 二、安装 2.1 右键…

百面嵌入式专栏(面试题)C语言面试题22道

沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇我们将介绍C语言相关面试题 。 宏定义是在编译的哪个阶段被处理的?答案:宏定义是在编译预处理阶段被处理的。 解读:编译预处理:头文件包含、宏替换、条件编译、去除注释、添加行号。 写一个“标准”宏MIN,这个…

备战蓝桥杯---搜索(进阶3)

看一道比较难又有趣的题&#xff1a; 下面是分析&#xff1a; 我们不妨把属性值看成点&#xff0c;一个装备可以看成一条边&#xff08;只能选一个端点&#xff09;不存在有装备属性值的当成一个点&#xff0c;于是我们便形成了树或图&#xff0c;如果是树的话&#xff0c;有一…

XSS攻击 - 不要再硬背了

XSS攻击是所有程序员都知道的一件事&#xff0c;它也是前后端面试的一个常考点。也正如标题所说&#xff0c;很多人在背它&#xff0c;为什么要背它&#xff1f;这点我深有感悟&#xff0c;最近我突破了那个key&#xff0c;所以我想将它分享出来。 XSS攻击&#xff0c;其实都是…

字节3面真题,LeetCode上hard难度,极具启发性题解

文章目录 &#x1f680;前言&#x1f680;LeetCode&#xff1a;41. 缺失的第一个正整数&#x1f680;思路&#x1f680;整个代码思路串一下&#x1f680;Code &#x1f680;前言 铁子们好啊&#xff01;阿辉来讲道题&#xff0c;这道题据说是23年字节3面真题&#xff0c;LeetC…