I’m looking at Task Manager’s list of processes, and enabled View > Select columns > Command line to see include exe path & command line arguments.
I tried to get the same thing working using GetModuleFileNameEx but there’s some problems; first, the result doesn’t include any arguments and it also fails for some processes, as basic as WinRar.exe or Opera.exe.
I know that Task Manager uses WMI to get some of this data (I tried shutting down the service and it failed just the way my script did, for the same processes), but I wonder, what makes a process’s path “ungettable”?
Task Manager uses the process’s
PEBstructure to access the command-line arguments (amongst other things). If you have aHANDLEto the target process (and sufficient rights to access its memory), you can access thePEBusing theNtQueryInformationProcess()function (set itsProcessInformationClassparameter toProcessBasicInformationto receive aPROCESS_BASIC_INFORMATIONstructure) to obtain the memory address of thePEBwithin the target process’s address space (amongst other things). You can then useReadProcessMemory()to read the contents of thePEBinto your app’s address space as needed. The command-line parameters are located by using thePEB::ProcessParametersfield, which is a pointer to aRTL_USER_PROCESS_PARAMETERSstructure, which contains aCommandLinefield of typeUNICODE_STRING.Things get a little trickier if you are a 32-bit process accessing the PEB of a 64-bit process, or vice versa. You have to take into account the different sizes of pointers (4 of 32-bit, 8 for 64-bit), which affects structure sizes and offsets.
But this is the gist of it.