Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

NtOpenKey - Access denied

236 views
Skip to first unread message

R.Wieser

unread,
Aug 4, 2014, 4:43:49 PM8/4/14
to
Hello All,

I'm walking the registry using only NTDLL calls, and am a bit stuck: A
seemingly quite normal key -- which I can open and view subkeys of in
RegEdit -- causes the NtOpenKey (using KEY_ALL_ACCESS - 0xF003F) to return a
0xC0000022 - STATUS_ACCESS_DENIED.

My question is: What do I need to do to get access to that key (and its sub
& data keys) ? Does RegEdit impersonate somebody else, and if so who ?
Where can I find an example of it (the NtOpenKey examples I found do not
seem to use a security descriptor) ?

-- Extra info:
The key in question, a the 'version' subkey to a ClassID key, seems to have
a bit different permissions than other subkeys on the same level. For
instance, it seems to have only three groups instead of five: Everyone, <the
only user, me> and Guests. Other keys have five, differently named groups
(including 'Administrators' and 'SYSTEM')

The group 'Everyone' hasn't any "allow" or "deny" boxes tagged (four usable,
two grayed-out), the <the only user, me> and the 'Guests' groups have got
all usable 'deny' boxes tagged (most likely the cause of my problem :-) ).

Regards,
Rudy Wieser



Geoff

unread,
Aug 4, 2014, 6:46:08 PM8/4/14
to
On Mon, 4 Aug 2014 22:43:49 +0200, "R.Wieser" <add...@not.available>
wrote:
Are you writing a kernel mode driver? Are you running it in kernel
mode or debugging it as yourself? The context is unclear to me.

User mode programs should use RegOpenKeyEx and RegCloseKey, not the
kernel mode functions. Other than that, I have no other advice.

JJ

unread,
Aug 4, 2014, 11:31:48 PM8/4/14
to
On Vista and newers, REGEDIT always run elevated, so it has all access. You
should do the same using manifest, if you don't have access to a resource.
Older Windows will need to run itself as a user that is a member of the
Administrators group. That's the easiest method, AFAIK.

R.Wieser

unread,
Aug 5, 2014, 4:00:27 AM8/5/14
to
Geoff,

> Are you writing a kernel mode driver? Are you running
> it in kernel mode or debugging it as yourself?

The Zw* versions of the functions are kernel mode, the Nt* versions are said
to be usermode. I'm using, as mentioned, the user-mode Nt* versions.

Regards,
Rudy Wieser


-- Origional message:
Geoff <ge...@invalid.invalid> schreef in berichtnieuws
kq20u9t6sq310923u...@4ax.com...

Deanna Earley

unread,
Aug 5, 2014, 4:46:27 AM8/5/14
to
On 04/08/2014 21:43, R.Wieser wrote:
> Hello All,
>
> I'm walking the registry using only NTDLL calls, and am a bit stuck: A
> seemingly quite normal key -- which I can open and view subkeys of in
> RegEdit -- causes the NtOpenKey (using KEY_ALL_ACCESS - 0xF003F) to return a
> 0xC0000022 - STATUS_ACCESS_DENIED.
>
> My question is: What do I need to do to get access to that key (and its sub
> & data keys) ?

What key is it?
Anything outside of HKCR is not available for writing unless you're
elevated.
In your case, you're using KEY_ALL_ACCESS which means you want write
access, and if you want to just read, you should use KEY_READ.

> Does RegEdit impersonate somebody else, and if so who ?

RegEdit runs with the highest available, meaning that for an "admin
user" it will ask for elevation, with LUA users just running with their
access.

> -- Extra info:
> The key in question, a the 'version' subkey to a ClassID key, seems to have
> a bit different permissions than other subkeys on the same level.

That suggests you're opening HKCR?
This is special...

> For
> instance, it seems to have only three groups instead of five: Everyone, <the
> only user, me> and Guests. Other keys have five, differently named groups
> (including 'Administrators' and 'SYSTEM')
>
> The group 'Everyone' hasn't any "allow" or "deny" boxes tagged (four usable,
> two grayed-out), the <the only user, me> and the 'Guests' groups have got
> all usable 'deny' boxes tagged (most likely the cause of my problem :-) ).

HKCR is an amalgam of several other global, and user specific keys, and
so may possibly have differing permissions.

--
Deanna Earley (dee.e...@icode.co.uk)
iCatcher Development Team
http://www.icode.co.uk/icatcher/

iCode Systems

(Replies direct to my email address will be printed, shredded then fed
to the rats. Please reply to the group.)

Deanna Earley

unread,
Aug 5, 2014, 4:50:08 AM8/5/14
to
On 05/08/2014 04:31, JJ wrote:
> On Vista and newers, REGEDIT always run elevated, so it has all access.

Only for admin users. LUA users still only run it unelevated, and will
get permission errors when they try and write outside of HKCU.

R.Wieser

unread,
Aug 5, 2014, 5:04:29 AM8/5/14
to
Hello JJ,

> On Vista and newers, REGEDIT always run elevated, so it has all access.

Hmmm .... I've got the same iteration using RegKeyOpenEx and RegEnumKeyEx,
and there I have no problem with that key whatsoever. To me that suggests
that elevated rights are not really the problem (unless that RegKeyOpenEx
function does that itself, which I would find a tad odd).

My guess is that RegKeyOpenEx -- which, AFAIK, also uses NtOpenKey to do its
work -- just provides a bit more info than I gave it. If only I could find
that "bit more" :-)

Regards,
Rudy Wieser



JJ <jj4p...@vfemail.net> schreef in berichtnieuws
h0qvvlxun69v$.14jl0bzff43xy.dlg@40tude.net...

R.Wieser

unread,
Aug 5, 2014, 5:40:56 AM8/5/14
to
Hey Deanna,

> What key is it?
> Anything outside of HKCR is not available for writing unless
> you're elevated.

Its a ClassID key, and yes, its located in HKCR. But odd, as I can, upto a
point, iterate other hives using the full-access setting too.

> In your case, you're using KEY_ALL_ACCESS which means you want
> write access, and if you want to just read, you should use KEY_READ.

Although I'm currently just accessing those keys to see if I can reach all
of them, my intention is to be able to write (change) keys too. Hence the
"all access" usage.

> HKCR is an amalgam of several other global, and user specific keys,
> and so may possibly have differing permissions.

As mentioned, they certainly do have. I can walk several other, similar
ClassID subtrees (on the same level) with no problem, just this one doesn't
want to cooperate.

And I've just tested, other than HKEY_CURRENT_CONFIG (HKCC?) all hives have
some keys that I can't access. Changing to read-access only (0x20019)
still shows keys that can't be accessed..

Regards,
Rudy Wieser


-- Origional message
Deanna Earley <dee.e...@icode.co.uk> schreef in berichtnieuws
lrq5lc$mb4$1...@speranza.aioe.org...

R.Wieser

unread,
Aug 5, 2014, 5:45:01 AM8/5/14
to
JJ,

> Hmmm .... I've got the same iteration using RegKeyOpenEx and
> RegEnumKeyEx, and there I have no problem with that key whatsoever.

I made a mistake there, I was using KEY_READ instead of KEY_ALL_ACCESS (used
an old program for a quick test). When I using the latter it "crapped out"
on the same key. :-\

Regards,
Rudy Wieser


-- Origional message
R.Wieser <add...@not.available> schreef in berichtnieuws
53e09de4$0$2897$e4fe...@news2.news.xs4all.nl...

Ant

unread,
Aug 6, 2014, 4:43:27 PM8/6/14
to
"R.Wieser" wrote:

> The Zw* versions of the functions are kernel mode, the Nt* versions are said
> to be usermode. I'm using, as mentioned, the user-mode Nt* versions.

In user mode you can use either - both versions have the same address
in ntdll and are directed to the implementing kernel code through the
System Service Despatch Table. When programming in kernel mode and
using these same exported names from ntoskrnl.exe, Zw* calls go
through the SSDT (same as user mode) and the Nt* routines are the
actual implementation. Kernel mode programmers are supposed to use the
Zw* versions. I've never understood why ntdll needs to export both
sets of names.

I presume you have set up the OBJECT_ATTRIBUTES structure correctly
since you're not getting messages like "invalid parameter". e.g.
ObjectName needs to be in native format (Registry\Machine\...,
Registry\User\... etc.) and you haven't done something silly like set
the OBJ_KERNEL_HANDLE flag!


R.Wieser

unread,
Aug 7, 2014, 4:52:04 AM8/7/14
to
Hello Ant,

> In user mode you can use either - both versions have the same
> address in ntdll

I know: :-) I read about it on MSDN, and saw the functions having the same
addresses when I extracted a .DEF file from the DLL. It was just that
Geoff thought that what I was doing was driver-only that I pretty-much
copy-pasted that MSDN phrase.

> I've never understood why ntdll needs to export both sets of names.

Most likely backwards compatibility to a time where those functions where
actually (a bit) different. Quite likely a remnant from when they merged
their OS streams (Windows NT and ... forgot which other one. Win2000 ?).

> I presume you have set up the OBJECT_ATTRIBUTES structure
> correctly since you're not getting messages like "invalid parameter".

Now ? It looks like it. But I was pestered with a number of"illegal memory
access" errors until I figured out that the Unicode string needed to be
DWORD aligned.

> and you haven't done something silly like set the
> OBJ_KERNEL_HANDLE flag!

I always tend to start as simple as I can, and in this case have only used
OBJ_CASE_INSENSITIVE flag. No SecurityDescriptor, no
SecurityQualityOfService (currently no idea what that last one does).


Although with KEY_QUERY_VALUE | KEY_ENUMERATE_SUBTREE I can now reach most
of the "\Registry" tree, some, like "SAM" still throw an "access denied".
One particular key, "HKLM\Software\microsoft\Windows
NT\CurrentVersion\perflib\009" (in XPsp3), throws an "invalid handle" when I
try to open it (no problem looking at it with RegEdit though).

Regards,
Rudy Wieser


-- Origional message
Ant <n...@home.today> schreef in berichtnieuws
b4udncua2-FTDn_O...@brightview.co.uk...

Ant

unread,
Aug 8, 2014, 7:44:15 AM8/8/14
to
"R.Wieser" wrote:

>> I've never understood why ntdll needs to export both sets of names.
>
> Most likely backwards compatibility to a time where those functions where
> actually (a bit) different. Quite likely a remnant from when they merged
> their OS streams (Windows NT and ... forgot which other one. Win2000 ?).

Windows 2000 was just the next version of NT (NT 5) and no change in
Nt/Zw functionality happened here. Are you thinking of Win9x/WinME?
These weren't so much merged as discarded. They have nothing in common
with NT4+ apart from the GUI look and feel. I don't think they ever
had Zw* routines and certainly not Nt* ones.

>> I presume you have set up the OBJECT_ATTRIBUTES structure
>> correctly since you're not getting messages like "invalid parameter".
>
> Now ? It looks like it. But I was pestered with a number of"illegal memory
> access" errors until I figured out that the Unicode string needed to be
> DWORD aligned.

When programming with the native API the Rtl* support routines can be
helpful. I've always used RtlInitUnicodeString() to set the string and
haven't had alignment problems.

> Although with KEY_QUERY_VALUE | KEY_ENUMERATE_SUBTREE I can now reach most
> of the "\Registry" tree, some, like "SAM" still throw an "access denied".

The keys in SAM require system privilege.

> One particular key, "HKLM\Software\microsoft\Windows
> NT\CurrentVersion\perflib\009" (in XPsp3), throws an "invalid handle" when I
> try to open it (no problem looking at it with RegEdit though).

I can't explain that.


R.Wieser

unread,
Aug 8, 2014, 8:56:09 AM8/8/14
to
Hello Ant,

> Are you thinking of Win9x/WinME?

:-) As I said, I forgot which one it was. But I'm quite certain about that
merging somewhere.

> When programming with the native API the Rtl* support routines
> can be helpful. I've always used RtlInitUnicodeString() to set the
> string and haven't had alignment problems.

Yep, found those too. And that one was exactly the one which created the
problem. It just copies the offered string-pointer and do some length
determining and storing, and does not throw any error on un-aligned strings.
Those only popped-up when trying to use the result with NtOpenKey. :-\

> The keys in SAM require system privilege.

Any idea how I, as a mere user on my computer, can do that ? How do I get
such a rights elevation ?

As for that matter, why do I, when using the registry-browsing program, get
those elevated rights by default. That does not really make sense to me ...

> I can't explain that.

Neither can I. Maybe I will bump into the answer and simply slap my head
because I made a mistake somewhere ....

Regards,
Rudy Wieser


-- Origional message:
Ant <n...@home.today> schreef in berichtnieuws
xPmdnXK99LbwJXnO...@brightview.co.uk...

Geoff

unread,
Aug 8, 2014, 12:08:13 PM8/8/14
to
On Fri, 8 Aug 2014 14:56:09 +0200, "R.Wieser" <add...@not.available>
wrote:

>> The keys in SAM require system privilege.
>
>Any idea how I, as a mere user on my computer, can do that ? How do I get
>such a rights elevation ?

You have to ID the process and ask the system to elevate the process
privilege level.

Regedit uses:

GetCurrentProcess
OpenProcessToken
LookupPrivilegeValue
AdjustTokenPrivileges

LookupAccountSid
InitializeAcl
GetSecurityInfo
InitializeSecurityDescriptor

RegOpenKeyEx
RegQueryValueEx
RegCloseKey

Regedit does not use any Nt* or Zw* functions and I still don't see
the point of restricting yourself to using them.

When the user isn't Administrator on Windows 7 the system prompts for
elevation. Behavior should be the same on XP but it's been so long I
don't remember what XP does.

P.S. I'm looking at x64 process on Windows 7 Pro, 64 bit.

R.Wieser

unread,
Aug 8, 2014, 8:56:34 PM8/8/14
to
Hello Geoff,

> You have to ID the process and ask the system to elevate the
> process privilege level.

Yep, thats what I figured too. Though I must say that I find it odd that a
process can elevate *itself* by using a few DLL functions (how is this *not*
abused ?)

Also, I hoped to se a link (or two) to some standard code, instead of me
trying to re-invent the proverbial wheel ....

> Regedit uses:

Thanks.

I will check those functions out. Though if I cannot find anything about
which arguments those functions need and/or how they are supposed to work
together only those function names alone won't help me much ...

> Regedit does not use any Nt* or Zw* functions and I still don't
> see the point of restricting yourself to using to using them.

Actually, regedit, or rather the Reg* functions it uses do. Those Reg*
functions are just skinny wrappers around the Nt* ones, to create a unified
Win32 interface.

As for you not seeing the point, how is that important to the answer ?

But as you are curious about it, the Reg* functions use zero-terminated
strings, while the Nt* functions use counted strings (for both the key names
and values). That means the Nt* functions can do some stuff the Reg*
functions cannot.

> When the user isn't Administrator on Windows 7 the system prompts
> for elevation. Behavior should be the same on XP but it's been so
> long I don't remember what XP does.

In my case regedit is able to show more content than the Reg* or Nt*
functions I've been using in my programs, which I find odd -- regedit does
show any "please elevate me" prompt.

Regards,
Rudy Wieser


-- Origional message:
Geoff <ge...@invalid.invalid> schreef in berichtnieuws
vio9u9ppd6lh35cai...@4ax.com...

Geoff

unread,
Aug 9, 2014, 2:36:35 AM8/9/14
to
On Sat, 9 Aug 2014 02:56:34 +0200, "R.Wieser" <add...@not.available>
wrote:

>Hello Geoff,
>
>> You have to ID the process and ask the system to elevate the
>> process privilege level.
>
>Yep, thats what I figured too. Though I must say that I find it odd that a
>process can elevate *itself* by using a few DLL functions (how is this *not*
>abused ?)

A process inherits the context of the user that launched it. A process
can't elevate itself but it can _ask_ to be elevated. If that user is
administrator the elevation is automatic and transparent, which is why
logging in as administrator and operating a Windows computer as
administrator is so hazardous. So, yes, processes may and often do
elevate themselves by simply doing so.

A bit of history:

Originally, in NT 4.0 and successors up to the Vista/XP era,
installations of Windows created the first account as Administrator,
which is equivalent to Linux "root". It didn't matter what the user
name was, it was in the Administrator's group and therefore it was
every bit an administrator as the account with the "Administrator"
login name.

The intent was that the owner would create a new account for himself
in the ordinary Users group and operate the computer from that login.
Unfortunately, NT didn't have a mechanism for easily transitioning
from User to Administrator rank and back again the way Unix/Linux
does, you can't type "sudo someprog", give the root password and
execute that process as root and go back about your business as
ordinary user again. You had to ctrl-alt-del, log out, log in, do
something in the new session, log out, log in. Tedious.

So everybody running Windows NT got used to running as administrator
and so did every program written for Windows NT, scribbling files all
over their home directories, into the %systemroot% and whatever.

Microsoft learned their lessons and eventually Windows XP and Windows
7 came along and did a better job of trying to lock things down.
Windows XP is still vulnerable to the lazy install problem described
above but Windows 7 manages to lock down "ordinary users" and even
administrators in some aspects but they can still elevate in the style
of sudo at the click of a mouse button. This is the origin of the
"User Account Control" dialog that pops up when RegEdit asks for
elevated privileges on Windows 7.

>
>Also, I hoped to se a link (or two) to some standard code, instead of me
>trying to re-invent the proverbial wheel ....
>

I can't help you there, I haven't quite delved into it enough to be
authoritative.

>> Regedit uses:
>
>Thanks.
>
>I will check those functions out. Though if I cannot find anything about
>which arguments those functions need and/or how they are supposed to work
>together only those function names alone won't help me much ...
>
>> Regedit does not use any Nt* or Zw* functions and I still don't
>> see the point of restricting yourself to using to using them.
>
>Actually, regedit, or rather the Reg* functions it uses do. Those Reg*
>functions are just skinny wrappers around the Nt* ones, to create a unified
>Win32 interface.
>

Well, yes and no, as you have described below. Regedit may ultimately
get down into those Nt* functions but it doesn't get there directly.
It does use the Reg* functions directly and it seems to know what it's
doing.

>As for you not seeing the point, how is that important to the answer ?
>

It's not, it was just a comment.

>But as you are curious about it, the Reg* functions use zero-terminated
>strings, while the Nt* functions use counted strings (for both the key names
>and values). That means the Nt* functions can do some stuff the Reg*
>functions cannot.
>
>> When the user isn't Administrator on Windows 7 the system prompts
>> for elevation. Behavior should be the same on XP but it's been so
>> long I don't remember what XP does.
>
>In my case regedit is able to show more content than the Reg* or Nt*
>functions I've been using in my programs, which I find odd -- regedit does
>show any "please elevate me" prompt.
>

I'm not sure I understand that last sentence. I think there's a typo
and you're saying there isn't a prompt from the system about elevating
RegEdit's access level.

If you're logged in as a member of Administrators then there won't be
any restrictions on any process you initiate and "elevations" are
going to be automatically granted to those processes.

My guess, and this is only a guess, is that KEY_ALL_ACCESS isn't
adequate in some cases for some keys and RegEdit is doing something
different.

FWIW, I just tried writing a key onto my Win7 HKLM registry using a
process I wrote and ran as a member of Administrators in Visual
Studio's debugger and the create failed. This is code that used to
work just fine in XP. I did not attempt just reading a key.

0 new messages