public FileSystemMonitor(MonitorCommandOptions opts, Action <FileMonitorObject> changeHandler) { options = opts ?? new MonitorCommandOptions(); this.changeHandler = changeHandler ?? throw new NullReferenceException(nameof(changeHandler)); fsc = new FileSystemCollector(new CollectorOptions() { DownloadCloud = false, GatherHashes = options.GatherHashes, }); foreach (var dir in options?.MonitoredDirectories.Any() is true ? options.MonitoredDirectories : fsc.Roots.ToList()) { foreach (var filter in defaultFiltersList) { var watcher = new FileSystemWatcher(); watcher.Path = dir; watcher.NotifyFilter = filter; watcher.IncludeSubdirectories = true; // Changed, Created and Deleted can share a handler, because they throw the same type of event watcher.Changed += GetFunctionForFilterType(filter); watcher.Created += GetFunctionForFilterType(filter); watcher.Deleted += GetFunctionForFilterType(filter); // Renamed needs a different handler because it throws a different kind of event watcher.Renamed += GetRenamedFunctionForFilterType(filter); watchers.Add(watcher); } } }
/// <summary> /// Uses ServiceController. /// </summary> internal void ExecuteWindows(CancellationToken cancellationToken) { try { SelectQuery sQuery = new SelectQuery("select * from Win32_Service"); // where name = '{0}'", "MCShield.exe")); using ManagementObjectSearcher mgmtSearcher = new ManagementObjectSearcher(sQuery); if (opts.SingleThread) { foreach (ManagementObject service in mgmtSearcher.Get()) { if (cancellationToken.IsCancellationRequested) { return; } ProcessManagementObject(service); } } else { var list = new List <ManagementObject>(); foreach (ManagementObject service in mgmtSearcher.Get()) { list.Add(service); } ParallelOptions po = new ParallelOptions() { CancellationToken = cancellationToken }; Parallel.ForEach(list, po, x => ProcessManagementObject(x)); } } catch (Exception e) { Log.Warning(e, "Failed to run Service Collector."); } var fsc = new FileSystemCollector(new CollectorOptions() { SingleThread = opts.SingleThread }); foreach (var file in Directory.EnumerateFiles("C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup")) { var name = file.Split(Path.DirectorySeparatorChar)[^ 1];
/// <summary> /// Parse all the Subkeys of the given SearchKey into ComObjects and returns a list of them /// </summary> /// <param name="SearchKey"> The Registry Key to search </param> /// <param name="View"> The View of the registry to use </param> public static IEnumerable <CollectObject> ParseComObjects(RegistryKey SearchKey, RegistryView View, bool SingleThreaded = false) { if (SearchKey == null) { return(new List <CollectObject>()); } List <ComObject> comObjects = new List <ComObject>(); var fsc = new FileSystemCollector(new CollectorOptions() { SingleThread = SingleThreaded }); Action <string> ParseComObjectsIn = SubKeyName => { try { RegistryKey CurrentKey = SearchKey.OpenSubKey(SubKeyName); var RegObj = RegistryWalker.RegistryKeyToRegistryObject(CurrentKey, View); if (RegObj != null) { ComObject comObject = new ComObject(RegObj); foreach (string ComDetails in CurrentKey.GetSubKeyNames()) { if (ComDetails.Contains("InprocServer32")) { var ComKey = CurrentKey.OpenSubKey(ComDetails); var obj = RegistryWalker.RegistryKeyToRegistryObject(ComKey, View); string?BinaryPath32 = null; if (obj != null && obj.Values?.TryGetValue("", out BinaryPath32) is bool successful) { if (successful && BinaryPath32 != null) { // Clean up cases where some extra spaces are thrown into the start // (breaks our permission checker) BinaryPath32 = BinaryPath32.Trim(); // Clean up cases where the binary is quoted (also breaks permission checker) if (BinaryPath32.StartsWith("\"") && BinaryPath32.EndsWith("\"")) { BinaryPath32 = BinaryPath32.AsSpan().Slice(1, BinaryPath32.Length - 2).ToString(); } // Unqualified binary name probably comes from Windows\System32 if (!BinaryPath32.Contains("\\") && !BinaryPath32.Contains("%")) { BinaryPath32 = Path.Combine(Environment.SystemDirectory, BinaryPath32.Trim()); } comObject.x86_Binary = fsc.FilePathToFileSystemObject(BinaryPath32.Trim()); } } } if (ComDetails.Contains("InprocServer64")) { var ComKey = CurrentKey.OpenSubKey(ComDetails); var obj = RegistryWalker.RegistryKeyToRegistryObject(ComKey, View); string?BinaryPath64 = null; if (obj != null && obj.Values?.TryGetValue("", out BinaryPath64) is bool successful) { if (successful && BinaryPath64 != null) { // Clean up cases where some extra spaces are thrown into the start // (breaks our permission checker) BinaryPath64 = BinaryPath64.Trim(); // Clean up cases where the binary is quoted (also breaks permission checker) if (BinaryPath64.StartsWith("\"") && BinaryPath64.EndsWith("\"")) { BinaryPath64 = BinaryPath64.AsSpan().Slice(1, BinaryPath64.Length - 2).ToString(); } // Unqualified binary name probably comes from Windows\System32 if (!BinaryPath64.Contains("\\") && !BinaryPath64.Contains("%")) { BinaryPath64 = Path.Combine(Environment.SystemDirectory, BinaryPath64.Trim()); } comObject.x64_Binary = fsc.FilePathToFileSystemObject(BinaryPath64.Trim()); } } } } comObjects.Add(comObject); } } catch (Exception e) when( e is System.Security.SecurityException || e is ObjectDisposedException || e is UnauthorizedAccessException || e is IOException) { Log.Debug($"Couldn't parse {SubKeyName}"); } }; try { if (SingleThreaded) { foreach (var subKey in SearchKey.GetSubKeyNames()) { ParseComObjectsIn(subKey); } } else { SearchKey.GetSubKeyNames().AsParallel().ForAll(subKey => ParseComObjectsIn(subKey)); } } catch (Exception e) { Log.Debug("Failing parsing com objects {0} {1}", SearchKey.Name, e.GetType()); } return(comObjects); }