WMI技术介绍和应用——Instance/Method Provider
在《WMI技术介绍和应用——事件通知》一文中,我们提到了提供者(Provider)这个概念。我们还是要引入WMI的结构图(转载请指明出于breaksoftware的csdn博客)
我们在1这层的Native C/C++里可以看到若干Provider,这些Provider将各个实例或者事件信息通过WMI core传递到上层。微软对这块内容在MSDN上没有给出详细的例子,所以一开始摸索起来非常困难,以致我一度想放弃对其的研究。但是好在找到一本《Developing WMI Solutions》,该书非常详细讲解了WMI的一些书写规则,虽然该书的网站已经不再维护,其事例代码也找不到了。但是循着书中的讲解,我还是将其摸索出来,以供大家参考。
instance provider
MSDN上说Virtual Studio的ATL模板里有WMI向导,并且推荐大家使用向导去生成WMI工程。需要注意的是,不是每个版本的VS都有这个向导,像我环境中的VS2015则没有,而VS2005则有。
我们先创建一个名字为Test_Instance的ATL工程
Server type选择Dynamic-link library (DLL),其他不选,我们将生成Test_Instance和Test_InstancePS两个工程。Test_InstancePS工程我们不用关心,直接删除就行了。我们选中Test_Instance工程,右击并选择Add,添加一个class。在向导里我们可以看到ATL下有WMI相关模板
Name字段还是填写Test_Instance,在Instance Provider的向导中,我们在short name项下填入我们需要实例化的类的名字TestClass
在WMI Class项中,我们不做任何修改,使用默认的root空间,其实最终我们真实使用的是root\default。
在Attribute项中,我们在Threading Model中选择Both,其他可选项都勾选上。
通过向导的设定,我们的工程中新增了TestClass.cpp、TestClass.h和Test_Instance.mof三个文件。Test_Instance.mof是我们向WMI仓库注册使用的文件,其他则是我们的代码文件。
向导已经帮我们在mof文件中生成了一大串内容。
#pragma autorecover#pragma namespace ("\\\\.\\root\\default")class Win32_ProviderEx : __Win32Provider
{[Description ( "Hosting Model, provides compatibility with Windows XP and Windows Server .NET. Do not override." ) , Override("HostingModel")]string HostingModel = "NetworkServiceHost";[Description("..."),Override("SecurityDescriptor")] string SecurityDescriptor; UInt32 version = 1;
} ;instance of Win32_ProviderEx as $TestClass
{Name = "TestClass" ; //Name is the key property for __Provider objects.//vendor|provider|version is the suggested format//to prevent name collisions.ClsId = "{7F1C3BD1-7732-403F-844F-CC6ED9CA85FE}" ; //provider GUIDDefaultMachineName = NULL; //NULL for local machineClientLoadableCLSID = NULL; //reservedImpersonationLevel = 0; //reservedInitializationReentrancy = 0; //Set of flags that provide information about serialization://0 = all initialization of this provider must be serialized//1 = all initializations of this provider in the same namespace must be serialized//2 = no initialization serialization is necessaryInitializeAsAdminFirst = FALSE; //Request to be fully initialized as "Admin" before //initializations begin for usersPerLocaleInitialization = FALSE; //Indicates whether the provider is initialized for each //locale if a user connects to the same namespace more //than once using different locales.PerUserInitialization = FALSE; //Indicates whether the provider is initialized once for each actual //Windows NT/Windows 2000 NTLM user making requests of the provider. //If set to FALSE, the provider is initialized once for all usersPure = TRUE; //A pure provider exists only to service requests from //applications and WMI. Most providers are pure providers.//Non-pure providers transition to the role of client after they have //finished servicing requests. UnloadTimeout = NULL; //Currently ignored//Use __CacheControl class in the root namespace to control provider unloading.//A string in the DMTF date/time format that specifies how long WMI //allows the provider to remain idle before it is unloaded.} ; instance of __InstanceProviderRegistration
{Provider = $TestClass;SupportsPut = "TRUE"; SupportsGet = "TRUE"; SupportsDelete = "TRUE"; SupportsEnumeration = "TRUE"; QuerySupportLevels = {"WQL:Associators","WQL:V1ProviderDefined","WQL:UnarySelect","WQL:References"};};instance of __MethodProviderRegistration
{Provider = $TestClass;
};
这一长串内容详细大家可以参看MSDN,其中主要的是__InstanceProviderRegistration和__MethodProviderRegistration实例申明。instance of __InstanceProviderRegistration是说我们需要一个Instance类型Provider的注册实例,instance of __MethodProviderRegistration是说我们需要一个Method类型Provider的注册实例。它们的Provider都是我们之前使用instance of Win32_ProviderEx as $TestClass申明的实例。前者用于实例方面的使用,比如获取对象、删除对象、查询信息等;后者用于方法方面的使用,比如我们之前说的Win32_Process的Create方法创建进程。
我们先修改mof文件,我们在文件末尾新增如下内容
[
dynamic : ToInstance,
provider("TestClass") : ToInstance, // uses the TestClass Provider
ClassContext("whatever!"), // information is dynamically// supported by the provider
DisplayName("ClassInstance"): ToInstance
] class ClassInstance
{
[key]
string name = "CIN";
[PropertyContext("ClassInstance_Member")]
string value = "CIV";
};
其中非常重要的是provider字段填写,它就是指向我们之前申明的provider。然后我们申明了一个ClassInstance的类,其有一个Key属性的变量name,还有一个普通类型变量value。
我们在到TestClass.cpp中修改相关内容。首先我们需要将类名定义为我们在mof文件中定义的类名
//TODO: define provided class name, e.g.:
const static WCHAR * s_pMyClassName = L"ClassInstance";
为了支持WQL查询,我们需要修改ExecQueryAsync方法,我们在其方法中新增如下逻辑
CComPtr<IWbemClassObject> sp_object;CComPtr<IWbemClassObject> pNewInst;hr = m_pClass->SpawnInstance(0, &pNewInst);if (FAILED(hr)) { return WBEM_E_INVALID_CLASS;}sp_object = pNewInst;CComVariant value;value.vt = VT_BSTR;value.bstrVal = CComBSTR("notepad.exe");sp_object->Put(L"name", 0, &value, 0);sp_object->Put(L"value", 0, &value, 0);hr = pResponseHandler->Indicate(1, &sp_object.p);hr = pResponseHandler->SetStatus(0, WBEM_S_NO_ERROR, NULL, NULL);
这段逻辑,我们通过SpawnInstance创建了mof定义的类的实例。然后通过Put方法,我们设置了其name和value变量的值。
代码修改好后,我们编译工程。工程编译中,会对mof文件进行检查和注册。我们还可以手工使用Mofcomp工具对mof文件进行注册。
使用regsvr32注册编译出来的dll文件。这样我们的实例便可以查询了,使用之前工程中的方法
CSynQueryData recvnotify(L"root\\default", L"SELECT * FROM ClassInstance");
recvnotify.ExcuteFun();
可以得到
method provider
我们再说说Method Provider。一个类的方法有静态和非静态之分,我们在mof里定义的类也是如此。我们对上例中的ClassInstance类新增两个方法
class ClassInstance
{
[key]
string name = "CIN";
[PropertyContext("ClassInstance_Member")]
string value = "CIV";[implemented]
void func();
[static, implemented]
void staticfunc();
};
其中func方法是非静态方法,staticfunc是静态方法。和C++中定义类似,静态方法我们要使用类名+方法名调用;非静态方法要使用对象调用。在WMI Provider中,执行方法的函数是ExecMethodAsync,我们对其进行修改
CComPtr<IWbemQualifierSet> pQualifierSet;hr = m_pClass->GetMethodQualifierSet(strMethodName, &pQualifierSet);if (SUCCEEDED(hr)) {hr = pQualifierSet->Get(L"static", 0, NULL, NULL);if (SUCCEEDED(hr)) {// static function. go on}else {CComPtr<IWbemClassObject> pInstance;hr = GetInstanceByPath(strObjectPath,&pInstance);if(FAILED(hr)) {// object is not existedreturn hr;}// object is existing. go on}}else{return hr;}
这段代码,我们检测函数是否使用了static修饰。如果是,则它是静态方法,我们就不用做对象是否存在的检查;如果不是静态方法,我们就要对对象是否存在进行检查,如果对象不存在,我们则应该返回相应错误,否则继续执行。
我想模拟Win32_Process的Create方法启动一个进程。我尝试了CreateProcess、ShellExcute等方法,均不成功。后来逆向了一下Win32_Process所以在的dll文件,发现其中启动进程是使用CreateProcessAsUser,且在此之前做了很多和用户有关的操作。为了简便,我们可以这样书写
HANDLE TokenHandle = NULL;OpenThreadToken(GetCurrentThread(), TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, 1, &TokenHandle);STARTUPINFO StartupInfo;memset(&StartupInfo, 0 , sizeof(StartupInfo));StartupInfo.wShowWindow = SW_SHOWNORMAL;PROCESS_INFORMATION ProcessInformation;memset(&ProcessInformation, 0, sizeof(ProcessInformation));BOOL bRet = CreateProcessAsUser( TokenHandle ,L"C:\\windows\\notepad.exe",NULL , NULL,NULL,FALSE , NORMAL_PRIORITY_CLASS | CREATE_BREAKAWAY_FROM_JOB ,NULL,NULL,&StartupInfo,&ProcessInformation);
该过程我们获取的权限和我们启动查询的进程中的线程相同。这样我们便将notepad启动起来。
我们对static方法的调用是这样的
CExcuteMethod* excute_method = NULL;{ParamsMap params;excute_method = new CExcuteMethod(L"root\\default", L"ClassInstance", L"", L"staticfunc", L"", params);excute_method->ExcuteFun();}delete excute_method;
对非static方法的调用,我们则要传入实例名
CExcuteMethod* excute_method = NULL;{ParamsMap params;excute_method = new CExcuteMethod(L"root\\default", L"ClassInstance", L"ClassInstance.name='notepad.exe'", L"staticfunc", L"", params);excute_method->ExcuteFun();}delete excute_method;
工程链接:http://pan.baidu.com/s/1geucuKb 密码:pcwl
相关文章:

SSH 组建轻量级架构 附录 -- 遇到的问题和解答
action: nulljava.lang.ClassNotFoundException: org.springframework.web.struts.ContextLoaderPlugIn解决方法:加载 spring.jar 包 报 无法初始化at org.apache.struts.action.ActionServlet.initModulePlugIns(解决方法:删除 asm-2.2.3.jar springda…
TIOBE 1月编程语言排行榜:C语言再度「C 位」出道,Python惜败
整理 | 屠敏来源 | CSDN(ID:CSDNnews)【导读】在 2020 年初雪来临之际,TIOBE 官方在最新发布的 1 月编程语言榜单中为我们最终揭开了「 2019 年度编程语言」的神秘面纱,然意料之外情理之中,获此殊荣的并非是…

my项目的总结2015.8.26编
这已经是上上个星期的事了,现在回顾一下: 负责的模块是"my",更精准的说应该是my里面的个人信息管理 由于项目分域,模块已经分好了,涉及到的只是在现有的基础上解决分域后遗留的历史问题 上点图吧:…
WMI技术介绍和应用——Event Provider
在《WMI技术介绍和应用——Instance/Method Provider》一文中,我们介绍了Instance和Method Provider的编写方法。本文我们将介绍更有意思的“事件提供者”。在《WMI技术介绍和应用——事件通知》中,我们曾经提到事件是分为两种:intrinsic eve…

Windows server 2003 IP路由配置
1、静态路由:在静态路由中必须明确指出从源到目标所经过的路径2、默认路由:默认路由是一种特殊的静态路由,为那些在路由表中没有找到明确匹配的路由信息的数据包指定下一步跳地址。在Windows server 2003的计算机上配置默认网关时就为该计算机…
人工智能的下一个前沿:识别“零”和“无”
所有参与投票的 CSDN 用户都参加抽奖活动群内公布奖项,还有更多福利赠送作者 | Max Versace译者 | 夕颜出品 | AI科技大本营(ID:rgznai100)声明:本文为客座文章,仅是为作者的观点,不代表 IEEE Spectrum 或 …

File Operations In Java
2019独角兽企业重金招聘Python工程师标准>>> The “File” class in Java defines many useful methods, here is a program which demonstrates some of these methods. import java.io.*;public class streams {public static void main(String []args){File f1ne…
Cascade RPN,结构的艺术带来极致提升 | NeurIPS 2019
作者 | VincentLee来源 | 晓飞的算法工程笔记(ID: gh_084c810bc839)导读:论文提出Cascade RPN算法来提升RPN模块的性能,该算法重点解决了RPN在迭代时anchor和feature不对齐的问题,论文创新点足,效果也很惊艳…

IIS+PHP+MySQL+Zend Optimizer+GD库+phpMyAdmin安装配置[完整修正实用版]
IISPHPMySQLZend OptimizerGD库phpMyAdmin安装配置[完整修正实用版]IISPHPMySQLZend OptimizerGD库phpMyAdmin安装配置[完整修正实用版][补充]关于参照本贴配置这使用中使用的相关问题请参考关于WIN主机下配置PHP的若干问题解决方案总结这个帖子尽量自行解决,谢谢[url]http://b…

WMI技术介绍和应用——Event Consumer Provider
在《WMI技术介绍和应用——Event Provider》和《WMI技术介绍和应用——接收事件》中,我们展现了如何处理和事件相关的WMI知识。而《WMI技术介绍和应用——接收事件》一文则主要讲解了如何查询事件,这种查询是在我们进程存在时发生的,一旦我们…

shell练习四
2019独角兽企业重金招聘Python工程师标准>>> 模拟linnux登录shell #!/bin/bash echo -n "login:" read name echo -n "passwd:" read passwdif [ $name"aaa" -a passwd"aaa" ]; thenecho "the host and passwd is rig…

WMI技术介绍和应用——总结(完)
断断续续的,历经三年将WMI这个主题给写完了。记得最开始时接触该技术,是因为传统获取CPU序列号的方法总是出错。于是接触了这种已经很老的技术。本着打破砂锅问到底的想法,我决定稍微研究一下,结果越来越深。正好借着年前这点时间…
2020年,大火的Python和JavaScript是否会被取而代之?
作者 | Richard Kenneth Eng 译者 | 明明如月,编辑 | 郭芮 来源 | CSDN(ID:CSDNnews) Python 和 JavaScript 是目前最火的两大编程语言。然而,他们不可能永远屹立不倒。最终,必将像其他编程语言一样跌下神坛…

WaveSwipeRefreshLayout
WaveSwipeRefreshLayout 介绍: 水滴效果的下拉刷新,效果非常不错。 http://itlanbao.com/code/20150815/10000/100423.html 运行效果: 相关代码 android Gallery 图片滚动 BalloonPerformerCountryRankDelightfulMenuDrawableFancyBackground…

Google Test(GTest)使用方法和源码解析——概况
GTest是很多开源工程的测试框架。虽然介绍它的博文非常多,但是我觉得可以深入到源码层来解析它的实现原理以及使用方法。这样我们不仅可以在开源工程中学习到实用知识,还能学习到一些思想和技巧。我觉得有时候思想和技巧是更重要的。(转载请指…
Reddit票选 | 2019年绝对不能错过的机器学习论文
来源 | reddit.com编辑 | 神经星星 神经小兮技术顾问 | 姜汉(openbayes.com)来源 | HyperAI超神经(ID:HyperAI)【导读】回顾 2019 年,人工智能领域时有大事发生,吸引着各界人士的关注。这一年,也…

ASP中的常用服务器检测源码
在写ASP网页时常用的检测代码:服务器现在时间: 引用<% now %>服务器CPU型号: 引用<%Request.ServerVariables("HTTP_UA_CPU")%>当前分辨率: 引用<% Request.ServerVariables("HTTP_UA_PIXELS")%>可显示颜色:[qoute]<%Request.ServerV…

选IDC房时,用脚本截取丢失包和rtt的值作比对
由于业务增长,需要选一个IDC房托管接入。网络质量要求比较高。在IDC给出测试机时,利用smokping来测试,是测出去的包。由于我们在各个地区都有接入机。再从这些接入机去测IDC网络质量,比对指标:丢失的包和rtt返回时延。…
Google Test(GTest)使用方法和源码解析——自动调度机制分析
在《Google Test(GTest)使用方法和源码解析——概况 》一文中,我们简单介绍了下GTest的使用和特性。从这篇博文开始,我们将深入代码,研究这些特性的实现。(转载请指明出于breaksoftware的csdn博客) 测试用例的自动保存…

D3D中简单的截图方法 (转)
【ZT】D3D中简单的截图方法 试了下,果然可以。在渲染完所有东东后(Present之前) 获得BackBuffer表面 然后用D3DX的函数保存 voidScreenShot (char*filename) { IDirect3DSurface9 *tmp NULL; IDirect3DSurface9 *back NULL; //生成固定…
2019年,自动化机器学习AutoML技术还火吗? | BDTC 2019
整理 | 王银出品 | AI科技大本营(ID:rgznai100) 【导读】12 月 5-7 日,由中国计算机学会主办,CCF 大数据专家委员会承办,CSDN、中科天玑协办的中国大数据技术大会(BDTC 2019)在北京长城饭店隆重…

第一次使用51cto博客
阿梅第一次使用51cto博客,以后将学习中的总结写到这里来。加油。转载于:https://blog.51cto.com/hopit/1690465

Google Test(GTest)使用方法和源码解析——结果统计机制分析
在分析源码之前,我们先看一个例子。以《Google Test(GTest)使用方法和源码解析——概况 》一文中最后一个实例代码为基准,修改最后一个“局部测试”结果为错误。(转载请指明出于breaksoftware的csdn博客) class ListTest : publi…
贾扬清感谢信:阿里开源10年,致敬千万开源人
整理 | 夕颜【导读】2019 年 10 月,有人曾根据 www.gharchive.org 的数据整理出一份 2019 年GitHub 开源贡献排行榜,获取 GitHub 2019 年的 PushEvent,通过分析 GitHub 用户提交记录中的邮件地址,分辨其所属组织。从这份榜单上可…

热烈庆祝我国神七发射成功!
热烈庆祝我国神七发射成功!
云计算设计模式(十)——守门员模式
云计算设计模式(十)——守门员模式 通过使用充当客户端和应用程序或服务之间的代理,验证和进行消毒的请求,并将它们之间的请求和数据的专用主机实例保护的应用程序和服务。这可以提供一个额外的安全层,并限制了系统的攻…
“不会Linux,怎么干程序员?”骨灰级工程师:干啥都不行!
说起优秀程序员的必备技能,我想大家都可以说很多,比如:数据结构、算法、数学、编程语言等等。但是,你可能会忽略了每一个程序员都应该掌握的技能:Linux。想一想,我们日常学习、求职、工作场景的中ÿ…
Google Test(GTest)使用方法和源码解析——Listener技术分析和应用
在《Google Test(GTest)使用方法和源码解析——结果统计机制分析》文中,我么分析了GTest如何对测试结果进行统计的。本文我们将解析其结果输出所使用到的Listener机制。(转载请指明出于breaksoftware的csdn博客) 解析 源码中,我们…

SSH连接不上Linux的解决方法
SSH连接不上Linux的解决方法: 连续弄了几次,今天早上终于把SSH连接虚拟机连接不通的问题解决了。 先简单说下概要: 主机装的是XP系统,虚拟机用的是red hat Linux。 我用的是nat连接方式是虚拟机内也能上网。 主机是用的校园内寝室共享上网。 …

熬夜翻译完的PureFTPd配置文件
[url]http://www.chinaunix.net[/url] 作者:jeffwu 发表于:2006-07-08 10:31:58 干了个通宵,一边玩一边把配置文件翻译完了,翻得不好的地方还请各位多多提点,少许不是很明白的地方就留在那了。 鼓励转贴,分发…