Wednesday, August 1, 2012

Waiting on Long Processes? Don't!

The Scene

[Cue dramatic organ music] You started imaging a large hard drive, and you need to follow that with a md5sum of the device to verify the data hash in the image is the same as the device.  But, its time to go home and the image isn't complete!  [dunt, Dunt, DUN!]  Yes, you could have written you command to start the md5sum program upon completion of the acquisition, but you didn't.  Is there anything you can do to ensure you can go home to a warm dinner AND still complete the hashing operation?

You bet!!

Much of life, computing and digital forensics included, is about processes.  First "A" happens, then "B", and next "C."  Forensic disk imaging is like that: First attach the device, then image the device, and next verify the image.  GUI tools can be handy for this in that they can be configured to do several sequential steps for us.  Take the Guymager imaging tool for example: it allows you to verify the image with a separate hash of the device, and it performs the imaging and verification, one after the other, without your intervention.

But what if you are working on the command line?  How can you start one process immediately after another completes?  Back to our scenario...

What You Could Have Done

The whole issue could have been solved at the BASH command line when you issued your acquisition command.  BASH allows control operators to control the flow of your commands.  You have the ability to run command_1 AND command_2, or alternatively, command_1 OR command_2, for example.  The linchpin is the exit status (success or failure) of command_1.

  • With the AND operator, which is represented in BASH by "&&", command_2 will execute if command_1 was successful (exit status 0).  
  • With the OR operator, which is represented in BASH by "||", command_2 will execute if command_1 was unsuccessful (non-zero exit status).

So, if I wanted to make an Expert Witness Format image with ewfacquire, a tool from the libewf library, and follow that automatically with a hash of the device, I could:
# ewfacquire /dev/sdd && md5sum /dev/sdd 
With that command, the md5sum of /dev/sdd will calculate if ewfacquire is successful,.  If ewfacquire fails for some reason, then the hashing operation will not execute.

Woulda, Coulda, Shoulda!

But in our scenario, you are already hours into an acquisition and it would be counter productive to stop ewfacquire process just to use the AND operator described above.  How can you cause the md5sum program to run after the acquisition in such a circumstance?  Well, two ways, as a matter of fact.

Wait

The wait command is a BASH builtin that takes a process ID as an argument.  When the process terminates, wait exits.  It can be used much like the example above:
# wait 1972 && md5sum /dev/sdd
Thus, when wait exits successfully, the md5sum operations begins.  If that seems too easy, in a sense, it is.  Wait only works on processes of the same shell session.  That means to use wait, you'd have to interrupt the ewfacquire process with ctrl-z, run it in the background with bg, and then determine its process ID before wait would work.  You'll may find pull this off, because ewfacquire messages will still print to stderr making working  in the shell difficult.

A better way

You can accomplish the same result as wait without backgrounding the ewfacquire process through the BASH test builtin command.  With test, it is possible to open another shell, determine the process ID of ewfacquire, and test for the presence of the process in the second shell.  Consider:
# ps -opid= -C ewfacquire
1972
# while [ -d /proc/1972 ]; do sleep 60; done && md5sum /dev/sdd
The first command, ps, shows current process.  The arguments here format the output to show only the process ID (-opid=) and search for the process by name (-c ewfacquire).  There are many ways to determine the process id, and this command is borrowed from here so you can see how it could be incorporated into a script.

The while loop uses test in the form of [ -d /proc/1972 ] to check for the presence of the /proc/1972 directory.  Every running process has a directory in the /proc file system which is removed when the process ends.  The sleep command pauses the while loop 60 seconds at a time.  The loop successfully terminates when the process directory is removed causing the md5sum the execute.


It may seem complicated at first blush, but its really not.  And, you get to go home to a warm meal instead of cold leftovers for your efforts.