I'm trying to use ETW to detect failed library loads. In ProcMon, I'd set a filter for the CreateFile operation, set the path to end with .dll and the result to "NAME NOT FOUND". This captures an applications attempt to access a DLL which doesn't exist.
Is there a way to do this using ETW? I'm able to capture the successful library loads, but not failed loads.
Here's my code so far:
using(session = new TraceEventSession(sessionName, null))
{
session.EnableKernelProvider(
KernelTraceEventParser.Keywords.ImageLoad |
KernelTraceEventParser.Keywords.Process,
KernelTraceEventParser.Keywords.None
);
using (TraceLogEventSource traceLogSource = TraceLog.CreateFromTraceEventSession(session))
{
Action<ImageLoadTraceData> PrintEvent = ((ImageLoadTraceData data) => Print(data));
Action<FileIOReadWriteTraceData> PrintFileEvent = ((FileIOReadWriteTraceData data) => PrintFile(data));
traceLogSource.Kernel.ImageLoad += PrintEvent;
timer = new Timer(delegate (object state)
{
if (session != null)
session.Dispose();
session = null;
}, null, monitoringTimeSec * 1000, Timeout.Infinite);
traceLogSource.Process();
}
}
And the PrintFile method for the ImageLoad event:
static void Print(ImageLoadTraceData data)
{
Console.WriteLine("[*] {0} loaded a library!", data.ProcessName);
Console.WriteLine("\t {0}", data.FileName);
}
This gives me output like this:
[*] GoogleUpdate loaded a library!
C:\Windows\SysWOW64\ntmarta.dll
I'd like to be able to capture only failed attempts to load a library. I could take each loaded event and work back up the DLL load order (https://learn.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order), but that seems like an unnecessarily naive approach.