in Lib/Collectors/ComObjectCollector.cs [29:140]
public static IEnumerable<CollectObject> ParseComObjects(RegistryKey SearchKey, RegistryView View, bool SingleThreaded = false)
{
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return new List<CollectObject>(); }
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;
}