Acquiring Registry Path using NtQueryObject - windows

I need to acquire registry path by it's handle in runtime. For this, I'm using NtQueryObject function. My problem is that NtQueryObject gives me the path in strange format (see image below).
I guess, this is the kind of format you need to use when you are writing drivers, but I want to have this path converted to standard reg path, such as
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run".
Currently I'm replacing
\REGISTRY\MACHINE\etc
with
HKEY_LOCAL_MACHINE\etc
but this Wow6432Node key is a problem. I guess it's name will vary across different machines, even 32 bit windows didn't have that key there. So my question is, is there any standard way to do reg path conversion (maybe some win api does it)?

The Wow6432Node really is part of the registry path to that particular key, although it is hidden from 32-bit processes. If you look in the Software key with Regedit you will find Wow6432Node.
On 64-bit systems both HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run and HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run exist. Depending on what you are trying to do, you may need to work with both of them or only one.
This describes the registry keys affected by WOW64:
http://msdn.microsoft.com/en-us/library/aa384253%28v=VS.85%29.aspx
You can explicitly access the 32-bit or 64-bit view of the registry as described here:
http://msdn.microsoft.com/en-us/library/aa384129%28v=VS.85%29.aspx

Related

Create file or registry key without calling NTDLL.DLL

I know that ntdll is always present in the running process but is there a way (not necessarily supported/stable/guaranteed to work) to create a file/key without ever invoking ntdll functions?
NTDLL is at the bottom of the user-mode hierarchy, some of its functions switch to kernel mode to perform their tasks. If you want to duplicate its code then I suppose there is nothing stopping you from decompiling NtCreateFile to figure out how it works. Keep in mind that on 32-bit Windows there are 3 different instructions used to enter kernel mode (depending on the CPU type), the exact way and where the transition code lives changes between versions and the system call ids change between versions (and even service packs). You can find a list of system call ids here.
I assume you are doing this to avoid people hooking your calls? Detecting your calls? Either way, I can't recommend that you try to do this. Having to test on a huge set of different Windows versions is unmanageable and your software might break on a simple Windows update at any point.
You could create a custom kernel driver that does the work for you but then you are on the hook for getting all the security correct. At least you would have documented functions to call in the kernel.
Technically, registry is stored in %WINDIR%\System32\config / %WINDIR%\SysWOW64\config, excepted your own user's registry which is stored in your own profile, in %USERPROFILE%\NTUSER.DAT.
And now, the problems...
You don't normally have even a read access to this folder, and this is true even from an elevated process. You'll need to change (and mess up a lot...) the permissions to simply read it.
Even for your own registry, you can't open the binary file - "Sharing violation"... So, for system/local machine registries... You can't in fact open ANY registry file for the current machine/session. You would need to shut down your Windows and mount its system drive in another machine/OS to be able to open - and maybe edit - registry files.
Real registry isn't a simple file like the .reg files. It's a database (you can look here for some elements on its structure). Even when having a full access to the binary files, it won't be fun to add something inside "from scratch", without any sotware support.
So, it's technically possible - after all, Windows does it, right? But I doubt that it can be done in a reasonable amount of time, and I simply can't see any benefit from doing that since, as you said, ntdll is ALWAYS present, loaded and available to be used.
If the purpose is to hack the current machine and/or bypass some lack of privileges, it's a hopeless approach, since you'll need even more privileges to do it - like being able to open your case and extract the system drive or being able to boot on another operating system on the same machine... If it's possible, then there is already tools to access the offline Windows, found on a well-known "Boot CD", so still no need to write in registry without any Windows support.

How to force sync between 64 bit registry and 32 bit registry

I have 2 windows machines. On one of them the registry get reflected to the WOW6432Node registry and the other one it doesn't which is causing key not found errors.
The code doesn't change at all between the 2 machines (the program is too large to post here). I can't figure out why it is not being reflected. Is there a way to check if the registry reflector is on and working, or is there a way to force the reflection to happen?
Reflection is built-in to WOW64's Registry access. You can't force a reflection sync, it "just happens" in real-time as data is being accessed. All you can do is turn it on and off as needed, per MSDN documentation:
Registry Reflection
To disable and enable registry reflection for a particular reflected key, use the RegDisableReflectionKey and RegEnableReflectionKey functions. These functions do not affect keys that are not on the list of reflected keys earlier in this topic. Applications should disable reflection only for the registry keys that they create and not attempt to disable reflection for the predefined keys such as HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER. To determine whether the keys on the reflection list have been disabled, use the RegQueryReflectionKey function.

For COM server and registry key redirection, does it need to do file path redirection translation?

Forgive me if the title is not so accurate.
I have met some problem when I am doing something related to COM server and registry redirection and not quite sure is my understanding is correct or not. Hoping anyone could share some light on it. Thanks in advance.
Basically a COM server has been registered in the registry before anyone can use its service. On a 64bit Windows OS, there could be 2 possible views in the registry table, one is for default and the other for the WOW64 view. For example, first registry key is: COMPUTER\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID{GUID}\LocalServer32 and the other is: COMPUTER\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID{GUID}\LocalServer32.
And depends on the process bitness (64bit vs. 32bit) that either one can be read by default, and also we can use KEY_WOW64_64KEY or KEY_WOW64_32KEY (as: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx) to access the other alternative registry key.
What I need is that, I want to get the LocalServer32 executable file by reading the registry key and this can work. The problem is that, for the executable file path I read back, do I need to do the file path translation (in order to get the correct value) depending on which view I get the value from? For example, if the file path is got from COMPUTER\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes\CLSID{GUID}\LocalServer32 and the file path is: C:\Windows\System32\abc.exe, do I need to translate the path to: C:\Windows\SysWow64\abc.exe? Or do I need to translate C:\Program Files\abc.exe to C:\Program Files(x86).exe?
Another question is that, if, for some registry key for COM, the values set in the two Views are different (for example, one has C:\Program Files\abc.exe and the other has C:\Program Files(x86)\abc.exe), then when the COM server is started, how could svchost.exe know which one to start, C:\Program Files\abc.exe or C:\Program Files(x86)\abc.exe? Does anyone know the logic for svchost.exe to determine this? Use the first one if it exists otherwise use the second one?
Thanks a lot.
A 64-bit version of Windows already has all the features in place to make it unnecessary for you to take care of it yourself. You just need to keep the rules in mind when you troubleshoot problems.
First is the registry redirector, it ensures that a 32-bit client program cannot accidentally read keys that contain configuration information that's only appropriate for 64-bit programs. You already know it, most of the HKLM\Software registry accesses are redirected to HKLM\Software\Wow6432Node. This redirection is already in place when the COM server is registered, a 32-bit installer is automatically redirected to write the keys to Wow6432Node instead. The installer is completely unaware that Wow6432Node even exists. Everything falls together automatically, the installer is redirected and the COM server client is redirected as well. All that you care about is knowing where to look to verify that the install was done properly, you do have to look at HKLM\Software\Wow6432Node\Classes\CLSID with Regedit.exe to find the keys back.
File redirection works much the same way, any access to c:\windows\system32 is redirected to c:\windows\syswow64, from c:\program files to c:\program files (x86). And very similarly, a 32-bit installer doesn't have to know beans about this, it can simply use the legacy 32-bit path names. Same for any 32-bit client program, it will be redirected the same way. All that you care about is knowing where to look for a file to verify the installer.
This can only go wrong if bitness is mixed, a 64-bit program reading registry keys or files installed by a 32-bit program. Or the other way around. Like it does with your troubleshooting tools, like Explorer, Regedit and SysInternals' Process Monitor. In general something that should be strongly avoided in COM, most servers are in-process servers and running 32-bit code in a 64-bit process is not possible. The biggest reason that the registry and file redirectors exist in the first place.

How are the GetObject progids maintained?

Windows Shell Scripting (vbs) has the following method:
object.GetObject(strPathname [,strProgID], [strPrefix])
Now suppose I have the following code:
set myval = getObject("myObjectRef:myObjectArgs")
This works on one machine - and not on another.
What I want to do is find the definitive list where all the myObjectRef/progIds are maintained.
My question is:How are the GetObject progids maintained?
Assumptions:
I'm looking for an answer more sophisticated that "do a search in the registry"
I'm looking to find a particular place where I can go looking for my progid to see if it exists or not.
I'm looking for an answer more sophisticated that "do a search in the registry"
Well, that's a bit difficult because that is really all it takes. You don't exactly have to "search", just look at where you expect it to find. Which is right underneath the HKEY_CLASSES_ROOT hive in regedit.exe, the keys are sorted alphabetically so just type the "m" key on your keyboard and you are already close the progid you are looking for. If you don't see the "myObjectRef.myObjectArgs" key then you can count on a kaboom at runtime when COM cannot find it either.
There is no "definite list" and no entity that maintains progids to ensure that they are unique. The list is specific to each machine, whatever was installed on that machine determines what you find back with Regedit.exe. They are simply a human-friendly version of the GUID, the value that really matters to locate a COM component. A Globally Unique ID that unambiguously identifies the server. The CLSID subkey of the progid key provides that GUID. It is a big number, not very human-friendly.
The progid key is written to the registry when the component installs itself. So a missing key simply means that it isn't installed.
A not uncommon problem on machines that boot a 64-bit version of Windows is that the COM server is only available as a 32-bit component but the client is a 64-bit process. This is resolved in the registry as well, the CLSID key is only present in HKLM\Software\Wow6432Node\Classes. The Wow6432Node section is what a 32-bit client sees. So a 64-bit client looks in HKLM\Software\Classes and won't find the key. Looks just like a "not-installed" problem, even though it is actually present. Just not the 64-bit version of it. SysInternals' Process Monitor is a great tool to diagnose problems like this. You see the failing client program searching through the registry.

How can I place data in WOW64's 32 bit registry view from the NT Native API?

I have an application where I am restricted to using the NtCreateKey / ZwCreateKey function(s). (e.g. in a driver) There is another application I don't control which runs under WOW64, which reads a value from this registry key.
I want to set the registry value such that this application can find it. However, WOW64 is implemented in kernel32 -- so I can't pass the KEY_WOW64_32KEY flag like I can when using RegOpenKeyEx.
The easiest way seems to be to include Wow6432Node in the path passed to ZwCreateKey, but MSDN discourages this:
WOW64 defines the following symbolic links only for compatibility with existing applications that may use hardcoded registry key paths containing Wow6432Node. New applications should avoid using Wow6432Node in registry key paths.
This seems to put me between a rock and a hard place... how can I place data in the 32 bit registry view? The MSDN language says "avoid" -- is this a situation where Wow6432Node is unavoidable?

Resources