Beispielcode für ein C#-32-Bit-Programm für den Zugriff auf die 64-Bit-Registrierung

黄舟
Freigeben: 2017-03-10 14:14:49
Original
2446 Leute haben es durchsucht


In meinem letzten Artikel wurde bereits „Der Unterschied zwischen 32-Bit-Programmen und 64-Bit-Programmen, die die Registrierung auf 64-Bit-Plattformen lesen und schreiben“ erklärt, daher werde ich antworten Die nächste Frage Eine Frage, die vom vorherigen Artikel übrig geblieben ist: Wie greifen 32-Bit-Programme auf die 64-Bit-Systemregistrierung zu (dh: den Registrierungsspeicherort, auf den 64-Bit-Programme zugreifen).

Wir wissen bereits:

①: 64-Bit-Programme im nativen Modus werden im nativen Modus ausgeführt, und Zugriffsschlüssel und Speicher werden unten registriert Wert im Tabellenunterschlüssel: HKEY_LOCAL_MACHINESoftware

 ②: Das 32-Bit-Programm läuft im WOW64-Modus, und der Zugriffsschlüssel und der Wert werden im folgenden Registrierungsunterschlüssel gespeichert: HKEY_LOCAL_MACHINESoftwareWOW6432nod

Um dann ein 32-Bit-Programm für den Zugriff auf 64-Bit-Registrierungsinformationen zu implementieren, müssen Sie auch die folgenden Konzepte kennen: 1: Dateisystemsteuerung. 2: Registry-Umleitung (Richtung). 3: Registrierungsreflexion.

 ①: Dateisystemumleitung

 32-Bit-Prozesse können keine 64-Bit-DLLs laden, und 64 auch nicht -Bit-Prozesse laden 32-Bit-DLL. Das Windows-Systemverzeichnis enthält alle installierten Anwendungen und deren DLL-Dateien. Gemäß den von uns beschriebenen Regeln

Es sollte in Verzeichnisse für 64-Bit-Anwendungen und Verzeichnisse für 64-Bit-Anwendungen unterteilt werden . Verzeichnis für 32-Bit-Anwendungen. Andernfalls könnten wir nicht zwischen 32-Bit- und 64-Bit-DLL-Dateien unterscheiden. Bei 64-Bit-Anwendungen werden ihre Dateien normalerweise in %windir%system32 und %programfiles% abgelegt (zum Beispiel: c:program files). Bei 32-Bit-Anwendungen liegen die Dateien normalerweise unter %windir%syswow64 und

 C:program files (x86). Wenn wir ein 32-Bit-Programm verwenden, um auf %windir%system32 zuzugreifen, unabhängig davon, ob wir Hardcodierung oder andere Methoden verwenden, leitet uns das System automatisch zu %windir%syswow64 weiter. Diese Umleitung ist standardmäßig für jede 32-Bit-Anwendung aktiviert. Aber eine solche Umleitung ist für uns nicht immer notwendig. Dann können wir die entsprechende API in C# aufrufen, um diese Art der Steuerung zu schließen und zu öffnen. Es gibt drei häufig verwendete Funktionen:

 Wow64DisableWow64FsRedirection (Systemumleitung ausschalten),

 Wow64RevertWow64FsRedirection (Systemumleitung einschalten),

   Wow64EnableWow64FsRedirection (Systemumleitung aktivieren).

Wow64EnableWow64FsRedirection ist jedoch nicht zuverlässig, wenn es im verschachtelten Modus verwendet wird. Daher wird die obige Wow64RevertWow64FsRedirection normalerweise zum Öffnen der Dateisystemumleitungsfunktion

verwendet. In C# können wir DllImport verwenden, um diese beiden Funktionen direkt aufzurufen.

 ②: Registrierungsumleitung (Richtung)

Zur Unterstützung der 32-Bit- und 64-Bit-COM-Registrierung zusammen mit Um den Koexistenzstatus des Programms anzuzeigen, bietet das WOW64-Subsystem eine weitere Ansicht der von 32-Bit-Programmen verwendeten Registrierung. Verwenden Sie die Registrierung

im WOW64-Subsystem, um zum Abfangen von Registrierungsaufrufen auf Bitebene umzuleiten. Durch die Registrierungsumleitung wird außerdem sichergestellt, dass Registrierungsaufrufe an den richtigen Zweig in der Registrierung weitergeleitet werden.

Wenn wir ein neues Programm installieren oder ein Programm auf einer Windows x64-Version des Computers ausführen, greift der Registrierungsaufruf des 64-Bit-Programms auf den HKEY_LOCAL_MACHINESoftware-Registrierungsunterschlüssel zu

Keine Weiterleitung. WOW64 fängt Registrierungsaufrufe von 32-Bit-Programmen an HKEY_LOCAL_MACHINESoftware ab und leitet sie dann an den Knotenunterschlüssel HKEY_LOCAL_MACHINESoftwareWOW6432 um. Indem WOW64 nur 32-Bit-Programmaufrufe umleitet, stellt es sicher, dass Programme immer in den entsprechenden Registrierungsunterschlüssel schreiben.

Die Registrierungsumleitung erfordert keine Änderung des Programmcodes und der Prozess ist für Benutzer transparent.
 ③: Registrierungsreflexion

Reflection erstellt zwei identische Registrierungen, um die gleichzeitige Ausführung dieser Datei zu unterstützen Eine physische Kopie der Maschine und WOW64-Vorgänge.

öffnet jederzeit den 64-Bit-Bereich der Registrierung und die Registrierungsreflexion bietet eine Echtzeitmethode zur Anpassung an 32-Bit.

Nachdem wir diese kurz verstanden haben, sprechen wir über die konkreten Umsetzungsschritte:

würde nicht in INED in INS auf der 64-Bit-Betriebsumleitung

den Handle zum Betriebsschlüsselwert

                               int (Registrierungsreflexion für bestimmte Elemente deaktivieren)

Zugriff erhalten Schlüsselwert

Registrierungsumleitung aktivieren (turn zur Registrierungsreflexion für bestimmte Elemente) )


                

  【Hinweis: Da wir DllImport verwenden das Programm, also muss der Namespace sein eingeführt: System.Runtime.InteropServices]

Bitte sehen Sie sich das Codebeispiel unten an
1 using System;
  2  using System.Collections.Generic;
  3  using System.Linq;
  4  using System.Text;
  5  using Microsoft.Win32;
  6  using System.Runtime.InteropServices;
  7 
  8  namespace OperateRegistrationTable
  9 {
 10     class Programe
 11     {
 12         static void Main(string[] args)
 13         {
 14             string myParentKeyName = "HKEY_LOCAL_MACHINE";
 15             string mySubKeyName = @"SOFTWARE\EricSun\MyTestKey";
 16             string myKeyName = "MyKeyName";
 17 
 18             string value = string.Empty;
 19             value = Utility.Get64BitRegistryKey(myParentKeyName, mySubKeyName, myKeyName);
 20             Console.WriteLine("The Value is: {0}", value);
 21         }
 22     }
 23 
 24     public class Utility
 25     {
 26         #region 32位程序读写64注册表
 27 
 28         static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)0x80000000;
 29         static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;
 30         static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
 31         static UIntPtr HKEY_USERS = (UIntPtr)0x80000003;
 32         static UIntPtr HKEY_CURRENT_CONFIG = (UIntPtr)0x80000005;
 33 
 34         // 关闭64位(文件系统)的操作转向
 35          [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 36         public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
 37         // 开启64位(文件系统)的操作转向
 38          [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 39         public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);    
 40    
 41         // 获取操作Key值句柄
 42          [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 43         public static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, 
                                  int samDesired, out IntPtr phkResult);
 44         //关闭注册表转向(禁用特定项的注册表反射)
 45         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 46         public static extern long RegDisableReflectionKey(IntPtr hKey);
 47         //使能注册表转向(开启特定项的注册表反射)
 48         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 49         public static extern long RegEnableReflectionKey(IntPtr hKey);
 50         //获取Key值(即:Key值句柄所标志的Key对象的值)
 51         [DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 52         private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved,
 53                                                   out uint lpType, System.Text.StringBuilder lpData,
 54                                                   ref uint lpcbData);
 55 
 56         private static UIntPtr TransferKeyName(string keyName)
 57         {
 58             switch (keyName)
 59             {
 60                 case "HKEY_CLASSES_ROOT":
 61                     return HKEY_CLASSES_ROOT;
 62                 case "HKEY_CURRENT_USER":
 63                     return HKEY_CURRENT_USER;
 64                 case "HKEY_LOCAL_MACHINE":
 65                     return HKEY_LOCAL_MACHINE;
 66                 case "HKEY_USERS":
 67                     return HKEY_USERS;
 68                 case "HKEY_CURRENT_CONFIG":
 69                     return HKEY_CURRENT_CONFIG;
 70             }
 71 
 72             return HKEY_CLASSES_ROOT;
 73         }
 74 
 75         public static string Get64BitRegistryKey(string parentKeyName, string subKeyName, string keyName)
 76         {
 77             int KEY_QUERY_VALUE = (0x0001);
 78             int KEY_WOW64_64KEY = (0x0100);
 79             int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY);
 80 
 81             try
 82             {
 83                 //将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
 84                 UIntPtr hKey = TransferKeyName(parentKeyName);
 85 
 86                 //声明将要获取Key值的句柄
 87                 IntPtr pHKey = IntPtr.Zero;
 88 
 89                 //记录读取到的Key值
 90                 StringBuilder result = new StringBuilder("".PadLeft(1024));
 91                 uint resultSize = 1024;
 92                 uint lpType = 0;
 93 
 94                 //关闭文件系统转向 
 95                 IntPtr oldWOW64State = new IntPtr();
 96                 if (Wow64DisableWow64FsRedirection(ref oldWOW64State))
 97                 {
 98                     //获得操作Key值的句柄
 99                     RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey);
100 
101                     //关闭注册表转向(禁止特定项的注册表反射)
102                     RegDisableReflectionKey(pHKey);
103 
104                     //获取访问的Key值
105                     RegQueryValueEx(pHKey, keyName, 0, out lpType, result, ref resultSize);
106 
107                     //打开注册表转向(开启特定项的注册表反射)
108                     RegEnableReflectionKey(pHKey);
109                 }
110 
111                 //打开文件系统转向
112                 Wow64RevertWow64FsRedirection(oldWOW64State);
113 
114                 //返回Key值
115                 return result.ToString().Trim();
116             }
117             catch (Exception ex)
118             {
119                 return null;
120             }
121         }
122 
123         #endregion
124     }
125 }
Nach dem Login kopieren

Die drei Parameter der Get64BitRegistryKey-Funktion repräsentieren jeweils: Primärschlüsselname (z. B. HKEY_LOCAL_MACHINE usw.), Unterschlüsselname, Schlüsselname und der zurückgegebene Wert ist der Wert des Schlüssels (64-Bit-Systemregistrierung). ) Schlüsselwert) Mit der oben genannten Methode ist es durchaus möglich, ein 32-Bit-Programm zu verwenden, um auf die 64-Bit-Systemregistrierung zuzugreifen (dh auf den Registrierungsspeicherort, auf den das 64-Bit-Programm zugreift).

Das obige ist der detaillierte Inhalt vonBeispielcode für ein C#-32-Bit-Programm für den Zugriff auf die 64-Bit-Registrierung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!