直接读取.evt / .evtx文件 [英] Reading .evt/.evtx files directly

查看:700
本文介绍了直接读取.evt / .evtx文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,有人知道如何读取.evt /.evtx,这是Windows事件日志文件,而不使用提供的api读取,我想使用 FILE I / O C / C ++ 中的api。

Hello does anybody know how to read .evt /.evtx which are Windows Event log files to read not using provided api's , I want to read them using FILE I/O apis in C/C++.

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

Or how to convert those files into .txt , I know splunk does this but not sure how they are doing this.

推荐答案

我可能来晚了,但是很好,它可以对将来的读者有所帮助,所以:

I might be late but well, it could help a future reader so :

要阅读 .evt 文件,您应该注意 ELF_LOGFILE_HEADER结构 EVENTLOGRECORD结构。此外,此处是事件日志文件格式。

To read an .evt file with standard lib (let's say in C++), you should be aware of ELF_LOGFILE_HEADER structure and EVENTLOGRECORD structure. In addition, here is the event log file format.

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

Now everything is simpler, what you have to do is :


  1. 日志头结构

  1. Log Header structure

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;  


  • 日志记录结构

  • Log Record structure

    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;
    




  • II让我们阅读!



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

    II Let's read !

    First declare a std::ifstream variable to open and read the file (binary)

    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);
        }
    }
    

    希望它可以帮助某人,

    这篇关于直接读取.evt / .evtx文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆