从事件跟踪ETW文件日志中的FileObject或FileKey获取FileName(C#)

3

我一直在寻找一个解决方案,可以从事件跟踪(ETW)会话中获取特定进程的所有读/写/打开/关闭文件的信息(我将处理实时会话的数据)。 我编写了下面这段代码,它可以获取操作中的所有事件,但无法获取事件中的FileNamePath。只有 FileObjectFileKey...
下面是获取事件的代码:

        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();
             }
        }

我运行我的代理程序并获取到类似以下的事件:

    <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"/>

在这个事件中,我如何获取受影响的FileName
FileObjectFileKey是什么?
我能从FileObjectFileKey获取FileName吗?


1
请参考此链接了解同一案例:http://bcl.codeplex.com/discussions/274260 - lsalamon
1
谢谢@Isalamon。这些链接很有用,我从中得到了灵感和问题的答案。我会分享答案。 - sa-es-ir
1
请查看此链接:https://dev59.com/O2Ik5IYBdhLWcg3wr_9o#26259197 - lsalamon
@Isalamon 再次感谢。您认为在使用C#的.NET 2.0内核模式中,是否有实现类似于此的事件的方法? - sa-es-ir
不可能的,只有更新版本的运行时才能提供这样的功能。 - lsalamon
2个回答

3
通过这段代码,我能获取到我想要的一切。
 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);
        }  
    }

在事件的ShareAccess属性中,您可以找到ReadWrite事件。每个事件中都有FileName。您还可以限制文件事件的目录,并使用此功能代替FileSystemWatcher。:)

0

在你订阅的session.Source中已经有一个内核解析器:

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);
    }
}

在这里,您可以按pid或进程名称进行过滤,并且您可以在data.FileName中获取文件名。订阅任何您想要处理的FileIO事件。


使用你的解决方案,我没有收到任何事件! - sa-es-ir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接