Closed GoogleCodeExporter closed 9 years ago
The sanity checks can be extended to reduce the FP to an acceptable level, even
if you find that you can not reflect through the Header.List member always.
Certainly you can try to follow PsActiveProcessHead and reflect through that,
or even PsLoadedModuleList. There is no reason why the scanner can not do these
checks to reduce the FPs.
The point is that the scan is signature free so works on all windows versions,
and extremely fast. Currently I can see about a 5x-10x speedup in the scudette
branch over trunk (e.g. pslist in trunk takes around 5 sec and in scudette
branch about 0.6 sec) and I think probably about 2 seconds of that is due to
the trunk kdbg scan being sub optimal.
Original comment by scude...@gmail.com
on 6 Jun 2012 at 1:04
Hey Scudette,
The speed improvement sounds impressive. Unfortunately every time I check out
the branch to test something, I don't end up getting very far. Without a branch
to test with, or a clear cut patch for trunk, its difficult to work with. I
took some commands you posted in Issue #224 and got the following. Is there
something I'm doing wrong?
$ svn info
Path: .
URL: https://volatility.googlecode.com/svn/branches/scudette
Repository Root: https://volatility.googlecode.com/svn
Repository UUID: 8d5d6628-2090-11de-9909-f37ff7dbbc12
Revision: 1847
Node Kind: directory
Schedule: normal
Last Changed Author: scudette@gmail.com
Last Changed Rev: 1832
Last Changed Date: 2012-06-04 20:54:13 -0400 (Mon, 04 Jun 2012)
$ python vol.py
Welcome to volshell!
To get help, type 'help()'
>>> session.filename =
"/Users/Michael/Desktop/memory/Win7SP0x86/win7_mcafee.vmem"
>>> session.profile = "Win7SP0x86"
>>> vol(plugins.pslist)
> /Users/Michael/volatility_scudette/volatility/obj.py(1338)Object()
-> logging.warning("Cant find object {0} in profile {1}?".format(theType, self))
(Pdb) Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/Michael/volatility_scudette/volatility/session.py", line 351, in vol
result = plugin_cls(**kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugins/windows/taskmods.py", line 61, in __init__
super(WinPsList, self).__init__(**kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugins/windows/common.py", line 413, in __init__
super(WinProcessFilter, self).__init__(**kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugins/windows/common.py", line 366, in __init__
super(KDBGMixin, self).__init__(**kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugin.py", line 149, in __init__
super(KernelASMixin, self).__init__(**kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugin.py", line 185, in __init__
self.session.plugins.load_as(session=self.session)
File "/Users/Michael/volatility_scudette/volatility/plugins/core.py", line 151, in __init__
**kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugins/core.py", line 179, in GuessAddressSpace
astype=astype, profile=self.profile, **kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugins/addrspaces/amd64.py", line 53, in __init__
super(AMD64PagedMemory, self).__init__(**kwargs)
File "/Users/Michael/volatility_scudette/volatility/plugins/addrspaces/intel.py", line 93, in __init__
find_dtb = self.session.plugins.find_dtb(session=self.session)
File "/Users/Michael/volatility_scudette/volatility/plugins/windows/common.py", line 98, in __init__
"_EPROCESS", "ImageFileName")
File "/Users/Michael/volatility_scudette/volatility/obj.py", line 1187, in get_obj_offset
tmp = self._get_dummy_obj(name)
File "/Users/Michael/volatility_scudette/volatility/obj.py", line 1182, in _get_dummy_obj
tmp = self.Object(theType = name, offset = 0, vm = self._dummy)
File "/Users/Michael/volatility_scudette/volatility/obj.py", line 1338, in Object
logging.warning("Cant find object {0} in profile {1}?".format(theType, self))
File "/Users/Michael/volatility_scudette/volatility/obj.py", line 1338, in Object
logging.warning("Cant find object {0} in profile {1}?".format(theType, self))
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 48, in trace_dispatch
return self.dispatch_line(frame)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 66, in dispatch_line
self.user_line(frame)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 158, in user_line
self.interaction(frame, None)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 210, in interaction
self.cmdloop()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cmd.py", line 130, in cmdloop
line = raw_input(self.prompt)
KeyboardInterrupt
>>> help()
Welocome to Volatility.
You can get help on any module or object by typing:
help object
Some interesting topics to get you started, explaining some volatility specific
concepts:
help addrspace - The address space.
help obj - The volatility objects.
help profile - What are Profiles?
>>> help profile
File "<console>", line 1
help profile
^
SyntaxError: invalid syntax
Original comment by michael.hale@gmail.com
on 6 Jun 2012 at 3:24
Hi Michael,
Only some of the profiles are currently enabled (the ones I use :-)
Try Win7SP1x64 instead :-). I will check the rest of the profiles in
shortly.
Since there is a testing framework now you can see exactly the
difference in performance for each plugin between the two versions
(The testing framework runs each tool and records details about the
run in a baseline file - then we can retest the tool again in future
to detect regressions etc):
http://code.google.com/p/volatility/source/browse/branches/scudette/test_data/xp
-laptop-2005-06-25_trunk/pslist
and
http://code.google.com/p/volatility/source/browse/branches/scudette/test_data/xp
-laptop-2005-06-25_ng/pslist
In this instance 0.23 sec vs 2.3 sec for trunk (Of course these
numbers are machine dependent, but both tests were run several times
in succession with no other load on the box).
I did some more analysis and I think the reasons trunk is slow are
varied (I did new tests this time on a different box):
Trunk:
time python vol.py -f xp-laptop-2005-06-25.img --profile WinXPSP2x86 pslist
real 0m4.936s
Scudette branch (you can now use the command line as well as the
interactive shell):
time python vol.py -f xp-laptop-2005-06-25.img --profile WinXPSP2x86 pslist
real 0m0.895s
- The kdbg scan accounts for about 3 seconds of the time (which is
huge!). If I supply --kdbg on the command line the time falls
significant:
real 0m1.997s
- The dtb scan seems to have less impact. Supplying --dtb to trunk gives:
real 0m1.870s
- Start up time is significant - I made an empty plugin null.py:
class Null(common.AbstractWindowsCommand):
def render_text(self, outfd, data):
pass
and I get in trunk.
real 0m1.526s
Whereas the same plugin in the scudette branch shows:
real 0m0.709s
So it seems the registry and plugin code in trunk are also very slow.
Michael.
Original comment by scude...@gmail.com
on 6 Jun 2012 at 8:06
Hmm I still can't get it to work, even with an XPSP2x86 profile
$ svn info
Path: .
URL: https://volatility.googlecode.com/svn/branches/scudette
Repository Root: https://volatility.googlecode.com/svn
Repository UUID: 8d5d6628-2090-11de-9909-f37ff7dbbc12
Revision: 1848
Node Kind: directory
Schedule: normal
Last Changed Author: scudette@gmail.com
Last Changed Rev: 1848
Last Changed Date: 2012-06-06 08:21:19 -0400 (Wed, 06 Jun 2012)
$ python vol.py -f ~/Desktop/memory/WinXPSP2x86/silentbanker.vmem --profile
WinXPSP2x86 pslist
Traceback (most recent call last):
File "vol.py", line 32, in <module>
from volatility import plugins
File "/Users/Michael/volatility_scudette/volatility/plugins/__init__.py", line 4, in <module>
from volatility.plugins import core
File "/Users/Michael/volatility_scudette/volatility/plugins/core.py", line 258, in <module>
class Null(WinMemDump):
NameError: name 'WinMemDump' is not defined
Original comment by michael.hale@gmail.com
on 6 Jun 2012 at 12:57
Ah I recently introduced a typo when committing the Null plugin we
discussed in this thread. Try again :-)
Original comment by scude...@gmail.com
on 6 Jun 2012 at 1:12
We're not going to hold 2.1.x back on this, given it's how it's always worked
(so people aren't getting *worse* performance).
Original comment by mike.auty@gmail.com
on 6 Jun 2012 at 8:30
Hey guys,
OK I've added the verbose output in r1866. The technique and order of
operatings when KDBG scanning has not changed yet since we agreed to keep that
the same through the next release. So currently you'll see something like this
now:
**************************************************
Instantiating KDBG using: Kernel AS VistaSP2x64 (6.0.6002 64bit)
Offset (V) : 0xf800019c1f20
Offset (P) : 0x19c1f20
KDBG owner tag check : True
Profile suggestion (KDBGHeader): Win2008SP2x64
Version64 : 0xf800019c1ed8 (Major: 15, Minor: 6002)
Service Pack (CmNtCSDVersion) : 2
Build string (NtBuildLab) : 6002.18005.amd64fre.lh_sp2rtm.09
PsActiveProcessHead : 0xfffff800019f4440 (52 processes)
PsLoadedModuleList : 0xfffff80001a14dd0 (153 modules)
KernelBase : 0xfffff80001850000 (Matches MZ: True)
Major (OptionalHeader) : 6
Minor (OptionalHeader) : 0
KPCR : 0xfffff800019c3500 (CPU 0)
If no one has objections to this format, then I'll close the issue and we can
open separate one(s) for speed related enhancements and of course for
auto-selecting the profile.
Scudette, if you want to add your reflect check to the output, that'd be cool
and would give us yet another factor to distinguish between FPs (and then it'll
be ready to use if we need it as an additional sanity check for
auto-selection). Also, 2003 and Vista images are the ones (in my experience)
that have multiple KDBGs with some being valid and some not, so I'll be glad to
test your branch more, but you'll have to enable support for those missing
profiles first.
Original comment by michael.hale@gmail.com
on 12 Jun 2012 at 10:58
Hi Michael,
This looks very nice. I especially like the Major and Minor versions from the OptionalHeader because I think this is very predictive of the operating system version. Accroding to:
https://media.blackhat.com/bh-eu-12/Haruyama/bh-eu-12-Haruyama-Memory_Forensic-S
lides.pdf slide 34
Some other tools use this value for detecting os version. Of course these
values are super easy to change by malware (So is KDBG), but they are a good
indication usually. It is actually possible to load these values completely
without an OS dependent profile since the KDBG structure itself is always the
same between all windows versions.
I looked at the scanner code again to try to understand where the difference in
speed comes from. The trunk version still looks for the KDBG tag first, and
then narrows the selection down by employing the other tests. If you count the
number of hits that actually get past the PoolTagCheck checker it is actually
only one. In the scudette branch this is 2 so not much different (because there
are no other checkers). OTOH the time it takes to set up all the profiles is
extremely significant - I count nearly 4 seconds out of a total time of 7
seconds in the calculate function until the scanner is actually instantiated.
I think you have implemented so many additional checks now that relying on
profile specific signatures is kind of pointless. A suggestion is maybe extract
the signatures all into a single data structure so you dont need to load all
profiles in their entirety before each run.
Original comment by scude...@gmail.com
on 14 Jun 2012 at 6:51
Yeah, I agree. The speed enhancements and auto-profile selection are at the top
of the list of things to do next. They're both related so we should be able to
knock them both out at the same time with some revisions to the KDBG and DTB
scanner (and possibly the profile/AS load order).
At a very high level, to choose the right profile in the fastest way possible I
was thinking something like:
1) Find the DTB so we can get a kernel space
2) Scan kernel AS for KDBGHeader or drop the signature and just look for "KDBG"
per your suggestion
3) Use the checks that kdbgscan currently prints to distinguish the Major,
Minor, and Service Pack
4) Update to the chosen profile
5) Run the plugin code
Preferably like you said, we would have some type of static setting and none of
the steps would require updating to all profiles before even starting the work.
The first hurdle I think would be finding the DTB before/without applying a
profile, since currently the DTB scanner needs the offsets to
EPROCESS.ImageFileName and KPROCESS.DirectoryTableBase. If we could do that, I
think the rest would be pretty easy.
Also I just wanted to mention that the "other tools" ;-) sometimes fail to
identify an image even if its a version they claim to support. So allowing
users to override with --profile and --kdbg is still a valuable feature I
think. That's part of the motivation behind the verbose kdbgscan output...while
we're planning the next steps we'll be gathering details on the reliability of
the different checks (through our own usage of the plugin and community bug
reports if any).
I'm not sure if anyone has ever tried loading an image in Redline (wouldn't be
surprised if you haven't) but it can take several hours before it shows the
initial GUI for investigation. Compared to that, our trunk speed for kdbgscan
is pretty darn fast.
So yeah, I look forward to us putting our heads together and developing a fast
and reliable auto-profile selection ;-)
Original comment by michael.hale@gmail.com
on 15 Jun 2012 at 5:26
Alright, I'll close this out since the sanity checks and more informational
output patches have been completed. We can reference this issue when discussing
kdbg stuff for 2.2.
Original comment by michael.hale@gmail.com
on 24 Jun 2012 at 8:00
Original issue reported on code.google.com by
michael.hale@gmail.com
on 1 Jun 2012 at 1:44