This tool is a command-line utility for Windows written in C that creates and configures persistent Event Tracing for Windows (ETW) AutoLogger sessions. AutoLoggers automatically start tracing specific ETW providers upon system boot, making them useful for capturing events that occur early in the boot process or for continuous monitoring scenarios.
This tool allows selecting predefined lists of ETW providers related to known EDR to include in the AutoLogger session via command-line arguments. It merges configurations if the same provider is included in multiple selected lists, ensuring the highest logging level is used and keyword flags are combined appropriately to maximize event coverage based on the selected lists.
- Creates persistent ETW AutoLogger sessions via registry configuration (
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\Autologger\Metamorph). - Starts automatically on system boot.
- Allows selection of predefined provider lists (
-Defender,-Crowdstrike,-MDE,-Sentinelone,-Cortex). - Option to enable all providers from all lists (
-All). - Option to enable noisy providers (some are automatically deleted to avoid filling the disks within seconds): (
-noisy) - Merges duplicate provider configurations:
- Keeps the highest
Levelspecified across all duplicates for a provider. - Combines
MatchAnyKeywordflags using bitwise OR from all duplicates (regardless of level) to ensure widest keyword coverage. - Uses the
MatchAllKeywordfrom the configuration entry that provided the highest level.
- Keeps the highest
- Configurable session name and log file path (defined as constants in the code).
You need a C compiler, such as the one included with Visual Studio.
- Open Metamorph.sln file
- Select "Release" and your target architecture (x64/x86)
- Compile and enjoy
There is no non standard imports, so Cl compilation should be possible without a lot of hassle.
Important: This tool modifies the Windows Registry (HKEY_LOCAL_MACHINE) and therefore requires Administrator privileges to run correctly.
- Open a Command Prompt or PowerShell window as Administrator and run the executable from there.
.\Metamorph.exe <options>
# Enable only providers from Defender
.\Metamorph.exe -Defender
# Enable providers from Defender and MDE, merging duplicates
.\Metamorph.exe -Defender -MDE
# Enable all providers from all engines, merging duplicates
.\Metamorph.exe -All
# Enabling one provider, also with noisy ones, because why not filling disk space after all?
.\Metamorph.exe -All -noisyAfter initialization, a reboot must occurs to start the newly registered provider.
In order to clean this provider, one must:
- Open regedit.exe
- Navigate to (
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\Autologger\Metamorph) - Right click to delete the aforementioned registry key.
- Reboot
ETW provides deep visibility into runtime events. This can be leveraged to detect potentially suspicious activities which might indicate malware activity or obfuscation techniques. Once installed, the providers should provide the same level of "Event log" telemetry than the "cloned" EDR. It should then ease research of IOC that could be left by internal tools.
After the system has rebooted and the applications of interest have run, the .etl file (e.g., Metamorph.etl) will contain the captured events.
Generated file (C:\Windows\System32\LogFiles\WMI\Metamorph.etl.00x) could be ingested by several public tools like:
- Event Viewer itself
- Perfview
- insert your preferred ETW tool here
Nota bene: Metamorph is using circular log files to avoid losing it accidentally after a reboot, but some tools need that the files is ended with .etl, so you will need to remove the suffix before usage.
Also, it is possible to basically translate the .etl file to a CSV file for dirty grep:
tracerpt MyKeywordMergedETWLogger.etl -o logdump.csv -of CSVLet's say we have the following Powershell program that load a file using Assembly.Load:
[Reflection.Assembly]::Load([System.Convert]::FromBase64String("TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAA[...]AAAAAAAAAAAAA"))
#Récupération du handle sur le process cible
$ProcessDesiredAccess = 0x00000400
$InheritHandle = 0
$ProcessId = $PID
$hProcess = [api32.run]::OpenProcess($ProcessDesiredAccess, $InheritHandle, $ProcessId)
if($hProcess -eq 0){ Write-Output "OpenProcess Error" }
#Récupération du handle sur le token du process cible
$hToken = [IntPtr]::Zero
$TokenDesiredAccess = 0x00000006
$Success = [api32.run]::OpenProcessToken($hProcess, $TokenDesiredAccess, [ref]$hToken)
if(-not $Success){ Write-Output "OpenProcessToken Error" }
#Duplication du token
$DesiredAccess = 0x10000000
$SecurityAttribute = New-Object api32.run+_SECURITY_ATTRIBUTES
$SecurityAttribute.lpSecurityDescriptor = [IntPtr]::Zero
$SecurityAttribute.bInheritHandle = $true
$ImpersonationLevel = 3
$TokenType = 1
$hDuplicatedToken = [IntPtr]::Zero
$Success = [api32.run]::DuplicateTokenEx($hToken, $DesiredAccess,[ref]$SecurityAttribute, $ImpersonationLevel, $TokenType,[ref]$hDuplicatedToken)
if(-not $Success) { Write-Debug "DuplicateTokenEx Error" }
#Creation du cmd avec le token dupliqué
$LogonFlags = 0
$ApplicationName = "cmd.exe"
$CommandLine = "/K whoami /all"
$CreationFlags = 0x00000010
$Environnement = [IntPtr]::Zero
$CurrentDirectory = "c:\windows\system32"
$StartUpinformation = New-Object api32.run+STARTUPINFOA
$ProcessInformation = New-Object api32.run+_PROCESS_INFORMATION
$Success = [api32.run]::CreateProcessWithTokenW($hDuplicatedToken, $LogonFlags,$ApplicationName, $CommandLine, $CreationFlags, $Environnement, $CurrentDirectory, [ref]$StartUpinformation,[ref]$ProcessInformation)
if(-not $Success) { Write-Debug "CreateProcessWithTokenW Error" }This script basically perform an attack like one that could be performed by the impersonate.exe tool.
- Open a powershell prompt with admin privileges
- Run poc.ps1
- Wait a few minutes to be sure that all ETW buffers have been flushed into the .etl file
- Open Perfview with admin privileges
- Load your .etl file through the dashboard and double click on events to access all providers data
- Navigate through the list of providers to investigate data based on what you did
- Choose relevant provider to inspect (here Microsoft-Windows-Powershell/Exécuterunecommandedistante)
- Inspecting Microsoft-Windows-DotNETRuntime/Loader/AssemblyLoad
So at the end, EDR and analysts have opportunity to perform signature analysis based on AssemblyName for known binaries (like: "Rubeus") and otherwise, they do have the possibility to retrieve Powershell scripts (including comments) for post-mortem analysis.
If you find this tool useful, you can add your own (or other) solutions following instructions in CONTRIBUTING.md. I will try to update it on a regular basis but as it will be completely dependent on solutions encountered during pentests, feel free to PR if you want your changes to be available for everyone.



