Mon dernier article a déjà expliqué "La différence entre les programmes 32 bits et les programmes 64 bits lisant et écrivant le registre sur les plateformes 64 bits", je vais donc répondre la question suivante Une question laissée par l'article précédent : Comment les programmes 32 bits accèdent-ils au registre système 64 bits (c'est-à-dire : l'emplacement du registre auquel accèdent les programmes 64 bits).
Nous le savons déjà :
① : Les programmes 64 bits en mode natif s'exécutent en mode natif, et les clés d'accès et le stockage sont enregistrés ci-dessous. valeur dans la sous-clé de la table : HKEY_LOCAL_MACHINESoftware
② : le programme 32 bits s'exécute en mode WOW64, et la clé d'accès et la valeur sont stockées dans la sous-clé de registre suivante : HKEY_LOCAL_MACHINESoftwareWOW6432nod
Ensuite, pour implémenter un programme 32 bits permettant d'accéder aux informations de registre 64 bits, vous devez également connaître les concepts suivants : 1 : Pilotage du système de fichiers. 2 : Redirection du registre (direction). 3 : Réflexion du registre.
① : Redirection du système de fichiers
Les processus 32 bits ne peuvent pas charger de DLL 64 bits, et les 64 bits non plus Processus -bit Chargez une DLL 32 bits. Le répertoire système Windows contient toutes les applications installées et leurs fichiers Dll. Selon les règles que nous avons décrites,
Il doit être divisé en répertoires pour les applications 64 bits et en répertoires pour le répertoire 32-. applications de bits. Sinon, nous ne serions pas en mesure de faire la différence entre les fichiers Dll 32 bits et 64 bits. Pour les applications 64 bits, leurs fichiers sont généralement placés dans %windir%system32 et %programfiles% (par exemple : c:program files). Pour les applications 32 bits, les fichiers se trouvent généralement sous %windir%syswow64 et
C:program files (x86). Si nous utilisons un programme 32 bits pour accéder à %windir%system32, que nous utilisions du codage en dur ou d'autres méthodes, le système nous redirigera automatiquement vers %windir%syswow64. Cette redirection est activée par défaut pour chaque application 32 bits. Mais ce type de réorientation n’est pas toujours nécessaire pour nous. Nous pouvons ensuite appeler l'API correspondante en C# pour fermer et ouvrir ce type de pilotage. Il existe trois fonctions couramment utilisées :
Wow64DisableWow64FsRedirection (désactiver la redirection du système),
Wow64RevertWow64FsRedirection (activer la redirection du système),
Wow64EnableWow64FsRedirection (activer la redirection du système).
Mais Wow64EnableWow64FsRedirection n'est pas fiable lorsqu'il est utilisé en mode imbriqué, donc Wow64RevertWow64FsRedirection ci-dessus est généralement utilisé pour ouvrir la fonction de redirection du système de fichiers
. En C#, nous pouvons utiliser DllImport pour appeler directement ces deux fonctions.
② : Redirection du registre (direction)
Pour prendre en charge l'enregistrement COM 32 bits et 64 bits Avec État de coexistence des programmes, le sous-système WOW64 fournit une autre vue du registre utilisé par les programmes 32 bits. Utilisez le registre
dans le sous-système WOW64 pour rediriger afin d'intercepter les appels de registre au niveau bit. La redirection du registre garantit également que les appels du registre sont dirigés vers la branche appropriée du registre.
Lorsque nous installons un nouveau programme ou exécutons un programme sur une version Windows x64 de l'ordinateur, l'appel de registre effectué par le programme 64 bits accède à la sous-clé de registre HKEY_LOCAL_MACHINESoftware
Aucune redirection. WOW64 intercepte les appels de registre effectués par des programmes 32 bits vers HKEY_LOCAL_MACHINESoftware, puis les redirige vers la sous-clé de nœud HKEY_LOCAL_MACHINESoftwareWOW6432. En redirigeant uniquement les appels de programme 32 bits, WOW64 garantit que les programmes écrivent toujours dans la sous-clé de registre correspondante.
La redirection du registre ne nécessite pas de modification du code du programme et le processus est transparent pour les utilisateurs.
③ : Réflexion du registre
La réflexion crée deux registres identiques pour prendre en charge l'exécution simultanée de ce fichier. une copie physique de la machine et des opérations WOW64,
ouvre la section 64 bits du registre à tout moment et la réflexion du registre fournit une méthode en temps réel pour prendre en charge 32 bits.
Après les avoir brièvement compris, parlons des étapes spécifiques de mise en œuvre :
serait recherché dans Ins sur la redirection de l'opération 64 bits (système de fichiers)
Obtenir le handle de l'opérationValeur clé
int (Désactiver la réflexion du registre pour des éléments spécifiques)
Obtenir l'accès à la valeur de la cléActiver la redirection du registre (activer sur la réflexion du registre pour des éléments spécifiques) )
【Remarque : Puisque nous sommes, DllImport est utilisé dans le programme, donc l'espace de noms doit être introduit : System.Runtime.InteropServices]
Veuillez consulter l'exemple de code ci-dessous
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 }
Les trois paramètres de la fonction Get64BitRegistryKey représentent respectivement : le nom de la clé primaire (tel que : HKEY_LOCAL_MACHINE, etc.), le nom de la sous-clé, le nom de la clé, et la valeur renvoyée est la valeur de la clé (registre système 64 bits ) Valeur clé), grâce à la méthode ci-dessus, il est tout à fait possible d'utiliser un programme 32 bits pour accéder au registre système 64 bits (c'est-à-dire : l'emplacement du registre auquel le programme 64 bits a accédé).
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!