none
How get pid of csrss.exe? RRS feed

  • Question

  • I have following code that promise return pid of csrss.exe, but this code is failing to open each process on line:

    if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid))) {

    #include <ntddk.h>
    #include "ntapi.h"
    
    #include <ntstrsafe.h>
    
    #pragma comment(lib, "ntstrsafe.lib")
    
    typedef struct _SYSTEM_HANDLE_INFORMATION_EX {
    	ULONG Count;
    	SYSTEM_HANDLE_INFORMATION Handle[1];
    }SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
    
    
    PSYSTEM_HANDLE_INFORMATION_EX GetSystemHandleInformation() {
    	PSYSTEM_HANDLE_INFORMATION_EX pSHInfo = NULL;
    	NTSTATUS Status = STATUS_NO_MEMORY;
    	ULONG SMInfoLen = 0x1000;
    	do {
    		pSHInfo = (PSYSTEM_HANDLE_INFORMATION_EX)ExAllocatePoolWithTag(PagedPool, SMInfoLen, 0);
    		if (!pSHInfo)
    			break;
    		Status = ZwQuerySystemInformation(SystemHandleInformation, pSHInfo, SMInfoLen, &SMInfoLen);
    		if (!NT_SUCCESS(Status)) {
    			ExFreePoolWithTag(pSHInfo, 0);
    			pSHInfo = NULL;
    		}
    	} while (Status == STATUS_INFO_LENGTH_MISMATCH);
    	return pSHInfo;
    }
    
    HANDLE GetCsrssPid() {
    	HANDLE CsrId = (HANDLE)0;
    	PSYSTEM_HANDLE_INFORMATION_EX pHandles = GetSystemHandleInformation();
    	if (pHandles) {
    		int i;
    		for (i = 0; i < pHandles->Count && !CsrId; i++) {
    			OBJECT_ATTRIBUTES obj; CLIENT_ID cid;
    			HANDLE Process, hObject;
    			InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
    			cid.UniqueProcess = (HANDLE)pHandles->Handle[i].ProcessId;
    			cid.UniqueThread = 0;
    			if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid))) {
    				DbgPrint("NtOpenProcess sucess!"); // this line never is executed. Why?
    				if (NT_SUCCESS(ZwDuplicateObject(Process, (PHANDLE)(pHandles->Handle[i].Handle), NtCurrentProcess(), &hObject, 0, FALSE, DUPLICATE_SAME_ACCESS))) {
    					UCHAR Buff[0x200];
    					POBJECT_NAME_INFORMATION ObjName = (POBJECT_NAME_INFORMATION)&Buff;
    					if (NT_SUCCESS(ZwQueryObject(hObject, ObjectTypeInformation, ObjName, sizeof(Buff), NULL))) {
    						if (ObjName->Name.Buffer && (!wcsncmp(L"Port", ObjName->Name.Buffer, 4) || !wcsncmp(L"ALPC Port", ObjName->Name.Buffer, 9))) {
    							if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, sizeof(Buff), NULL))) {
    								if (ObjName->Name.Buffer && !wcsncmp(L"\\\\Windows\\\\ApiPort", ObjName->Name.Buffer, 20))
    									CsrId = (HANDLE)pHandles->Handle[i].ProcessId;
    							}
    						}
    					}
    					ZwClose(hObject);
    				}
    				ZwClose(Process);
    			}
    		}
    		ExFreePoolWithTag(pHandles, 0);
    	}
    	return CsrId;
    }

    ntapi.h used => http://pastebin.com/QNR9ncha

    Someone have some idea why fails?







    • Edited by FLASHCODER Friday, January 20, 2017 6:12 PM
    Friday, January 20, 2017 2:43 AM

Answers

  • @Don Burn, i'm already solved this question!

    The error was the wrong declaration to PSYSTEM_PROCESS_INFORMATION

    The correct and that have worked for me is:

    typedef struct _SYSTEM_PROCESS_INFORMATION {
        ULONG NextEntryOffset;
        ULONG NumberOfThreads;
        LARGE_INTEGER Reserved[3];
        LARGE_INTEGER CreateTime;
        LARGE_INTEGER UserTime;
        LARGE_INTEGER KernelTime;
        UNICODE_STRING ImageName;
        KPRIORITY BasePriority;
        HANDLE UniqueProcessId;
        HANDLE InheritedFromUniqueProcessId;
        ULONG HandleCount;
        ULONG SessionId;
        ULONG PageDirectoryBase;
        VM_COUNTERS VirtualMemoryCounters;
        SIZE_T PrivatePageCount;
        IO_COUNTERS IoCounters;
      } SYSTEM_PROCESS_INFORMATION,*PSYSTEM_PROCESS_INFORMATION;
    

    Thank you very much by your attention.

    • Marked as answer by FLASHCODER Tuesday, January 24, 2017 1:45 AM
    Monday, January 23, 2017 9:16 PM

All replies

  • Well since the SystemHandleInformation option is undocumented this is likely to be a problem.  See https://msdn.microsoft.com/en-us/library/windows/desktop/ms725506(v=vs.85).aspx for what Microsoft considers safe and documented.   In general ZwQuerySystemInformation is a red flag to me, since while there has been plenty of websites that "document" the other options, most of these are based on a book written in the Windows NT4 / Windows 2000 era, and by the time the book was published the data was wrong.   

    This is the type of stuff that is better done with a user space service.  There is nothing gained by trying to get some of this information in the kernel, and it is guaranteed to cause you problems.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, January 20, 2017 12:11 PM
  • Really, not is a good idea use ZwQuerySystemInformation. Based on MSDN docs, i think that this api only is no more longer avaiable from of Windows 8 or higher.


    but i'm testing my driver on Windows 7 x86 and line below works fine!

    if (pHandles) {

    returns "true".

    My trouble is only with NtOpenProcess

    Friday, January 20, 2017 4:00 PM
  • Why are you using NtOpenProcess instead of ZwOpenProcess?  There are reasons to use ZwOpenProcess instead look at http://www.osronline.com/article.cfm?article=257


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, January 20, 2017 4:05 PM
  • Why are you using NtOpenProcess instead of ZwOpenProcess?  There are reasons to use ZwOpenProcess instead look at http://www.osronline.com/article.cfm?article=257


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    I tested, but unfortunately ZwOpenProcess not was the solution :-(

    Friday, January 20, 2017 6:10 PM
  • What is the status code that NtOpenProcess returns?  In general to debug kernel code it is better to do:

    status = NtOpenProcess(...)
    if ( NT_SUCCESS( status ) )
    {
        ...
    }

    With the above you can always add an else to print the status that is causing the failure.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, January 20, 2017 6:21 PM
  • Use %x then look it up in ntstatus.h


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, January 20, 2017 8:30 PM
  • @Don Burn,

    My test was like this:

    NTSTATUS ntStatus; ... ntStatus = ZwOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid); if ( NT_SUCCESS( ntStatus )) { ... } else { DbgPrint("0x%x\n", ntStatus);

    DbgPrint( ("[*] pid : %d\n ", cid.UniqueProcess) );   }

    ntStatus was: 0xC000000B => STATUS_INVALID_CID => An invalid client ID was specified.

    MSDN doc for NTSTATUS

    and cid.UniqueProcess returns diferents random numbers with eight digts like: 40370215


    • Edited by FLASHCODER Saturday, January 21, 2017 1:45 AM
    Friday, January 20, 2017 10:40 PM
  • @Don Burn,

    I have a new code but still not works.

    See:

    #include <ntddk.h>

    #include "ntapi.h"

    #include <ntstrsafe.h>

    #pragma comment(lib, "ntstrsafe.lib")

    #define echo(x) x #define label(x) echo(x)__LINE__ #define RTL_CONSTANT_STRINGW(s) { sizeof( s ) - sizeof( (s)[0] ), sizeof( s ),(PWSTR)(s) } #define STATIC_UNICODE_STRING(name, str) static const WCHAR label(__)[] = L##str; static const UNICODE_STRING name = RTL_CONSTANT_STRINGW(label(__))

    typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffsset;

    ULONG NumberOfThreads;

    HANDLE UniqueProcessId;

    UNICODE_STRING ImageName;

    }SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;


    NTSTATUS GetCsrssPid(HANDLE* pUniqueProcessId) { NTSTATUS status; ULONG cb = 0x10000; do { status = STATUS_INSUFFICIENT_RESOURCES; if (PVOID buf = ExAllocatePool(PagedPool, cb)) { if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &cb))) { status = STATUS_NOT_FOUND; union { PSYSTEM_PROCESS_INFORMATION pspi; PVOID pv; PUCHAR pb; }; pv = buf; ULONG NextEntryOffset = 0; do { pb += NextEntryOffset; STATIC_UNICODE_STRING(csrss, "csrss.exe"); if (pspi->UniqueProcessId) DbgPrint("%p %wZ\n", pspi->UniqueProcessId, &pspi->ImageName); if (RtlEqualUnicodeString(&csrss, &pspi->ImageName, TRUE)) { ///////// This part never is executed /////// *pUniqueProcessId = pspi->UniqueProcessId; DbgPrint("%p\n", *pUniqueProcessId); status = STATUS_SUCCESS; break; //////////////////////////////////////////// } } while (NextEntryOffset = pspi->NextEntryOffset); } ExFreePool(buf); } } while (status == STATUS_INFO_LENGTH_MISMATCH); return status; }

    Usage:

    HANDLE hCsrssPid = (HANDLE)0;
    GetCsrssPid(&hCsrssPid);

    What's error that have this code?




    • Edited by FLASHCODER Tuesday, January 24, 2017 1:46 AM
    Monday, January 23, 2017 1:46 AM
  • Well as I have pointed out multiple times, ZwQuerySystemInformation is not really documented, and keeps changing.  Under any circumstances the last Microsoft documentation in this area https://msdn.microsoft.com/en-us/library/windows/desktop/ms725506(v=vs.85).aspx shows a very different structure than you are using.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Monday, January 23, 2017 6:59 PM
  • Hi FlashCoder

    I can see you have a problem with 'union': See https://msdn.microsoft.com/en-us/library/5dxy4b7b.aspx

    Regards

    Chong



    Monday, January 23, 2017 9:04 PM
  • @Don Burn, i'm already solved this question!

    The error was the wrong declaration to PSYSTEM_PROCESS_INFORMATION

    The correct and that have worked for me is:

    typedef struct _SYSTEM_PROCESS_INFORMATION {
        ULONG NextEntryOffset;
        ULONG NumberOfThreads;
        LARGE_INTEGER Reserved[3];
        LARGE_INTEGER CreateTime;
        LARGE_INTEGER UserTime;
        LARGE_INTEGER KernelTime;
        UNICODE_STRING ImageName;
        KPRIORITY BasePriority;
        HANDLE UniqueProcessId;
        HANDLE InheritedFromUniqueProcessId;
        ULONG HandleCount;
        ULONG SessionId;
        ULONG PageDirectoryBase;
        VM_COUNTERS VirtualMemoryCounters;
        SIZE_T PrivatePageCount;
        IO_COUNTERS IoCounters;
      } SYSTEM_PROCESS_INFORMATION,*PSYSTEM_PROCESS_INFORMATION;
    

    Thank you very much by your attention.

    • Marked as answer by FLASHCODER Tuesday, January 24, 2017 1:45 AM
    Monday, January 23, 2017 9:16 PM