阅读.evt /.直接使用Evtx文件
Reading .evt/.evtx files directly
你好,有人知道怎么读。evt/吗?这是Windows事件日志文件读取不使用提供的api,我想在C/C++
中使用FILE I/O
api读取它们。
或者如何将这些文件转换为.txt
,我知道splunk
这样做,但不确定他们是如何做到这一点的。
我可能迟到了,但是,它可以帮助未来的读者,所以:
读取。evt文件与标准库(让我们说在c++中),你应该知道ELF_LOGFILE_HEADER结构和EVENTLOGRECORD结构。另外,这里是事件日志文件格式。
现在一切都简单了,你要做的是:
。日志头结构
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;
日志记录结构
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;
让我们一起读!
日志头结构
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;
日志记录结构
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(' ')){
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(' ')){
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(' ')){
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);
}
}
希望它能帮助别人,
相关文章:
- .cpp和.h文件中的模板专用化声明
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 文本文件中的单词链表
- CMake-按正确顺序将项目与C运行时对象文件链接
- 使用新行和不使用新行读取文件
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 挂起和取消挂起一个文件DLL
- 如何确定我已使用非编码文件到达 EOF?
- 命名空间中具有.h和.cpp文件的类
- 如何使用ndk-build.cmd构建Android.so文件
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 读取文件并输入到矢量中
- 在C++中查找文件
- c++库的公共头文件中应该包含什么
- 用c++从输入文件中读取另一行
- Cppcheck生成xml转储文件
- 读取文件的最后一行并输入到链接列表时出错
- 在给定路径中读取保存的EVTX文件
- 尝试读取evtx文件时出现编译器错误
- 阅读.evt /.直接使用Evtx文件