2017-04-07 141 views
1

我使用WMI监视进程创建事件使用WMI监视进程的创建活动

根据其他职位(How to detect win32 process creation/termination in c++

我按照它来注册我的回调函数,但它不工作。

什么都没有发生,当我运行这个程序,并打开IEXPLORE

请帮帮我,谢谢

#define _WIN32_DCOM 
#include <iostream> 
using namespace std; 
#include <comdef.h> 
#include <Wbemidl.h> 
#include <atlcomcli.h> 

#pragma comment(lib, "wbemuuid.lib") 
#include "CreationEvent.h" 

class EventSink : public IWbemObjectSink { 
    friend void CreationEvent::registerCreationCallback(TNotificationFunc callback); 

    CComPtr<IWbemServices> pSvc; 
    CComPtr<IWbemObjectSink> pStubSink; 
    LONG m_IRef; 
    CreationEvent::TNotificationFunc m_callback; 

public: 
    EventSink(CreationEvent::TNotificationFunc callback) :m_IRef(0), m_callback(callback){} 
    ~EventSink(){ 
    } 

    virtual ULONG STDMETHODCALLTYPE AddRef() { 
     return InterlockedIncrement(&m_IRef); 
    } 

    virtual ULONG STDMETHODCALLTYPE Release() { 
     LONG IRef = InterlockedDecrement(&m_IRef); 
     if (IRef == 0) 
      delete this; 
     return IRef; 
    } 

    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppv) { 
     if (riid == IID_IUnknown || riid == IID_IWbemObjectSink) { 
      *ppv = (IWbemObjectSink*) this; 
      AddRef(); 
      return WBEM_S_NO_ERROR; 
     } 
     else return E_NOINTERFACE; 
    } 

    virtual HRESULT STDMETHODCALLTYPE Indicate(
     LONG lObjectCount, 
     IWbemClassObject __RPC_FAR *__RPC_FAR *apObjArray 
    ){ 
     m_callback(); 
     /* Unregister event sink */ 
     pSvc->CancelAsyncCall(pStubSink); 
     return WBEM_S_NO_ERROR; 
    } 
    virtual HRESULT STDMETHODCALLTYPE SetStatus(LONG IFlags, HRESULT hResult, BSTR strParam, IWbemClassObject __RPC_FAR *pObjParam) { 
     return WBEM_S_NO_ERROR; 
    } 
}; 

void CreationEvent::registerCreationCallback(TNotificationFunc callback) { 
    CComPtr<IWbemLocator> pLoc; 
    CoInitialize(NULL); 
    HRESULT hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID*)&pLoc); 

    if (FAILED(hres)) { 
     cout << "Failed to create IWbemLocator object." 
      << " Err code = 0x" 
      << hex << hres << endl; 
     throw std::exception("CreationEvent initialization failed"); 
    } 
    CComPtr<EventSink> pSink(new EventSink(callback)); 

    hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSink->pSvc); 
    if (FAILED(hres)) { 
     cout << "Could not connect. Error code = 0x" << hex << hres << endl; 
     throw std::exception("CreationEvent initialization failed"); 
    } 
    hres = CoSetProxyBlanket(pSink->pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); 
    if (FAILED(hres)) { 
     cout << "Coult not set proxy blanket, Error code =0x" << hex << hres << endl; 
     throw std::exception("CreationEvent initialization failed"); 
    } 

    CComPtr<IUnsecuredApartment> pUnsecApp; 
    hres = CoCreateInstance(CLSID_UnsecuredApartment, NULL, CLSCTX_LOCAL_SERVER, IID_IUnsecuredApartment, (void**)&pUnsecApp); 
    CComPtr<IUnknown> pStubUnk; 
    pUnsecApp->CreateObjectStub(pSink, &pStubUnk); 
    pStubUnk->QueryInterface(IID_IWbemObjectSink, (void**)&pSink->pStubSink); 


    char buffer[512]; 
    sprintf_s(buffer, "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name = 'iexplore.exe'"); 

    hres = pSink->pSvc->ExecNotificationQueryAsync(_bstr_t("WQL"), _bstr_t(buffer), WBEM_FLAG_SEND_STATUS, NULL, pSink->pStubSink); 

    if (FAILED(hres)) { 
     cout << "ExecNotificationQueryAsync failed with = 0x" << hex << hres << endl; 
     throw std::exception("CreationEvent initialization failed"); 
    } 
} 

void k() { cout << "KKKKK " << endl; } 

int main() { 
    CreationEvent::registerCreationCallback(k); 
    cin.get(); 
} 

CreationEvent.h

#pragma once 
#ifndef _CreationEvent_h__ 
#define _CreationEvent_h__ 

#include <boost/function.hpp> 

namespace CreationEvent { 
    typedef boost::function<void(void)> TNotificationFunc; 
    void registerCreationCallback(TNotificationFunc callback); 
} 

#endif 
+0

建议 - 尝试省略'AND TargetInstance.Name =“iexplore.exe''条款,以确保您的回调当任何*进程启动时调用。如果有效,请尝试排除其他过滤条件。 –

+0

我曾尝试过,但它不起作用 –

+0

此MSDN文章看起来像几乎完全一样你想要做的(没有进程名称过滤器)。我会深入探讨所有步骤,看看你是否能够运行。另外,如果以管理员身份运行,我会对知道它是否以不同的方式工作感兴趣。 [示例:通过WMI接收事件通知](https://msdn.microsoft.com/en-us/library/aa390425(v = vs.85).aspx) –

回答

2

回去,并审阅本文Example: Receiving Event Notifications Through WMI,并发现了一个显然重要的区别。

在方法CreationEvent::registerCreationCallback(...),替换:

CoInitialize(NULL); 

有:

CoInitializeEx(0, COINIT_MULTITHREADED); 
+0

谢谢你的帮助,它的工作原理!我没有注意到-Ex之间的区别。 –

+0

很高兴听到,很高兴帮助! –