1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
// SPDX-License-Identifier: GPL-3.0-or-later
#include "windows-events-query-builder.h"
// --------------------------------------------------------------------------------------------------------------------
// query without XPath
typedef struct static_utf8_8k {
char buffer[8192];
size_t size;
size_t len;
} STATIC_BUF_8K;
typedef struct static_unicode_16k {
wchar_t buffer[16384];
size_t size;
size_t len;
} STATIC_UNI_16K;
static bool wevt_foreach_selected_value_cb(FACETS *facets __maybe_unused, size_t id, const char *key, const char *value, void *data) {
STATIC_BUF_8K *b = data;
b->len += snprintfz(&b->buffer[b->len], b->size - b->len,
"%s%s=%s",
id ? " or " : "", key, value);
return b->len < b->size;
}
wchar_t *wevt_generate_query_no_xpath(LOGS_QUERY_STATUS *lqs, BUFFER *wb) {
static __thread STATIC_UNI_16K q = {
.size = sizeof(q.buffer) / sizeof(wchar_t),
.len = 0,
};
static __thread STATIC_BUF_8K b = {
.size = sizeof(b.buffer) / sizeof(char),
.len = 0,
};
lqs_query_timeframe(lqs, ANCHOR_DELTA_UT);
usec_t seek_to = lqs->query.start_ut;
if(lqs->rq.direction == FACETS_ANCHOR_DIRECTION_BACKWARD)
// windows events queries are limited to millisecond resolution
// so, in order not to lose data, we have to add
// a millisecond when the direction is backward
seek_to += USEC_PER_MS;
// Convert the microseconds since Unix epoch to FILETIME (used in Windows APIs)
FILETIME fileTime = os_unix_epoch_ut_to_filetime(seek_to);
// Convert FILETIME to SYSTEMTIME for use in XPath
SYSTEMTIME systemTime;
if (!FileTimeToSystemTime(&fileTime, &systemTime)) {
nd_log(NDLS_COLLECTORS, NDLP_ERR, "FileTimeToSystemTime() failed");
return NULL;
}
// Format SYSTEMTIME into ISO 8601 format (YYYY-MM-DDTHH:MM:SS.sssZ)
q.len = swprintf(q.buffer, q.size,
L"Event/System[TimeCreated[@SystemTime%ls\"%04d-%02d-%02dT%02d:%02d:%02d.%03dZ\"]",
lqs->rq.direction == FACETS_ANCHOR_DIRECTION_BACKWARD ? L"<=" : L">=",
systemTime.wYear, systemTime.wMonth, systemTime.wDay,
systemTime.wHour, systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
if(lqs->rq.slice) {
b.len = snprintf(b.buffer, b.size, " and (");
if (facets_foreach_selected_value_in_key(
lqs->facets,
WEVT_FIELD_LEVEL,
sizeof(WEVT_FIELD_LEVEL) - 1,
used_hashes_registry,
wevt_foreach_selected_value_cb,
&b)) {
b.len += snprintf(&b.buffer[b.len], b.size - b.len, ")");
if (b.len < b.size) {
utf82unicode(&q.buffer[q.len], q.size - q.len, b.buffer);
q.len = wcslen(q.buffer);
}
}
b.len = snprintf(b.buffer, b.size, " and (");
if (facets_foreach_selected_value_in_key(
lqs->facets,
WEVT_FIELD_EVENTID,
sizeof(WEVT_FIELD_EVENTID) - 1,
used_hashes_registry,
wevt_foreach_selected_value_cb,
&b)) {
b.len += snprintf(&b.buffer[b.len], b.size - b.len, ")");
if (b.len < b.size) {
utf82unicode(&q.buffer[q.len], q.size - q.len, b.buffer);
q.len = wcslen(q.buffer);
}
}
}
q.len += swprintf(&q.buffer[q.len], q.size - q.len, L"]");
buffer_json_member_add_string(wb, "_query", channel2utf8(q.buffer));
return q.buffer;
}
// --------------------------------------------------------------------------------------------------------------------
// query with XPath
|