0x00 Preface
---
The second article in the Windows XML Event Log (EVTX) single log deletion series introduces methods for deleting single log entries from specified EVTX files, addresses multiple design considerations in programming, and provides open-source implementation code.
0x01 Introduction
---
This article will cover the following topics:
- Approach for deleting single log entries from specified EVTX files
- Program implementation details
- Open-source code
0x02 Approach for Deleting Single Log Entries from Specified EVTX Files
---
The previous article, 'Windows XML Event Log (EVTX) Single Log Deletion (Part 1) – Deletion Approach and Examples', explained the principles and an example of deleting single log entries from EVTX files by modifying log lengths.
The implementation approach is illustrated below:

Note:
Image from https://blog.fox-it.com/2017/12/08/detection-and-recovery-of-nsas-covered-up-tracks/
This method is relatively simple to implement, but multiple different scenarios need to be considered:
- Delete intermediate log
- Delete the last log
- Delete the first log
0x03 Delete intermediate log
---
Method as follows:
- Decrease the Next record identifier value in the File header by 1
- Recalculate the Checksum in the File header
- Recalculate the previous log length, involving 2 positions (offset 4 and the last 4 bytes of the current log)
- Decrease the Event record identifier of subsequent logs by 1 sequentially
- Decrease the Last event record number in ElfChuk by 1
- Decrease the Last event record identifier in ElfChuk by 1
- Recalculate checksum of Event records in ElfChuk
- Recalculate checksum in ElfChuk
In program implementation, the specific details are as follows:
1. Decrement the Next record identifier value in File header by 1
Read log file content
Define log file format structure and parse the log file format
Decrement Next record identifier value by 1:
FileHeader->NextRecordIdentifier = FileHeader->NextRecordIdentifier-1 |
2. Recalculate the Checksum in File header
C code for calculating CRC checksum:
unsigned int CRC32[256]; |
Calculate the checksum of the first 120 bytes of the File header
Code is as follows:
unsigned char *ChecksumBuf = new unsigned char[120]; |
3. Recalculate the length of the previous log, involving 2 positions (offset 4 and the last 4 bytes of the current log)
Locate Event Records one by one by searching for the magic string 0x2A 0x2A 0x00 0x00
(1) Locate the log to be deleted: CurrentRecord
Read the length, i.e., CurrentRecord->Size
(2) Locate the previous log: PrevRecord
Read the length, i.e., PrevRecord->Size
Calculate the merged length:
NewSize = CurrentRecord->Size + PrevRecord->Size |
Update the length:
PrevRecord->Size = NewSize |
(3) Locate the next log record NextRecord
Replace the 4 bytes before the starting point of NextRecord with NewSize:
*(PULONG)((PBYTE)NextRecord-4) = NewSize |
4. Decrement the Event record identifier of subsequent logs by 1 sequentially
Traverse subsequent logs, decrementing the Event record identifier by 1 sequentially
Two locations need to be modified:
CurrentRecord->EventRecordIdentifier = CurrentRecord->EventRecordIdentifier-1 |
5. Decrement the Last event record number in ElfChuk by 1
ElfChuk->LastEventRecordNumber = ElfChuk->LastEventRecordNumber-1 |
6. Decrement the Last event record identifier in ElfChuk by 1
ElfChuk->LastEventRecordIdentifier = ElfChuk->LastEventRecordIdentifier-1 |
7. Recalculate the Event records checksum in ElfChuk
unsigned char *ChecksumBuf = new unsigned char[currentChunk->FreeSpaceOffset - 512]; |
8. Recalculate the Checksum in ElfChuk
unsigned char *ChecksumBuf = new unsigned char[504]; |
0x04 Delete the last log entry
---
Deleting the last log entry was demonstrated in the previous article 'Windows XML Event Log (EVTX) Single Log Entry Deletion (Part 1) – Deletion Approach and Example'. The method is essentially the same as deleting a middle log entry.
The differences are as follows:
- The Event record identifier of subsequent logs does not need to be decremented by 1, as there are no subsequent logs.
- The Last event record data offset in ElfChuk needs to be recalculated.
The program details are as follows:
1. Recalculate the Last event record data offset in ElfChuk
ElfChuk->LastEventRecordDataOffset = ElfChuk->LastEventRecordDataOffset - LastRecord->Size |
0x05 Delete the first log
---
The method of modifying log length is not applicable for deleting the first log, because there is no previous log to overwrite the current one
If you still want to achieve this using the overwrite length method, further analysis of the log file format is required
We know that the content of Event Records is stored in Binary XML format
For reference on Binary XML format:
https://github.com/libyal/libevtx/blob/master/documentation/Windows%20XML%20Event%20Log%20(EVTX).asciidoc#4-binary-xml
To merge logs by modifying the Binary XML format content, the following items need to be modified:
- Written date and time
- Template definition Data size
- Next template definition offset
Note:
This method is also applicable for modifying middle logs and the last log, so understanding the log format means deletion methods are not unique
For other implementation details, refer to the open-source code at the following address:
`An open-source project
The code implements reading the specified log file c:\\test\\Setup.evtx, deleting a single log entry (EventRecordID=14), and saving it as a new log file c:\\test\\SetupNew.evtx
Note:
In the implementation details of the code, I referred to the demo code on KanXue, with the address as follows:
https://bbs.pediy.com/thread-219313.htm
0x06 Summary
---
This article introduces the approach and program implementation details for deleting a single log entry from an evtx file, with open-source code. The method for deleting a single log entry is not unique. Next, multiple methods for deleting a single log entry from the current system will be introduced.