From dd0da529abde549f02e640d746e336d09321e7ae Mon Sep 17 00:00:00 2001 From: Michael Ligh Date: Tue, 14 Nov 2017 08:03:36 -0600 Subject: [PATCH] Move wow64 code to windows64.py and don't apply wow64 types globally --- .../plugins/overlays/windows/pe_vtypes.py | 66 +---------------- .../plugins/overlays/windows/windows.py | 16 ----- .../plugins/overlays/windows/windows64.py | 70 +++++++++++++++++++ 3 files changed, 72 insertions(+), 80 deletions(-) diff --git a/volatility/plugins/overlays/windows/pe_vtypes.py b/volatility/plugins/overlays/windows/pe_vtypes.py index 18942a20..554f1f47 100644 --- a/volatility/plugins/overlays/windows/pe_vtypes.py +++ b/volatility/plugins/overlays/windows/pe_vtypes.py @@ -18,12 +18,11 @@ # along with Volatility. If not, see . # -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']]], - }]}) \ No newline at end of file + }) \ No newline at end of file diff --git a/volatility/plugins/overlays/windows/windows.py b/volatility/plugins/overlays/windows/windows.py index ebeb615b..311591e9 100644 --- a/volatility/plugins/overlays/windows/windows.py +++ b/volatility/plugins/overlays/windows/windows.py @@ -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, diff --git a/volatility/plugins/overlays/windows/windows64.py b/volatility/plugins/overlays/windows/windows64.py index 6ecead71..48157535 100644 --- a/volatility/plugins/overlays/windows/windows64.py +++ b/volatility/plugins/overlays/windows/windows64.py @@ -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']]], + }]}) \ No newline at end of file