NtQuerySystemInformation #SystemProcessIdInformation

Just starting out? Need help? Post your questions and find answers here.
User avatar
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: NtQuerySystemInformation #SystemProcessIdInformation

Post 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
Last edited by JHPJHP on Wed Apr 09, 2014 3:44 am, edited 3 times in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: NtQuerySystemInformation #SystemProcessIdInformation

Post 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.
Last edited by Thunder93 on Tue Apr 08, 2014 11:22 pm, edited 1 time in total.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
JHPJHP
Addict
Addict
Posts: 2257
Joined: Sat Oct 09, 2010 3:47 am

Re: NtQuerySystemInformation #SystemProcessIdInformation

Post by JHPJHP »

Works here on Windows 7 64bit - nice job Thunder93.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: NtQuerySystemInformation #SystemProcessIdInformation

Post by Thunder93 »

Thanks JHPJHP.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: NtQuerySystemInformation #SystemProcessIdInformation

Post by Thunder93 »

I should have used #MAX_PATH as a starting point. :|
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Thunder93
Addict
Addict
Posts: 1788
Joined: Tue Mar 21, 2006 12:31 am
Location: Canada

Re: NtQuerySystemInformation #SystemProcessIdInformation

Post 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.
ʽʽSuccess is almost totally dependent upon drive and persistence. The extra energy required to make another effort or try another approach is the secret of winning.ʾʾ --Dennis Waitley
User avatar
Teddy Rogers
User
User
Posts: 98
Joined: Sun Feb 23, 2014 2:05 am
Location: Australia
Contact:

Re: NtQuerySystemInformation #SystemProcessIdInformation

Post 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.
Post Reply