source: nscp/modules/CheckEventLog/eventlog_record.hpp @ 98113da

0.4.00.4.10.4.2
Last change on this file since 98113da was 98113da, checked in by Michael Medin <michael@…>, 21 months ago
  • Real-time CheckEventLog working (still only for one, and I think application log)
  • Added python tests to validfate that Real-time eventlog is working.
  • Fixed som defects here and there (now builds on Linux again)
  • Fixed so it builds in "debug mode"
  • Fixed issue in grammar which caused infiniate loop in som cases
  • Fixed so error rendering in eventlog works with "infininate number of argumnets"
  • Added support for targeting execs (in API)
  • Fixed some invalid return messages
  • Streamlined submissions wrappers to be more inline with "other wrappers"
  • Fixed a myrriad of minor python script bugs
  • Added sleep command (which sometimes causes issues so use with care)
  • Property mode set to 100644
File size: 8.8 KB
Line 
1#pragma once
2
3#include "simple_registry.hpp"
4#include <config.h>
5
6class EventLogRecord {
7        const EVENTLOGRECORD *pevlr_;
8        __int64 currentTime_;
9        std::wstring file_;
10public:
11        EventLogRecord(std::wstring file, const EVENTLOGRECORD *pevlr, __int64 currentTime) : file_(file), pevlr_(pevlr), currentTime_(currentTime) {
12        }
13        inline __int64 timeGenerated() const {
14                return (currentTime_-pevlr_->TimeGenerated)*1000;
15        }
16        inline __int64 timeWritten() const {
17                return (currentTime_-pevlr_->TimeWritten)*1000;
18        }
19        inline __int64 generated() const {
20                return pevlr_->TimeGenerated;
21        }
22        inline __int64 written() const {
23                return pevlr_->TimeWritten;
24        }
25        inline std::wstring eventSource() const {
26                return reinterpret_cast<const WCHAR*>(reinterpret_cast<const BYTE*>(pevlr_) + sizeof(EVENTLOGRECORD));
27        }
28        inline DWORD eventID() const {
29                return (pevlr_->EventID&0xffff);
30        }
31        inline DWORD severity() const {
32                return (pevlr_->EventID>>30);
33        }
34
35        inline DWORD eventType() const {
36                return pevlr_->EventType;
37        }
38
39        std::wstring userSID() const {
40                if (pevlr_->UserSidOffset == 0)
41                        return _T("");
42                PSID p = NULL; // = reinterpret_cast<const void*>(reinterpret_cast<const BYTE*>(pevlr_) + + pevlr_->UserSidOffset);
43                DWORD userLen = 0;
44                DWORD domainLen = 0;
45                SID_NAME_USE sidName;
46
47                LookupAccountSid(NULL, p, NULL, &userLen, NULL, &domainLen, &sidName);
48                LPTSTR user = new TCHAR[userLen+10];
49                LPTSTR domain = new TCHAR[domainLen+10];
50
51                LookupAccountSid(NULL, p, user, &userLen, domain, &domainLen, &sidName);
52                user[userLen] = 0;
53                domain[domainLen] = 0;
54                std::wstring ustr = user;
55                std::wstring dstr = domain;
56                delete [] user;
57                delete [] domain;
58                if (!dstr.empty())
59                        dstr = dstr + _T("\\");
60                if (ustr.empty() && dstr.empty())
61                        return _T("missing");
62
63                return dstr + ustr;
64        }
65
66        std::wstring enumStrings() const {
67                std::wstring ret;
68                const TCHAR* p = reinterpret_cast<const TCHAR*>(reinterpret_cast<const BYTE*>(pevlr_) + pevlr_->StringOffset);
69                for (unsigned int i =0;i<pevlr_->NumStrings;i++) {
70                        std::wstring s = p;
71                        if (!s.empty())
72                                s += _T(", ");
73                        ret += s;
74                        p = &p[wcslen(p) + 1];
75                }
76                return ret;
77        }
78
79        static DWORD appendType(DWORD dwType, std::wstring sType) {
80                return dwType | translateType(sType);
81        }
82        static DWORD subtractType(DWORD dwType, std::wstring sType) {
83                return dwType & (!translateType(sType));
84        }
85        static DWORD translateType(std::wstring sType) {
86                if (sType.empty())
87                        return EVENTLOG_ERROR_TYPE;
88                if (sType == _T("error"))
89                        return EVENTLOG_ERROR_TYPE;
90                if (sType == _T("warning"))
91                        return EVENTLOG_WARNING_TYPE;
92                if (sType == _T("success"))
93                        return EVENTLOG_SUCCESS;
94                if (sType == _T("info"))
95                        return EVENTLOG_INFORMATION_TYPE;
96                if (sType == _T("auditSuccess"))
97                        return EVENTLOG_AUDIT_SUCCESS;
98                if (sType == _T("auditFailure"))
99                        return EVENTLOG_AUDIT_FAILURE;
100                return strEx::stoi(sType);
101        }
102        static std::wstring translateType(DWORD dwType) {
103                if (dwType == EVENTLOG_ERROR_TYPE)
104                        return _T("error");
105                if (dwType == EVENTLOG_WARNING_TYPE)
106                        return _T("warning");
107                if (dwType == EVENTLOG_SUCCESS)
108                        return _T("success");
109                if (dwType == EVENTLOG_INFORMATION_TYPE)
110                        return _T("info");
111                if (dwType == EVENTLOG_AUDIT_SUCCESS)
112                        return _T("auditSuccess");
113                if (dwType == EVENTLOG_AUDIT_FAILURE)
114                        return _T("auditFailure");
115                return strEx::itos(dwType);
116        }
117        static DWORD translateSeverity(std::wstring sType) {
118                if (sType.empty())
119                        return 0;
120                if (sType == _T("success"))
121                        return 0;
122                if (sType == _T("informational"))
123                        return 1;
124                if (sType == _T("warning"))
125                        return 2;
126                if (sType == _T("error"))
127                        return 3;
128                return strEx::stoi(sType);
129        }
130        static std::wstring translateSeverity(DWORD dwType) {
131                if (dwType == 0)
132                        return _T("success");
133                if (dwType == 1)
134                        return _T("informational");
135                if (dwType == 2)
136                        return _T("warning");
137                if (dwType == 3)
138                        return _T("error");
139                return strEx::itos(dwType);
140        }
141        std::wstring get_dll() const {
142                try {
143                        return simple_registry::registry_key::get_string(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\") + file_ + (std::wstring)_T("\\") + eventSource(), _T("EventMessageFile"));
144                } catch (simple_registry::registry_exception &e) {
145                        NSC_LOG_ERROR_STD(_T("Could not extract DLL for eventsource: ") + eventSource() + _T(": ") + e.what());
146                        return _T("");
147                }
148        }
149
150        struct tchar_array {
151                TCHAR **buffer;
152                unsigned int size;
153                tchar_array(unsigned int size) : buffer(NULL), size(size) {
154                        buffer = new TCHAR*[size];
155                        for (int i=0;i<size;i++)
156                                buffer[i] = NULL;
157                }
158                ~tchar_array() {
159                        for (int i=0;i<size;i++)
160                                delete [] buffer[i];
161                        delete [] buffer;
162                }
163                unsigned int set(int i, const TCHAR* str) {
164                        unsigned int len = wcslen(str);
165                        buffer[i] = new TCHAR[len+2];
166                        wcsncpy(buffer[i], str, len+1);
167                        return len;
168                }
169                TCHAR** get_buffer_unsafe() { return buffer; }
170
171        };
172        std::wstring render_message(DWORD dwLang = 0) const {
173                std::vector<std::wstring> args;
174                const TCHAR* p = reinterpret_cast<const TCHAR*>(reinterpret_cast<const BYTE*>(pevlr_) + pevlr_->StringOffset);
175
176                tchar_array buffer(pevlr_->NumStrings);
177                for (unsigned int i =0;i<pevlr_->NumStrings;i++) {
178                        unsigned int len = buffer.set(i, p);
179                        p = &(p[len+1]);
180                }
181                std::wstring ret;
182                strEx::splitList dlls = strEx::splitEx(get_dll(), _T(";"));
183                for (strEx::splitList::const_iterator cit = dlls.begin(); cit != dlls.end(); ++cit) {
184                        //std::wstring msg = error::format::message::from_module((*cit), eventID(), _sz);
185                        std::wstring msg;
186                        try {
187                                HMODULE hDLL = LoadLibraryEx((*cit).c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES);
188                                if (hDLL == NULL) {
189                                        msg = _T("failed to load: ") + (*cit) + _T(", reason: ") + strEx::itos(GetLastError());
190                                        continue;
191                                }
192                                LPVOID lpMsgBuf;
193                                if (dwLang == 0)
194                                        dwLang = MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT);
195                                unsigned long dwRet = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE|FORMAT_MESSAGE_ARGUMENT_ARRAY,hDLL,
196                                        eventID(),dwLang,(LPTSTR)&lpMsgBuf,0,reinterpret_cast<va_list*>(buffer.get_buffer_unsafe()));
197                                if (dwRet == 0) {
198                                        DWORD err = GetLastError();
199                                        FreeLibrary(hDLL);
200                                        if (err == 317) {
201                                                msg = _T("");
202                                                continue;
203                                        }
204                                        msg = _T("failed to lookup error code: ") + strEx::itos(eventID()) + _T(" from DLL: ") + (*cit) + _T("( reson: ") + strEx::itos(err) + _T(")");
205                                        continue;
206                                }
207                                msg = reinterpret_cast<wchar_t*>(lpMsgBuf);
208                                LocalFree(lpMsgBuf);
209                                FreeLibrary(hDLL);
210                        } catch (...) {
211                                msg = _T("Unknown exception getting message");
212                        }
213                        strEx::replace(msg, _T("\n"), _T(" "));
214                        strEx::replace(msg, _T("\t"), _T(" "));
215                        std::string::size_type pos = msg.find_last_not_of(_T("\n\t "));
216                        if (pos != std::string::npos) {
217                                msg = msg.substr(0,pos);
218                        }
219                        if (!msg.empty()) {
220                                if (!ret.empty())
221                                        ret += _T(", ");
222                                ret += msg;
223                        }
224                }
225                return ret;
226        }
227        SYSTEMTIME get_time(DWORD time) const {
228                FILETIME FileTime, LocalFileTime;
229                SYSTEMTIME SysTime;
230                __int64 lgTemp;
231                __int64 SecsTo1970 = 116444736000000000;
232
233                lgTemp = Int32x32To64(time,10000000) + SecsTo1970;
234
235                FileTime.dwLowDateTime = (DWORD) lgTemp;
236                FileTime.dwHighDateTime = (DWORD)(lgTemp >> 32);
237
238                FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
239                FileTimeToSystemTime(&LocalFileTime, &SysTime);
240                return SysTime;
241        }
242
243        SYSTEMTIME get_time_generated() const {
244                return get_time(pevlr_->TimeGenerated);
245        }
246        SYSTEMTIME get_time_written() const {
247                return get_time(pevlr_->TimeWritten);
248        }
249
250        std::wstring render(bool propper, std::wstring syntax, std::wstring date_format = DATE_FORMAT, DWORD langId = 0) const {
251                if (propper) {
252                        // To obtain the appropriate message string from the message file, load the message file with the LoadLibrary function and use the FormatMessage function
253                        strEx::replace(syntax, _T("%message%"), render_message(langId));
254                } else {
255                        strEx::replace(syntax, _T("%message%"), _T("%message% needs the descriptions flag set!"));
256                }
257
258                strEx::replace(syntax, _T("%source%"), eventSource());
259                strEx::replace(syntax, _T("%generated%"), strEx::format_date(get_time_generated(), date_format));
260                strEx::replace(syntax, _T("%written%"), strEx::format_date(get_time_written(), date_format));
261                strEx::replace(syntax, _T("%generated-raw%"), strEx::itos(pevlr_->TimeGenerated));
262                strEx::replace(syntax, _T("%written-raw%"), strEx::itos(pevlr_->TimeWritten));
263                strEx::replace(syntax, _T("%type%"), translateType(eventType()));
264                strEx::replace(syntax, _T("%severity%"), translateSeverity(severity()));
265                strEx::replace(syntax, _T("%strings%"), enumStrings());
266                strEx::replace(syntax, _T("%id%"), strEx::itos(eventID()));
267                strEx::replace(syntax, _T("%user%"), userSID());
268                return syntax;
269        }
270};
Note: See TracBrowser for help on using the repository browser.