Move wow64 code to windows64.py and don't apply wow64 types globally

This commit is contained in:
Michael Ligh
2017-11-14 08:03:36 -06:00
parent b4c70ff6db
commit dd0da529ab
3 changed files with 72 additions and 80 deletions
@@ -18,12 +18,11 @@
# along with Volatility. If not, see <http://www.gnu.org/licenses/>.
#
import struct, copy
import struct
import volatility.exceptions as exceptions
import volatility.obj as obj
import volatility.debug as debug
import volatility.addrspace as addrspace
import volatility.registry as registry
pe_vtypes = {
'_IMAGE_EXPORT_DIRECTORY': [ 0x28, {
@@ -1043,65 +1042,4 @@ class WinPEObjectClasses(obj.ProfileModification):
'_VS_FIXEDFILEINFO': _VS_FIXEDFILEINFO,
'_VS_VERSION_INFO': _VS_VERSION_INFO,
'VerStruct': VerStruct,
})
# apply to any 64bit version of Windows
class WinPeb32(obj.ProfileModification):
conditions = {'os': lambda x: x == 'windows',
'memory_model': lambda x: x == '64bit'}
before = ['WinPEVTypes', 'WinPEx64VTypes', 'WinPEObjectClasses', 'WindowsObjectClasses']
def cast_as_32bit(self, source_vtype):
vtype = copy.copy(source_vtype)
# the members of the structure
members = vtype[1]
mapping = {
"pointer": "pointer32",
"_UNICODE_STRING": "_UNICODE32_STRING",
"_LIST_ENTRY": "LIST_ENTRY32",
}
for name, member in members.items():
datatype = member[1][0]
if datatype in mapping:
member[1][0] = mapping[datatype]
return vtype
def modification(self, profile):
profiles = registry.get_plugin_classes(obj.Profile)
meta = profile.metadata
# find the equivalent 32-bit profile to this 64-bit profile
profile_32bit = None
for prof in profiles.values():
if (prof._md_major == meta.get("major") and
prof._md_minor == meta.get("minor") and
prof._md_build == meta.get("build") and
prof._md_memory_model == "32bit"):
profile_32bit = prof()
break
if profile_32bit == None:
debug.warning("Cannot find a 32-bit equivalent profile. The "\
"WoW64 plugins (dlllist, ldrmodules, etc) may not work.")
return
profile.vtypes.update({
"_PEB32_LDR_DATA": self.cast_as_32bit(profile_32bit.vtypes["_PEB_LDR_DATA"]),
"_LDR32_DATA_TABLE_ENTRY": self.cast_as_32bit(profile_32bit.vtypes["_LDR_DATA_TABLE_ENTRY"]),
'_UNICODE32_STRING': self.cast_as_32bit(profile_32bit.vtypes["_UNICODE_STRING"]),
})
profile.object_classes.update({
"_LDR32_DATA_TABLE_ENTRY": _LDR_DATA_TABLE_ENTRY
})
profile.merge_overlay({
'_PEB32': [None, {
'Ldr': [None, ['pointer32', ['_PEB32_LDR_DATA']]],
}]})
})
@@ -255,11 +255,6 @@ class _LIST_ENTRY(obj.CType):
def __iter__(self):
return self.list_of_type(self.obj_parent.obj_name, self.obj_name)
# for LIST_ENTRY32, the LDR member is an unsigned long not a Pointer as regular LIST_ENTRY
class LIST_ENTRY32(_LIST_ENTRY):
def get_next_entry(self, member):
return obj.Object("LIST_ENTRY32", offset = self.m(member).v(), vm = self.obj_vm)
class WinTimeStamp(obj.NativeType):
"""Class for handling Windows Time Stamps"""
@@ -1212,14 +1207,6 @@ import kdbg_vtypes
import tcpip_vtypes
import ssdt_vtypes
unicode32_vtypes = {
'_UNICODE32_STRING' : [ 12, {
'Length' : [ 0x0, ['unsigned short']],
'MaximumLength' : [ 0x2, ['unsigned short']],
'Buffer' : [ 0x4, ['pointer32', ['unsigned short']]],
}],
}
class WindowsOverlay(obj.ProfileModification):
conditions = {'os': lambda x: x == 'windows'}
before = ['BasicObjectClasses', 'WindowsVTypes']
@@ -1237,7 +1224,6 @@ class WindowsVTypes(obj.ProfileModification):
profile.vtypes.update(kdbg_vtypes.kdbg_vtypes)
profile.vtypes.update(tcpip_vtypes.tcpip_vtypes)
profile.vtypes.update(ssdt_vtypes.ssdt_vtypes)
profile.vtypes.update(unicode32_vtypes)
class WindowsObjectClasses(obj.ProfileModification):
conditions = {'os': lambda x: x == 'windows'}
@@ -1246,9 +1232,7 @@ class WindowsObjectClasses(obj.ProfileModification):
def modification(self, profile):
profile.object_classes.update({
'_UNICODE_STRING': _UNICODE_STRING,
'_UNICODE32_STRING': _UNICODE_STRING,
'_LIST_ENTRY': _LIST_ENTRY,
'LIST_ENTRY32': LIST_ENTRY32,
'WinTimeStamp': WinTimeStamp,
'DosDate':DosDate,
'_EPROCESS': _EPROCESS,
@@ -21,6 +21,9 @@
import copy
import volatility.obj as obj
import volatility.plugins.overlays.windows.windows as windows
import volatility.plugins.overlays.windows.pe_vtypes as pe_vtypes
import volatility.registry as registry
import volatility.debug as debug
# File-wide pylint message disable because we have a few situations where we access structs starting _
#pylint: disable-msg=W0212
@@ -38,6 +41,11 @@ class Pointer64Decorator(object):
class _EX_FAST_REF(windows._EX_FAST_REF):
MAX_FAST_REF = 15
class LIST_ENTRY32(windows._LIST_ENTRY):
"""the LDR member is an unsigned long not a Pointer as regular LIST_ENTRY"""
def get_next_entry(self, member):
return obj.Object("LIST_ENTRY32", offset = self.m(member).v(), vm = self.obj_vm)
class ExFastRefx64(obj.ProfileModification):
before = ['WindowsOverlay', 'WindowsObjectClasses']
conditions = {'os': lambda x : x == 'windows',
@@ -78,3 +86,65 @@ class Windows64Overlay(obj.ProfileModification):
# and therefore can't just be instantiated in object_classes
# using profile.object_classes.update({'pointer64': obj.Pointer})
profile._list_to_type = Pointer64Decorator(profile._list_to_type)
class WinPeb32(obj.ProfileModification):
conditions = {'os': lambda x: x == 'windows',
'memory_model': lambda x: x == '64bit'}
before = ['WinPEVTypes', 'WinPEx64VTypes', 'WinPEObjectClasses', 'WindowsObjectClasses']
def cast_as_32bit(self, source_vtype):
vtype = copy.copy(source_vtype)
# the members of the structure
members = vtype[1]
mapping = {
"pointer": "pointer32",
"_UNICODE_STRING": "_UNICODE32_STRING",
"_LIST_ENTRY": "LIST_ENTRY32",
}
for name, member in members.items():
datatype = member[1][0]
if datatype in mapping:
member[1][0] = mapping[datatype]
return vtype
def modification(self, profile):
profiles = registry.get_plugin_classes(obj.Profile)
meta = profile.metadata
# find the equivalent 32-bit profile to this 64-bit profile
profile_32bit = None
for prof in profiles.values():
if (prof._md_major == meta.get("major") and
prof._md_minor == meta.get("minor") and
prof._md_build == meta.get("build") and
prof._md_memory_model == "32bit"):
profile_32bit = prof()
break
if profile_32bit == None:
debug.warning("Cannot find a 32-bit equivalent profile. The "\
"WoW64 plugins (dlllist, ldrmodules, etc) may not work.")
return
profile.vtypes.update({
"_PEB32_LDR_DATA": self.cast_as_32bit(profile_32bit.vtypes["_PEB_LDR_DATA"]),
"_LDR32_DATA_TABLE_ENTRY": self.cast_as_32bit(profile_32bit.vtypes["_LDR_DATA_TABLE_ENTRY"]),
'_UNICODE32_STRING': self.cast_as_32bit(profile_32bit.vtypes["_UNICODE_STRING"]),
})
profile.object_classes.update({
"_LDR32_DATA_TABLE_ENTRY": pe_vtypes._LDR_DATA_TABLE_ENTRY,
"_UNICODE32_STRING": windows._UNICODE_STRING,
"LIST_ENTRY32": LIST_ENTRY32,
})
profile.merge_overlay({
'_PEB32': [None, {
'Ldr': [None, ['pointer32', ['_PEB32_LDR_DATA']]],
}]})