5

I am using WMI to monitor the process creation event

According to other post(How to detect win32 process creation/termination in c++)

I follow it to register my callback function, but it doesn't work.

Nothing happened when I run this program and open the iexplore

Please help me, thank you

#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
Community
  • 1
  • 1
Lion Kuo
  • 239
  • 4
  • 13
  • Suggestion - try omitting the `AND TargetInstance.Name = 'iexplore.exe'` clause to make sure that your callback is called when *any* process is started. If that works then try to troubleshoot the additional filtering criteria. – Phil Brubaker Apr 07 '17 at 03:37
  • I have tried, but it doesn't work – Lion Kuo Apr 07 '17 at 03:41
  • This MSDN article looks like almost exactly like what you want to do (without the process name filter). I would go through all of the steps in depth and see if you're able to get it to run. Also I'd be interested in knowing if it works differently if you run as Administrator. [Example: Receiving Event Notifications Through WMI](https://msdn.microsoft.com/en-us/library/aa390425(v=vs.85).aspx) – Phil Brubaker Apr 07 '17 at 04:07
  • Yes, I also follow the MSDN article for trying, and run as Administrator, but I still can't receive any process creation event. I am run it on Windows 10. – Lion Kuo Apr 07 '17 at 04:12
  • Can you edit and share the source for `"CreationEvent.h"`? – Phil Brubaker Apr 07 '17 at 04:21
  • Ok, I have updated in the post, and the "boost" library is not used in this stage. I have try to print something in [HRESULT STDMETHODCALLTYPE Indicate] function without register my callback. It still doesn't work. – Lion Kuo Apr 07 '17 at 04:35
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/140137/discussion-between-lion-kuo-and-phil-brubaker). – Lion Kuo Apr 07 '17 at 04:39

1 Answers1

4

Went back and reviewed this article Example: Receiving Event Notifications Through WMI, and spotted an apparently important difference.

In method CreationEvent::registerCreationCallback(...), replace:

CoInitialize(NULL);

with:

CoInitializeEx(0, COINIT_MULTITHREADED);
Phil Brubaker
  • 1,257
  • 3
  • 11
  • 14