直接读取.evt / .evtx文件

您好,有谁知道如何读取.evt / .evtx这是Windows事件日志文件读取不使用提供的API,我想读取他们使用FILE I/O API在C/C++

或者如何将这些文件转换为.txt文件,我知道splunk做到这一点,但不知道他们是如何做到的。

Solutions Collecting From Web of "直接读取.evt / .evtx文件"

我可能会迟到但很好,可以帮助未来的读者:

要用标准库读取.evt文件(比如用C ++),你应该知道ELF_LOGFILE_HEADER结构和EVENTLOGRECORD结构 。 另外, 这里是事件日志文件格式。

现在一切都比较简单,你要做的是:

I.声明结构

  1. 日志标题结构

     typedef unsigned long ULONG; typedef struct _EVENTLOGHEADER { ULONG HeaderSize; ULONG Signature; ULONG MajorVersion; ULONG MinorVersion; ULONG StartOffset; ULONG EndOffset; ULONG CurrentRecordNumber; ULONG OldestRecordNumber; ULONG MaxSize; ULONG Flags; ULONG Retention; ULONG EndHeaderSize; } EVENTLOGHEADER, *PEVENTLOGHEADER; 
  2. 日志记录结构

     typedef unsigned long DWORD; typedef unsigned short WORD; typedef struct _EVENTLOGRECORD { DWORD Length; DWORD Reserved; DWORD RecordNumber; DWORD TimeGenerated; DWORD TimeWritten; DWORD EventID; WORD EventType; WORD NumStrings; WORD EventCategory; WORD ReservedFlags; DWORD ClosingRecordNumber; DWORD StringOffset; DWORD UserSidLength; DWORD UserSidOffset; DWORD DataLength; DWORD DataOffset; } EVENTLOGRECORD, *PEVENTLOGRECORD; 

我们来看看!

首先声明一个std::ifstream变量来打开并读取文件(二进制)

 using namespace std; ifstream file; file.open(fileName,ios::in|ios::binary); if(file.is_open()){ _EVENTLOGHEADER logheader; _EVENTLOGRECORD logRecord; //Reading the header file.read((char*)&logheader,sizeof(_EVENTLOGHEADER)); int startOfLog; //Loop on every record for(unsigned int numberFile=0;numberFile < logheader.CurrentRecordNumber -1;numberFile++){ //Save the position startOfLog = file.tellg(); //Read log record file.read((char*)&logRecord,sizeof(_EVENTLOGRECORD)); /******************************************************* Here are the other information (section 'Remarks' on the 'EVENTLOGRECORD structure' link ********************************************************/ //Reading sourcename wchar_t buffData; wstring SourceName; file.read((char*)&buffData,sizeof(wchar_t)); while(buffData!=_T('\0')){ SourceName.push_back(buffData); file.read((char*)&buffData,sizeof(wchar_t)); } //Reading computer name wstring ComputerName; file.read((char*)&buffData,sizeof(wchar_t)); while(buffData!=_T('\0')){ ComputerName.push_back(buffData); file.read((char*)&buffData,sizeof(wchar_t)); } //Sets the position to the SID offset int readCursor = startOfLog + logRecord.UserSidOffset; file.seekg(readCursor); char * userSid = NULL; if(logRecord.UserSidLength != 0) { userSid = (PCHAR)malloc(logRecord.UserSidLength); file.read(userSid,logRecord.UserSidLength); //Reading the sid //Here you can work on the SiD (but you need win32 API).If you need it, I could show you how i deal with this sid free(userSid); } //Sets the position to the Strings offset readCursor = startOfLog + logRecord.StringOffset; file.seekg(readCursor); wstring buffString; vector<wstring> allStrings; //Reading all the strings for(int i=0; i< logRecord.NumStrings; i++) { file.read((char*)&buffData,sizeof(wchar_t)); while(buffData!=_T('\0')){ buffString.push_back(buffData); file.read((char*)&buffData,sizeof(wchar_t)); } allStrings.push_back(buffString); buffString.clear(); } //Sets the position to the Data offset readCursor = startOfLog + logRecord.DataOffset; file.seekg(readCursor); unsigned char *Data = (unsigned char *)malloc(logRecord.DataLength*sizeof(unsigned char)); file.read((char*)Data,logRecord.DataLength); //Lecture des données //Sets the position to the end of log offset readCursor = startOfLog + logRecord.Length - sizeof(DWORD) ; file.seekg(readCursor); DWORD length; file.read((char*)&length,sizeof(DWORD)); //Do what you want with the log record //Clean before reading next log ComputerName.clear(); SourceName.clear(); allStrings.clear(); free(Data); } } 

希望它可以帮助别人,