Hi Guys,
I just wanted to send a quick email to let you know of where the
scudette branch is heading in the near future. The main goal of
development is to create a volatility library that can be easily used
from external programs, and also to make it far easier for people to
use volatility and in particular automate it through simple scripts
(without needing to necessarily write a plugin).
The idea is to extend volshell to make it THE way to use volatility.
These are the major goals:
- Get rid of the caching system - its not needed if we run everything
from inside volshell since command instances can just do their own
caching if they need it.
- Separate the concept of a profile from the address space - currently
the address space carries the profile (as.profile) but really has
nothing to do with it. In the new implementation the config object
carries both address spaces, and profiles. The refactor removes the
global obj.Object() factory and instead moves this factory to the
profile - this strengthen the relation between the profile and objects
it create (i.e. it is the profile which actually creates the object
instances on a given address space.).
- Remove all the magic around the place - currently when I want to do
a pslist, it automatically does a scan behind the scenes, which may or
may not work. The new architecture removes automatic behind the scene
actions, and requires the user to explicitely set them. If a command
requires a value for KDBG offset, this must be provided (i.e. the user
will scan for it first, then provide the correct value). Since all
this happens in the shell we dont really have a high startup time each
time - so the user can just try the first result from the scan
themselves (this is what happens now anyway but if the first his is
incorrect things break badly without users knowing what to do next).
- The current VOLATILITY_MAGIC member of the profile will go into a
constants attribute of the profile. This is essentially the same as
the linux profile's idea of a smap (the system symbol map). It also
makes it much more intuitive for the user that they can just get
profile specific constants by getting profile.constants["KDBGHeader"].
Automatic code executing by the volatility magic will disappear as I
mentioned.
- The new system automatically exports all command modules as volshell
commands (which return the instance). This makes it easy to call
different command plugins from inside the shell - with no additional
startup time (profile parsing etc). Also since we return a handle to
the command plugin, it can export all its useful methods for people to
use. For example:
class PSList(....)
def list_tasks(self):
""" A generator over all the tasks."""
def render_text(self):
for task in self.list_tasks():
... pretty print in a table...
There is no longer confusion over exactly what kind of data
calculate() returns since it does not really matter (The calculate
method for all plugins will be renamed something more suggestive of
its function). In the shell one simply does:
for task in pslist().list_tasks():
print task.comm
or:
pslist().render()
or:
pslist().render_text()
To see the old output.
Also in the new code the name of the command plugin is unrelated to
the class name, so you can have multiple implementations of pslist
which are selected based on the profile. (e.g. a windows pslist and a
linux pslist). In the volshell, launching pslist, will pick the right
one.
In addition to this we will no longer have complex and brittle
inheritence structure for commands. Currently we inherit from a
command if we need to use one of its methods (e.g. dlllist, pslist,
moddump etc all share the same base class because they all need to
list tasks!). This will simply not be necessary since any module could
easily call any other module through a global command factory - so for
getting moddump to get a process list, a plugin can just do:
for task in self.RunModule("pslist"):
....
without needing to be inherited from pslist directly.
Also inside volshell (if you use ipython) we can easily run scripts.
For example this is one of my scripts to find the current process
(i.e. python) task struct in memory (This is intended to run on
/dev/pmem):
import os
for task in pslist().list_tasks():
if os.getpid() == task.pid:
print "My task is at 0x%X (pid %s)" % (task.obj_offset, task.pid)
break
Then from ipython I can run this script in the context of the shell:
In [2]: run -i /home/mic/test.py
My task is at 0xFFFF880013C1AE40 (pid 1315)
and in the end the variable "task" will contain my own task. If I
still want a pretty printed table:
pslist().render_text()
An added bonus is that I can use ipython's awesome double tab
expansion to see all the members of task:
In [2]: task. (tab-tab)
Display all 200 possibilities? (y or n)
task._CType__initialized task.bio_list
task.io_context
task.__class__ task.blocked task.ioac
task.__delattr__ task.btrace_seq
task.irqaction
task.__dict__ task.cast
task.is_valid
....
This is an awesome interactive experience for volatility.
Thanks,
Michael.