Friday 26 August 2016

How to load registry hive of logged off users in C#.Net

In HKEY_USERS, SIDs of only logged in users are present by default. If you need to make changes in any user's registry in logged off state, you will have to load the registry hive of that particular user.

Registry hive can be loaded by using NTUser.dat file loacted in "C:\Users\{Username}". {Username} is the name of the logged off user.

Following is the sample code required for this task:

 internal static readonly IntPtr HKEY_USERS = new IntPtr(unchecked((int)0x80000003));

[DllImport("advapi32.dll", SetLastError = true)]
static extern Int32 RegLoadKey(IntPtr hKey, string lpSubKey, string lpFile);

Create a below function:

 public static void loadUserRegistryHive(string username, string keyName)
        {
            try
            {
                string path ="C:\Users\{Username}\NTUSER.DAT";
                FileInfo fi = new FileInfo(path);
                if (fi.Exists)
                {
                    int retVal = RegLoadKey(HKEY_USERS, keyName, path);
                    if (retVal  == 0)
                            MessageBox.Show("Success");
                    else
                            MessageBox.Show("Failure");                  
                }
                else
                {
                    MessageBox.Show("NTUSER.DAT file does not exist in path");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

General Exception:

While using RegLoadKey in the above function, you may get 1314 as the return value. This is the indication that you don't have the necessary privileges to load the registry hive. To do so, use the below code:

public static void adjustPriviledge()
        {
            try
            {
                // Access token handle reused within the using block.
                using (AccessTokenHandle accessTokenHandle =
                    Process.GetCurrentProcess().GetAccessTokenHandle(
                        TokenAccessRights.AdjustPrivileges | TokenAccessRights.Query))
                {
                    // Enable privileges using the same access token handle.
                    AdjustPrivilegeResult backupResult = accessTokenHandle.EnablePrivilege(Privilege.Backup);
                    AdjustPrivilegeResult restoreResult = accessTokenHandle.EnablePrivilege(Privilege.Restore);
                }
            }
            catch (Exception ex)
            {
                      MessageBox.Show(ex.Message);
            }
        }

The above function will add the SE_BACKUP_NAME and SE_RESTORE_NAME privileges required to load the registry hive.

To use the function above you will have to include the below dll:
ProcessPrivileges.dll

You can download it from here:
https://processprivileges.codeplex.com/

It's an open source dll:
License details: https://processprivileges.codeplex.com/license

You will have to call function "adjustPriviledge" in function "loadUserRegistryHive" just before calling function "RegLoadKey" as shown below:

 adjustPriviledge();
 int retVal = RegLoadKey(HKEY_USERS, keyName, path);

1 comment:

  1. Will it have any impact when user is trying to log in and at the same time this program loads the registry from SYSTEM account?

    ReplyDelete