Манипулировать файлами хранилища реестра с C#

#c# #registry #hive

#c# #реестр #hive

Вопрос:

1.) Как загружать, редактировать и сохранять двоичные файлы Hive для реестра с C #?

Я нашел этот Win32 api. http://msdn.microsoft.com/en-us/library/ee210770(VS.85).aspx

Этот парень поделился кодом для вывода содержимого двоичных файлов Hive в текст. http://www.codeproject.com/KB/recipes/RegistryDumper.aspx

2.) В дополнение к манипулированию файлами Hive, я также ищу способ загрузки файла Hive в реестр во время выполнения с использованием C # (аналогично командам Load Hive и Unload Hive для File many в regedit)

/ Спасибо

Комментарии:

1. Для win32 api существует .NET-оболочка: github.com/LordMike/OffregLib

Ответ №1:

Вы смотрели на классы Registry и RegistryKey в Microsoft.Win32?

http://msdn.microsoft.com/en-us/library/microsoft.win32.aspx

Похоже, вам может потребоваться создать свое собственное представление для чтения файла hive и либо поставить его в очередь, либо немедленно внести соответствующие изменения в реестр. Аналогично, вам нужно было бы записать свой собственный конвертер обратно на диск.

Ответ №2:

В статье ниже объясняется, как проанализировать файл реестра без использования WinAPI (advapi32.dll ). В данном конкретном случае парень использует Mono:

http://volatile-minds.blogspot.com/2011/01/analyzing-windows-nt-registry-without.html

 using (FileStream fs = File.OpenRead (path)) {
 var data = new byte[checked((int)fs.Length)];
 int i = 0;
 int read;

 using (var ms = new MemoryStream (checked((int)fs.Length))) {

  while ((read = fs.Read (data, 0, data.Length)) > 0) {
   ms.Write (data, 0, read);
   i  = read;
  }

  byte[] hive = ms.ToArray ();
  char[] cList = new char[fs.Length];

  i = 0;
  foreach (byte b in hive)
   cList[i  ] = (char)b;

         string d = new string (cList);


  int all = 0;

  foreach (Match mx in lf.Matches (d)) { //you can change out the regex you want here.
   byte[] bb = new byte[mx.Value.Length];
   char[] cb = new char[mx.Value.Length];

   for (int k = 0; k < mx.Value.Length; k  ) {
    bb[k] = (byte)mx.Value[k];
    cb[k] = (char)bb[k];

   }

   all  ;

   //Console.WriteLine (new string (cb));
  }

  Console.WriteLine (all.ToString ());
  all = 0;
 }
}
  

Комментарии:

1. На самом деле я написал приведенный выше код, это мой блог. Этот код действительно убогий, и я не рекомендую его использовать. Я написал настоящую автономную библиотеку чтения реестра на Ruby , а инструмент, использующий ее, находится в Metasploit framework (tools / reg.rb). В конечном итоге я буду внедрять эту библиотеку и на C #, но не в ближайшее время.

2. что ж .. это произойдет не в ближайшее время… а ты?? 🙂 @user1577946

Ответ №3:

Этому 9 лет, но я подумал, что это может помочь кому-то еще. Я написал этот класс, который позволяет вам делать что-то вроде этого:

 Hive.AcquirePrivileges() // Acquires the privileges necessary for loading the hive
Hive myregistryhive = Hive.LoadFromFile("hivepathhere") // Loads the hive
// use myregistryhive.RootKey (a RegistryKey), read and/or write to it and its sub keys
myregistryhive.SaveAndUnload() // Unloads the hive
Hive.ReturnPrivileges() // De-elevate back to normal privileges.
  

Код для класса:

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

    [DllImport("advapi32.dll", SetLastError = true)]
    static extern int RegSaveKey(IntPtr hKey, string lpFile, uint securityAttrPtr = 0);

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

    [DllImport("ntdll.dll", SetLastError = true)]
    static extern IntPtr RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out bool PreviousValue);

    [DllImport("advapi32.dll")]
    static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, ref UInt64 lpLuid);

    [DllImport("advapi32.dll")]
    static extern bool LookupPrivilegeValue(IntPtr lpSystemName, string lpName, ref UInt64 lpLuid);

    private RegistryKey parentKey;
    private string name;
    private string originalPath;
    public RegistryKey RootKey;

    private Hive() { }

    public static Hive LoadFromFile(string Path)
    {
        Hive result = new Hive();

        result.parentKey = RegistryKey.OpenBaseKey(RegistryHive.Users, RegistryView.Default);
        result.name = Guid.NewGuid().ToString();
        result.originalPath = Path;
        IntPtr parentHandle = result.parentKey.Handle.DangerousGetHandle();
        RegLoadKey(parentHandle, result.name, Path);
        //Console.WriteLine(Marshal.GetLastWin32Error());
        result.RootKey = result.parentKey.OpenSubKey(result.name, true);
        return resu<
    }
    public static void AcquirePrivileges()
    {
        ulong luid = 0;
        bool throwaway;
        LookupPrivilegeValue(IntPtr.Zero, "SeRestorePrivilege", ref luid);
        RtlAdjustPrivilege((int)luid, true, false, out throwaway);
        LookupPrivilegeValue(IntPtr.Zero, "SeBackupPrivilege", ref luid);
        RtlAdjustPrivilege((int)luid, true, false, out throwaway);
    }
    public static void ReturnPrivileges()
    {
        ulong luid = 0;
        bool throwaway;
        LookupPrivilegeValue(IntPtr.Zero, "SeRestorePrivilege", ref luid);
        RtlAdjustPrivilege((int)luid, false, false, out throwaway);
        LookupPrivilegeValue(IntPtr.Zero, "SeBackupPrivilege", ref luid);
        RtlAdjustPrivilege((int)luid, false, false, out throwaway);
    }
    public void SaveAndUnload()
    {
        RootKey.Close();
        RegUnLoadKey(parentKey.Handle.DangerousGetHandle(), name);
        parentKey.Close();
    }
}
  

Редактировать: Обратите внимание, что для этого требуются права администратора.