Exemplo n.º 1
0
 private Task <String> findCurrentComputerName()
 {
     return(Task.Run(() =>
     {
         showMsg("Find Computer Name: Getting list of logical drives...", loadImg);
         string[] drives = Environment.GetLogicalDrives();
         showMsg("Find Computer Name: Searching in offline registries...", loadImg);
         foreach (string drive in drives)
         {
             string rPath = drive + @"Windows\System32\config\SYSTEM";
             if (File.Exists(rPath))
             {
                 try
                 {
                     Registry.RegistryHiveOnDemand registryHive = new Registry.RegistryHiveOnDemand(rPath);
                     Registry.Abstractions.RegistryKey key = registryHive.GetKey(@"ControlSet001\Control\ComputerName\ComputerName");
                     foreach (Registry.Abstractions.KeyValue value in key.Values)
                     {
                         if (value.ValueName == "ComputerName")
                         {
                             return value.ValueData;
                         }
                     }
                 }
                 catch (IOException) { }
             }
         }
         showMsg("Find Computer Name: Searching in online registry...", loadImg);
         Microsoft.Win32.RegistryKey computerName = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\ControlSet001\Control\ComputerName\ComputerName", false);
         hideMsg();
         return (string)computerName.GetValue("ComputerName");
     }));
 }
        /// <summary>
        /// allows iteration over offline registry keys in a foreach loop
        /// </summary>
        private IEnumerable <RegistryKeyWrapper> GetOfflineRegistryKeyIterator(string registryFilePath)
        {
            int count = 0;
            OfflineRegistryHive hive;

            try
            {
                hive = new OfflineRegistryHive(registryFilePath);
            }
            catch (Exception)
            {
                yield break;
            }

            foreach (string location in Config.ShellbagRootLocations)
            {
                string userOfHive = FindOfflineUsername(hive);
                foreach (RegistryKeyWrapper keyWrapper in IterateOfflineRegistry(hive.GetKey(location), hive, location,
                                                                                 null, ""))
                {
                    if (userOfHive != string.Empty)
                    {
                        keyWrapper.RegistryUser = userOfHive;
                    }

                    count++;
                    yield return(keyWrapper);
                }
            }
        }
        private void AdaptOfflineKey(OfflineRegistryKey registryKey, OfflineRegistryHive hive)
        {
            //obtain SID and Username(?)

            //HKEY USERS registry is UserSID\....
            string UserSID = registryKey.KeyPath.Split('\\')[0];

            // "_classes" is actually just a user's usrclass.dat, not a seperate user.
            UserSID     = UserSID.ToUpper().Replace("_CLASSES", "");
            RegistrySID = UserSID;

            //if we dont know the username, default to the SID.
            RegistryUser = RegistrySID;

            //obtain NodeSlot (Shellbag Path in registry)
            SlotModifiedDate      = DateTime.MinValue;
            LastRegistryWriteDate = DateTime.MinValue;
            NodeSlot = null;

            string nodeSlotPath = null;

            foreach (OfflineKeyValue kv in registryKey.Values)
            {
                if (kv.ValueName.Equals("NodeSlot"))
                {
                    NodeSlot     = int.Parse(kv.ValueData);
                    nodeSlotPath = string.Format("{0}{1}\\{2}", registryKey.KeyPath.Substring(0, registryKey.KeyPath.IndexOf("BagMRU", StringComparison.Ordinal)), "Bags", NodeSlot);
                    break;
                }
            }

            if (nodeSlotPath != null)
            {
                SlotModifiedDate = hive.GetKey(nodeSlotPath).LastWriteTime.Value.LocalDateTime;
            }

            //obtain the date the registry last wrote this key
            LastRegistryWriteDate = registryKey.LastWriteTime.Value.UtcDateTime;
        }
        /// <summary>
        /// Recursively iterates over the a registry key and its subkeys for enumerating all values of the keys and subkeys
        /// </summary>
        /// <param name="rk">the root registry key to start iterating over</param>
        /// <param name="hive">the offline registry hive</param>
        /// <param name="subKey">the path of the first subkey under the root key</param>
        /// <param name="indent"></param>
        /// <param name="path_prefix">the header to the current root key, needed for identification of the registry store</param>
        /// <returns></returns>
        private static IEnumerable <RegistryKeyWrapper> IterateOfflineRegistry(OfflineRegistryKey rk, OfflineRegistryHive hive, string subKey, RegistryKeyWrapper parent, string path_prefix)
        {
            if (rk == null)
            {
                yield break;
            }

            foreach (OfflineRegistryKey valueName in rk.SubKeys)
            {
                if (valueName.KeyName.ToUpper() == "ASSOCIATIONS")
                {
                    continue;
                }

                string             sk = GetSubkeyString(subKey, valueName.KeyName);
                OfflineRegistryKey rkNext;
                try
                {
                    rkNext = hive.GetKey(GetSubkeyString(rk.KeyPath, valueName.KeyName));
                }
                catch (SecurityException)
                {
                    continue;
                }

                string             path          = path_prefix;
                RegistryKeyWrapper rkNextWrapper = null;

                bool isNumeric = int.TryParse(valueName.KeyName, out _);
                if (isNumeric)
                {
                    OfflineKeyValue rkValue = null;
                    try
                    {
                        rkValue = rk.Values.First(val => val.ValueName == valueName.KeyName);
                    }
                    catch (InvalidOperationException) { }

                    if (rkValue == null)
                    {
                        continue;
                    }

                    byte[] byteVal = rkValue.ValueDataRaw;
                    yield return(rkNextWrapper = new RegistryKeyWrapper(rkNext, byteVal, hive, parent));
                }

                foreach (var wrapper in IterateOfflineRegistry(rkNext, hive, sk, rkNextWrapper, path))
                {
                    yield return(wrapper);
                }
            }
        }
        private string FindOfflineUsername(OfflineRegistryHive hive)
        {
            string retval = string.Empty;

            try
            {
                //todo refactor Parser.GetUsernameLocations() into key-value pairs for lookup, we have to hardcode key-values otherwise.
                //todo we know of the Desktop value inside the "Shell Folders" location, so naively try this until a better way is found
                Dictionary <string, int> likelyUsernames = new Dictionary <string, int>();
                foreach (string usernameLocation in Config.UsernameLocations)
                {
                    if (hive.GetKey(usernameLocation) == null)
                    {
                        continue;
                    }

                    Func <string, string> extractUsername = (string path) =>
                    {
                        if (!Path.IsPathFullyQualified(path))
                        {
                            return(null);
                        }

                        //break string up into it's path
                        string[] pathParts = path.Split('\\');
                        if (pathParts.Length > 2 && pathParts[1] == "Users")
                        {
                            return(pathParts[2]); //usually in the form of C:\Users\username
                        }

                        return(null);
                    };

                    //based on the values in '...\Explorer\Shell Folders' the [2] value in the string may not always be the username, but it does appear the most.
                    foreach (OfflineKeyValue value in hive.GetKey(usernameLocation).Values)
                    {
                        var username = extractUsername(value.ValueData);

                        if (username != null)
                        {
                            if (!likelyUsernames.ContainsKey(username))
                            {
                                likelyUsernames[username] = 1;
                            }
                            else
                            {
                                likelyUsernames[username]++;
                            }
                        }

                        username = extractUsername(value.ValueName);

                        if (username != null)
                        {
                            if (!likelyUsernames.ContainsKey(username))
                            {
                                likelyUsernames[username] = 1;
                            }
                            else
                            {
                                likelyUsernames[username]++;
                            }
                        }
                    }
                }

                //most occurred value is probably the username.
                if (likelyUsernames.Count >= 1)
                {
                    retval = likelyUsernames.OrderByDescending(pair => pair.Value).First().Key;
                }
            }
            catch (Exception)
            { }

            return(retval);
        }
 /// <summary>
 /// Adapts a ShellBag RegistryKey to a common standard for retrieval of important information independent of key retrieval methodologies
 /// </summary>
 /// <param name="registryKey">A Registry Key associated with a Shellbag, retrieved from a offline registry reader API</param>
 /// <param name="keyValue">The Value of a Registry key containing Shellbag information. Found in the Parent of the registryKey being inspected</param>
 /// <param name="parent">The parent of the currently inspected registryKey. Can be null.</param>
 public RegistryKeyWrapper(OfflineRegistryKey registryKey, byte[] keyValue, OfflineRegistryHive hive, RegistryKeyWrapper parent = null) : this(keyValue)
 {
     Parent       = parent;
     RegistryPath = registryKey.KeyPath;
     AdaptOfflineKey(registryKey, hive);
 }