Sunday, January 21, 2007

Real time command line spy

Generally, every script you write involves running some Windows built-in tools. Applications like regedit.exe or cmd.exe are the most common. For this tools to operate within a script, a command line argument must be supplied to tell the application what "task" to perform otherwise it will just run with the default settings.

As I see it, command line arguments and switches are both fascinating and powerful. There are even undocumented switches, which makes them even more mysterious. For example, running control panel applets can be done with tools like control.exe or rundll32.exe, both with some arguments.

CONTROL.EXE <cplfilename.cpl> RUNDLL32.EXE <dllname>,<entrypoint> <optional arguments>

To run the Internet Properties dialog, type:

control.exe inetcpl.cpl or rundll32.exe shell32.dll,Control_RunDLL INETCPL.CPL

You can even open the applets with another tab in front (using the tab Index number). To open the Internet Properties dialog with the Privacy tab in front, type:

control.exe inetcpl.cpl,,2 rundll32.exe shell32.dll,Control_RunDLL INETCPL.CPL,,2

Traditionally, you will use the /? switch to reveal your application's help, but, if you run rundll32.exe /? you'll end up with nothing, searching for help on these kind of files can be a quiet a challenge, and as you can see with the rundll sample this is not ordinary stuff like cmd.

For quite some time I was puzzled by this. How can I find the rundll's or any other file command line switches and arguments? Can I find more than "exist" in the default documentation or help parameter?.

I started to Google, with no luck. Including the words "command line" in Google's search was a pain. I had to filter out dozens of links, ohhh... until I came across Bryan Keadle's Cool Tools page.

One of Bryan tools called "Intercept" was made exactly for this task. Intercept will replace itself with the selected program, show the parameters being passed, then continue on to the original executable. Fantastic, I downloaded the file, tested it and it worked just fine.

While "Intercept" did a great job on a small scale I was looking for a better solution. Than I came across SysInternals "Process Explorer" (now hosted on TechNet). If you used Sysinternals tools before, than names like regmon, filemon, tcpview and others are no stranger to you (if you didn't use there tools shame on ya :-), you can download the entire Sysinternals Suite (8 MB) from here).

Double-clicking any process in Process Explorer launched the process property dialog. This dialog lists a plethora of information on the process including the command line that started it.


Now, all I had to do is click the processes and investigating their command line, and testing them offline. As for the above rundll example, go to the control panel and run any applet you like, once you launched it look for rundll process in Process Explorer, double-click it and view its command line, then you can include it in your scripts.

As for processes that took very small amount of time to execute and appear in the display, I used the "spacebar" key to "freeze" the display from refreshing and then double-clicked the process. This method became very wearying while waiting for processes to execute, much like a mouse and cat chase. The last step in this quest was the release of SysInternals Process Monitor (By Mark Russinovich and Bryce Cogswell).

Process Monitor includes regmon, filemon and Process Explorer in one tool. It captures all the activity of registry, file system, and processes/threads in real time, and logs the results to a file on the local disk. Boom, this was what I looked for. Here is my way of real time spying/monitoring command lines:

1. Run procmon.exe
2. Toggle off registry activity
3. Right Click any Column header and choose "Select Columns..." (or Click Options > Select Columns) and uncheck everything except "Process Name" and "Command Line".


4. Viola! Procmon.exe scrolls the results and from now on, no command line switch is immune.


In addition filters can be applied to adjust the displayed processes. If you wish to exclude a Process, just right click it and choose "Exclude > Process Name".

Finally, you can save the results to a CSV file for later use. One can even make a Command line Database :-)


I strongly recommend viewing Mark's session on "Advanced Windows Troubleshooting with Process Monitor"


Enjoy $hay