How can I get the full command line of all the processes after doing a process walk of the snapshot?

StackOverflow https://stackoverflow.com/questions/21945606

  •  14-10-2022
  •  | 
  •  

Question

So, my goal is to get the full command line of all the currently running processes. Towards that what I do is take a snapshot of processes using the CreateToolhelp32Snapshot API and then do a process walk to store the PROCESSENTRY32 type processes in an array called process_list:

BOOL GetProcessList( FILE *f, PROCESSENTRY32* process_list, int process_count)
{
  HANDLE hProcessSnap;
  HANDLE hProcess;
  PROCESSENTRY32 pe32;
  DWORD dwPriorityClass;


  hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
  if( hProcessSnap == INVALID_HANDLE_VALUE )
  {
    return( FALSE );
  }

  // Set the size of the structure before using it.
  pe32.dwSize = sizeof( PROCESSENTRY32 );

  // Retrieve information about the first process,
  // and exit if unsuccessful
  if( !Process32First( hProcessSnap, &pe32 ) )

  {
    CloseHandle( hProcessSnap );          // clean the snapshot object
    return( FALSE );
  }
  // Now walk the snapshot of processes, and
  // display information about each process in turn
  int i = 0;
  do
  {
    // Retrieve the priority class.
    dwPriorityClass = 0;
    hProcess = OpenProcess( PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, pe32.th32ProcessID );

    if( hProcess == NULL ) { }

    else
    {
      dwPriorityClass = GetPriorityClass( hProcess );
      if( !dwPriorityClass )
      CloseHandle( hProcess );
    }

    process_list[i] = pe32;
    i++;

  } while( Process32Next( hProcessSnap, &pe32 ) && i <= process_count);

  CloseHandle( hProcessSnap );
  return( TRUE );
}

Now, is it possible to traverse this array of processes and gather the full command line of each of the processes? How can I do that?

If it is important, I will be compiling the code as a 64bit process and would need the full command line for all the processes running on the host machine.

Was it helpful?

Solution

For each Process ID:

  1. use OpenProcess() to get a HANDLE to the process.

  2. then use QueryFullProcessImageName(), GetProcessImageFileName(), or GetModuleFileNameEx to get the path and filename of the process.

  3. then use NtQueryInformationProcess() to retrieve the address of the process's PEB structure, which contains a ProcessParameters member containing the command-line arguments for the process (you can also get the image path from the PEB as well). Use ReadProcessMemory() to read the contents of the PEB.

Have a look at the following article for more details:

Get Process Info with NtQueryInformationProcess

OTHER TIPS

There are some good examples of how to do this with NtQueryInformationProcess(), but it's ugly. WMI can be slow, but it's as simple as this:

        string cmdLine = string.Empty;

        try
        {
            // Searcher.Get() throws an exception if process is protected or has exited already, so this is inside a try-catch
            var searcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + processId.ToString());
            ManagementObjectCollection moc = searcher.Get();
            searcher.Dispose();

            foreach (ManagementObject item in moc) // should only be one item
            {
                cmdLine = item["CommandLine"].ToString();
            }
        }

        catch
        {
            // write an error
        }

        return cmdLine;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top