Hey Folks,
I was just reading Gleeda's blog & CEIC presentation,
and was interested to discover that Volatility modules had been written
for Linux and Vista. Now I'm wondering why these modules haven't shown
up anywhere I can see them, including in the public view of the SVN
repository. After digging for a bit, I did see that they (or at least a
modified version of the Linux ones) have apparently been incorporated
into the Pyflag distribution, but that just caused me more confusion. If
they're stable enough to release as part of Pyflag, why aren't they in
the public Volatility repository?
Also, are you expecting to release an 'official' update
anytime soon? The last update available from the main Volatility page is
still 1.3_Beta. Is there some defined list of fixes or features that has
to be ready before an 'official' 1.3 version is released? Or has that
been bypassed, so that current work is really going toward 1.4? Maybe a
roadmap section would make a good addition to the main Volatility page.
I'm sure there are a lot of people who would be interested in what's
going on.
Thanks much (Sorry if I sound like I'm
ranting, you guys really have done some awesome work!)
John
----------------------------------------------------------
Quis custodiet ipsos custodes?... I do!
Hello,
Please find attached a patch to speed up the Volatility strings
command. On my slow laptop, a particular search for a single string
required around 2 hours and 25 minutes. After these changes, the same
search requires 35 minutes. (Measured in wall clock time.)
Notable changes include:
- Switched from guess-and-check style address probing (during the
reverse map construction) to using get_available_pages(). On my
test image, this cuts the number of vtop() calls down from 1M to
something on the order of 55K for each process. This more than made
up for the additional overhead of calling get_available_pages().
- The above change also eliminates a 32bit address space assumption
appearing in top-level code, which I assume is a good thing.
- Reduced the number of reverse_map lookups
- Moved parsing of the strings input file to an earlier point in
processing so users don't have to wait until the end of the job to
discover they didn't specify things correctly.
I can think of several other ways to make this faster and/or more
memory efficient, but most require changes to the address interface
(ever thought of providing a page iterator?).
Also, I added a few comments for future improvements to the user
interface and output. I think currently there are problems with the
way that addresses appearing in large pages are reported, but I'm not
100% sure what the output is intended to mean, so I just kept it the
same for now.
DISCLAIMER: This is the first time I've seriously looked at the
Volatility code. Please review/test it carefully before committing
the changes.
thanks!
tim
Hi everybody,
My apologies if this has been addressed in a previous patch, but I had
a Volatility crash today. The system died because a module created a
BufferAddressSpace of n bytes and then attempted to read greater than
n from it. The problem appears to be a lack of checks in the
FileAddressSpace class that the requested address to read from exists
in the file (or buffer). Here's a patch to fix it:
$ svn diff forensics/addrspace.py
Index: forensics/addrspace.py
===================================================================
--- forensics/addrspace.py (revision 16)
+++ forensics/addrspace.py (working copy)
@@ -1,6 +1,6 @@
# Volatility
# Copyright (C) 2007,2008 Volatile Systems
-#
+
# Original Source:
# Copyright (C) 2004,2005,2006 4tphi Research
# Author: {npetroni,awalters}(a)4tphi.net (Nick Petroni and AAron Walters)
@@ -51,15 +51,28 @@
return self.fast_fhandle.read(len)
def read(self, addr, len):
+ '''
+ Read and return len bytes from the address addr.
+ If any of those bytes are not available, return None.
+ '''
+ if not self.is_valid_address(addr):
+ return None
self.fhandle.seek(addr)
return self.fhandle.read(len)
def zread(self, addr, len):
- return self.read(addr, len)
+ '''
+ Read and return len bytes from the address addr.
+ If any of those bytes are not available, return len bytes of
zeros.
+ '''
+ tmp = self.read(addr, len)
+ if tmp is None:
+ return '\x00' * len
+ return tmp
def read_long(self, addr):
string = self.read(addr, 4)
- (longval, ) = struct.unpack('=L', string)
+ (longval, ) = struct.unpack('<L', string)
return longval
def get_address_range(self):
--
Jesse Kornblum
Hi everybody,
I've found that if you interrupt the hibernation file restore on
Windows XP the header changes from "hibr" to "wake". Unfortunately
such hibernation files cannot be processed by Volatility due to a
simple check in vutils.py. The code attached patches vutils to allow
parsing of these files.
--
Jesse
Hi everybody,
Attached please find a drop-in replacement for forensics/x86.py. It's
a complete rewrite of the code using the latest edition of the Intel
Architectures Software Developer's Manual [1]. The manual, now at
revision 031, has changed significantly over the past few years. The
current version has a new (and much simpler) approach for finding
offsets. The result is cleaner code! Hopefully this will be easier to
maintain over the years! I've also added pydoc style documentation for
each function.
Please let me know what you think,
[1] http://www.intel.com/products/processor/manuals/index.htm
--
Jesse
research(a)jessekornblum.com
Hi everybody,
We might be able to simplify the virtual to physical address
translation in the Volatility framework. While it's not always wise to
mess with something that works already, making this code clearer would
help people trying to learn the framework and about memory forensics
in general. The code in question is all in forensics/x86.py. I've
attached a drop-in replacement for forensics/x86.py to illustrate the
kind of changes I'm proposing [1]. Right now it only works for non-PAE
system (e.g. xp-laptop-2005-*). If you like this I can expand it work
on PAE systems as well.
I was reading the Intel Architectures Software Developer's Manual [2]
and took particular note of how they described the lookups for PDEs
and PTEs. Using PDEs, for example, Volatility uses the value in CR3 as
a base address and add to it an index number multiplied by a size
value. The index comes from shifting bits around in the original
virtual address. It looks like this:
address = [Cr3] + (([vaddr] >> shift) & ((ptrs - 1)) * pointer_size)
This calculation is broken into two functions and uses three magic
values.
The Intel manual takes a different approach. To them the PDE offset
just a series of bits grabbed from various sources. In their words:
<snip>
A PDE is selected using the physical address defined as follows:
— Bits 39:32 are all 0.
— Bits 31:12 are from CR3.
— Bits 11:2 are bits 31:22 of the linear address.
— Bits 1:0 are 0.
</snip>
In other words:
address = ([Cr3] & mask) & ([vaddr] & mask >> shift)
In Volatility it would look like:
pgd_addr = (self.pgd_vaddr & 0xfffff000) | ((vaddr & 0xffc00000) >> 20)
I've even included a helper function, bitmask(), that computes
bitmasks on the fly. Avoid it might take slightly longer to execute,
it would hopefully avoid coding errors.
pgd_addr = (self.pgd_vaddr & bitmask(12,31)) | ((vaddr &
bitmask(22,31)) >> 20)
What do you think?
[1] Warning! This code *only* works on non-PAE systems for now. It
also contains some code to make Volatility work on big endian machines.
[2] http://www.intel.com/products/processor/manuals/index.htm
--
Jesse
research(a)jessekornblum.com