You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
683 lines
17 KiB
683 lines
17 KiB
// KernelTraceProvider.cpp : Implementation of CKernelTraceProvider
|
|
#include "precomp.h"
|
|
#include "Krnlprov.h"
|
|
#include "KernelTraceProvider.h"
|
|
#include <GroupsForUser.h>
|
|
|
|
|
|
void Trace(LPCTSTR szFormat, ...)
|
|
{
|
|
va_list ap;
|
|
TCHAR szMessage[512];
|
|
|
|
va_start(ap, szFormat);
|
|
StringCchVPrintf(szMessage,512,szFormat,ap);
|
|
va_end(ap);
|
|
|
|
StringCchCat(szMessage, 512, TEXT("\n"));
|
|
|
|
OutputDebugString(szMessage);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CKernelTraceProvider
|
|
|
|
// Because the event trace API won't allow you to get back a user-defined
|
|
// value when events are received!
|
|
CKernelTraceProvider *g_pThis;
|
|
|
|
CKernelTraceProvider::CKernelTraceProvider()
|
|
: m_bDone(FALSE), m_hProcessTraceThread(NULL)
|
|
{
|
|
g_pThis = this;
|
|
}
|
|
|
|
void CKernelTraceProvider::FinalRelease()
|
|
{
|
|
StopTracing();
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE CKernelTraceProvider::Initialize(
|
|
/* [in] */ LPWSTR pszUser,
|
|
/* [in] */ LONG lFlags,
|
|
/* [in] */ LPWSTR pszNamespace,
|
|
/* [in] */ LPWSTR pszLocale,
|
|
/* [in] */ IWbemServices __RPC_FAR *pNamespace,
|
|
/* [in] */ IWbemContext __RPC_FAR *pCtx,
|
|
/* [in] */ IWbemProviderInitSink __RPC_FAR *pInitSink)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
m_pNamespace = pNamespace;
|
|
|
|
// Tell Windows Management our initialization status.
|
|
pInitSink->SetStatus(SUCCEEDED(hr) ? WBEM_S_INITIALIZED : WBEM_E_FAILED, 0);
|
|
|
|
return hr;
|
|
}
|
|
|
|
#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
|
|
|
|
HRESULT CKernelTraceProvider::InitEvents()
|
|
{
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Win32_ProcessStartTrace
|
|
|
|
LPCWSTR szProcessStartTraceNames[] =
|
|
{
|
|
L"PageDirectoryBase",
|
|
L"ProcessID",
|
|
L"ParentProcessID",
|
|
L"SessionID",
|
|
L"Sid",
|
|
L"ProcessName"
|
|
};
|
|
|
|
m_eventProcessStart.Init(
|
|
m_pNamespace,
|
|
L"Win32_ProcessStartTrace",
|
|
szProcessStartTraceNames,
|
|
COUNTOF(szProcessStartTraceNames),
|
|
CObjAccess::FAILED_PROP_FAIL);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Win32_ProcessStopTrace
|
|
|
|
LPCWSTR szProcessStopTraceNames[] =
|
|
{
|
|
L"PageDirectoryBase",
|
|
L"ProcessID",
|
|
L"ParentProcessID",
|
|
L"SessionID",
|
|
L"ExitStatus",
|
|
L"Sid",
|
|
L"ProcessName"
|
|
};
|
|
|
|
m_eventProcessStop.Init(
|
|
m_pNamespace,
|
|
L"Win32_ProcessStopTrace",
|
|
szProcessStopTraceNames,
|
|
COUNTOF(szProcessStopTraceNames),
|
|
CObjAccess::FAILED_PROP_FAIL);
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Win32_ThreadStartTrace
|
|
|
|
LPCWSTR szThreadStartNames[] =
|
|
{
|
|
L"StackBase",
|
|
L"StackLimit",
|
|
L"UserStackBase",
|
|
L"UserStackLimit",
|
|
L"StartAddr",
|
|
L"Win32StartAddr",
|
|
L"ProcessID",
|
|
L"ThreadID",
|
|
L"WaitMode",
|
|
};
|
|
|
|
m_eventThreadStart.Init(
|
|
m_pNamespace,
|
|
L"Win32_ThreadStartTrace",
|
|
szThreadStartNames,
|
|
COUNTOF(szThreadStartNames),
|
|
CObjAccess::FAILED_PROP_FAIL);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Win32_ThreadStopTrace
|
|
|
|
LPCWSTR szThreadStopNames[] =
|
|
{
|
|
L"ProcessID",
|
|
L"ThreadID",
|
|
};
|
|
|
|
m_eventThreadStop.Init(
|
|
m_pNamespace,
|
|
L"Win32_ThreadStopTrace",
|
|
szThreadStopNames,
|
|
COUNTOF(szThreadStopNames),
|
|
CObjAccess::FAILED_PROP_FAIL);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// Win32_ModuleLoadTrace
|
|
|
|
LPCWSTR szModuleNames[] =
|
|
{
|
|
L"ImageBase",
|
|
L"ImageSize",
|
|
L"ProcessID",
|
|
L"FileName",
|
|
};
|
|
|
|
m_eventModuleLoad.Init(
|
|
m_pNamespace,
|
|
L"Win32_ModuleLoadTrace",
|
|
szModuleNames,
|
|
COUNTOF(szModuleNames),
|
|
CObjAccess::FAILED_PROP_FAIL);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
#define REALTIME
|
|
#define BUFFER_SIZE 64
|
|
#define MIN_BUFFERS 20
|
|
#define MAX_BUFFERS 200
|
|
#define FLUSH_TIME 1
|
|
|
|
//#define USE_KERNEL_GUID
|
|
|
|
#ifdef USE_KERNEL_GUID
|
|
#define LOGGER_NAME L"NT Kernel Logger"
|
|
#define WMI_KERNEL_TRACE_GUID guidSystemTrace
|
|
#define ENABLE_FLAGS EVENT_TRACE_FLAG_PROCESS | EVENT_TRACE_FLAG_THREAD | EVENT_TRACE_FLAG_IMAGE_LOAD
|
|
#else
|
|
#define LOGGER_NAME L"WMI Event Logger"
|
|
#define WMI_KERNEL_TRACE_GUID guidWMITrace
|
|
#define ENABLE_FLAGS 0
|
|
#endif
|
|
|
|
#ifndef REALTIME
|
|
#define MAX_FILE_SIZE 20 // In MB
|
|
#define LOGGER_FILE L"c:\\temp\\wmi.etl"
|
|
#endif
|
|
|
|
GUID guidProcess =
|
|
// {3d6fa8d0-fe05-11d0-9dda-00c04fd7ba7c}
|
|
{0x3d6fa8d0, 0xfe05, 0x11d0, 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c};
|
|
|
|
GUID guidThread =
|
|
// {3d6fa8d1-fe05-11d0-9dda-00c04fd7ba7c}
|
|
{0x3d6fa8d1, 0xfe05, 0x11d0, 0x9d, 0xda, 0x00, 0xc0, 0x4f, 0xd7, 0xba, 0x7c};
|
|
|
|
GUID guidImage =
|
|
// {2cb15d1d-5fc1-11d2-abe1-00a0c911f518}
|
|
{0x2cb15d1d, 0x5fc1, 0x11d2, 0xab, 0xe1, 0x00, 0xa0, 0xc9, 0x11, 0xf5, 0x18};
|
|
|
|
GUID guidSystemTrace =
|
|
// 9e814aad-3204-11d2-9a82-006008a86939
|
|
{0x9e814aad, 0x3204, 0x11d2, 0x9a, 0x82, 0x00, 0x60, 0x08, 0xa8, 0x69, 0x39};
|
|
|
|
GUID guidWMITrace =
|
|
// 44608a51-1851-4456-98b2-b300e931ee41
|
|
{0x44608a51, 0x1851, 0x4456, 0x98, 0xb2, 0xb3, 0x00, 0xe9, 0x31, 0xee, 0x41};
|
|
|
|
HRESULT CKernelTraceProvider::InitTracing()
|
|
{
|
|
DWORD status;
|
|
|
|
m_bDone = FALSE;
|
|
|
|
// See if the logger is already running. If not, set it up.
|
|
if (QueryTrace(
|
|
NULL,
|
|
LOGGER_NAME,
|
|
&m_properties) != ERROR_SUCCESS)
|
|
{
|
|
// Initialize property values here.
|
|
#ifdef REALTIME
|
|
m_properties.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
|
|
StringCchCopy( m_properties.szLoggerName, MAX_PATH, LOGGER_NAME );
|
|
#else
|
|
m_properties.LogFileMode = EVENT_TRACE_FILE_MODE_SEQUENTIAL;
|
|
//properties.LogFileMode = EVENT_TRACE_FILE_MODE_CIRCULAR;
|
|
|
|
// MaximumFileSize is in MB.
|
|
m_properties.MaximumFileSize = MAX_FILE_SIZE;
|
|
|
|
StringCchCopy( m_properties.szLogFileName, MAX_PATH, LOGGER_FILE );
|
|
#endif
|
|
|
|
m_properties.Wnode.Guid = WMI_KERNEL_TRACE_GUID;
|
|
|
|
// Set the buffer size. BufferSize is in KB.
|
|
m_properties.BufferSize = BUFFER_SIZE;
|
|
m_properties.MinimumBuffers = MIN_BUFFERS;
|
|
m_properties.MaximumBuffers = MAX_BUFFERS;
|
|
|
|
// Number of seconds before timer is flushed.
|
|
m_properties.FlushTimer = FLUSH_TIME;
|
|
|
|
m_properties.EnableFlags |= ENABLE_FLAGS;
|
|
|
|
// Start tracing.
|
|
status =
|
|
StartTrace(
|
|
&m_hSession,
|
|
LOGGER_NAME,
|
|
&m_properties);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
TRACE(L"StartTrace error=%d (GetLastError=0x%x)",
|
|
status, GetLastError());
|
|
|
|
return WBEM_E_FAILED;
|
|
}
|
|
}
|
|
else
|
|
m_hSession = NULL;
|
|
|
|
EVENT_TRACE_LOGFILE eventFile;
|
|
|
|
ZeroMemory(&eventFile, sizeof(eventFile));
|
|
|
|
//eventFile.BufferCallback = BufferCallback;
|
|
//eventFile.EventCallback = DumpEvent;
|
|
eventFile.LoggerName = (LPTSTR) LOGGER_NAME;
|
|
|
|
#ifdef REALTIME
|
|
eventFile.LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
|
|
#else
|
|
eventFile.LogFileMode = 0;
|
|
eventFile.LogFileName = (LPTSTR) LOGGER_FILE;
|
|
#endif
|
|
|
|
|
|
SetTraceCallback(&guidProcess, OnProcessEvent);
|
|
SetTraceCallback(&guidThread, OnThreadEvent);
|
|
SetTraceCallback(&guidImage, OnImageEvent);
|
|
|
|
m_hTrace = OpenTrace(&eventFile);
|
|
|
|
TRACE(L"Ready to call ProcessTrace (m_hTrace = %d)...\n", m_hTrace);
|
|
|
|
DWORD dwID;
|
|
|
|
m_hProcessTraceThread =
|
|
CreateThread(
|
|
NULL,
|
|
0,
|
|
(LPTHREAD_START_ROUTINE) DoProcessTrace,
|
|
this,
|
|
0,
|
|
&dwID);
|
|
|
|
if ( m_hProcessTraceThread == NULL )
|
|
{
|
|
return HRESULT_FROM_WIN32( GetLastError() );
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
DWORD WINAPI CKernelTraceProvider::DoProcessTrace(CKernelTraceProvider *pThis)
|
|
{
|
|
#ifndef REALTIME
|
|
FILETIME filetime;
|
|
|
|
GetSystemTimeAsFileTime(&filetime);
|
|
#endif
|
|
|
|
while(!pThis->m_bDone)
|
|
{
|
|
DWORD status;
|
|
|
|
status =
|
|
ProcessTrace(
|
|
&pThis->m_hTrace,
|
|
1,
|
|
#ifdef REALTIME
|
|
NULL,
|
|
#else
|
|
&filetime,
|
|
#endif
|
|
NULL);
|
|
|
|
#ifndef REALTIME
|
|
// Save this off for our next all.
|
|
GetSystemTimeAsFileTime(&filetime);
|
|
#endif
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
TRACE(L"Error processing with status=%dL (GetLastError=0x%x)",
|
|
status, GetLastError());
|
|
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
#ifndef REALTIME
|
|
TRACE(L"ProcessTrace exited successfully, sleeping...");
|
|
|
|
Sleep(5000);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
TRACE(L"Exiting StartTracing.");
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CKernelTraceProvider::StopTracing()
|
|
{
|
|
CInCritSec cs(&g_pThis->m_cs);
|
|
DWORD status;
|
|
|
|
m_bDone = TRUE;
|
|
|
|
RemoveTraceCallback(&guidProcess);
|
|
RemoveTraceCallback(&guidThread);
|
|
RemoveTraceCallback(&guidImage);
|
|
|
|
status = CloseTrace(m_hTrace);
|
|
|
|
status =
|
|
StopTrace(
|
|
m_hSession,
|
|
LOGGER_NAME,
|
|
&m_properties);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
TRACE(L"StopTrace error=%d (GetLastError=0x%x)\n",
|
|
status, GetLastError());
|
|
}
|
|
|
|
if ( m_hProcessTraceThread != NULL )
|
|
{
|
|
WaitForSingleObject( m_hProcessTraceThread, INFINITE );
|
|
CloseHandle( m_hProcessTraceThread );
|
|
}
|
|
}
|
|
|
|
const LPCWSTR szQueries[CKernelTraceProvider::SINK_COUNT] =
|
|
{
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Process queries
|
|
|
|
L"select * from Win32_ProcessStartTrace",
|
|
L"select * from Win32_ProcessStopTrace",
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Thread queries
|
|
|
|
L"select * from Win32_ThreadStartTrace",
|
|
L"select * from Win32_ThreadStopTrace",
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// Module queries
|
|
|
|
L"select * from Win32_ModuleLoadTrace"
|
|
};
|
|
|
|
HRESULT STDMETHODCALLTYPE CKernelTraceProvider::ProvideEvents(
|
|
/* [in] */ IWbemObjectSink __RPC_FAR *pSink,
|
|
/* [in] */ long lFlags)
|
|
{
|
|
HRESULT hr;
|
|
IWbemEventSinkPtr pEventSink;
|
|
|
|
hr = pSink->QueryInterface(IID_IWbemEventSink, (LPVOID*) &pEventSink);
|
|
|
|
for (int i = 0; i < SINK_COUNT && SUCCEEDED(hr); i++)
|
|
{
|
|
hr =
|
|
pEventSink->GetRestrictedSink(
|
|
1,
|
|
&szQueries[i],
|
|
NULL,
|
|
&m_pSinks[i]);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
hr = InitEvents();
|
|
|
|
if (SUCCEEDED(hr))
|
|
hr = InitTracing();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT STDMETHODCALLTYPE CKernelTraceProvider::AccessCheck(
|
|
/* [in] */ WBEM_CWSTR wszQueryLanguage,
|
|
/* [in] */ WBEM_CWSTR wszQuery,
|
|
/* [in] */ long lSidLength,
|
|
/* [unique][size_is][in] */ const BYTE __RPC_FAR *pSid)
|
|
{
|
|
if ( NULL == pSid )
|
|
{
|
|
HRESULT hr = CoImpersonateClient();
|
|
|
|
if( FAILED( hr ) )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
HANDLE hToken;
|
|
if( !OpenThreadToken( GetCurrentThread( ), TOKEN_READ, TRUE, &hToken ) )
|
|
{
|
|
CoRevertToSelf( );
|
|
return WBEM_E_FAILED;
|
|
}
|
|
|
|
hr = WBEM_E_ACCESS_DENIED;
|
|
|
|
BOOL bRet = FALSE;
|
|
PSID pRawSid;
|
|
SID_IDENTIFIER_AUTHORITY id = SECURITY_NT_AUTHORITY;
|
|
|
|
if( AllocateAndInitializeSid( &id, 2,
|
|
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
|
|
0,0,0,0,0,0,&pRawSid ) )
|
|
{
|
|
if ( CheckTokenMembership( hToken, pRawSid, &bRet ) && bRet )
|
|
{
|
|
hr = WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
FreeSid( pRawSid );
|
|
}
|
|
|
|
CloseHandle( hToken );
|
|
CoRevertToSelf();
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// SID IS NOT NULL HERE
|
|
//
|
|
|
|
if ( IsUserAdministrator( ( PSID )pSid ) )
|
|
{
|
|
return WBEM_E_ACCESS_DENIED;
|
|
}
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
|
|
#define PROCESS_START 1
|
|
#define PROCESS_END 2
|
|
|
|
struct CProcessTrace
|
|
{
|
|
DWORD_PTR dwPageDirBase;
|
|
DWORD dwProcessID,
|
|
dwParentProcessID,
|
|
dwSessionID;
|
|
DWORD dwExitStatus;
|
|
BYTE cSidBegin[1];
|
|
};
|
|
|
|
void WINAPI CKernelTraceProvider::OnProcessEvent(PEVENT_TRACE pEvent)
|
|
{
|
|
CInCritSec cs(&g_pThis->m_cs);
|
|
CObjAccess *pObjEx;
|
|
IWbemEventSink *pSink;
|
|
|
|
if (pEvent->Header.Class.Type == PROCESS_START)
|
|
{
|
|
pSink = g_pThis->m_pSinks[SINK_PROCESS_START];
|
|
|
|
if (pSink->IsActive() != WBEM_S_NO_ERROR)
|
|
return;
|
|
|
|
pObjEx = &g_pThis->m_eventProcessStart;
|
|
}
|
|
else if (pEvent->Header.Class.Type == PROCESS_END)
|
|
{
|
|
pSink = g_pThis->m_pSinks[SINK_PROCESS_STOP];
|
|
|
|
if (pSink->IsActive() != WBEM_S_NO_ERROR)
|
|
return;
|
|
|
|
pObjEx = &g_pThis->m_eventProcessStop;
|
|
}
|
|
else
|
|
// Ignore anything else.
|
|
return;
|
|
|
|
CProcessTrace *pProcess = (CProcessTrace*) pEvent->MofData;
|
|
|
|
// Find out where the SID is.
|
|
LPBYTE pCurrent = (LPBYTE) &pProcess->cSidBegin,
|
|
pSid;
|
|
DWORD nSidLen;
|
|
|
|
if (*(DWORD*) pCurrent == 0)
|
|
{
|
|
pSid = NULL;
|
|
pCurrent += sizeof(DWORD);
|
|
}
|
|
else
|
|
{
|
|
// These numbers were taken from tracedmp.c of the sdktool
|
|
// tracedmp.exe. There's no explanation as to how they came up with
|
|
// them, but I'm assuming it's documented somewhere in the SDK.
|
|
pCurrent += sizeof( TOKEN_USER );
|
|
nSidLen = 8 + (4 * pCurrent[1]);
|
|
pSid = pCurrent;
|
|
pCurrent += nSidLen;
|
|
}
|
|
|
|
_bstr_t strProcess = (LPSTR) pCurrent;
|
|
|
|
// Extrinsic events
|
|
pObjEx->WriteDWORD64(0, pProcess->dwPageDirBase);
|
|
pObjEx->WriteDWORD(1, pProcess->dwProcessID);
|
|
pObjEx->WriteDWORD(2, pProcess->dwParentProcessID);
|
|
pObjEx->WriteDWORD(3, pProcess->dwSessionID);
|
|
|
|
if (pEvent->Header.Class.Type == PROCESS_END)
|
|
{
|
|
pObjEx->WriteDWORD(4, pProcess->dwExitStatus);
|
|
|
|
if (pSid)
|
|
pObjEx->WriteNonPackedArrayData(5, pSid, nSidLen, nSidLen);
|
|
else
|
|
pObjEx->WriteNULL(5);
|
|
|
|
pObjEx->WriteString(6, (LPCWSTR) strProcess);
|
|
}
|
|
else
|
|
{
|
|
if (pSid)
|
|
pObjEx->WriteNonPackedArrayData(4, pSid, nSidLen, nSidLen);
|
|
else
|
|
pObjEx->WriteNULL(4);
|
|
|
|
pObjEx->WriteString(5, (LPCWSTR) strProcess);
|
|
}
|
|
|
|
pSink->Indicate(1, pObjEx->GetObjForIndicate());
|
|
}
|
|
|
|
struct CThreadStart
|
|
{
|
|
DWORD dwProcessID,
|
|
dwThreadID;
|
|
DWORD_PTR dwStackBase,
|
|
dwStackLimit,
|
|
dwUserStackBase,
|
|
dwUserStackLimit,
|
|
dwStartAddr,
|
|
dwWin32StartAddr;
|
|
char cWaitMode;
|
|
};
|
|
|
|
struct CThreadStop
|
|
{
|
|
DWORD dwProcessID,
|
|
dwThreadID;
|
|
};
|
|
|
|
void WINAPI CKernelTraceProvider::OnThreadEvent(PEVENT_TRACE pEvent)
|
|
{
|
|
CInCritSec cs(&g_pThis->m_cs);
|
|
|
|
if (pEvent->Header.Class.Type == PROCESS_START)
|
|
{
|
|
if (g_pThis->m_pSinks[SINK_THREAD_START]->IsActive() != WBEM_S_NO_ERROR)
|
|
return;
|
|
|
|
CObjAccess *pObjEx = &g_pThis->m_eventThreadStart;
|
|
CThreadStart *pStart = (CThreadStart*) pEvent->MofData;
|
|
|
|
pObjEx->WriteDWORD64(0, pStart->dwStackBase);
|
|
pObjEx->WriteDWORD64(1, pStart->dwStackLimit);
|
|
pObjEx->WriteDWORD64(2, pStart->dwUserStackBase);
|
|
pObjEx->WriteDWORD64(3, pStart->dwUserStackLimit);
|
|
pObjEx->WriteDWORD64(4, pStart->dwStartAddr);
|
|
pObjEx->WriteDWORD64(5, pStart->dwWin32StartAddr);
|
|
pObjEx->WriteDWORD(6, pStart->dwProcessID);
|
|
pObjEx->WriteDWORD(7, pStart->dwThreadID);
|
|
pObjEx->WriteDWORD(8, pStart->cWaitMode);
|
|
|
|
g_pThis->m_pSinks[SINK_THREAD_START]->
|
|
Indicate(1, pObjEx->GetObjForIndicate());
|
|
}
|
|
else if (pEvent->Header.Class.Type == PROCESS_END)
|
|
{
|
|
if (g_pThis->m_pSinks[SINK_THREAD_STOP]->IsActive() != WBEM_S_NO_ERROR)
|
|
return;
|
|
|
|
CObjAccess *pObjEx = &g_pThis->m_eventThreadStop;
|
|
CThreadStop *pStop = (CThreadStop*) pEvent->MofData;
|
|
|
|
pObjEx->WriteDWORD(0, pStop->dwProcessID);
|
|
pObjEx->WriteDWORD(1, pStop->dwThreadID);
|
|
|
|
g_pThis->m_pSinks[SINK_THREAD_STOP]->
|
|
Indicate(1, pObjEx->GetObjForIndicate());
|
|
}
|
|
}
|
|
|
|
struct CImageLoad
|
|
{
|
|
DWORD_PTR dwImageBase;
|
|
DWORD_PTR dwImageSize;
|
|
DWORD dwProcessID;
|
|
WCHAR szFileName[4];
|
|
};
|
|
|
|
void WINAPI CKernelTraceProvider::OnImageEvent(PEVENT_TRACE pEvent)
|
|
{
|
|
CInCritSec cs(&g_pThis->m_cs);
|
|
|
|
if (g_pThis->m_pSinks[SINK_MODULE_LOAD]->IsActive() == WBEM_S_NO_ERROR)
|
|
{
|
|
CObjAccess *pObjEx = &g_pThis->m_eventModuleLoad;
|
|
CImageLoad *pLoad = (CImageLoad*) pEvent->MofData;
|
|
LPBYTE pData = (LPBYTE) pEvent->MofData;
|
|
|
|
// Extrinsic events
|
|
pObjEx->WriteDWORD64(0, pLoad->dwImageBase);
|
|
pObjEx->WriteDWORD64(1, pLoad->dwImageSize);
|
|
pObjEx->WriteDWORD(2, pLoad->dwProcessID);
|
|
pObjEx->WriteString(3, pLoad->szFileName);
|
|
|
|
g_pThis->m_pSinks[SINK_MODULE_LOAD]->Indicate(1, pObjEx->GetObjForIndicate());
|
|
}
|
|
}
|