Page 2 of 2

Re: NtQuerySystemInformation #SystemProcessIdInformation

Posted: Tue Apr 08, 2014 10:19 pm
by JHPJHP
So much documentation on the subject - each with a different declaration; this is what I have so far:

Code: Select all

Structure UNICODE_STRING Align #PB_Structure_AlignC
  Length.w
  MaximumLength.w
  Buffer.i
EndStructure

Structure VM_COUNTERS Align #PB_Structure_AlignC
  PeakVirtualSize.l
  VirtualSize.l
  PageFaultCount.l
  PeakWorkingSetSize.l
  WorkingSetSize.l
  QuotaPeakPagedPoolUsage.l
  QuotaPagedPoolUsage.l
  QuotaPeakNonPagedPoolUsage.l
  QuotaNonPagedPoolUsage.l
  PagefileUsage.l
  PeakPagefileUsage.l
EndStructure

Structure IO_COUNTERS Align #PB_Structure_AlignC
  ReadOperationCount.LARGE_INTEGER
  WriteOperationCount.LARGE_INTEGER
  OtherOperationCount.LARGE_INTEGER
  ReadTransferCount.LARGE_INTEGER
  WriteTransferCount.LARGE_INTEGER
  OtherTransferCount.LARGE_INTEGER
EndStructure

Structure SYSTEM_THREAD Align #PB_Structure_AlignC
  KernelTime.LARGE_INTEGER
  UserTime.LARGE_INTEGER
  CreateTime.LARGE_INTEGER
  WaitTime.l
  StartAddress.l
  UniqueProcess.l
  UniqueThread.l
  Priority.l
  BasePriority.l
  ContextSwitchCount.l
  State.l
  WaitReason.l
  Reserved1.l
EndStructure

Structure SYSTEM_PROCESS_INFORMATION Align #PB_Structure_AlignC
  NextEntryOffset.l
  NumberOfThreads.l
  Reserved1.LARGE_INTEGER[3]
  CreateTime.LARGE_INTEGER
  UserTime.LARGE_INTEGER
  KernelTime.LARGE_INTEGER
  ModuleName.UNICODE_STRING
  BasePriority.l
  ProcessID.i
  InheritedFromProcessId.l
  HandleCount.l
  Reserved2.l[2]
  VirtualMemoryCounters.VM_COUNTERS
  PrivatePageCount.l
  IOCounters.IO_COUNTERS
  ThreadInfo.SYSTEM_THREAD[1]
EndStructure

#SystemProcessInformation = 5
NtQuerySystemInformation_(#SystemProcessInformation, #Null, 0, @ReturnLength)
*spi.SYSTEM_PROCESS_INFORMATION
*spi = AllocateMemory(ReturnLength)
NtQuerySystemInformation_(#SystemProcessInformation, *spi, ReturnLength, #Null)
*spi\ModuleName\Buffer = AllocateMemory(#MAX_PATH)

While *spi\NextEntryOffset
  Debug Str(*spi\ProcessId) + " | " + PeekS(*spi\ModuleName\Buffer, *spi\ModuleName\Length, #PB_Unicode)
  *spi + *spi\NextEntryOffset
Wend

Re: NtQuerySystemInformation #SystemProcessIdInformation

Posted: Tue Apr 08, 2014 10:42 pm
by Thunder93
This is how its done.... :wink:

Code: Select all

Procedure.s GetProcessImageFileName(pID.l)
  Protected ProcessID
  
  #SystemProcessIdInformation = 88
  #STATUS_INFO_LENGTH_MISMATCH = $C0000004
  
  Structure UNICODE_STRING Align #PB_Structure_AlignC
    Length.w
    MaximumLength.w
    Buffer.i
  EndStructure
  
  Structure ProcessFileName
    ProcessId.i
    ImageName.UNICODE_STRING
  EndStructure
  
  Protected processIdInfo.ProcessFileName
  
  
  *uBuffer = AllocateMemory(256)
  processIdInfo\ProcessId = pID
  processIdInfo\ImageName\Length = 0
  processIdInfo\ImageName\MaximumLength = 256
  processIdInfo\ImageName\Buffer = *uBuffer
  
  ;         Status = CallFunctionFast(NtQuerySystemInformation, #SystemProcessIdInformation, @processIdInfo, SizeOf(processIdInfo), #Null)
  Status = NtQuerySystemInformation_(#SystemProcessIdInformation, @processIdInfo, SizeOf(processIdInfo), #Null)
  Debug Status
  
  If Status = #STATUS_INFO_LENGTH_MISMATCH    
    ;// Our buffer was too small. The required buffer length is stored in MaximumLength.
    Debug "Increasing Buffer"
    ReAllocateMemory(*uBuffer, processIdInfo\ImageName\MaximumLength)
    processIdInfo\ImageName\Buffer = *uBuffer
    Status = NtQuerySystemInformation_(#SystemProcessIdInformation, @processIdInfo, SizeOf(processIdInfo), #Null)
  EndIf
  
  If Not Status
    FileName$ = PeekS(processIdInfo\ImageName\Buffer, -1, #PB_Unicode)
    Debug "File: "+FileName$
  EndIf 
  
  If *uBuffer : FreeMemory(*uBuffer) : EndIf
  ProcedureReturn GetFilePart(FileName$)
EndProcedure

Debug GetProcessImageFileName(3516)
Update 3516 to the process-id shown in TaskManager that you want info about.

Re: NtQuerySystemInformation #SystemProcessIdInformation

Posted: Tue Apr 08, 2014 11:21 pm
by JHPJHP
Works here on Windows 7 64bit - nice job Thunder93.

Re: NtQuerySystemInformation #SystemProcessIdInformation

Posted: Tue Apr 08, 2014 11:23 pm
by Thunder93
Thanks JHPJHP.

Re: NtQuerySystemInformation #SystemProcessIdInformation

Posted: Tue Apr 08, 2014 11:38 pm
by Thunder93
I should have used #MAX_PATH as a starting point. :|

Re: NtQuerySystemInformation #SystemProcessIdInformation

Posted: Wed Apr 09, 2014 1:55 am
by Thunder93
JHPJHP.. you still need to change the ProcessID type from .l to .i in the structure SYSTEM_PROCESS_INFORMATION. Right now when compiling your code via x64, the ProcessID is always returning zeros.

Re: NtQuerySystemInformation #SystemProcessIdInformation

Posted: Fri Apr 11, 2014 10:00 am
by Teddy Rogers
Sorry for the late reply, again been busy with work and other things and not had any time to revisit this. Thunder93, thank you for the code! Works very well and thanks for the help in getting the PB structure correct, I will peruse your code properly when I get some time at the weekend as I would like to understand better.

I just quickly wanted to say that I added this to your code to change the image mapping path to a real path. All the code does is generate a drive name by cycling through the letters of the alphabet then queries QueryDosDevice to get the mapping path. It then tries to find that path in the result generated from NtQuerySystemInformation. If it matches then it replaces that string with the drive letter. We have the real path.

Code: Select all

  If Not Status
    FileName$ = PeekS(processIdInfo\ImageName\Buffer, -1, #PB_Unicode)
    TargetPath = AllocateMemory(#MAX_PATH)
  
    For Num = 65 To 90
      QueryDosDevice_((Chr(Num)+":"), TargetPath, #MAX_PATH)
      Peek$ = PeekS(TargetPath)
      If FindString(FileName$, Peek$)
        FileName$ = ReplaceString(FileName$, Peek$, (Chr(Num)+":"))
        ;Debug FileName$
        Break
      EndIf
    Next Num

    FreeMemory(TargetPath)
    
  EndIf
Thank you to JHPJHP who helped me out and posted sample code, it is appreciated!

Ted.