The key's default owner is SYSTEM,I can change it manually in regedit but, I want my program can do this(change the owner of Registry)
A way is with Win32 APIs (tested on Windows 10 21H1, as Admin (Manifest)) :
if (!EnablePrivilege(SE_TAKE_OWNERSHIP_NAME, true))
return;
string sName = "Christian";
System.Security.Principal.NTAccount ntAccount = new System.Security.Principal.NTAccount(sName);
string sSid = ntAccount.Translate(typeof(System.Security.Principal.SecurityIdentifier)).Value;
// S-1-5-21-3423049853-1102793660-1424913857-1001
IntPtr pSid = IntPtr.Zero;
ConvertStringSidToSid(sSid, out pSid);
IntPtr hKey = IntPtr.Zero;
uint dwErr = RegOpenKeyEx((IntPtr)HKEY_CLASSES_ROOT, "CLSID\\{1eeb5b5a-06fb-4732-96b3-975c0194eb39}\\InProcServer32", 0, KEY_WOW64_64KEY | WRITE_OWNER, ref hKey);
if (dwErr == 0)
{
uint dwRet = SetSecurityInfo(hKey,
SE_OBJECT_TYPE.SE_REGISTRY_KEY,
OWNER_SECURITY_INFORMATION,
pSid,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
RegCloseKey(hKey);
}
Utility function :
// From MS SDK : Win7Samples\winbase\bootconfigurationdata\bcdsamplelib\Utils.cs
private bool EnablePrivilege(string lpszPrivilege, bool bEnablePrivilege)
{
bool retval = false;
int ltkpOld = 0;
IntPtr hToken = IntPtr.Zero;
TOKEN_PRIVILEGES tkp = new TOKEN_PRIVILEGES();
tkp.Privileges = new int[3];
TOKEN_PRIVILEGES tkpOld = new TOKEN_PRIVILEGES();
tkpOld.Privileges = new int[3];
LUID tLUID = new LUID();
tkp.PrivilegeCount = 1;
if (bEnablePrivilege)
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
tkp.Privileges[2] = 0;
if (LookupPrivilegeValue(null, lpszPrivilege, out tLUID))
{
System.Diagnostics.Process proc = System.Diagnostics.Process.GetCurrentProcess();
if (proc.Handle != IntPtr.Zero)
{
if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken) != false)
{
tkp.PrivilegeCount = 1;
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
tkp.Privileges[1] = tLUID.HighPart;
tkp.Privileges[0] = tLUID.LowPart;
const int bufLength = 256;
IntPtr tu = Marshal.AllocHGlobal(bufLength);
Marshal.StructureToPtr(tkp, tu, true);
if (AdjustTokenPrivileges(hToken, false, tu, bufLength, IntPtr.Zero, ref ltkpOld) != false)
{
int nErr = Marshal.GetLastWin32Error();
// successful AdjustTokenPrivileges doesn't mean privilege could be changed
//ERROR_NOT_ALL_ASSIGNED 1300(0x514)
if (nErr == 0)
{
retval = true; // Token changed
}
}
TOKEN_PRIVILEGES tokp = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(tu, typeof(TOKEN_PRIVILEGES));
Marshal.FreeHGlobal(tu);
}
}
}
if (hToken != IntPtr.Zero)
{
CloseHandle(hToken);
}
return retval;
}
Declarations :
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegOpenKeyEx(IntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, ref IntPtr phkResult);
public const int HKEY_CURRENT_USER = unchecked((int)0x80000001);
public const int HKEY_CLASSES_ROOT = unchecked((int)0x80000000);
public const int KEY_WOW64_64KEY = 0x0100;
public const int WRITE_OWNER = 0x00080000;
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegCloseKey(IntPtr hKey);
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LookupPrivilegeValue([In] string lpSystemName, [In] string lpName, [Out] out LUID Luid);
[StructLayout(LayoutKind.Sequential)]
public struct LUID
{
public int LowPart;
public int HighPart;
}
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, bool DisableAllPrivileges, IntPtr NewState, int BufferLength, IntPtr PreviousState, ref int ReturnLength);
[StructLayout(LayoutKind.Sequential)]
public struct LUID_AND_ATTRIBUTES
{
public LUID Luid;
public int Attributes;
}
[StructLayout(LayoutKind.Sequential)]
internal struct TOKEN_PRIVILEGES
{
internal int PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
internal int[] Privileges;
}
public const int TOKEN_ASSIGN_PRIMARY = 0x1;
public const int TOKEN_DUPLICATE = 0x2;
public const int TOKEN_IMPERSONATE = 0x4;
public const int TOKEN_QUERY = 0x8;
public const int TOKEN_QUERY_SOURCE = 0x10;
public const int TOKEN_ADJUST_PRIVILEGES = 0x20;
public const int TOKEN_ADJUST_GROUPS = 0x40;
public const int TOKEN_ADJUST_DEFAULT = 0x80;
public const int TOKEN_ALL_ACCESS = TOKEN_ASSIGN_PRIMARY
+ TOKEN_DUPLICATE + TOKEN_IMPERSONATE + TOKEN_QUERY
+ TOKEN_QUERY_SOURCE + TOKEN_ADJUST_PRIVILEGES
+ TOKEN_ADJUST_GROUPS + TOKEN_ADJUST_DEFAULT;
public const string SE_RESTORE_NAME = "SeRestorePrivilege";
public const string SE_DEBUG_NAME = "SeDebugPrivilege";
public const string SE_TCB_NAME = "SeTcbPrivilege";
public const string SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege";
public const int SE_PRIVILEGE_ENABLED_BY_DEFAULT = (0x00000001);
public const int SE_PRIVILEGE_ENABLED = (0x00000002);
public const int SE_PRIVILEGE_REMOVED = (0X00000004);
public const int SE_PRIVILEGE_USED_FOR_ACCESS = unchecked((int)0x80000000);
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool OpenProcessToken(IntPtr hProcess, uint desiredAccess, out IntPtr hToken);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint SetSecurityInfo(IntPtr handle, SE_OBJECT_TYPE ObjectType, uint SecurityInfo,
IntPtr psidOwner, IntPtr psidGroup, IntPtr pDacl, IntPtr pSacl);
public const int OWNER_SECURITY_INFORMATION = 0x00000001;
public enum SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY,
SE_REGISTRY_WOW64_64KEY,
}
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool ConvertStringSidToSid(string StringSid, out IntPtr Sid);