0x00 Preface

---

The third article in the series on Windows Event Viewer Log (EVT) single log deletion introduces methods and detailed testing procedures for deleting EVT log records for a specified time period on the current system, explains the reasons why the number of logs cannot be modified, and finally provides open-source implementation code for querying and modifying log content.

0x01 Introduction

---

This article will cover the following topics:

  • Method for enumerating all system handles on Windows XP
  • Criteria for filtering log file handles
  • Example code for DLL injection on Windows XP
  • Actual testing process
  • Reasons why the number of logs cannot be modified
  • Implementation details of the log query program
  • Implementation details of the log modification program

0x02 Enumerating System Handles on Windows XP

---

The previous article "Windows Single Log Deletion (5) – Deleting Current System Single Log Records by Obtaining Log File Handles via DuplicateHandle" introduced the implementation method for Windows 8 and later systems:

  1. Using NtQuerySystemInformation to query SystemHandleInformation can obtain handle information for all processes
  2. Obtaining handle names and specific numerical information via NtDuplicateObject
  3. Filtering out the desired handles
  4. Duplicating handles via DuplicateHandle
  5. Obtaining permission to modify log files

On Windows XP systems, NtQuerySystemInformation cannot be used to query SystemHandleInformation to obtain process handle information

Referring to Process Hacker's source code to find implementation methods

Code location:

https://github.com/processhacker/processhacker/blob/e2d793289dede80f6e3bda26d6478dc58b20b7f8/ProcessHacker/hndlprv.c#L307

Obtained reference materials:

On Windows 8 and later, NtQueryInformationProcess with ProcessHandleInformation is the most efficient method.

On Windows XP and later, NtQuerySystemInformation with SystemExtendedHandleInformation.

Otherwise, NtQuerySystemInformation with SystemHandleInformation can be used.

Attempt the second method: query SystemExtendedHandleInformation using NtQuerySystemInformation

Note:

The second method supports Windows XP and later systems

0x03 Filter handles for specified log files

---

1. Filter handles of type file

ObjectTypeNumber = 0x1c

Note:

For Windows 8 and later systems, ObjectTypeNumber = 0x1e

For Windows XP and Windows 7 systems, ObjectTypeNumber = 0x1c

2. Filter out handles that may cause hangs

Determine via the WaitForSingleObject API

Otherwise, it will cause the process to hang

3. Narrow down the scope by specifying file attributes

Log file attributes are fixed: handle->GrantedAccess = 0x0012019f

The complete implementation code has been open-sourced, download link is as follows:

An open-source project).cpp

The code implements searching based on input keywords to obtain corresponding handle names and Handle values

0x04 Log Deletion Implementation Method 1: Obtaining Handle Operation Permissions via DLL Injection

---

Inject a DLL into the system process, the DLL file can then obtain the handle to the log file

The subsequent operations are:

  1. Call the function CreateFileMapping() to create a file mapping kernel object
  2. Call the function MapViewOfFile() to map the file data into the process's address space
  3. Modify the data in memory to delete specified log records
  4. Call the function FlushViewOfFile() to write the memory data to disk
  5. Clear the memory mapping object

For the complete implementation process, refer to the previously introduced article on deleting single evtx file logs: 'Windows XML Event Log (EVTX) Single Log Deletion (Part 4) – Deleting Current System Single Log Records by Injecting to Obtain Log File Handle'

Under the XP system, the method of NtCreateThreadEx + LdrLoadDll cannot be used to inject DLL; you can directly call CreateRemoteThread

Implementation code can be referenced:

An open-source project

0x05 Log Deletion Method 2: Obtaining Handle Operation Permissions via DuplicateHandle

---

Refer to the previous article "Windows XML Event Log (EVTX) Single Log Deletion (5) – Deleting a Single Log Record from the Current System by Obtaining Log File Handle via DuplicateHandle"

After filtering the handles, call NtDuplicateObject again to obtain the real handle and perform deletion operations on the log file

Similarly, the following operations are required:

  1. Call the CreateFileMapping() function to create a file mapping kernel object
  2. Call the MapViewOfFile() function to map the file data into the process's address space
  3. Modify the data in memory to delete the specified log record
  4. Call the FlushViewOfFile() function to write the memory data to disk
  5. Clear the memory mapping object

For the log deletion part, refer to the previous article "Windows Event Viewer Log (EVT) Single Log Deletion (2) – Program Implementation to Delete Log Records within a Specified Timeframe from an EVT File"

Here is a complete implementation code:

`An open-source project

The code implements the deletion of multiple log records within a specified timeframe from a given EVT file and generates debug files sys2.evt and sys3.evt

sys2.evt saves the array content after log deletion

sys3.evt saves the content mapped into memory

After program execution, sys2.evt and sys3.evt successfully deleted the specified logs, but the current system's log file generated errors

For comparative testing, I adjusted the deletion time period to values outside the current logs, meaning no logs would be deleted. After program execution, the current system's log file remained normal

Furthermore, as long as the number of logs is not changed, modifying the log content keeps the current system's log file normal

This leads to a conclusion:It is impossible to change the number of logs by obtaining the log file handle and modifying memory data

Similarly, directly modifying the File header of the memory file through ProcessHacker also cannot change the number of logs

Wrote a program to verify, using the API GetNumberOfEventLogRecords to query the number of logs

C code as follows:

#include
#pragma comment(lib,"Advapi32.lib")

int main(int argc, char *argv[])
{
HANDLE hEventLog = NULL;

hEventLog = OpenEventLog(NULL, argv[1]);
if (NULL == hEventLog)
{
printf("OpenEventLog failed with 0x%x.\n", GetLastError());
goto cleanup;
}

DWORD NumberOfRecords = 0;
BOOL flag = GetNumberOfEventLogRecords(hEventLog, &NumberOfRecords);

if (NULL == flag)
{
printf("GetNumberOfEventLogRecords failed with 0x%x.\n", GetLastError());
goto cleanup;
}
printf("%d\n", NumberOfRecords);

cleanup:

if (hEventLog)
CloseEventLog(hEventLog);

}

cmd:

GetNumberOfEventLogRecords.exe system

Get the number of log records

Directly modify the Last (newest) record number in the File header and the Last (newest) record number in the End of file record of the memory file via ProcessHacker

Execute the program again to obtain the number of log records, and find that the obtained number of log records remains unchanged

Verify the conclusion: modifying log content in memory cannot change the actual number of log records

0x06 Program Implementation Details for Log Query and Log Modification

The code for log query is as follows:

`An open-source project

The code implements traversing logs and displaying information for each log

The code for log modification is as follows:

`An open-source project

The code implements modifying information of specified logs

0x07 Summary

---

This article introduces two methods for deleting evt log records within a specified time period in the current system: obtaining handle operation permissions through DLL injection and DuplicateHandle respectively, and utilizing these handles to modify log files

The deletion method is not simple overwriting but complete removal of logs from a certain period. Evtx file log deletion can also refer to this approach, though implementation is relatively more complex. Implementation code for evtx will be updated subsequently