Get FileName from FileObject or FileKey in event trace ETW file log C#

2k Views Asked by At

I've been searching for a solution to get all Read/Write/Open/Close files by a specific process from an event trace (ETW) session (I will process data from a real-time session). I write this code and get all event in that operation but I can't get FileName or Path in events. there is just FileObject and FileKey,...
this is my code to get events:

        var sessionName = "ETWEventSession";
        using (var session = new TraceEventSession(sessionName, null))
        {
        session.StopOnDispose = true;
            using (var source = new ETWTraceEventSource(sessionName, TraceEventSourceType.Session))
            {
                Action<TraceEvent> logAction = delegate(TraceEvent data)
                {
                    Console.WriteLine(log);
                };
                var registerParser = new RegisteredTraceEventParser(source);
                registerParser.All += logAction;
               var fileProviderGuid = TraceEventSession.GetProviderByName("Microsoft-Windows-Kernel-File");


                session.EnableProvider(fileProviderGuid, TraceEventLevel.Informational, 0x0200);

                source.Process();
             }
        }

I run my agent and get events like this:

    <Event MSec="0.0000" PID="11376" PName="" TID="24668" 
EventName="Write" ProviderName="Microsoft-Windows-Kernel-File" 
ByteOffset="102386" Irp="0xffffe00148e8c478" FileObject="0xffffe00146c43210" 
FileKey="0xffffc0019d3f8140" IssuingThreadId="24668" 
IOSize="7" IOFlags="0" ExtraFlags="0"/>

How can I get FileName that affected in this event?
What is FileObject or FileKey?
can I get FileName from FileObject or FileKey?

2

There are 2 best solutions below

0
On BEST ANSWER

With this code, can get every thing what I want.

 var KernelSession = new TraceEventSession(KernelTraceEventParser.KernelSessionName, null);
        var KernelSource = new ETWTraceEventSource(KernelTraceEventParser.KernelSessionName, TraceEventSourceType.Session);
        var KernelParser = new KernelTraceEventParser(KernelSource);
        KernelSession.StopOnDispose = true;

        KernelSession.EnableKernelProvider(
            KernelTraceEventParser.Keywords.DiskFileIO |
            KernelTraceEventParser.Keywords.FileIOInit |
            KernelTraceEventParser.Keywords.Thread |
            KernelTraceEventParser.Keywords.FileIO
            );
        KernelParser.All += GetLog;

        KernelSource.Process();

    }

    private static void GetLog(TraceEvent obj)
    {
        var log = obj.ToString();
        if (log.Contains(@"E:\Final\ETW"))//&& !log.Contains("FileIo/Create")
        {
            Console.WriteLine(log);
        }  
    }

In ShareAccess property of event you can find ReadWrite event . FileName is in each event. also you can restrict your directory for file events and use this instead of FileSystemWatcher :).

1
On

There is already an Kernel Parser in the session.Source which you subscribe to:

var kernel = session.Source.Kernel;
kernel.FileIORead += HandleFileIoReadWrite;
kernel.FileIOWrite += HandleFileIoReadWrite;

private void HandleFileIoReadWrite(FileIOReadWriteTraceData data)
{
    if (data.ProcessID == pid) // (data.ProcessName.Contains("foo"))
    {
            Console.WriteLine(data.FileName);
    }
}

here filter per pid or Processname and here you can get the filename at data.FileName. Subscribe to any FileIO event you want to handle.