Skip to content

Commit

Permalink
Change the class EvtxDecoder to fit for the revised evtx_dump tool
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffreyZhang512 committed May 7, 2023
1 parent ddb417a commit 93d1fc6
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 57 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ This is a Qt based tool to decode Windows log files(.etl and .evtx) to txt files

For the binary release, please goto:
https://github.com/JeffreyZhang512/winlogdecoder/releases
The latest release version is v0.4.0.0.
The latest release version is v0.5.0.0 which also includes the revised evtx_dump tool.
To run the binary, you need install the Microsoft Visual C++ Redistributable as well. You can download it from Microsoft website.

## etl files
Expand All @@ -20,10 +20,10 @@ Notes:
## evtx files
The purpose of decoding evtx files is to show the events recorded by Windows. The process is as following:
- Call the evtx_dump tool (https://github.com/omerbenamram/evtx) to convert the evtx files to xml files.
- The xml files converted by the evtx_dump tool can't be completely parsed by the Qt class QXmlStreamReader, so I have to revise the format.
- Then parse the revised xml files and extract the information to .txt files.
- The problem is that the output of the evtx_dump tool is in XML format but not a valid xml file which can't be completely parsed by the Qt class QXmlStreamReader, so I have to change the evtx_dump tool to make the output file as a valid xml file.

Notes:
- The format of the generated txt file is like this:
[level] timestamp {guid of the provider}or[name of the provider][process id][thread id] eventID (Task Category)
- Currently, all events are printed to the txt file. You can modify the class EvtxDecoder to print the eventIDs you are interested only.
- Currently, all events are printed to the txt file. You can modify the class EvtxDecoder to print the eventIDs you are interested only.
2 changes: 1 addition & 1 deletion common/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#define VERSION_H

#ifndef APP_VERSION
#define APP_VERSION "0.4.0.0"
#define APP_VERSION "0.5.0.0"
#endif

#ifndef APP_ORGANIZATION_NAME
Expand Down
66 changes: 18 additions & 48 deletions tools/winlogdecoder/src/DecoderCtrl/EvtxDecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,59 +13,29 @@ EvtxDecoder::~EvtxDecoder()
}


bool EvtxDecoder::ParseXml(QString xmlFileName)
void EvtxDecoder::ParseNoOfRecords()
{
if (cancel)
return true;

QFile xmlFile(xmlFileName);
if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
QRegularExpressionMatch match = reRecords.match(extProcessMessage);
if (match.hasMatch())
{
emit log(QString("Decoder: Open %1 failed").arg(xmlFileName).toStdString(), LOG_ERROR);
return false;
noOfEvents = match.captured(1).toULongLong();
}
}

QFile xmlFileRevised(xmlFileName + QString(".xml"));
if (!xmlFileRevised.open(QIODevice::WriteOnly | QIODevice::Text))
return false;
QTextStream xmlRevisedOut(&xmlFileRevised);

xmlRevisedOut << QString("<Events>\n");
QString recordString;
while (!cancel && !xmlFile.atEnd())
{
QString line = xmlFile.readLine();
if (line == QString("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"))
continue;
else if (line.left(7) == QString("Record "))
{
recordString = line;
continue;
}
xmlRevisedOut << line;
}
bool EvtxDecoder::ParseXml(QString xmlFileName)
{
if (cancel)
return true;

xmlRevisedOut << QString("</Events>\n");

xmlFile.close();
xmlFileRevised.close();

// Get noOfEvents
QRegularExpressionMatch matchRecord = reRecord.match(recordString);
if (matchRecord.hasMatch())
{
noOfEvents = matchRecord.captured(1).toULongLong();
}

if (!xmlFileRevised.open(QIODevice::ReadOnly | QIODevice::Text))
QFile xmlFile(xmlFileName);
if (!xmlFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
emit log(QString("Decoder: Open %1 failed").arg(xmlFileName + QString(".xml")).toStdString(), LOG_ERROR);
emit log(QString("Decoder: Open %1 failed").arg(xmlFileName).toStdString(), LOG_ERROR);
return false;
}

reader.setDevice(&xmlFileRevised);
reader.setDevice(&xmlFile);

QFile txtFile(xmlFileName + QString(".txt"));
if (!txtFile.open(QIODevice::WriteOnly | QIODevice::Text))
Expand Down Expand Up @@ -111,9 +81,9 @@ bool EvtxDecoder::ParseXml(QString xmlFileName)
emit log(QString("Decoder: failed to parse %1, error = %2 ").arg(xmlFileName, reader.errorString()).toStdString(), LOG_ERROR);
return false;
}
if (xmlFileRevised.error() != QFile::NoError)
if (xmlFile.error() != QFile::NoError)
{
emit log(QString("Decoder: error happens in reading %1").arg(xmlFileName + QString(".xml")).toStdString(), LOG_ERROR);
emit log(QString("Decoder: error happens in reading %1").arg(xmlFileName).toStdString(), LOG_ERROR);
return false;
}
if (txtFile.error() != QFile::NoError)
Expand Down Expand Up @@ -160,7 +130,7 @@ void EvtxDecoder::doDecoding(QString evtxFileName, QString destFolder)
{
// long long threadId = reinterpret_cast<long long>(QThread::currentThreadId());
this->fileName = evtxFileName;
QString evtxdump = "evtx_dump-v0.8.1.exe";
QString evtxdump = "evtx_dump-v0.8.1_revised.exe";

extProcess = new QProcess(this);
// slotes for process
Expand All @@ -174,9 +144,9 @@ void EvtxDecoder::doDecoding(QString evtxFileName, QString destFolder)

QFileInfo fileInfo = QFileInfo(evtxFileName);
QString xmlFileName = QString("%1/%2.xml").arg(destFolder, fileInfo.fileName());
extProcessCommand = evtxdump + QString(" -f ") + xmlFileName.replace("/", "\\") + QString(" --no-confirm-overwrite -t 1 ") + evtxFileName.replace("/", "\\");
extProcessCommand = evtxdump + QString(" -f ") + xmlFileName.replace("/", "\\") + QString(" --no-confirm-overwrite --dont-show-record-number ") + evtxFileName.replace("/", "\\");
QStringList arguments;
arguments << "-f" << xmlFileName << "--no-confirm-overwrite" << "-t" << "1" << evtxFileName;
arguments << "-f" << xmlFileName << "--no-confirm-overwrite" << "--dont-show-record-number" << evtxFileName;

extProcess->start(evtxdump, arguments);
extProcess->waitForFinished(-1);
Expand All @@ -186,8 +156,8 @@ void EvtxDecoder::doDecoding(QString evtxFileName, QString destFolder)
{
// evtx_dump returns success
emit log(QString("Decoder: converted to %1 successfully").arg(xmlFileName).toStdString(), LOG_OK);
// Parse the summary file to get the total number of events
// ParseSummary(summaryFileName);
// Get the total number of events
ParseNoOfRecords();
// Then parser the xml file and generate the txt file
if (ParseXml(xmlFileName))
{
Expand Down
3 changes: 2 additions & 1 deletion tools/winlogdecoder/src/DecoderCtrl/EvtxDecoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ class EvtxDecoder : public EtlDecoder
~EvtxDecoder();

private:
QRegularExpression reRecord = QRegularExpression("^Record\\s+(\\d+)\n");
QRegularExpression reRecords = QRegularExpression("^Records:\\s+(\\d+)$", QRegularExpression::MultilineOption);

void ParseNoOfRecords();
bool ParseXml(QString xmlFileName);
bool ParseEvent(QTextStream& txtOut);

Expand Down
8 changes: 4 additions & 4 deletions tools/winlogdecoder/winlogdecoder.rc
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
IDI_ICON1 ICON "resource/winlogdecoder.ico"

VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,4,0,0
PRODUCTVERSION 0,4,0,0
FILEVERSION 0,5,0,0
PRODUCTVERSION 0,5,0,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
Expand All @@ -21,12 +21,12 @@ BEGIN
BEGIN
VALUE "CompanyName", ""
VALUE "FileDescription", "Windows Log Decoder"
VALUE "FileVersion", "0.4.0.0"
VALUE "FileVersion", "0.5.0.0"
VALUE "InternalName", "WinLogDecoder.exe"
VALUE "LegalCopyright", "2023 Zhang, Jeffrey"
VALUE "OriginalFilename", "WinLogDecoder.exe"
VALUE "ProductName", "Windows Log Decoder"
VALUE "ProductVersion", "0.4.0.0"
VALUE "ProductVersion", "0.5.0.0"
END
END
BLOCK "VarFileInfo"
Expand Down

0 comments on commit 93d1fc6

Please sign in to comment.