Closed GoogleCodeExporter closed 9 years ago
Michael,
You can create your own class to handle this, e.g.:
class OrFlags(obj.NATIVE_TYPE):
def __init__(self, theType, offset, vm, parent = None,
target = "long", choices=None):
self.choices = choices
... call baseclass ...
def v(self):
return [f for f in self.choices if self.choices[f] & val]
The in your plugin add this to the profile's object classes
AbstractWindows.object_classes['OrFlags'] = OrFlags
and overlay like you had before. Remember to call profile.add_types() to
recompile the vtypes.
You should be able to just do SERVICE_TYPES.v() to get the breakdown.
Original comment by scude...@gmail.com
on 30 Sep 2011 at 7:22
On second look are you not really looking for a bitmap here? Remember that the
bitmap value is the single bit position which selects that value:
bitmap = dict(
SERVICE_KERNEL_DRIVER = 0x01,
SERVICE_FILE_SYSTEM_DRIVER = 0x02,
SERVICE_WIN32_OWN_PROCESS = 0x4,
SERVICE_WIN32_SHARE_PROCESS = 0x6,
SERVICE_INTERACTIVE_PROCESS = 0x9,
)
Currently the str() method separates the values with a ,. It might be a good
idea to change the .v() method to return a list of strings.
Original comment by scude...@gmail.com
on 30 Sep 2011 at 7:30
Thanks Scudette, you're a huge help. I'm about the try the
OrFlags(obj.NativeType) method. I don't think bitmap is what I need after
giving that a shot. Here's the bitmap method:
'Type' : [ 0x28, ['Flags', {'bitmap': {'SERVICE_KERNEL_DRIVER': 0x1,
'SERVICE_FILE_SYSTEM_DRIVER': 0x2, 'SERVICE_WIN32_OWN_PROCESS': 0x10,
'SERVICE_WIN32_SHARE_PROCESS': 0x20, 'SERVICE_INTERACTIVE_PROCESS': 0x100}}]],
When the actual value is 0x1, 0x10, 0x20, 0x110, or 0x120, the result of
printing object.Type or str(object.Type) is just an empty string. If the actual
value is 0x2, it prints "SERVICE_KERNEL_DRIVER". Does that make sense? Does it
look like I'm using the bitmap method correctly?
Anyway, I'll let you know how the OrFlags(obj.NativeType) method goes. That for
sure should work, just wanted to try and avoid writing the extra code if not
necessary.
Original comment by michael.hale@gmail.com
on 30 Sep 2011 at 11:48
Alright, the OrFlags(obj.NativeType) method worked. Here's what I did just for
documentation purposes.
The type is like this:
'Type' : [ 0x28, ['OrFlags', dict(target = 'long', choices = {1:
'SERVICE_KERNEL_DRIVER', 2: 'SERVICE_FILE_SYSTEM_DRIVER', 0x10:
'SERVICE_WIN32_OWN_PROCESS', 0x20: 'SERVICE_WIN32_SHARE_PROCESS', 0x100:
'SERVICE_INTERACTIVE_PROCESS'})]],
The class looks like this:
class OrFlags(obj.NativeType):
"Classic OR flag handler"
def __init__(self, theType = None, offset = 0, vm = None, parent = None,
choices = None, name = None, target = "unsigned long",
**args):
self.choices = choices or {}
self.target_obj = obj.Object(target, offset = offset, vm = vm, parent = parent)
obj.NativeType.__init__(self, theType, offset, vm, parent, **args)
def v(self):
return self.target_obj.v()
def __str__(self):
value = self.v()
try:
return self.choices[value]
except KeyError:
return ' | '.join([self.choices[f] for f in self.choices.keys() if f & value])
In the plugin, I added the class like this:
addr_space.profile.object_classes['OrFlags'] = OrFlags
So, Scudette, my two questions for you are:
1) Do you agree that a separate obj.NativeType like OrFlags is required for
this functionality, as opposed to using bitmaps with the Flags class?
2) If yes, do you think we should include OrFlags in basic.py for use by other
plugins (for example it could be used instead of this:
http://code.google.com/p/volatility/source/browse/trunk/volatility/win32/rawreg.
py#137)
Thanks again...
Original comment by michael.hale@gmail.com
on 1 Oct 2011 at 1:56
Argh sorry I am lousy doing maths in my head. So the Flags class takes a bitmap
parameter which is a dict. The keys of the DICT are the flag values and the
values are the bit position which signifies the flag is set. The example you
gave is:
SERVICE_TYPES = dict(
SERVICE_KERNEL_DRIVER = 0x01,
SERVICE_FILE_SYSTEM_DRIVER = 0x02,
SERVICE_WIN32_OWN_PROCESS = 0x10,
SERVICE_WIN32_SHARE_PROCESS = 0x20,
SERVICE_INTERACTIVE_PROCESS = 0x100,
)
so the SERVICE_KERNEL_DRIVER is on when the 0'th bit is on (i.e. & 0x1). The
numbers are related via a logarithmic relation (e.g. math.log(0x100, 2) = 8
etc).
So the bitmap should be:
bitmap = dict(
SERVICE_KERNEL_DRIVER = 0x0,
SERVICE_FILE_SYSTEM_DRIVER = 0x01,
SERVICE_WIN32_OWN_PROCESS = 0x4,
SERVICE_WIN32_SHARE_PROCESS = 0x5,
SERVICE_INTERACTIVE_PROCESS = 0x8,
)
It might be easier to just add an additional parameter to the Flags class so it
can be initialized in the way you prefer to think about it (i.e. with mask
types). Although it actually does not make any practical sense to specify flags
in term of non whole powers of 2 so I would doubt there are instances of flags
which really work this way.
Original comment by scude...@gmail.com
on 1 Oct 2011 at 11:58
Alright, I'll go with the Flags:bitmap method using math.log versions of the
actual constants. It's a little less readable than I'd hoped for (since you'd
expect to see the same constants used in windows source code or in C header
files), but at least this way we don't have to change anything. Final version
just for documentation purposes is:
'Type' : [ 0x28, ['Flags', {'bitmap': {'SERVICE_KERNEL_DRIVER': 0, 'SERVICE_FILE_SYSTEM_DRIVER': 1, 'SERVICE_WIN32_OWN_PROCESS': 4, 'SERVICE_WIN32_SHARE_PROCESS': 5, 'SERVICE_INTERACTIVE_PROCESS': 8}}]],
Thanks guys!
Original comment by michael.hale@gmail.com
on 20 Oct 2011 at 12:48
Original issue reported on code.google.com by
michael.hale@gmail.com
on 30 Sep 2011 at 6:12