CmdLine from Process (API)

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

CmdLine from Process (API)

Post by JHPJHP »

I removed my last post concerning this because it was way off the mark, but I managed to get this working... somewhat.

*** Great work on the SDK ToniPB ***
Structures from: https://github.com/ToniPB/PureBasic_Win ... /ntdll.pbi

The following script works on a 32bit process, but not (yet) on a 64bit process, but maybe someone here already has a fix?

I believe it has to do with the PROCESS_BASIC_INFORMATION structure, and possibly Offset's:

Debugging the GetPBI(hProcess) procedure you see that pbi\PebBaseAddress returns 0 for 64bit process'.

Code: Select all

Prototype.b protoIsWow64Process(hProcess, Wow64Process.b)
Global IsWow64Process.protoIsWow64Process

Structure UNICODE_STRING
  Length.w
  MaximumLength.w
  Buffer.i
EndStructure

Structure RTL_DRIVE_LETTER_CURDIR
  Flags.w
  Length.w
  TimeStamp.l
  DosPath.UNICODE_STRING
EndStructure

Structure RTL_USER_PROCESS_PARAMETERS
  MaximumLength.l
  Length.l
  Flags.l
  DebugFlags.l
  ConsoleHandle.i
  ConsoleFlags.i
  StdInputHandle.i
  StdOutputHandle.i
  StdErrorHandle.i
  CurrentDirectoryPath.UNICODE_STRING
  CurrentDirectoryHandle.i
  DllPath.UNICODE_STRING
  ImagePathName.UNICODE_STRING
  CommandLine.UNICODE_STRING
  Environment.i
  StartingPositionLeft.l
  StartingPositionTop.l
  Width.l
  Height.l
  CharWidth.l
  CharHeight.l
  ConsoleTextAttributes.l
  WindowFlags.l
  ShowWindowFlags.l
  WindowTitle.UNICODE_STRING
  DesktopName.UNICODE_STRING
  ShellInfo.UNICODE_STRING
  RuntimeData.UNICODE_STRING
  DLCurrentDirectory.RTL_DRIVE_LETTER_CURDIR[$20]
EndStructure

Structure PEB
  InheritedAddressSpace.b
  ReadImageFileExecOptions.b
  BeingDebugged.b
  Spare.b
  Mutant.i
  ImageBaseAddress.i
  *LoaderData.PEB_LDR_DATA
  *ProcessParameters.RTL_USER_PROCESS_PARAMETERS
  SubSystemData.i
  ProcessHeap.i
  FastPebLock.i
  *FastPebLockRoutine.PEBLOCKROUTINE
  *FastPebUnlockRoutine.PEBLOCKROUTINE
  EnvironmentUpdateCount.l
  KernelCallbackTable.i
  EventLogSection.i
  EventLog.i
  *FreeList.PEB_FREE_BLOCK
  TlsExpansionCounter.l
  TlsBitmap.i
  TlsBitmapBits.l[$2]
  ReadOnlySharedMemoryBase.i
  ReadOnlySharedMemoryHeap.i
  ReadOnlyStaticServerData.i
  AnsiCodePageData.i
  OemCodePageData.i
  UnicodeCaseTableData.i
  NumberOfProcessors.l
  NtGlobalFlag.l
  Spare2.b[$4]
  CriticalSectionTimeout.LARGE_INTEGER
  HeapSegmentReserve.l
  HeapSegmentCommit.l
  HeapDeCommitTotalFreeThreshold.l
  HeapDeCommitFreeBlockThreshold.l
  NumberOfHeaps.l
  MaximumNumberOfHeaps.l
  ProcessHeaps.i
  GdiSharedHandleTable.i
  ProcessStarterHelper.i
  GdiDCAttributeList.i
  LoaderLock.i
  OSMajorVersion.l
  OSMinorVersion.l
  OSBuildNumber.l
  OSPlatformId.l
  ImageSubsystem.l
  ImageSubSystemMajorVersion.l
  ImageSubSystemMinorVersion.l
  GdiHandleBuffer.l[$22]
  PostProcessInitRoutine.l
  TlsExpansionBitmap.l
  TlsExpansionBitmapBits.b[$80]
  SessionId.l
EndStructure

Structure PROCESS_BASIC_INFORMATION
  ExitStatus.i
  *PebBaseAddress.PEB
  AffinityMask.i
  BasePriority.i
  UniqueProcessId.i
  InheritedFromUniqueProcessId.i
EndStructure

Procedure ShowError()
  dwMessageId = GetLastError_()

  If dwMessageId
    *lpBuffer = AllocateMemory(255)
    FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, #Null, dwMessageId, #Null, *lpBuffer, MemorySize(*lpBuffer), #Null)
    Debug "-- Error: " + Str(dwMessageId) + " - " + PeekS(*lpBuffer)
    FreeMemory(*lpBuffer)
  EndIf
EndProcedure

Procedure.b AdjustProcessPrivilege()
  Protected Result.b = #False

  If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @TokenHandle)
    lpLuid.LUID

    If LookupPrivilegeValue_(#Null, #SE_DEBUG_NAME, @lpLuid)
      NewState.TOKEN_PRIVILEGES

      With NewState
        \PrivilegeCount = 1
        \Privileges[0]\Luid\LowPart = lpLuid\LowPart
        \Privileges[0]\Luid\HighPart = lpLuid\HighPart
        \Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
      EndWith
      Result = AdjustTokenPrivileges_(TokenHandle, #False, @NewState, SizeOf(TOKEN_PRIVILEGES), @PreviousState.TOKEN_PRIVILEGES, @ReturnLength)
    EndIf
    CloseHandle_(TokenHandle)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetPBI(hProcess)
  Protected Result = #Null
  #ProcessBasicInformation = 0
  Protected pbi.PROCESS_BASIC_INFORMATION

  If Not NtQueryInformationProcess_(hProcess, #ProcessBasicInformation, @pbi, SizeOf(pbi), @ReturnLength)
    If pbi\PebBaseAddress
      Result = pbi\PebBaseAddress
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetPEB(hProcess, PebBaseAddress, OffSet)
  Protected Result = #Null
  Protected peb.PEB

  If ReadProcessMemory_(hProcess, PebBaseAddress + OffSet, @peb, SizeOf(PEB), #Null)
    If peb\ProcessParameters
      Result = peb\ProcessParameters
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure.s GetCMD(hProcess, ProcessParameters, OffSet)
  Protected Result.s = ""
  Protected rtl.RTL_USER_PROCESS_PARAMETERS

  If ReadProcessMemory_(hProcess, ProcessParameters + OffSet, @rtl, SizeOf(rtl), #Null)
    If rtl\CommandLine\Buffer
      *CmdLine = AllocateMemory(rtl\CommandLine\MaximumLength)

      If ReadProcessMemory_(hProcess, rtl\CommandLine\Buffer, *CmdLine, rtl\CommandLine\MaximumLength, #Null)
        Result = PeekS(*CmdLine, rtl\CommandLine\MaximumLength, #PB_Unicode)
      EndIf
      FreeMemory(*CmdLine)
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetProcessList()
  hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, #Null)

  If hSnapshot
    ProcEntry.PROCESSENTRY32
    ProcEntry\dwSize = SizeOf(PROCESSENTRY32)

    If Process32First_(hSnapshot, @ProcEntry)
      While Process32Next_(hSnapshot, @ProcEntry)
        AdjustProcessPrivilege()
        dwProcessId = ProcEntry\th32ProcessID
        hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, dwProcessId)

        If hProcess
          kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")

          If IsLibrary(kernel32)
            IsWow64Process = GetFunction(kernel32, "IsWow64Process")
            IsWow64Process(hProcess, @Wow64Process)
            CloseLibrary(kernel32)
          EndIf
          Protected pbi.PROCESS_BASIC_INFORMATION
          pbi\PebBaseAddress = GetPBI(hProcess)

;          If Wow64Process : OffSet = 0 : Else : OffSet = OffsetOf(PROCESS_BASIC_INFORMATION\PebBaseAddress) : EndIf

          Protected peb.PEB
          peb\ProcessParameters = GetPEB(hProcess, pbi\PebBaseAddress, OffSet)

;          If Wow64Process : OffSet = 0 : Else : OffSet = OffsetOf(RTL_USER_PROCESS_PARAMETERS\CommandLine) : EndIf

          CommandLine.s = GetCMD(hProcess, peb\ProcessParameters, OffSet)

          If CommandLine : Debug CommandLine : Else : ShowError() : EndIf

          CloseHandle_(hProcess)
        EndIf
      Wend
    EndIf
    CloseHandle_(hSnapshot)
  EndIf
EndProcedure
GetProcessList()
Last edited by JHPJHP on Fri Aug 02, 2013 3:04 pm, 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
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: CmdLine from Process (API)

Post by em_uk »

Great work - Can't get it to work here though - I have Droopy lib which already has a IsWow64Process proc.

I tried to changed the prototype but was thrown an error. I am on x64 anyway.
----

R Tape loading error, 0:1
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: CmdLine from Process (API)

Post by JHPJHP »

Thanks for trying em_uk,

- I tested it on Windows 7 64bit, and thats where the "299" error occurs on the 64bit process'.
- I just tested it on Windows XP 32bit, without error.

*** I removed a remnant of code from the above script... left over from previous tests (I was closing the Library twice). ***
Last edited by JHPJHP on Fri Aug 02, 2013 6:33 am, edited 1 time 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.
LuCiFeR[SD]
666
666
Posts: 1033
Joined: Mon Sep 01, 2003 2:33 pm

Re: CmdLine from Process (API)

Post by LuCiFeR[SD] »

This works for me on 64bit windows 7 PB 5.20 Beta 8

Code: Select all

Prototype.b protoIsWow64Process(hProcess, Wow64Process.b)
Global IsWow64Process.protoIsWow64Process

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

Structure RTL_DRIVE_LETTER_CURDIR Align #PB_Structure_AlignC
  Flags.w
  Length.w
  TimeStamp.l
  DosPath.UNICODE_STRING
EndStructure

Structure RTL_USER_PROCESS_PARAMETERS Align #PB_Structure_AlignC
  MaximumLength.l
  Length.l
  Flags.l
  DebugFlags.l
  ConsoleHandle.i
  ConsoleFlags.i
  StdInputHandle.i
  StdOutputHandle.i
  StdErrorHandle.i
  CurrentDirectoryPath.UNICODE_STRING
  CurrentDirectoryHandle.i
  DllPath.UNICODE_STRING
  ImagePathName.UNICODE_STRING
  CommandLine.UNICODE_STRING
  Environment.i
  StartingPositionLeft.l
  StartingPositionTop.l
  Width.l
  Height.l
  CharWidth.l
  CharHeight.l
  ConsoleTextAttributes.l
  WindowFlags.l
  ShowWindowFlags.l
  WindowTitle.UNICODE_STRING
  DesktopName.UNICODE_STRING
  ShellInfo.UNICODE_STRING
  RuntimeData.UNICODE_STRING
  DLCurrentDirectory.RTL_DRIVE_LETTER_CURDIR[$20]
EndStructure

Structure PEB Align #PB_Structure_AlignC
  InheritedAddressSpace.b
  ReadImageFileExecOptions.b
  BeingDebugged.b
  Spare.b
  Mutant.i
  ImageBaseAddress.i
  *LoaderData.PEB_LDR_DATA
  *ProcessParameters.RTL_USER_PROCESS_PARAMETERS
  SubSystemData.i
  ProcessHeap.i
  FastPebLock.i
  *FastPebLockRoutine.PEBLOCKROUTINE
  *FastPebUnlockRoutine.PEBLOCKROUTINE
  EnvironmentUpdateCount.l
  KernelCallbackTable.i
  EventLogSection.i
  EventLog.i
  *FreeList.PEB_FREE_BLOCK
  TlsExpansionCounter.l
  TlsBitmap.i
  TlsBitmapBits.l[$2]
  ReadOnlySharedMemoryBase.i
  ReadOnlySharedMemoryHeap.i
  ReadOnlyStaticServerData.i
  AnsiCodePageData.i
  OemCodePageData.i
  UnicodeCaseTableData.i
  NumberOfProcessors.l
  NtGlobalFlag.l
  Spare2.b[$4]
  CriticalSectionTimeout.LARGE_INTEGER
  HeapSegmentReserve.l
  HeapSegmentCommit.l
  HeapDeCommitTotalFreeThreshold.l
  HeapDeCommitFreeBlockThreshold.l
  NumberOfHeaps.l
  MaximumNumberOfHeaps.l
  ProcessHeaps.i
  GdiSharedHandleTable.i
  ProcessStarterHelper.i
  GdiDCAttributeList.i
  LoaderLock.i
  OSMajorVersion.l
  OSMinorVersion.l
  OSBuildNumber.l
  OSPlatformId.l
  ImageSubsystem.l
  ImageSubSystemMajorVersion.l
  ImageSubSystemMinorVersion.l
  GdiHandleBuffer.l[$22]
  PostProcessInitRoutine.l
  TlsExpansionBitmap.l
  TlsExpansionBitmapBits.b[$80]
  SessionId.l
EndStructure

Structure PROCESS_BASIC_INFORMATION Align #PB_Structure_AlignC
  ExitStatus.i
  *PebBaseAddress.PEB
  AffinityMask.i
  BasePriority.i
  UniqueProcessId.i
  InheritedFromUniqueProcessId.i
EndStructure

Procedure ShowError()
  dwMessageId = GetLastError_()

  If dwMessageId
    *lpBuffer = AllocateMemory(255)
    FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, #Null, dwMessageId, #Null, *lpBuffer, MemorySize(*lpBuffer), #Null)
    Debug "-- Error: " + Str(dwMessageId) + " - " + PeekS(*lpBuffer)
    FreeMemory(*lpBuffer)
  EndIf
EndProcedure

Procedure.b AdjustProcessPrivilege()
  Protected Result.b = #False

  If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @TokenHandle)
    lpLuid.LUID

    If LookupPrivilegeValue_(#Null, #SE_DEBUG_NAME, @lpLuid)
      NewState.TOKEN_PRIVILEGES

      With NewState
        \PrivilegeCount = 1
        \Privileges[0]\Luid\LowPart = lpLuid\LowPart
        \Privileges[0]\Luid\HighPart = lpLuid\HighPart
        \Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
      EndWith
      Result = AdjustTokenPrivileges_(TokenHandle, #False, @NewState, SizeOf(TOKEN_PRIVILEGES), @PreviousState.TOKEN_PRIVILEGES, @ReturnLength)
    EndIf
    CloseHandle_(TokenHandle)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetPBI(hProcess)
  Protected Result = #Null
  #ProcessBasicInformation = 0
  Protected pbi.PROCESS_BASIC_INFORMATION

  If Not NtQueryInformationProcess_(hProcess, #ProcessBasicInformation, @pbi, SizeOf(pbi), @ReturnLength)
    If pbi\PebBaseAddress
      Result = pbi\PebBaseAddress
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetPEB(hProcess, PebBaseAddress, OffSet)
  Protected Result = #Null
  Protected peb.PEB

  If ReadProcessMemory_(hProcess, PebBaseAddress + OffSet, @peb, SizeOf(PEB), #Null)
    If peb\ProcessParameters
      Result = peb\ProcessParameters
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure.s GetCMD(hProcess, ProcessParameters, OffSet)
  Protected Result.s = ""
  Protected rtl.RTL_USER_PROCESS_PARAMETERS

  If ReadProcessMemory_(hProcess, ProcessParameters + OffSet, @rtl, SizeOf(rtl), #Null)
    If rtl\CommandLine\Buffer
      *CmdLine = AllocateMemory(rtl\CommandLine\MaximumLength)

      If ReadProcessMemory_(hProcess, rtl\CommandLine\Buffer, *CmdLine, rtl\CommandLine\MaximumLength, #Null)
        Result = PeekS(*CmdLine, rtl\CommandLine\MaximumLength, #PB_Unicode)
      EndIf
      FreeMemory(*CmdLine)
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetProcessList()
  hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, #Null)

  If hSnapshot
    ProcEntry.PROCESSENTRY32
    ProcEntry\dwSize = SizeOf(PROCESSENTRY32)

    If Process32First_(hSnapshot, @ProcEntry)
      While Process32Next_(hSnapshot, @ProcEntry)
        AdjustProcessPrivilege()
        dwProcessId = ProcEntry\th32ProcessID
        hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, dwProcessId)

        If hProcess
          kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")

          If IsLibrary(kernel32)
            IsWow64Process = GetFunction(kernel32, "IsWow64Process")
            IsWow64Process(hProcess, @Wow64Process)
            CloseLibrary(kernel32)
          EndIf
          Protected pbi.PROCESS_BASIC_INFORMATION
          pbi\PebBaseAddress = GetPBI(hProcess)

;          If Wow64Process : OffSet = 0 : Else : OffSet = OffsetOf(PROCESS_BASIC_INFORMATION\PebBaseAddress) : EndIf

          Protected peb.PEB
          peb\ProcessParameters = GetPEB(hProcess, pbi\PebBaseAddress, OffSet)

;          If Wow64Process : OffSet = 0 : Else : OffSet = OffsetOf(RTL_USER_PROCESS_PARAMETERS\CommandLine) : EndIf

          CommandLine.s = GetCMD(hProcess, peb\ProcessParameters, OffSet)

          If CommandLine : Debug CommandLine : Else : ShowError() : EndIf

          CloseHandle_(hProcess)
        EndIf
      Wend
    EndIf
    CloseHandle_(hSnapshot)
  EndIf
EndProcedure
GetProcessList()
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: CmdLine from Process (API)

Post by JHPJHP »

First thing first... LuCiFeR[SD] you rock!!!

Now, are you kidding me - I had it working the whole time! I removed the alignments from the structures after they made no difference in PureBasic 32bit. It was only after that that I tested it in PureBasic 64bit, and without the alignments in place, it failed again on the 64bit process'.

I would have spent another 20 hours trying to figure this out, and never would have gone back to testing in PureBasic 64bit...

Let me say it again, LuCiFeR[SD] you rock!!!

*** this was just an exercise to see if I could - from what I read it's still recommended to do this via WMI (COMatePLUS): http://www.purebasic.fr/english/viewtop ... =5&t=54292 ***

If interested - compile the following in PureBasic 64bit (64bit processors), or PureBasic 32bit (32bit processors): I'm sure it still has its uses :wink:

Code: Select all

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

Structure RTL_DRIVE_LETTER_CURDIR Align #PB_Structure_AlignC
  Flags.w
  Length.w
  TimeStamp.l
  DosPath.UNICODE_STRING
EndStructure

Structure RTL_USER_PROCESS_PARAMETERS Align #PB_Structure_AlignC
  MaximumLength.l
  Length.l
  Flags.l
  DebugFlags.l
  ConsoleHandle.i
  ConsoleFlags.i
  StdInputHandle.i
  StdOutputHandle.i
  StdErrorHandle.i
  CurrentDirectoryPath.UNICODE_STRING
  CurrentDirectoryHandle.i
  DllPath.UNICODE_STRING
  ImagePathName.UNICODE_STRING
  CommandLine.UNICODE_STRING
  Environment.i
  StartingPositionLeft.l
  StartingPositionTop.l
  Width.l
  Height.l
  CharWidth.l
  CharHeight.l
  ConsoleTextAttributes.l
  WindowFlags.l
  ShowWindowFlags.l
  WindowTitle.UNICODE_STRING
  DesktopName.UNICODE_STRING
  ShellInfo.UNICODE_STRING
  RuntimeData.UNICODE_STRING
  DLCurrentDirectory.RTL_DRIVE_LETTER_CURDIR[$20]
EndStructure

Structure PEB Align #PB_Structure_AlignC
  InheritedAddressSpace.b
  ReadImageFileExecOptions.b
  BeingDebugged.b
  Spare.b
  Mutant.i
  ImageBaseAddress.i
  *LoaderData.PEB_LDR_DATA
  *ProcessParameters.RTL_USER_PROCESS_PARAMETERS
  SubSystemData.i
  ProcessHeap.i
  FastPebLock.i
  *FastPebLockRoutine.PEBLOCKROUTINE
  *FastPebUnlockRoutine.PEBLOCKROUTINE
  EnvironmentUpdateCount.l
  KernelCallbackTable.i
  EventLogSection.i
  EventLog.i
  *FreeList.PEB_FREE_BLOCK
  TlsExpansionCounter.l
  TlsBitmap.i
  TlsBitmapBits.l[$2]
  ReadOnlySharedMemoryBase.i
  ReadOnlySharedMemoryHeap.i
  ReadOnlyStaticServerData.i
  AnsiCodePageData.i
  OemCodePageData.i
  UnicodeCaseTableData.i
  NumberOfProcessors.l
  NtGlobalFlag.l
  Spare2.b[$4]
  CriticalSectionTimeout.LARGE_INTEGER
  HeapSegmentReserve.l
  HeapSegmentCommit.l
  HeapDeCommitTotalFreeThreshold.l
  HeapDeCommitFreeBlockThreshold.l
  NumberOfHeaps.l
  MaximumNumberOfHeaps.l
  ProcessHeaps.i
  GdiSharedHandleTable.i
  ProcessStarterHelper.i
  GdiDCAttributeList.i
  LoaderLock.i
  OSMajorVersion.l
  OSMinorVersion.l
  OSBuildNumber.l
  OSPlatformId.l
  ImageSubsystem.l
  ImageSubSystemMajorVersion.l
  ImageSubSystemMinorVersion.l
  GdiHandleBuffer.l[$22]
  PostProcessInitRoutine.l
  TlsExpansionBitmap.l
  TlsExpansionBitmapBits.b[$80]
  SessionId.l
EndStructure

Structure PROCESS_BASIC_INFORMATION Align #PB_Structure_AlignC
  ExitStatus.i
  *PebBaseAddress.PEB
  AffinityMask.i
  BasePriority.i
  UniqueProcessId.i
  InheritedFromUniqueProcessId.i
EndStructure

Procedure TestForError()
  dwMessageId = GetLastError_()

  If dwMessageId
    *lpBuffer = AllocateMemory(#MAX_PATH)
    FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, #Null, dwMessageId, #Null, *lpBuffer, #MAX_PATH, #Null)
    dwErrorMsg.s = Trim(PeekS(*lpBuffer, #MAX_PATH, #PB_Ascii))
    Debug "-- Error: " + Str(dwMessageId) + " - " + Left(dwErrorMsg, Len(dwErrorMsg) - 2)
    FreeMemory(*lpBuffer)
  EndIf
EndProcedure

Procedure.b AdjustProcessPrivilege()
  Protected Result.b = #False

  If OpenProcessToken_(GetCurrentProcess_(), #TOKEN_ADJUST_PRIVILEGES | #TOKEN_QUERY, @TokenHandle)
    lpLuid.LUID

    If LookupPrivilegeValue_(#Null, #SE_DEBUG_NAME, @lpLuid)
      NewState.TOKEN_PRIVILEGES

      With NewState
        \PrivilegeCount = 1
        \Privileges[0]\Luid\LowPart = lpLuid\LowPart
        \Privileges[0]\Luid\HighPart = lpLuid\HighPart
        \Privileges[0]\Attributes = #SE_PRIVILEGE_ENABLED
      EndWith
      Result = AdjustTokenPrivileges_(TokenHandle, #False, @NewState, SizeOf(TOKEN_PRIVILEGES), @PreviousState.TOKEN_PRIVILEGES, @ReturnLength)
    EndIf
    CloseHandle_(TokenHandle)
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetPBI(hProcess)
  Protected Result = #Null
  #ProcessBasicInformation = 0
  Protected pbi.PROCESS_BASIC_INFORMATION

  If Not NtQueryInformationProcess_(hProcess, #ProcessBasicInformation, @pbi, SizeOf(pbi), @ReturnLength)
    If pbi\PebBaseAddress
      Result = pbi\PebBaseAddress
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetPEB(hProcess, PebBaseAddress)
  Protected Result = #Null
  Protected peb.PEB

  If ReadProcessMemory_(hProcess, PebBaseAddress, @peb, SizeOf(PEB), #Null)
    If peb\ProcessParameters
      Result = peb\ProcessParameters
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure.s GetCMD(hProcess, ProcessParameters)
  Protected Result.s = ""
  Protected rtl.RTL_USER_PROCESS_PARAMETERS
  ZeroMemory_(@rtl, SizeOf(rtl))

  If ReadProcessMemory_(hProcess, ProcessParameters, @rtl, SizeOf(rtl), #Null)
    If rtl\CommandLine\Buffer
      *CmdLine = AllocateMemory(rtl\CommandLine\MaximumLength)

      If ReadProcessMemory_(hProcess, rtl\CommandLine\Buffer, *CmdLine, rtl\CommandLine\MaximumLength, #Null)
        Result = PeekS(*CmdLine, rtl\CommandLine\MaximumLength, #PB_Unicode)
      EndIf
      FreeMemory(*CmdLine)
    EndIf
  EndIf
  ProcedureReturn Result
EndProcedure

Procedure GetProcessList()
  hSnapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, #Null)

  If hSnapshot
    ProcEntry.PROCESSENTRY32
    ProcEntry\dwSize = SizeOf(PROCESSENTRY32)

    If Process32First_(hSnapshot, @ProcEntry)
      While Process32Next_(hSnapshot, @ProcEntry)
        AdjustProcessPrivilege()
        dwProcessId = ProcEntry\th32ProcessID
        hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, dwProcessId)

        If hProcess
          Protected pbi.PROCESS_BASIC_INFORMATION
          ZeroMemory_(@pbi, SizeOf(pbi))
          pbi\PebBaseAddress = GetPBI(hProcess)
          Protected peb.PEB
          ZeroMemory_(@peb, SizeOf(PEB))
          peb\ProcessParameters = GetPEB(hProcess, pbi\PebBaseAddress)
          CommandLine.s = GetCMD(hProcess, peb\ProcessParameters)

          If CommandLine : Debug CommandLine : Else : TestForError() : EndIf

          CloseHandle_(hProcess)
        EndIf
      Wend
    EndIf
    CloseHandle_(hSnapshot)
  EndIf
EndProcedure
GetProcessList()

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

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
Post Reply