直接读取.evt / .evtx文件

时间:2011-08-19 06:55:06

标签: c++ windows event-log splunk

Hello有没有人知道如何阅读.evt /.evtx这些Windows事件日志文件不能使用提供的API阅读,我想在FILE I/O中使用C/C++ apis阅读它们。

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

1 个答案:

答案 0 :(得分:7)

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

要阅读带有标准库的 .evt 文件(比方说在C ++中),您应该知道ELF_LOGFILE_HEADER structureEVENTLOGRECORD structure。此外,here是事件日志文件格式。

现在一切都变得简单了,你要做的是:

予。声明结构

  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;
    
  3. II让我们读一读!

    首先声明一个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);
        }
    }
    

    希望它可以帮助某人,