Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I access 64 bit registry hive information from a application running in 32 bit mode on a 64 bit machine(WOW) using WMI through C#

I think the question really sums up what i'm trying to do. Here is the code that i'm using. It works in every scenario except if my application is running in 32 bit mode on a 64 bit machine. No matter how I play arround with the __ProviderArchitecture and __RequiredArchitecture flags, i can always only seem to access the 32 bit section of the hive (WOW6432Node)

uint LOCAL_MACHINE = 0x80000002;
string results = "";
ConnectionOptions options = new ConnectionOptions();
options.Impersonation = ImpersonationLevel.Impersonate;
options.EnablePrivileges = true;
options.Username = this.txtUser.Text;
options.Password = this.txtPassword.Text;

ManagementScope myScope = new ManagementScope("\\\\" + this.txtMachine.Text + "\\root\\default", options);
ManagementPath mypath = new ManagementPath("StdRegProv");
ManagementClass mc = new ManagementClass(myScope, mypath, null);

ManagementBaseObject inParams = mc.GetMethodParameters("EnumKey");
inParams["hDefKey"] = LOCAL_MACHINE;
inParams["sSubKeyName"] = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";

ManagementNamedValueCollection objCtx = new ManagementNamedValueCollection();
objCtx.Add("__ProviderArchitecture", 64);
objCtx.Add("__RequiredArchitecture", true);


InvokeMethodOptions invokeOptions = new InvokeMethodOptions();
invokeOptions.Context = objCtx;
ManagementBaseObject outParams = mc.InvokeMethod("EnumKey", inParams, invokeOptions);

inParams = mc.GetMethodParameters("GetStringValue");
inParams["hDefKey"] = LOCAL_MACHINE;

foreach(string name in (string[])outParams["sNames"])
{
      inParams["sSubKeyName"] = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" + "\\" + name;
      inParams["sValueName"] = "DisplayName";
      outParams = mc.InvokeMethod("GetStringValue", inParams, invokeOptions);

      if (!string.IsNullOrEmpty(((string)outParams["sValue"])))
      {
          results += outParams["sValue"] + "\t";
      }
 }
like image 461
Mark Avatar asked Dec 29 '22 11:12

Mark


2 Answers

I think there is no need to launch a separate process. I was able to access the 64bits registry of a remote machine from a 32bits process. In the sample you have above I've added the options to the scope directly, instead of setting them in the invoke options.

myScope.Options.Context.Add("__ProviderArchitecture", 64);
myScope.Options.Context.Add("__RequiredArchitecture", true);

It is also to be noted that in .net 4 there is now a parameter (RegistryView) on the OpenRemoteBaseKey function see on msdn here

like image 72
Guillaume Gros Avatar answered Jan 24 '23 12:01

Guillaume Gros


You need to open keys with the KEY_WOW64_64KEY flag set. The MSDN documentation covers this well.

Note in particular that you still just ask for HKLM/Software or similar. You mustn't try to go through the WoW6432Node redirectors, otherwise you'll get stuck in a loop! More details on that topic are here

like image 34
Sam Holloway Avatar answered Jan 24 '23 11:01

Sam Holloway