Click here to Skip to main content
Click here to Skip to main content

User SID of thread in kernel driver

By , 26 Mar 2013
 

Introduction

From theory, the request to kernel driver from user space application is handled in the user application thread. Cool, so there should be SID associated... To get SID in user space application is about two lines, but how to do we do it in kernel? Is it possible? Yep it is, and here comes code snippet, which can save you a substantial quantum of reading...

Using the code

The first function GetCurrentThreadSid obtains SID in binary form into newly allocated pooled memory (free it with call to ExFreePoolWithTag). GetCurrentThreadUnicodeStringSid converts binary SID into UTF16 textual form. GetCurrentThreadStringSid converts UTF16 to ANSII. 

#include <ntddk.h>
#include <ntifs.h>

NTSTATUS GetCurrentThreadSid(OUT PISID *pSid);
NTSTATUS GetCurrentThreadStringSid(OUT UCHAR **pStringSid, ULONG *pSidLen);
NTSTATUS GetCurrentThreadUnicodeStringSid(OUT PUNICODE_STRING pStringSid);

#pragma alloc_text("PAGED_CODE", GetCurrentThreadSid)
#pragma alloc_text("PAGED_CODE", GetCurrentThreadStringSid)
#pragma alloc_text("PAGED_CODE", GetCurrentThreadUnicodeStringSid)

NTSTATUS GetCurrentThreadSid(OUT PISID *pSid)
{
    NTSTATUS ret=STATUS_UNSUCCESSFUL;
    PTOKEN_USER user=NULL;
    ULONG nTokenInfo=0;
    HANDLE hToken=NULL;
    ULONG nSidLen=0;
    PAGED_CODE()
    if(!pSid)
        return STATUS_INVALID_PARAMETER;
    ret=ZwOpenThreadTokenEx( ZwCurrentThread(), GENERIC_READ, TRUE, OBJ_KERNEL_HANDLE , &hToken);
    if(ret!=STATUS_SUCCESS)
    {
        ret=ZwOpenProcessTokenEx(ZwCurrentProcess() ,GENERIC_READ, OBJ_KERNEL_HANDLE , &hToken);
        if(!hToken)
            goto cleanup;
    }
    ret=ZwQueryInformationToken(hToken,TokenUser ,NULL, 0, &nTokenInfo);
    if(ret!=STATUS_BUFFER_TOO_SMALL)
        goto cleanup;
    user=(PTOKEN_USER)ExAllocatePoolWithTag(PagedPool, nTokenInfo, 'N000');
    if(!user)
    {
        ret=STATUS_NO_MEMORY;
        goto cleanup;
    }
    ret=ZwQueryInformationToken(hToken,TokenUser ,user, nTokenInfo, &nTokenInfo);
    if(ret!=STATUS_SUCCESS)
        goto cleanup;
    if(!RtlValidSid(user->User.Sid))
    {
        ret=STATUS_UNSUCCESSFUL;
        goto cleanup;
    }
    nSidLen=RtlLengthSid(user->User.Sid);
    *pSid=(PISID)ExAllocatePoolWithTag(PagedPool, nSidLen, 'N000');
    if(!*pSid)
    {
        ret=STATUS_NO_MEMORY;
        goto cleanup;
    }
    RtlCopyMemory(*pSid,user->User.Sid,nSidLen);
    if(!RtlValidSid(*pSid))
    {
        ExFreePoolWithTag(*pSid, 'N000');
        *pSid=NULL;
        ret=STATUS_UNSUCCESSFUL;
        goto cleanup;
    }
    ret=STATUS_SUCCESS;
cleanup:
    if(user)
        ExFreePoolWithTag(user, 'N000');
    if(hToken)
	ZwClose(hToken);
    return ret;
}

NTSTATUS GetCurrentThreadUnicodeStringSid(OUT PUNICODE_STRING pStringSid)
{
    NTSTATUS ret=STATUS_UNSUCCESSFUL;
    PISID pSid=NULL;
    PAGED_CODE()

    if(!pStringSid)
        return STATUS_INVALID_PARAMETER;
    ret=GetCurrentThreadSid(&pSid);
    if(ret!=STATUS_SUCCESS)
        return ret;

    ret=RtlConvertSidToUnicodeString(pStringSid,pSid,TRUE);
    ExFreePoolWithTag(pSid, 'N000');
    return ret;
}

NTSTATUS GetCurrentThreadStringSid(OUT UCHAR **pStringSid, OUT ULONG *pSidLen)
{
    NTSTATUS ret=STATUS_UNSUCCESSFUL;
    UNICODE_STRING StringSid={0};
    ULONG i;
    ULONG charlen=0;
    PAGED_CODE()

    if(!pStringSid || !pSidLen)
        return STATUS_INVALID_PARAMETER;

    ret=GetCurrentThreadUnicodeStringSid(&StringSid);
    if(ret!=STATUS_SUCCESS)
        return ret;
    
    charlen=StringSid.Length/sizeof(WCHAR);

    *pStringSid=ExAllocatePoolWithTag(PagedPool, charlen+1,'N000');
    if(!*pStringSid)
    {
        ret=STATUS_NO_MEMORY;
        goto cleanup;
    }
    for(i=0;i<charlen;i++)
    {
        //SID is only ANSI characters...
        (*pStringSid)[i]=(UCHAR)StringSid.Buffer[i];
    }
    (*pStringSid)[charlen]=0;
    *pSidLen=charlen;
    ret=STATUS_SUCCESS;
cleanup:
    RtlFreeUnicodeString(&StringSid);
    return ret;
}

History  

Fixed hToken closing and string length in conversion from UTF16 to ANSI. Added zipped source codes.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

jan.mach71
Software Developer (Senior) Nexthink
Switzerland Switzerland
Member
Please have a look at http://cz.linkedin.com/pub/jan-mach/22/6b1/815/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130513.1 | Last Updated 26 Mar 2013
Article Copyright 2013 by jan.mach71
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid