Ejemplo n.º 1
0
        // existingBase is passed for performance optimization
        // TODO: encapsulate existingBase in a class and extract methods
        // with it a first argument there
        private bool TryOpenImpl(KeyIdentity existingBase, KeyDisposition disposition,
                                 KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl)
        {
            openedImpl = null;
            if (disposition != KeyDisposition.DIFF_HIVE)
            {
                if (diffHive_.IsMarkedAsDeleted(existingBase, identity))
                {
                    return(false);
                }
            }
            IKeyImplOpenFactory factory = null;

            switch (disposition)
            {
            case KeyDisposition.WINDOWS_REG:
                factory = windowsKeyFactory_;
                break;

            case KeyDisposition.BASE_HIVE:
                factory = baseHive_;
                break;

            case KeyDisposition.DIFF_HIVE:
                factory = diffHive_;
                break;
            }
            if (factory == null)
            {
                // In case if specified hive is not used (currently used
                // only for null baseHive_)
                return(false);
            }
            return(factory.TryOpen(identity, samDesired, out openedImpl));
        }
Ejemplo n.º 2
0
 private bool TryOpenOrCreateDiffKey(KeyIdentity existingBase, KeyIdentity identity,
                                     KeySecurity samDesired, out IKeyImpl openedImpl)
 {
     if (TryOpen(existingBase, KeyDisposition.DIFF_HIVE, identity, samDesired, out openedImpl))
     {
         return(true);
     }
     // If some modification operation is requested and offreg key
     // does not exist, but it is in one of readonly hives - creating it
     if (samDesired.IsOnlyForRead() ||
         !KeyExistsInROHives(identity))
     {
         return(false);
     }
     try
     {
         openedImpl = Create(identity,
                             null, (int)Win32Api.RegOption.REG_OPTION_NON_VOLATILE, IntPtr.Zero,
                             IntPtr.Zero);
         return(true);
     }
     catch (FileNotFoundException)
     {
         return(false);
     }
 }
Ejemplo n.º 3
0
        // Create key and if needed all parent keys
        private OffregLib.OffregKey CreateKeys(OffregLib.OffregHive hiveImpl, string path,
                                               string lpClass, Win32Api.RegOption dwOptions, IntPtr lpSecurityDescriptor,
                                               IntPtr lpdwDisposition)
        {
            OffregLib.OffregKey result = null;
            try
            {
                OffRegHive.ConvertException(() => result = hiveImpl.Root.OpenSubKey(path));
                return(result);
            }
            catch (FileNotFoundException) { }
            // We either take the first subkey of the path, or the last
            string parentPath, subkey;

            if (KeyIdentity.PartitionPath(path, out parentPath, out subkey))
            {
                OffregLib.OffregKey parentKey = CreateKeys(hiveImpl, parentPath, lpClass, dwOptions,
                                                           lpSecurityDescriptor, lpdwDisposition);
                OffRegHive.ConvertException(() => parentKey.Close());
            }
            // TODO: do something with lpClass, lpSecurityDescriptor, for now they are ignored
            OffRegHive.ConvertException(() =>
                                        result = hiveImpl.Root.CreateSubKey(
                                            path, (OffregLib.RegOption)dwOptions));
            if (lpdwDisposition != IntPtr.Zero)
            {
                Marshal.WriteInt32(lpdwDisposition, (int)Win32Api.RegKeyDisposition.REG_CREATED_NEW_KEY);
            }
            // TODO: if there is an existing key in windows registry, but we create one
            // in offreg hive, which disposition do we need to return?
            return(result);
        }
Ejemplo n.º 4
0
 internal IKeyImpl Create(KeyIdentity identity, string lpClass,
                          Win32Api.RegOption dwOptions, IntPtr lpSecurityDescriptor,
                          IntPtr lpdwDisposition)
 {
     return(new OffRegKey(this, hive_, identity, lpClass, dwOptions,
                          lpSecurityDescriptor, lpdwDisposition));
 }
Ejemplo n.º 5
0
 internal IKeyImpl Create(KeyIdentity identity, string lpClass,
                          Win32Api.RegOption dwOptions, IntPtr lpSecurityDescriptor,
                          IntPtr lpdwDisposition)
 {
     return(diffHive_.Create(identity, lpClass, dwOptions, lpSecurityDescriptor,
                             lpdwDisposition));
 }
Ejemplo n.º 6
0
 private void OpenKey(KeyIdentity existingBase, KeyIdentity identity, KeySecurity samDesired,
                      out IntPtr phkResult)
 {
     phkResult = IntPtr.Zero;
     phkResult = keyStorage_.Add(
         factory_.OpenKeyPreliminarily(existingBase, identity, samDesired));
 }
Ejemplo n.º 7
0
        public bool TryOpen(KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl)
        {
            OffRegKey offregKey;
            bool      result = OffRegKey.TryOpen(this, hive_, identity, out offregKey);

            openedImpl = offregKey;
            return(result);
        }
Ejemplo n.º 8
0
        internal VirtualKey CreatePredefinedKey(IntPtr hKey)
        {
            KeyIdentity identity = new KeyIdentity(hKey);

            return(new VirtualKey(factory_, identity, factory_.Open(
                                      KeyDisposition.WINDOWS_REG, identity, new KeySecurity(Win32Api.KeySecurity.KEY_READ)),
                                  alterer_));
        }
Ejemplo n.º 9
0
 private string CallStrAlterers(KeyIdentity key, string valueName, string value)
 {
     foreach (StrAlterer alterer in strAlterers_)
     {
         value = alterer(key, valueName, value);
     }
     return(value);
 }
Ejemplo n.º 10
0
        public bool TryOpen(KeyIdentity identity, KeySecurity samDesired, out IKeyImpl openedImpl)
        {
            WindowsKey windowsKey;
            bool       result = WindowsKey.TryOpen(identity, samDesired, out windowsKey);

            openedImpl = windowsKey;
            return(result);
        }
Ejemplo n.º 11
0
 internal OffRegKey(OffRegHive hive, OffregLib.OffregHive hiveImpl, KeyIdentity identity,
                    string lpClass, Win32Api.RegOption dwOptions, IntPtr lpSecurityDescriptor,
                    IntPtr lpdwDisposition)
 {
     hive_     = hive;
     identity_ = identity;
     key_      = CreateKeys(hiveImpl, GetMainOffRegPath(identity), lpClass,
                            dwOptions, lpSecurityDescriptor, lpdwDisposition);
 }
Ejemplo n.º 12
0
 internal VirtualKey(VirtualKeyFactory opener, KeyIdentity identity,
                     IKeyImpl baseKeyImpl, DataAlterer alterer)
 {
     opener_   = opener;
     identity_ = identity;
     baseImpl_ = baseKeyImpl;
     alterer_  = alterer;
     ReinitializeCache();
 }
Ejemplo n.º 13
0
 internal static string GetMainOffRegPath(KeyIdentity identity)
 {
     if (!predefinedPaths_.ContainsKey((Int64)identity.BaseKey))
     {
         // Not thrown in usual cases, may be thrown very rarely if identity.BaseKey
         // points to some specific place (may be)
         throw new FileNotFoundException();
     }
     return(KeyIdentity.CombinePaths(predefinedPaths_[(Int64)identity.BaseKey][0], identity.GetRegPath()));
 }
Ejemplo n.º 14
0
        internal IKeyImpl Open(KeyDisposition disposition, KeyIdentity identity,
                               KeySecurity samDesired)
        {
            IKeyImpl result;

            if (!TryOpen(null, disposition, identity, samDesired, out result))
            {
                throw new FileNotFoundException();
            }
            return(result);
        }
Ejemplo n.º 15
0
 // returns false if the key does not exist in the given disposition,
 // on other errors throws exception.
 private bool TryOpen(KeyIdentity existingBase, KeyDisposition disposition, KeyIdentity identity,
                      KeySecurity samDesired, out IKeyImpl openedImpl)
 {
     if (!TryOpenImpl(existingBase, disposition, identity, samDesired, out openedImpl))
     {
         return(false);
     }
     baseKeyManager_.BaseKeyCopied(identity.BaseKey);
     openedImpl = new KeyImplDecoratorHookingClose(openedImpl,
                                                   () => baseKeyManager_.BaseKeyClosed(identity.BaseKey));
     return(true);
 }
Ejemplo n.º 16
0
        private bool TryOpenKey(KeyIdentity existingBase, KeyDisposition disposition,
                                KeyIdentity identity, KeySecurity samDesired, out VirtualKey key)
        {
            KeyImplHolder holder;

            key = null;
            if (!TryOpenHolder(existingBase, disposition, identity, samDesired, out holder))
            {
                return(false);
            }
            key = new VirtualKey(this, identity, holder.ReleaseKeyImpl(), alterer_);
            return(true);
        }
Ejemplo n.º 17
0
        internal string GetKeySystemPath(IntPtr hKey)
        {
            VirtualKey key = GetKeyOrPickUp(hKey);

            if (key == null)
            {
                if (hKey == IntPtr.Zero)
                {
                    return("<null>");
                }
                return(KeyIdentity.UknownHKeyStr(hKey));
            }
            return(key.Identity.GetSystemPath());
        }
Ejemplo n.º 18
0
 public bool Handle(WindowsKey key)
 {
     if (!KeyIdentity.IsPredefined(key.Handle))
     {
         return Win32Exception.CheckIfFoundAndNoError(
             Win32Api.NtQueryKey(key.Handle, KeyInformationClass_, KeyInformation_, Length_,
             out ResultLength_));
     }
     // Predefined key handle values are valid only on the advapi32.dll level
     // on the ntdll.dll level we have to replace them with appropriate ntdll.dll handles
     IntPtr hNtKey = IntPtr.Zero;
     string objectName = KeyIdentity.GetSystemBasePath(key.Handle);
     Win32Api.UNICODE_STRING usObjectName = new Win32Api.UNICODE_STRING();
     usObjectName.Length = unchecked((ushort)(sizeof(char) * objectName.Length));
     usObjectName.MaximumLength = usObjectName.Length;
     using (HGlobalPtr pObjectNameBuffer = new HGlobalPtr(Marshal.StringToHGlobalUni(objectName)))
     {
         usObjectName.Buffer = pObjectNameBuffer.Ptr;
         using (HGlobalPtr pObjectName = new HGlobalPtr(Marshal.SizeOf(typeof(Win32Api.UNICODE_STRING))))
         {
             Marshal.StructureToPtr(usObjectName, pObjectName.Ptr, false);
             Win32Api.OBJECT_ATTRIBUTES oa = new Win32Api.OBJECT_ATTRIBUTES();
             oa.Length = unchecked((uint)Marshal.SizeOf(typeof(Win32Api.OBJECT_ATTRIBUTES)));
             oa.RootDirectory = IntPtr.Zero;
             oa.ObjectName = pObjectName.Ptr;
             oa.Attributes = (uint)Win32Api.ObjectAttributes.OBJ_CASE_INSENSITIVE;
             oa.SecurityDescriptor = IntPtr.Zero;
             oa.SecurityQualityOfService = IntPtr.Zero;
             using (HGlobalPtr pOA = new HGlobalPtr(Marshal.SizeOf(typeof(Win32Api.OBJECT_ATTRIBUTES))))
             {
                 Marshal.StructureToPtr(oa, pOA.Ptr, false);
                 if (!Win32Exception.CheckIfFoundAndNoError(
                     Win32Api.NtOpenKey(out hNtKey, (uint)Win32Api.KeySecurity.KEY_QUERY_VALUE, pOA.Ptr)))
                 {
                     return false;
                 }
                 try
                 {
                     return Win32Exception.CheckIfFoundAndNoError(
                         Win32Api.NtQueryKey(hNtKey, KeyInformationClass_, KeyInformation_, Length_,
                         out ResultLength_));
                 }
                 finally
                 {
                     Win32Api.NtClose(hNtKey);
                 }
             }
         }
     }
 }
Ejemplo n.º 19
0
 // If the keyImpl is added, returns NotOwningKeyImplHolder,
 // otherwise returns original KeyImplHolder
 public KeyImplHolder Add(KeyIdentity identity, KeyDisposition disposition, KeyImplHolder keyHolder)
 {
     lock (this)
     {
         CacheKey cacheKey = new CacheKey {
             Identity = identity, Disposition = disposition
         };
         if (cachedKeyImpls_.ContainsKey(cacheKey))
         {
             return(keyHolder);
         }
         cachedKeyImpls_.Add(cacheKey, keyHolder);
         return(new NotOwningKeyImplHolder(keyHolder.GetKeyImpl()));
     }
 }
Ejemplo n.º 20
0
        internal void OpenKey(IntPtr hKey,
                              string lpSubKey,
                              int ulOptions,
                              Win32Api.KeySecurity samDesired,
                              out IntPtr phkResult)
        {
            // ulOptions are ignored as this is a reserved parameter
            phkResult = IntPtr.Zero;
            KeySecurity keySecurity;

            Win32Api.RegWow64Options wowOptions;
            KeySecurity.ExtractWow64Options(samDesired, out keySecurity, out wowOptions);
            KeyIdentity baseIdentity = GetKey(hKey).Identity;

            OpenKey(baseIdentity, new KeyIdentity(baseIdentity, wowOptions, lpSubKey),
                    keySecurity, out phkResult);
        }
Ejemplo n.º 21
0
        internal void BaseKeyCopied(IntPtr baseKey)
        {
            if (KeyIdentity.IsPredefined(baseKey))
            {
                return;
            }
            Int64 key = baseKey.ToInt64();

            lock (this)
            {
                if (!baseKeyRefCount_.ContainsKey(key))
                {
                    baseKeyRefCount_[key] = 0;
                }
                baseKeyRefCount_[key]++;
            }
        }
Ejemplo n.º 22
0
        internal void BaseKeyClosed(IntPtr baseKey)
        {
            if (KeyIdentity.IsPredefined(baseKey))
            {
                return;
            }
            Int64 key = baseKey.ToInt64();

            lock (this)
            {
                baseKeyRefCount_[key]--;
                if (baseKeyRefCount_[key] == 0)
                {
                    baseKeyRefCount_.Remove(key);
                    Win32Exception.CheckResult(Win32Api.RegCloseKey(baseKey));
                }
            }
        }
Ejemplo n.º 23
0
 private static bool CheckSystemKeyAccess(KeyDisposition disposition,
                                          KeyIdentity identity, KeySecurity samDesired)
 {
     // This way we redirect system registry locations into windows registry
     // and make it fail for write operations
     if (disposition != KeyDisposition.WINDOWS_REG &&
         identity.IsSystemKey())
     {
         if (samDesired.IsOnlyForRead())
         {
             // So that it retries to read from system registry
             return(false);
         }
         // So that user gets appropriate error code
         throw new AccessDeniedException();
     }
     return(true);
 }
Ejemplo n.º 24
0
        internal static List <string> GetOffRegPaths(KeyIdentity identity)
        {
            if (!predefinedPaths_.ContainsKey((Int64)identity.BaseKey))
            {
                return(new List <string>());
            }
            List <string> result    = new List <string>();
            List <string> basePaths = predefinedPaths_[(Int64)identity.BaseKey];
            string        regPath   = identity.GetRegPath();

            foreach (string basePath in basePaths)
            {
                // offreg hive does not distinguish between 32bit and 64 bit branches for now
                // so we use path w/o Wow6432Node
                result.Add(KeyIdentity.CombinePaths(basePath, regPath));
            }
            return(result);
        }
Ejemplo n.º 25
0
 internal void MarkKeyAsDeleted(KeyIdentity identity)
 {
     try
     {
         string[] subkeys = identity.SplitPath();
         int      existingLevels, nonRemovableLevels;
         CalcNonRemovableLevels(null, identity, out existingLevels, out nonRemovableLevels);
         if (subkeys.Length <= nonRemovableLevels)
         {
             // We can't mark root keys as deleted
             return;
         }
         using (HGlobalPtr pData = new HGlobalPtr(Marshal.SizeOf(typeof(int))))
         {
             Marshal.WriteInt32(pData.Ptr, 1);
             // Conciously suppressing errors
             OffRegKey key = null;
             try
             {
                 key = new OffRegKey(this, hive_,
                                     KeyIdentity.Build(identity.BaseKey, subkeys, subkeys.Length - 1), null,
                                     Win32Api.RegOption.REG_OPTION_NON_VOLATILE, IntPtr.Zero,
                                     IntPtr.Zero);
                 key.SetValue(DELETED_PREFIX + subkeys[subkeys.Length - 1],
                              Win32Api.RegValueType.REG_DWORD,
                              pData.Ptr, Marshal.SizeOf(typeof(int)));
             }
             catch (Win32Exception)
             {
                 // Suppressing errors because there might be access issues
                 // or may be other stuff
                 if (key != null)
                 {
                     key.Close();
                 }
             }
         }
     }
     catch (FileNotFoundException)
     {
         // We don't know anything about the key, so we can't mark it as deleted
         return;
     }
 }
Ejemplo n.º 26
0
        private bool TryGetSubKey(KeyDisposition disposition, string lpSubKey,
                                  KeySecurity samDesired, Win32Api.RegWow64Options wowOptions, out KeyImplHolder subKeyHolder)
        {
            KeyIdentity subKeyIdentity = new KeyIdentity(identity_, wowOptions, lpSubKey);
            IKeyImpl    keyImpl        = cachedKeyImpls_.TryGet(subKeyIdentity, disposition, samDesired);

            if (keyImpl != null)
            {
                subKeyHolder = new NotOwningKeyImplHolder(keyImpl);
                return(true);
            }
            KeyImplHolder newOne;

            if (!opener_.TryOpenHolder(identity_, disposition, subKeyIdentity, samDesired, out newOne))
            {
                subKeyHolder = null;
                return(false);
            }
            subKeyHolder = cachedKeyImpls_.Add(subKeyIdentity, disposition, newOne);
            return(true);
        }
Ejemplo n.º 27
0
        // Returns keyImpl owned by cache, thus KeyHolder is not used
        public IKeyImpl TryGet(KeyIdentity identity, KeyDisposition disposition, KeySecurity samDesired)
        {
            lock (this)
            {
                CacheKey cacheKey = new CacheKey {
                    Identity = identity, Disposition = disposition
                };
                if (!cachedKeyImpls_.ContainsKey(cacheKey))
                {
                    return(null);
                }

                KeyImplHolder cached = cachedKeyImpls_[cacheKey];
                if (!samDesired.IsSubSetOf(cached.GetKeyImpl().GetAccessMode()))
                {
                    return(null);
                }

                return(cached.GetKeyImpl());
            }
        }
Ejemplo n.º 28
0
        private static bool GetNativeHKeyName(IntPtr hKey, out KeyIdentity identity)
        {
            identity = null;
            uint cbData;
            int  result = Win32Api.NtQueryKey(hKey,
                                              Win32Api.KeyInformationClass.KeyNameInformation,
                                              IntPtr.Zero, 0, out cbData);

            if (result != (int)Win32Api.Status.STATUS_BUFFER_TOO_SMALL)
            {
                DebugLogger.WriteLine("Error querying key name {0}", result);
                return(false);
            }
            using (HGlobalPtr pData = new HGlobalPtr(cbData))
            {
                result = Win32Api.NtQueryKey(hKey,
                                             Win32Api.KeyInformationClass.KeyNameInformation,
                                             pData.Ptr, cbData, out cbData);
                if (result != 0)
                {
                    DebugLogger.WriteLine("Error querying key name {0}", result);
                    return(false);
                }
                cbData = (uint)Marshal.ReadInt32(pData.Ptr);
                string name = Marshal.PtrToStringUni(
                    (IntPtr)(pData.Ptr.ToInt64() + Marshal.SizeOf(typeof(uint))),
                    (int)cbData / sizeof(char));

                foreach (KeyValuePair <string, IntPtr> m in HKeySysNameMappings)
                {
                    if (name.StartsWith(m.Key, StringComparison.CurrentCultureIgnoreCase))
                    {
                        identity = new KeyIdentity(m.Value, RemovePrefix(name, m.Key.Length));
                        return(true);
                    }
                }
                DebugLogger.WriteLine("Can't interpret key name {0}", name);
            }
            return(false);
        }
Ejemplo n.º 29
0
        private VirtualKey GetKeyOrPickUp(IntPtr hKey)
        {
            if (hKey == IntPtr.Zero)
            {
                return(null);
            }
            VirtualKey key = keyStorage_.Get(hKey);

            if (key != null)
            {
                return(key);
            }
            // The key might be open by a native Reg* function before
            // OpenSandbox was embedded
            try
            {
                KeyIdentity identity = new KeyIdentity(hKey);
                key = new VirtualKey(factory_, identity, factory_.Open(
                                         KeyDisposition.WINDOWS_REG, identity, new KeySecurity(Win32Api.KeySecurity.KEY_READ)),
                                     alterer_);
                // ATTENTION: resource leak is happening here and may lead to AV:
                // returned VirtualKey has a cache of open keys which never gets closed
                // and the base keyImpl does not get closed too.
                // Closing is called in finalizers after registry is shutdown, which is UB.

                // We put the key to the storage for the case if it will be accessed
                // further and to avoid resource leaks
                keyStorage_.Add(hKey, key);
                DebugLogger.WriteLine("Picked up key 0x{0} {1}", hKey.ToString("X"), identity);
                return(key);
            }
            catch (InvalidHandleException)
            {
                return(null);
            }
            catch (FileNotFoundException)
            {
                return(null);
            }
        }
Ejemplo n.º 30
0
 internal bool IsMarkedAsDeleted(KeyIdentity existingBase, KeyIdentity identity)
 {
     if (identity.IsSystemKey())
     {
         return(false);
     }
     try
     {
         return(DoesntExistOrMarkedAsDeleted(existingBase, identity,
                                             IMAD_pData_.Ptr, IMAD_pcbData_.Ptr) == DoesntExistOrMarkedAsDeletedState.MarkedAsDeleted);
     }
     catch (FileNotFoundException)
     {
         // We don't know anything about the key, so it was not marked as deleted
         return(false);
     }
     catch (Win32Exception ex)
     {
         DebugLogger.WriteLine("IsDeleted exception " + ex.ToString());
         throw;
     }
 }