static EtwProviderSelectionViewModel()
 {
     _providers = TraceEventProviders.GetPublishedProviders().Select(g => new Provider {
         Name = TraceEventProviders.GetProviderName(g),
         Guid = g
     }).ToArray();
 }
예제 #2
0
        //Level 4 is default -- after keywords
        public ProviderBrowser(Window parent, Action <string, string, string> update)
        {
            Owner          = parent;
            m_keyStrings   = new List <String>();
            m_selectedKeys = new List <string>();
            m_keys         = new Dictionary <string, ProviderDataItem>();
            m_processNames = new List <String>();
            m_updateParent = update;
            m_level        = "Verbose";
            InitializeComponent();

            ProviderNameFilter.Focus();

            LevelListBox.Items.Add("Always");
            LevelListBox.Items.Add("Critical");
            LevelListBox.Items.Add("Error");
            LevelListBox.Items.Add("Warning");
            LevelListBox.Items.Add("Informational");
            LevelListBox.Items.Add("Verbose");
            LevelListBox.SelectedItem = "Verbose";

            var processInfos = new ProcessInfos();

            m_processNames.Add("*");
            foreach (var process in processInfos.Processes)
            {
                // If the name is null, it is likely a system process, it will not have managed code, so don't bother.
                if (process.Name == null)
                {
                    continue;
                }
                // if (process.ProcessID == myProcessId)
                //    continue;

                /*// Only show processes with GC heaps.
                 * if (!allProcs && !m_procsWithHeaps.ContainsKey(process.ProcessID))
                 *  continue;*/
                m_processNames.Add(process.ToString());
            }

            ProcessNameListBox.ItemsSource = m_processNames;
            // Get Provider names
            m_providerNames = new List <String>();
            foreach (Guid guid in TraceEventProviders.GetPublishedProviders())
            {
                m_providerNames.Add(TraceEventProviders.GetProviderName(guid));
                //keyStrings.Add(TraceEventProviders.GetProviderKeywords(guid).ToString());
            }

            // setup GUI controls.
            ProviderNameListBox.ItemsSource = m_providerNames;
            KeyNameListBox.ItemsSource      = m_keyStrings;
        }
예제 #3
0
파일: Program.cs 프로젝트: sd37/myetrace
 private static void List()
 {
     if ((options.List & ListFlags.CLR) != 0)
     {
         Console.WriteLine("\nSupported CLR keywords (use with --clr):\n");
         foreach (var keyword in Enum.GetNames(typeof(ClrTraceEventParser.Keywords)))
         {
             Console.WriteLine($"\t{keyword}");
         }
     }
     if ((options.List & ListFlags.Kernel) != 0)
     {
         Console.WriteLine("\nSupported kernel keywords (use with --kernel):\n");
         foreach (var keyword in Enum.GetNames(typeof(KernelTraceEventParser.Keywords)))
         {
             Console.WriteLine($"\t{keyword}");
         }
     }
     if ((options.List & ListFlags.Registered) != 0)
     {
         Console.WriteLine("\nRegistered or enabled providers (use with --other):\n");
         foreach (var provider in
                  TraceEventProviders.GetRegisteredOrEnabledProviders()
                  .Select(guid => TraceEventProviders.GetProviderName(guid))
                  .OrderBy(n => n))
         {
             Console.WriteLine($"\t{provider}");
         }
     }
     if ((options.List & ListFlags.Published) != 0)
     {
         Console.WriteLine("\nPublished providers (use with --other):\n");
         foreach (var provider in
                  TraceEventProviders.GetPublishedProviders()
                  .Select(guid => TraceEventProviders.GetProviderName(guid))
                  .OrderBy(n => n))
         {
             Console.WriteLine($"\t{provider}");
         }
     }
     if ((options.List & ListFlags.Framework) != 0)
     {
         Console.WriteLine("\nPublished providers (use with --framework):\n");
         foreach (var keyword in Enum.GetNames(typeof(FrameworkEventSourceTraceEventParser.Keywords)))
         {
             Console.WriteLine($"\t{keyword}");
         }
     }
 }
예제 #4
0
        private void DoProcessSelected(object sender, SelectionChangedEventArgs e)
        {
            var selectedItem = ProcessNameListBox.SelectedItem;

            if (selectedItem != null)
            {
                m_keyStrings       = new List <String>();
                m_selectedKeys     = new List <string>();
                m_providerNames    = new List <String>();
                m_selectedProvider = null;
                m_providerNames    = new List <String>();
                if (selectedItem.ToString() == "*")
                {
                    foreach (Guid guid in TraceEventProviders.GetPublishedProviders())
                    {
                        m_providerNames.Add(TraceEventProviders.GetProviderName(guid));
                    }
                }
                else
                {
                    //if (selectedItem.ToString() == "*")
                    //    TemplateProperty;
                    // else
                    m_selectedProcess = selectedItem.ToString();
                    int begin = m_selectedProcess.IndexOf("|");
                    int end   = m_selectedProcess.IndexOf("| Alive", begin + 1);
                    m_selectedProcess = m_selectedProcess.Substring(begin + 8, end - begin - 8);
                    foreach (var provider in TraceEventProviders.GetRegisteredProvidersInProcess(int.Parse(m_selectedProcess)))
                    {
                        m_providerNames.Add(TraceEventProviders.GetProviderName(provider));
                    }

                    KeyNameListBox.ItemsSource = m_keyStrings;
                }
                ProviderNameListBox.ItemsSource = m_providerNames;
                updateDisplays();
            }
        }
예제 #5
0
 private static void GetRegisteredProvidersInProcess()
 {
     new List <string>(TraceEventProviders.GetRegisteredProvidersInProcess(System.Diagnostics.Process.GetCurrentProcess().Id)
                       .Select(p => TraceEventProviders.GetProviderName(p))).ForEach(name => Debug.WriteLine(name));
 }
예제 #6
0
        public static EtwManifest ParseWmiEventTraceClass(Guid provider)
        {
            // we make a best effort attempt to fit the metadata of this Legacy (MOF) provider into the instrumentation manifest format

            // we need to find the EventTrace class where the Guid class qualifier matches our provider Guid
            // afaik you can't query for qualifiers...just classes and properties.  :-/
            // so we loop through all of the EventTrace classes and compare
            var             providerSearcher = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = 'EventTrace'", null);
            ManagementClass providerClass    = null;

            foreach (ManagementClass candidateProviderClass in providerSearcher.Get())
            {
                foreach (QualifierData qd in candidateProviderClass.Qualifiers)
                {
                    if (qd.Name.ToLower() == "guid" && new Guid((string)qd.Value) == provider)
                    {
                        providerClass = candidateProviderClass;
                        break; // found
                    }
                }

                if (providerClass != null)
                {
                    break; // found
                }
            }

            if (providerClass == null)
            {
                throw new ApplicationException($"Provider {provider} has no corresponding EventTrace class in WMI Repository"); // not found
            }
            var manifest = new EtwManifest(string.Empty)
            {
                ProviderGuid   = provider,
                ProviderSymbol = (string)providerClass["__CLASS"]
            };

            var events      = new SortedDictionary <string, EtwEvent>();
            var templates   = new List <EtwTemplate>();
            var stringTable = new Dictionary <string, string>();

            // the provider name is usually in the Description Qualifier for the EventTrace class (but not always?)
            // and the keywords are properties for the EventTrace class
            // but we can already get both of these easily from Microsoft.Diagnostics.Tracing
            manifest.ProviderName = TraceEventProviders.GetProviderName(provider);
            manifest.Keywords     = TraceEventProviders.GetProviderKeywords(provider).Select(info => new EtwKeyword
            {
                Name    = info.Name,
                Mask    = info.Value,
                Message = info.Description
            }).ToArray();

            // event details are in the grandchildren of the top-level (EventTrace) provider class
            // WMI EventTrace children ~ a versioned category grouping
            // WMI EventTrace grandchildren ~ instrumentation manifest templates
            // note - event version can be set on the category and/or the event
            var templateNames = new SortedSet <string>();
            var taskSearcher  = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = '{providerClass["__CLASS"]}'", null);

            foreach (ManagementClass categoryVersionClass in taskSearcher.Get())
            {
                var categoryVersion     = 0;
                var category            = string.Empty;
                var categoryDescription = string.Empty;
                var displayName         = string.Empty;
                foreach (QualifierData qd in categoryVersionClass.Qualifiers)
                {
                    if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "eventversion")
                    {
                        categoryVersion = (Int32)qd.Value;
                    }
                    else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "guid")
                    {
                        category = (string)qd.Value;
                    }
                    else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "description")
                    {
                        categoryDescription = (string)qd.Value;
                    }
                    else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "displayname")
                    {
                        displayName = (string)qd.Value;
                    }
                }

                var templateSearcher = new ManagementObjectSearcher("root\\WMI", $"SELECT * FROM meta_class WHERE __superclass = '{categoryVersionClass["__CLASS"]}'", null);
                foreach (ManagementClass templateClass in templateSearcher.Get())
                {
                    // EventTypeName qualifier ~ OpCode
                    var template    = (string)templateClass["__CLASS"];
                    var eventType   = string.Empty;
                    var version     = categoryVersion;
                    var description = categoryDescription;
                    foreach (QualifierData qd in templateClass.Qualifiers)
                    {
                        if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "eventversion")
                        {
                            version = (Int32)qd.Value; // override category version with specific event version
                        }
                        else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "eventtypename")
                        {
                            eventType = (string)qd.Value;
                        }
                        else if (qd.Value.GetType() == typeof(String) && qd.Name.ToLower() == "description")
                        {
                            description = (string)qd.Value;
                        }
                    }
                    if (!string.IsNullOrEmpty(categoryDescription))
                    {
                        stringTable.Add(template, categoryDescription);
                    }

                    // EventType -> id(s)
                    var ids = new SortedSet <Int32>();
                    foreach (QualifierData qd in templateClass.Qualifiers)
                    {
                        if (qd.Name.ToLower() == "eventtype")
                        {
                            if (qd.Value.GetType() == typeof(Int32))
                            {
                                ids.Add((Int32)qd.Value);
                            }
                            else if (qd.Value.GetType().IsArray)
                            {
                                foreach (var element in (Array)qd.Value)
                                {
                                    if (element.GetType() == typeof(Int32))
                                    {
                                        ids.Add((Int32)element);
                                    }
                                }
                            }
                            break;
                        }
                    }

                    // sort by category, id, version
                    foreach (var id in ids)
                    {
                        events.Add($"{category}{id,6}{version,6}",
                                   new EtwEvent
                        {
                            Value    = id,
                            Symbol   = template,
                            Opcode   = eventType,
                            Version  = version,
                            Template = template,
                            Keyword  = description,
                            Task     = category
                        });
                    }

                    // create a template from the properties
                    var templateData = new SortedDictionary <int, EtwTemplateData>();
                    foreach (PropertyData pd in templateClass.Properties)
                    {
                        foreach (QualifierData qd in pd.Qualifiers)
                        {
                            if (qd.Value.GetType() == typeof(Int32) && qd.Name.ToLower() == "wmidataid")
                            {
                                var id = (int)qd.Value;
                                templateData[id] = new EtwTemplateData
                                {
                                    Name = pd.Name,
                                    Type = pd.Type.ToString()
                                };
                                break;
                            }
                        }
                    }

                    templates.Add(new EtwTemplate(template, templateData.Values.ToArray()));
                }
            }

            manifest.Events      = events.Values.ToArray();
            manifest.Templates   = templates.ToArray();
            manifest.StringTable = stringTable;

            return(manifest);
        }
        static void Main()
        {
            /*
             * output all ETW events in a single line 'grep-able' format per provider
             *
             * Microsoft.Diagnostics.Tracing does the heavy lifting and provides us with a (partial) ETW manifest,
             * but lallousx86's WEPExplorer provides improved metadata for providers that are also
             * Eventlog Providers (i.e. channel, message template).
             * Unfortunately it it doesn't output event names, so we need to combine both.
             *
             * This ticket would remove the need for the dependency on WEPExplorer -
             * https://github.com/microsoft/perfview/issues/1067
             *
             * And these two tickets would improve the quality of the generated manifest XML
             * https://github.com/microsoft/perfview/issues/1068
             * https://github.com/microsoft/perfview/issues/1069
             *
             * For convenience, I also use the manifest parsing code from EtwExplorer.
             * And was about to contribute back my MOF parsing code.
             */

            /*
             * you need to separately build WEPExplorer and copy cli.exe to your working directory
             * https://github.com/lallousx86/WinTools/tree/master/WEPExplorer
             */
            var useWEPExplorer = File.Exists(WinTools.Cli.CLI_PATH);

            if (!useWEPExplorer)
            {
                Console.WriteLine($"{Cli.CLI_PATH} from WEPExplorer is missing - Eventlog provider data will be incomplete");
            }

            var outputDir         = "output";
            var manifestOutputDir = Path.Combine(outputDir, "manifest");
            var mofOutputDir      = Path.Combine(outputDir, "mof");
            var unknownOutputDir  = Path.Combine(outputDir, "unknown");

            Directory.CreateDirectory(outputDir);
            Directory.CreateDirectory(manifestOutputDir);
            Directory.CreateDirectory(mofOutputDir);
            Directory.CreateDirectory(unknownOutputDir);

            var product = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ProductName", "").ToString();
            var release = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "ReleaseId", "").ToString();
            var build   = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", "BuildLabEx", "").ToString();

            using (var windowsVersionFile = new StreamWriter(Path.Combine(outputDir, "version.txt")))
            {
                windowsVersionFile.WriteLine($"{product} {release} ({build})");
            }

            foreach (var provider in TraceEventProviders.GetPublishedProviders())
            {
                var name = TraceEventProviders.GetProviderName(provider);

                // use the provider name as the output filename, but...
                // ':' is not a valid filename character - use a dash instead
                // and I just don't like spaces in filenames - use an underscore instead
                var tsvFilename = $"{name}.tsv".Replace(' ', '_').Replace(':', '-');

                bool        foundProviderDetails = false;
                EtwManifest manifest             = null;

                // is this is manifest-based provider?
                string manifestXML = string.Empty;
                try
                {
                    manifestXML = RegisteredTraceEventParser.GetManifestForRegisteredProvider(provider);

                    using (var tsvFile = new StreamWriter(Path.Combine(manifestOutputDir, tsvFilename)))
                    {
                        // Summary:
                        //     Given a provider GUID that has been registered with the operating system, get
                        //     a string representing the ETW manifest for that provider. Note that this manifest
                        //     is not as rich as the original source manifest because some information is not
                        //     actually compiled into the binary manifest that is registered with the OS.

                        // a few hacky escaping fixes so that we can parse the xml...
                        if (name == "Microsoft-Windows-AppXDeployment-Server")
                        {
                            manifestXML = manifestXML.Replace("\"any\"", "&quot;any&quot;");
                        }
                        if (name == "Microsoft-Windows-GroupPolicy")
                        {
                            manifestXML = manifestXML.Replace("\"No loopback mode\"", "&quot;No loopback mode&quot;");
                            manifestXML = manifestXML.Replace("\"Merge\"", "&quot;Merge&quot;");
                            manifestXML = manifestXML.Replace("\"Replace\"", "&quot;Replace&quot;");
                        }
                        if (name == "Microsoft-Windows-NetworkProvider")
                        {
                            manifestXML = manifestXML.Replace("<Property>", "&lt;Property&gt;");
                            manifestXML = manifestXML.Replace("<Value>", "&lt;Value&gt;");
                            manifestXML = manifestXML.Replace("<Integer>", "&lt;Integer&gt;");
                            manifestXML = manifestXML.Replace("<Quoted String>", "&lt;Quoted String&gt;");
                        }
                        if (name == "Microsoft-Windows-Ntfs")
                        {
                            manifestXML = manifestXML.Replace("\"CHKDSK /SCAN\"", "&quot;CHKDSK /SCAN&quot;");
                            manifestXML = manifestXML.Replace("\"CHKDSK /SPOTFIX\"", "&quot;CHKDSK /SPOTFIX&quot;");
                            manifestXML = manifestXML.Replace("\"CHKDSK /F\"", "&quot;CHKDSK /F&quot;");
                            manifestXML = manifestXML.Replace("\"REPAIR-VOLUME <drive:> -SCAN\"", "&quot;REPAIR-VOLUME &lt;drive:&gt; -SCAN&quot;");
                            manifestXML = manifestXML.Replace("\"REPAIR-VOLUME <drive:>\"", "&quot;REPAIR-VOLUME &lt;drive:&gt;&quot;");
                            manifestXML = manifestXML.Replace("<unknown>", "&lt;unknown&gt;");
                        }

                        manifest = ManifestParser.Parse(manifestXML);

                        foundProviderDetails = true;

                        tsvFile.WriteLine($"provider\tevent_id\tversion\tevent(fields)\topcode\tkeywords\ttask\tlevel\tevtlog_channel\tevtlog_message");
                        foreach (var evt in manifest.Events)
                        {
                            var fields = string.Empty;
                            try
                            {
                                foreach (var param in manifest.Templates.First(t => t.Id == evt.Template).Items)
                                {
                                    if (fields != string.Empty)
                                    {
                                        fields += ", ";
                                    }
                                    fields += $"{param.Type} {param.Name}";
                                }
                            }
                            catch (InvalidOperationException) { } // no fields


                            var Channel = string.Empty;
                            var Message = string.Empty;
                            if (useWEPExplorer)
                            {
                                // add channel and message from WEPExplorer (if available)
                                var xmlNode = WEPExplorer.GetProviderMetadataXml(name);
                                try
                                {
                                    if (xmlNode != null && xmlNode.HasChildNodes)
                                    {
                                        foreach (XmlNode xnEvent in xmlNode.SelectNodes($"/{WEPExplorer.XML_PROVIDERS}/{WEPExplorer.XML_PROVIDER}/{WEPExplorer.XML_EVENT_METADATA}/{WEPExplorer.XML_EVENT}[{WEPExplorer.XML_ID}={evt.Value}][{WEPExplorer.XML_VERSION}={evt.Version}]"))
                                        {
                                            Channel = WEPExplorer.xnGetText(xnEvent, WEPExplorer.XML_CHANNEL);
                                            Message = WEPExplorer.xnGetText(xnEvent, WEPExplorer.XML_MESSAGE).Replace("\r", @"\r").Replace("\n", @"\n");
                                        }
                                    }
                                }
                                catch
                                {
                                    var errorFilename = "ERROR_WEPExplorer.xml";
                                    Console.WriteLine($"WEPExplorer XML PARSE FAILURE - name={name} file={errorFilename}");
                                    using (var errorFile = new StreamWriter(Path.Combine(outputDir, errorFilename)))
                                    {
                                        errorFile.WriteLine(xmlNode.OuterXml);
                                    }
                                }
                            }

                            var etwEvent = $"{name}\t{evt.Value}\t{evt.Version}\t{evt.Symbol}({fields})\t{evt.Opcode}\t{evt.Keyword}\t{evt.Task}\t{evt.Level}\t{Channel}\t{Message}";
                            etwEvent = etwEvent.Replace("&quot;", "\"").Replace("&lt;", "<").Replace("&gt;", ">");
                            tsvFile.WriteLine(etwEvent);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (manifestXML.Length != 0)
                    {
                        var errorFilename = "ERROR_Manifest.xml";
                        Console.WriteLine($"MANIFEST PARSE FAILURE - name={name} size={manifestXML.Length} file={errorFilename}");
                        using (var errorFile = new StreamWriter(Path.Combine(outputDir, errorFilename)))
                        {
                            errorFile.WriteLine(manifestXML);
                        }
                        throw e;
                    }
                }


                // is this a legacy (MOF-based) provider
                manifest = null;
                try
                {
                    manifest = ManifestParser.ParseWmiEventTraceClass(provider);
                }
                catch (ApplicationException) { }

                if (manifest != null)
                {
                    foundProviderDetails = true;
                    using (var tsv_file = new StreamWriter(Path.Combine(mofOutputDir, tsvFilename)))
                    {
                        tsv_file.WriteLine($"provider\tcategory\tevent_id\tversion\tevent(fields)\tevent_type\tdescription");
                        foreach (var evt in manifest.Events)
                        {
                            var fields = string.Empty;
                            try
                            {
                                foreach (var param in manifest.Templates.First(t => t.Id == evt.Template).Items)
                                {
                                    if (!string.IsNullOrEmpty(fields))
                                    {
                                        fields += ", ";
                                    }
                                    fields += $"{param.Type} {param.Name}";
                                }
                            }
                            catch (InvalidOperationException) { } // no fields

                            var etwEvent = $"{name}\t{evt.Task}\t{evt.Value}\t{evt.Version}\t{evt.Symbol}({fields})\t{evt.Opcode}\t{evt.Keyword}";
                            etwEvent = etwEvent.Replace("&quot;", "\"").Replace("&lt;", "<").Replace("&gt;", ">");
                            tsv_file.WriteLine(etwEvent);
                        }
                    }
                }


                // no manifest and no MOF...
                if (!foundProviderDetails)
                {
                    using (var tsv_file = new StreamWriter(Path.Combine(unknownOutputDir, tsvFilename)))
                    {
                        tsv_file.WriteLine($"provider");
                        tsv_file.WriteLine(name);
                    }
                }
            }

            Console.WriteLine("All done");
        }
예제 #8
0
        /// <summary>
        /// Main function (entry point)
        /// </summary>
        /// <param name="args">Provider Name as first parameter, Output file as second parameter</param>
        static int Main(string[] args)
        {
            if (args.Length == 1)
            {
                foreach (var providerName in TraceEventProviders.GetPublishedProviders().Select(x => TraceEventProviders.GetProviderName(x)))
                {
                    Console.WriteLine("Create dissector for provider " + providerName);
                    if (providerName == "TPM")
                    {
                        continue;
                    }

                    // Ignore this provider during install
                    // because we made it by hand to handle
                    // upper layer
                    if (providerName == "Microsoft-Windows-NDIS-PacketCapture")
                    {
                        continue;
                    }

                    if (System.Environment.OSVersion.Version.Major == 6 && System.Environment.OSVersion.Version.Minor == 1)
                    {
                        if (providerName == "Microsoft-Windows-UIAutomationCore")
                        {
                            Console.WriteLine("Ignore provider " + providerName + " on Windows 7");
                            continue;
                        }
                    }
                    Directory.CreateDirectory(args[0]);
                    CreateDissectorFromProvider(providerName, Path.Combine(args[0], providerName.Replace("-", "_").Replace(" ", "_") + ".lua"));
                }
            }
            else if (args.Length == 2)
            {
                CreateDissectorFromProvider(args[0], args[1]);
                return(0);
            }
            else
            {
                PrintUsage();
            }

            return(0);
        }