Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results


Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging

The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.

Check out The OSR Learning Library at:


GoldLordGoldLord Member Posts: 3


I am developing a Windows Minifilter driver and I am trying to get the user's SID from the IO_SECURITY_CONTEXT structure in the PreCreate operation. I am aware that there is no way to directly get the SID from the IO_SECURITY_CONTEXT in other operations as the SID is only checked by the system on create operations.

I have tried multiple solutions in order to extract the SID_AND_ATTRIBUTES structure from the IO_SECURITY_CONTEXT structure. As for now I am trying the following:

  1. Get the token from SECURITY_SUBJECT_CONTEXT inside PACCESS_STATE inside IO_SECURITY_CONTEXT (SecurityContext->AccessState.SecuritySubjectContext). If the ClientToken is NULL, then I take the PrimaryToken.
  2. Call ObOpenObjectByPointer(AccessToken, OBJ_CASE_INSENSITIVE, NULL, TOKEN_QUERY, NULL, KernelMode, &TokenHandle); Where TokenHandle is a HANDLE.
  3. Call ZwQueryInformationToken to query for TokenUser with a NULL buffer in order to get the return length size.
  4. Allocate the buffer with the given size.
  5. Call ZwQueryInformationToken again with the newly allocated buffer. This should fill the buffer with a SID_AND_ATTRIBUTES structure.
  6. Call ZwClose on the TokenHandle.

The problem is that on step 2, calling ObOpenObjectByPointer generates a 00000000c0000005 access violation.

An exception happened while executing a system service routine.
Arg1: 00000000c0000005, Exception code that caused the bugcheck
Arg2: fffff8047d518d62, Address of the instruction which caused the bugcheck
Arg3: fffffe87a08ad8a0, Address of the context record for the exception that caused the bugcheck
Arg4: 0000000000000000, zero.

I have checked the contents of the SECURITY_SUBJECT_CONTEXT using the command kp and I can see the following token pointers inside this structure:

(*((<REDACTED>!_SECURITY_SUBJECT_CONTEXT *)0xffffb30e4656b900))                 [Type: _SECURITY_SUBJECT_CONTEXT]
    [+0x000] ClientToken      : 0x3066744e03030000 [Type: void *]
    [+0x008] ImpersonationLevel : SecurityAnonymous (0) [Type: _SECURITY_IMPERSONATION_LEVEL]
    [+0x010] PrimaryToken     : 0xffffb30e458aa460 [Type: void *]
    [+0x018] ProcessAuditId   : 0xffffb30e466cd448 [Type: void *]

Now I check the data on both of the memory addresses (ClientToken and PrimaryToken) using the db command and I get lots of question marks, I guess that means that memory is not accessible by the driver?

3066744e`03030000  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????
3066744e`03030010  ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ??  ????????????????

Sometimes the PrimaryToken pointer will point to access data, but sometimes both (Client and Primary) will point to inaccessible data.

I basically want to get the SID in order to pass it as a string representation to one of my user mode modules. Despite following all kinds of posts on this and other forums I have been unable to get the SID_AND_ATTRIBUTES from the SECURITY_CONTEXT in PreCreate. I have now been stuck for several weeks with this problem.

How may I solve this problem? What am I doing wrong? Any help is really appreciated.


  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,266

    During create processing you are guaranteed to be in the correct security context, so you don't need to look at the IRP, just interrogate the current thread.

  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,678

    That client token address is bogus. Looks like the start of a pool block instead of a valid pointer:

    0: kd> .formats 0x3066744e03030000 
    Evaluate expression:
      Chars:   0ftN....

    So, you're grabbing the wrong pointer somehow (or you're looking at freed memory). I recently posted a working example here if you want to try that.


  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,678

    @rod_widdowson said:
    During create processing you are guaranteed to be in the correct security context, so you don't need to look at the IRP, just interrogate the current thread.

    A minifilter above you could post the create to another thread before sending it down. Not common but it works (the file systems use the token in the IRP so they "just work")


  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,266

    A minifilter above you could post the create to another thread before sending it down

    Yes, but they are obliged to handle the security by impersonating (otherwise the FSD would complain when it did security checks).

  • GoldLordGoldLord Member Posts: 3

    Thanks for your responses! I will try out the working example provided by Scott and will let you know if it worked.

  • rod_widdowsonrod_widdowson Member - All Emails Posts: 1,266

    Of course as I my comment becomes uneditable I realise that the FSD should be looking at the SecurityContext as well (not the thread context) - in my experience this isn't always the case.... So whenever I post a create I also impersonate - but I'd agree that the architecture means you shouldn't have to.

  • GoldLordGoldLord Member Posts: 3

    Scott's code worked like a charm! It was very similar to one of the first I tried to use. The only difference was that I was not calling SeLockSubjectContext before using the SeQuerySubjectContextToken macro.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 13-17 May 2024 Live, Online
Developing Minifilters 1-5 Apr 2024 Live, Online
Internals & Software Drivers 11-15 Mar 2024 Live, Online
Writing WDF Drivers 20-24 May 2024 Live, Online