My task is to make an ETW real-time consumer with events provided by 'Microsoft Windows Security Auditing'.
I made a simple controller and consumer application, basing on this example http://msdn.microsoft.com/en-us/library/windows/desktop/ee441325%28v=vs.85%29.aspx and changing flags to work in real-time mode.
The main function looks this way:
LPTSTR SessionName = L"hahahaaa";
ULONG status = ERROR_SUCCESS;
PEVENT_TRACE_PROPERTIES pSessionProperties = NULL;
EVENT_TRACE_LOGFILE trace;
TRACEHANDLE hTrace = 0;
TRACEHANDLE hSession = 0;
const GUID providerId = { 0x54849625, 0x5478, 0x4994, { 0xA5, 0xBA, 0x3E, 0x3B, 0x03, 0x28, 0xC3, 0x0D } };
//const GUID providerId = { 0xA68CA8B7, 0x004F, 0xD7B6, { 0xA6, 0x98, 0x07, 0xE2, 0xDE, 0x0F, 0x1F, 0x5D } };
HANDLE hToken = NULL;
HANDLE hProcess = NULL;
hProcess = GetCurrentProcess();
if (OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken) == FALSE) {
printf("Error: Couldn't open the process token\n");
goto cleanup;
}
if(!SetPrivilege(hToken, SE_SECURITY_NAME, TRUE)) goto cleanup;
if (!pSessionProperties) {
const size_t buffSize = sizeof(EVENT_TRACE_PROPERTIES)+(_tcslen(SessionName) + 1) * sizeof(TCHAR);
pSessionProperties = reinterpret_cast<EVENT_TRACE_PROPERTIES *>(malloc(buffSize));
ZeroMemory(pSessionProperties, buffSize);
pSessionProperties->Wnode.BufferSize = buffSize;
pSessionProperties->Wnode.ClientContext = 1;
pSessionProperties->Wnode.Flags = WNODE_FLAG_TRACED_GUID;
pSessionProperties->LogFileMode = EVENT_TRACE_REAL_TIME_MODE;
pSessionProperties->LoggerNameOffset = sizeof(EVENT_TRACE_PROPERTIES);
}
// Create the trace session.
status = StartTrace(&hSession, SessionName, pSessionProperties);
if (ERROR_SUCCESS != status) {
wprintf(L"StartTrace() failed with %lu\n", status);
goto cleanup;
}
status = EnableTraceEx2(hSession, &providerId, EVENT_CONTROL_CODE_ENABLE_PROVIDER, TRACE_LEVEL_VERBOSE, 0, 0, 0, NULL);
if (ERROR_SUCCESS != status) {
wprintf(L"EnableTrace() failed with %lu\n", status);
goto cleanup;
}
ZeroMemory(&trace, sizeof(EVENT_TRACE_LOGFILE));
trace.LogFileName = NULL;
trace.LoggerName = SessionName;
trace.CurrentTime = 0;
trace.BuffersRead = 0;
trace.BufferSize = 0;
trace.Filled = 0;
trace.EventsLost = 0;
trace.Context = NULL;
trace.ProcessTraceMode = PROCESS_TRACE_MODE_REAL_TIME | PROCESS_TRACE_MODE_EVENT_RECORD;
trace.EventRecordCallback = (PEVENT_RECORD_CALLBACK)(ProcessEvent);
hTrace = OpenTrace(&trace);
if (INVALID_PROCESSTRACE_HANDLE == hTrace)
{
wprintf(L"OpenTrace failed with %lu\n", GetLastError());
goto cleanup;
}
status = ProcessTrace(&hTrace, 1, 0, 0);
if (status != ERROR_SUCCESS && status != ERROR_CANCELLED)
{
wprintf(L"ProcessTrace failed with %lu\n", status);
goto cleanup;
}
The application at 'ProcessTrace()' point should wait for incoming events and write to stdout theirs meta-data. But it simply does not. All generated events by me (i.e. I turn on Detailed Tracking - Process Creation and run an application) are shown in EventViewer, but my program shows nothing.
I thought that it might be some privileges problem, and using this example http://msdn.microsoft.com/en-us/library/windows/desktop/aa446619%28v=vs.85%29.aspx I set SE_SECURITY_NAME privilege and of course run application in Administrator's mode. But nothing changed.
Another try was a session name. Maybe it is the same problem as with 'Windows Kernel Trace' which can log only to system session 'NT Kernel Logger'. Only thing which I found was that 'Microsoft Windows Security Auditing' is correlated with 'Eventlog-Security' session, but when I set session name by this I received 'Access Denied' error. I don't know which extra privilege I should set to handle this.
Last try was to use 'logman' and collect events into a file, but everything was the same. When I set session name by 'Eventlog-Security' I received 'Access Denied'. On the other hand, when I set it by something else I only received one event, provided by 'MSNT_SystemTrace', which is the abstract class for other events.
If I change provider to i.e. 'Microsoft Windows Kernel General' (commented GUID) and generate an event (update system clock) everything works as it should (in my application and using 'logman').
I works in Windows 7 Professional x64 and Visual Studio Ultimate 2013.
My question is, what can I do to receive events from 'Microsoft Windows Security Auditing' provider?
Thanks for any help!
EDIT As I wrote in comment, if we set SessionName on Eventlog-Security, the application is shortened to OpenTrace() and ProcessTrace().
EDIT 2 As Luke suggested in comment, I ran my application with LocalSystem privileges, and everything started working.