Flesh out symbol system, reworking several parts. Still requires on-demand resolving of symbols.

This commit is contained in:
Mike Auty
2013-04-14 20:17:15 +01:00
parent 3dab0a3418
commit b0345ce9ab
10 changed files with 415 additions and 177 deletions
+14 -6
View File
@@ -4,14 +4,22 @@ Created on 10 Mar 2013
@author: mike
'''
from volatility.framework import xp_sp2_x86_vtypes, symbols
from volatility.framework import xp_sp2_x86_vtypes, context
from volatility.framework.symbols import vtypes, native
if __name__ == '__main__':
vtypes = xp_sp2_x86_vtypes.ntkrnlmp_types
virtual_types = xp_sp2_x86_vtypes.ntkrnlmp_types
ntkrnlmp = vtypes.VTypeSymbolList('ntkrnlmp', virtual_types)
native = native.x86NativeSymbolList
ctx = context.Context()
ctx.add_symbol_list(native)
ctx.add_symbol_list(ntkrnlmp)
print("Symbols,", native.symbols)
ntkrnlmp = symbols.VTypeSymbolList('ntkrnlmp', vtypes)
sspace = symbols.SymbolSpace()
sspace.append(ntkrnlmp)
for i in ntkrnlmp.symbols:
print(sspace.resolve('ntkrnlmp!' + i))
symbol = ctx.resolve('ntkrnlmp!' + i)
print(symbol)
# objthing = symbol(context, layer_name = '', offset = 0)
+9 -9
View File
@@ -5,7 +5,6 @@ Created on 12 Feb 2013
'''
import volatility.framework.symbols as symbols
import volatility.framework.exceptions as exceptions
class Context(object):
"""Maintains the context within which to construct objects"""
@@ -18,14 +17,15 @@ class Context(object):
def add_symbol_list(self, symbol_list):
"""Adds a symbol list to the symbol space used by the context"""
if symbol_list.name in self._symbol_space:
raise exceptions.SymbolSpaceError("Symbol list " + symbol_list.name + " already exists in this space.")
self._symbol_space[symbol_list.name] = symbol_list
self._symbol_space.append(symbol_list)
def remove_symbol_list(self, symbol_list_name):
if not symbol_list_name in self._symbol_space:
raise exceptions.SymbolSpaceError("No symbol list named " + symbol_list_name + " present in the symbol space.")
del self._symbol_space[symbol_list_name]
"""Removes a symbol list from the symbol space used by the context"""
self._symbol_space.remove(symbol_list_name)
def resolve(self, symbol_name):
"""Resolves a symbol name from the various symbol lists in the symbol space"""
return self._symbol_space.resolve(symbol_name)
### Address Space Functions
@@ -35,7 +35,7 @@ class Context(object):
### Object Factory Functions
def object(self, symbol, offset, layername = None):
def object(self, symbol, layer_name, offset):
"""Object factory, takes a context, symbol, offset and optional layername
Looks up the layername in the context, finds the object template based on the symbol,
@@ -44,5 +44,5 @@ class Context(object):
Returns a fully constructed object
"""
object_template = self._symbol_space.resolve(symbol)
return object_template(v)
return object_template(self, layer_name = layer_name, offset = offset)
+18
View File
@@ -0,0 +1,18 @@
'''
Created on 12 Apr 2013
@author: mike
'''
class ObjectInterface(object):
""" A base object required to be the ancestor of every object used in volatility """
def __init__(self, context, layer_name, offset, symbol_name, size, **kwargs):
self._context = context
self._offset = offset
self._layer_name = layer_name
self._symbol_name = symbol_name
self._size = size
def cast(self, new_symbol_name):
object_template = self._context.resolve()
return object_template(context = self._context, layer_name = self._layer_name, offset = self._offset)
+46 -14
View File
@@ -6,18 +6,10 @@ Created on 17 Feb 2013
import struct
import collections
import volatility.framework.interfaces as interfaces
import volatility.framework.templates as templates
class ObjectInterface(object):
""" A base object required to be the ancestor of every object used in volatility """
def __init__(self, context, layer_name, offset, symbol_name, size, **kwargs):
self._context = context
self._offset = offset
self._layer_name = layer_name
self._symbol_name = symbol_name
self._size = size
class PrimitiveObject(ObjectInterface):
class PrimitiveObject(interfaces.ObjectInterface):
"""PrimitiveObject is an interface for any objects that should simulate a Python primitive"""
@classmethod
@@ -32,7 +24,7 @@ class Integer(PrimitiveObject, int):
"""Primitive Object that handles standard numeric types"""
def __new__(cls, context, layer_name, offset, symbol_name, struct_format, **kwargs):
struct_format, struct_size = context.get_primitive_struct_type("int", symbol_name)
struct_format = context.get_primitive_struct_type("int", symbol_name)
struct_size = struct.calcsize(struct_format)
return cls._struct_value(struct_format, context, layer_name, offset, symbol_name, size = struct_size)
@@ -40,7 +32,7 @@ class Float(PrimitiveObject, float):
"""Primitive Object that handles double or floating point numbers"""
def __new__(cls, context, layer_name, offset, symbol_name, size, **kwargs):
struct_format, struct_size = context.get_primitive_struct_type("float", symbol_name)
struct_format = context.get_primitive_struct_type("float", symbol_name)
struct_size = struct.calcsize(struct_format)
return cls._struct_value(struct_format, context, layer_name, offset, symbol_name, size = struct_size)
@@ -60,7 +52,41 @@ class String(PrimitiveObject, str):
def __new__(cls, context, layer_name, offset, symbol_name, size = None, length = 1):
return cls._struct_value(str(length) + "s", context, layer_name, offset, symbol_name, size)
class Struct(ObjectInterface):
class Pointer(Integer):
"""Pointer which points to another object"""
def __init__(self, context, layer_name, offset, symbol_name, size = None, target = None):
if not isinstance(target, interfaces.ObjectInterface):
raise TypeError("Pointer targets must be an ObjectInterface")
super(Pointer, self).__init__(context, layer_name, offset, symbol_name, size)
self._target = target
def derefenence(self):
"""Dereferences the pointer"""
# Cache the target
if isinstance(self._target, templates.ObjectTemplate):
self._target = self.target(context = self._context, layer_name = self._layer_name, offset = self, self = self._target.size, parent = self)
return self._target
def __getattr__(self, attr):
"""Convenience function to access unknown attributes by getting them from the target object"""
return getattr(self.dereference(), attr)
class BitField(Integer):
""""""
def __new__(self, context, layer_name, offset, symbol_name, size = None, start_bit = 0, end_bit = 0):
# TODO: Determine endianness of the bitfield
struct_size = (end_bit + 7) // 8
if struct_size == 1:
struct_format = "c"
elif struct_size <= 2:
struct_format = "H"
elif struct_size <= 4:
struct_format = "I"
else:
struct_format = "Q"
return super(BitField, self).__new__(context, layer_name, offset, symbol_name, size = None, struct_format = struct_format)
class Struct(interfaces.ObjectInterface):
"""Object which can contain members that are other objects"""
def __init__(self, context, layer_name, offset, symbol_name, size = None, members = None):
@@ -79,6 +105,12 @@ class Struct(ObjectInterface):
self._members = members
def __getattr__(self, attr):
"""Method for accessing members of the structure"""
if attr in self._members:
return self._members[attr]
member = self._members[attr]
# Cache the constructed object
if isinstance(member, templates.ObjectTemplate):
member = member(context = self.context, layer_name = self.layer_name, offset = self.offset + member.relative_offset, parent = self)
self._members[attr] = member
return member
raise AttributeError("'" + self._symbol_name + "' Struct has no attribute '" + attr + "'")
-137
View File
@@ -1,137 +0,0 @@
'''
Created on 7 Feb 2013
@author: mike
'''
import volatility.framework.exceptions as exceptions
from volatility.framework import templates
from volatility.framework import obj
class SymbolSpace(list):
"""Handles a collection of SymbolLists"""
def resolve(self, symbol):
symarr = symbol.split("!")
if len(symarr) == 2:
listname = symarr[0]
symname = symarr[1]
for symlist in self:
if symlist.name == listname:
if symname in symlist:
return symlist.resolve(symname)
else:
raise exceptions.SymbolNotFoundException("Symbol " + symname + " could not be found in the " + listname + " list")
else:
raise exceptions.SymbolNotFoundException("Symbol list " + listname + " was not present in the symbol space")
elif len(symarr) == 1:
for slist in self:
if symbol in slist:
return slist.resolve(symbol)
else:
raise exceptions.SymbolNotFoundException("Symbol " + symbol + " could not be found in any symbol list")
else:
raise exceptions.SymbolNotFoundException("Malformed symbol name")
# Consider maintaining a list of symbollist names
# A list of potentially conflicting symbols (for when no listname is provided)
class SymbolListInterface(object):
"""Handles a list of symbols"""
def __init__(self, name, *args, **kwargs):
super(SymbolListInterface, self).__init__(*args, **kwargs)
if not isinstance(name, str) or not name:
raise exceptions.SymbolSpaceError("Symbol lists cannot be nameless")
self.name = name
### Required Symbol List functions
def resolve(self, symbol):
"""Resolves a symbol name into an object template"""
@property
def symbols(self):
"""Returns an iterator of the symbol names"""
def set_object_class(self, symbol, clazz):
"""Overrides the object class for a specific symbol"""
def get_object_class(self, symbol):
"""Returns the class associated with a symbol"""
### Helper functions that can be overridden
def __len__(self):
"""Returns the number of items in the symbol list"""
return len(self.symbols)
def __getitem__(self, key):
"""Resolves a symbol name into an object template"""
return self.resolve(key)
def __iter__(self):
"""Returns an iterator of the available keys"""
return self.symbols
def __contains__(self, symbol):
"""Determines whether a symbol exists in the list or not"""
return symbol in self.symbols
class VTypeSymbolList(SymbolListInterface):
"""Symbol List that handles"""
def __init__(self, name, vtype_dictionary):
super(VTypeSymbolList, self).__init__(name)
self._vtypedict = vtype_dictionary
self._classdict = {}
def _vtypedict_to_template(self, dictionary):
"""Converts a vtypedict into an object template"""
if not dictionary:
raise exceptions.SymbolSpaceError("Invalid vtype dictionary: " + repr(dictionary))
# print(repr(dictionary))
symbol_name = dictionary[0]
result = {"objclass": self.get_object_class(symbol_name), "symbol_name": symbol_name, "size" : 0}
# Handle specific vtypes
if symbol_name == 'array':
result["length"] = dictionary[1]
result["target"] = templates.ObjectTemplate(**self._vtypedict_to_template(dictionary[2]))
result["size"] = dictionary[1] * result["target"].size
elif symbol_name == 'pointer':
result["target"] = templates.ObjectTemplate(**self._vtypedict_to_template(dictionary[1]))
elif symbol_name == 'Enumeration':
result.update(dictionary[1])
result["target"] = templates.ObjectTemplate(**self._vtypedict_to_template([result["target"]]))
elif symbol_name == 'BitField':
result["fields"] = dictionary[1]
elif len(dictionary) > 1:
raise exceptions.SymbolSpaceError("Unknown vtype format: " + repr(dictionary))
# print(result)
return result
def set_object_class(self, key, value):
"""Overrides a symbol's class from a Struct to the value"""
self._classdict[key] = value
def get_object_class(self, key):
return self._classdict.get(key, obj.Struct)
@property
def symbols(self):
"""Returns an iterator of the symbol names"""
return set(self._classdict.keys()).union(set(self._vtypedict.keys()))
def resolve(self, symbolname):
if symbolname not in self._vtypedict:
raise exceptions.SymbolNotFoundException
size, curdict = self._vtypedict[symbolname]
members = []
for item in curdict:
relative_offset, vtypedict = curdict[item]
member = templates.MemberTemplate(relative_offset = relative_offset, **self._vtypedict_to_template(vtypedict))
members.append(member)
return templates.ObjectTemplate(self.get_object_class(symbolname), symbol_name = symbolname, size = size, members = members)
+141
View File
@@ -0,0 +1,141 @@
'''
Created on 7 Feb 2013
@author: mike
'''
import collections
import volatility.framework.exceptions as exceptions
from volatility.framework import obj, templates, interfaces
from volatility.framework.exceptions import SymbolNotFoundException
class SymbolSpace(collections.Mapping):
"""Handles an ordered collection of SymbolLists
This collection is ordered so that resolution of symbols can
proceed down through the ranks if a namespace isn't specified.
"""
def __init__(self):
self._dict = collections.OrderedDict()
def __len__(self):
return len(self._dict)
def __getitem__(self, i):
return self._dict[i]
def __iter__(self):
return self._dict.__iter__(self)
def append(self, value):
"""Adds a symbol_list to the end of the space"""
if not isinstance(value, SymbolListInterface):
raise TypeError(value)
if value.name in self._dict:
del self._dict[value.name]
self._dict[value.name] = value
def remove(self, key):
"""Removes a named symbol_list from the space"""
del self._dict[key]
def resolve(self, symbol, start_from = None):
"""Takes a symbol name and resolves it"""
symarr = symbol.split("!")
if len(symarr) == 2:
listname = symarr[0]
symname = symarr[1]
for symlistname in reversed(self._dict):
if symlistname == listname:
if symname in self[symlistname]:
return self[symlistname].resolve(symname, self)
else:
raise exceptions.SymbolNotFoundException("Symbol \"" + symname + "\" could not be found in the \"" + listname + "\" list")
else:
raise exceptions.SymbolNotFoundException("Symbol list \"" + listname + "\" was not present in the symbol space")
elif len(symarr) == 1:
# Establish skipping all elements before the symbol list to start from
skip = (start_from is not None)
for slist in reversed(self._dict):
if skip:
skip = (slist.name != start_from)
else:
if symbol in self[slist]:
return self[slist].resolve(symbol, self)
else:
if skip:
raise exceptions.SymbolSpaceError("Symbol search for \"" + symbol + "\" failed because symbol list \"" + start_from.name + "\" is not in the search space")
raise exceptions.SymbolNotFoundException("Symbol \"" + symbol + "\" could not be found in any symbol list")
else:
raise exceptions.SymbolNotFoundException("Malformed symbol name")
raise RuntimeError("Symbol Space Resolution hit an unexpected branch!")
class SymbolListInterface(object):
"""Handles a list of symbols"""
def __init__(self, name, symbol_space = None, *args, **kwargs):
super(SymbolListInterface, self).__init__(*args, **kwargs)
if not isinstance(name, str) or not name:
raise exceptions.SymbolSpaceError("Symbol lists cannot be nameless")
self.name = name
self._overrides = {}
### Required Symbol List functions
def resolve(self, symbol, symbol_space = None):
"""Resolves a symbol name into an object template
symbol_space is used to resolve any target symbols if they don't exist in this list
"""
@property
def symbols(self):
"""Returns an iterator of the symbol names"""
### Functions for overriding classes
def set_symbol_class(self, symbol, clazz):
"""Overrides the object class for a specific symbol
We can only override existing classes, otherwise determining the complete symbol list
will become complicated for each subclass.
"""
if not symbol in self.symbols:
raise exceptions.SymbolNotFoundException("Cannot override \"" + symbol + "\" in \"" + self.name + "\", symbol not already present")
if not issubclass(clazz, interfaces.ObjectInterface):
raise exceptions.SymbolSpaceError("Attempting to add an object that does not inherit from ObjectInterface as a symbol class override")
self._overrides[symbol] = clazz
def has_symbol_class(self, symbol):
"""Returns whether the symbol's class has bee overridden or not"""
return symbol in self._overrides
def get_symbol_class(self, symbol):
"""Returns the class associated with a symbol or None if there is no associated symbol
"""
return self._overrides[symbol]
def del_symbol_class(self, symbol):
"""Removes the associated class override for a specific symbol"""
del self._overrides[symbol]
### Helper functions that can be overridden
def __len__(self):
"""Returns the number of items in the symbol list"""
return len(self.symbols)
def __getitem__(self, key):
"""Resolves a symbol name into an object template"""
return self.resolve(key)
def __iter__(self):
"""Returns an iterator of the available keys"""
return self.symbols
def __contains__(self, symbol):
"""Determines whether a symbol exists in the list or not"""
return symbol in self.symbols
+58
View File
@@ -0,0 +1,58 @@
'''
Created on 10 Apr 2013
@author: mike
'''
import copy
import struct
import volatility.framework.obj as obj
import volatility.framework.symbols as symbols
import volatility.framework.templates as templates
import volatility.framework.exceptions as exceptions
class NativeSymbolList(symbols.SymbolListInterface):
"""Symbol List that handles Native types"""
def __init__(self, name, native_dictionary):
super(NativeSymbolList, self).__init__(name)
self._native_dictionary = native_dictionary
for item in self._native_dictionary:
self._overrides[item] = obj.Integer
@property
def symbols(self):
return self._native_dictionary.keys()
def resolve(self, symbol, symbol_space = None):
"""Resolve the native symbols by looking up their struct types in a dictionary"""
if symbol in self._native_dictionary:
fmt = self._native_dictionary[symbol]
return templates.ObjectTemplate(self.get_symbol_class(symbol), symbol_name = symbol, size = struct.calcsize(fmt), format_string = fmt)
if isinstance(symbol_space, symbols.SymbolSpace):
return symbol_space.resolve(symbol, self.name)
raise exceptions.SymbolNotFoundException()
x86_native_types = {'int' : '<i',
'long': '<i',
'unsigned long' : '<I',
'unsigned int' : '<I',
'address' : '<I',
'char' : '<c',
'unsigned char' : '<B',
'unsigned short int' : '<H',
'unsigned short' : '<H',
'unsigned be short' : '>H',
'short' : '<h',
'long long' : '<q',
'unsigned long long' : '<Q',
'void': "<I",
'float': "",
'double': "d"}
x64_native_types = copy.deepcopy(x86_native_types)
x64_native_types['address'] = '<Q'
x86NativeSymbolList = NativeSymbolList("native", x86_native_types)
x64NativeSymbolList = NativeSymbolList("native", x64_native_types)
for ftype in ['double', 'float']:
x86NativeSymbolList.set_symbol_class(ftype, obj.Float)
x64NativeSymbolList.set_symbol_class(ftype, obj.Float)
+98
View File
@@ -0,0 +1,98 @@
'''
Created on 10 Apr 2013
@author: mike
'''
import volatility.framework.exceptions as exceptions
import volatility.framework.symbols as symbols
import volatility.framework.templates as templates
import volatility.framework.obj as obj
### TODO
#
# All symbol lists should take a label to an object template
#
# Templates for targets etc should be looked up recursively just like anything else
# We therefore need a way to unroll rolled-up types
# Generate mangled names on the fly (prohibits external calling)
#
# Symbol list could be a dict with knowledge of its parent?
# Class split is arbitrary, it's an extension for developers
# Object template should contain both class and initial parameters
class VTypeSymbolList(symbols.SymbolListInterface):
"""Symbol List that handles vtype datastructures"""
def __init__(self, name, vtype_dictionary):
super(VTypeSymbolList, self).__init__(name)
self._vtypedict = vtype_dictionary
self._default_object_class = obj.Struct
def _vtypedict_to_template(self, dictionary, symbol_space = None):
"""Converts a vtypedict into an object template"""
if not dictionary:
raise exceptions.SymbolSpaceError("Invalid vtype dictionary: " + repr(dictionary))
# print(repr(dictionary))
symbol_name = dictionary[0]
# Establish the defaults
result = {"object_class": self._default_object_class, "symbol_name": symbol_name, "size" : 0}
# Can we handle the next layer ourselves?
if symbol_name in self.symbols:
# Check if the class has been overridden
if self.has_symbol_class(symbol_name):
result["object_class"] = self.get_symbol_class(symbol_name)
if symbol_name not in self.symbols:
# Handle specific "well known" symbols
if symbol_name == 'array':
result["object_class"] = obj.Integer
result["count"] = dictionary[1]
result["target"] = self._vtypedict_to_template(dictionary[2], symbol_space = symbol_space)
result["size"] = dictionary[1] * result["target"].size
elif symbol_name == 'pointer':
result["object_class"] = obj.Pointer
result["target"] = self._vtypedict_to_template(dictionary[1], symbol_space = symbol_space)
elif symbol_name == 'Enumeration':
result["object_class"] = obj.Integer
result.update(dictionary[1])
result["target"] = self._vtypedict_to_template([result["target"]], symbol_space = symbol_space)
elif symbol_name == 'BitField':
result["object_class"] = obj.Pointer
result["fields"] = dictionary[1]
elif symbol_name == 'void':
result["object_class"] = obj.Integer
elif len(dictionary) > 1:
raise exceptions.SymbolSpaceError("Unknown vtype format: " + repr(dictionary))
elif isinstance(symbol_space, symbols.SymbolSpace):
# Resolve the object class for this
return symbol_space.resolve(symbol_name)
else:
raise exceptions.SymbolNotFoundException("Unable to resolve \"" + symbol_name + "\" in \"" + self.name + "\", no symbol space to rescurse through")
elif self.has_symbol_class(symbol_name):
result["object_class"] = self.get_symbol_class(symbol_name)
print(result)
return templates.ObjectTemplate(**result) #pylint: disable-msg=W0142
@property
def symbols(self):
"""Returns an iterator of the symbol names"""
return self._vtypedict.keys()
def resolve(self, symbol_name, symbol_space = None):
"""Resolves an individual symbol"""
if symbol_name not in self._vtypedict:
raise exceptions.SymbolNotFoundException
size, curdict = self._vtypedict[symbol_name]
members = {}
for member_name in curdict:
relative_offset, vtypedict = curdict[member_name]
member = templates.member_from_object_template(relative_offset = relative_offset, object_template = self._vtypedict_to_template(vtypedict, symbol_space))
members[member_name] = member
object_class = self._default_object_class
if self.has_symbol_class(symbol_name):
object_class = self.get_symbol_class(symbol_name)
return templates.ObjectTemplate(object_class = object_class, symbol_name = symbol_name, size = size, members = members)
+31 -9
View File
@@ -4,6 +4,9 @@ Created on 1 Mar 2013
@author: mike
'''
import copy
import volatility.framework.interfaces as interfaces
class ObjectTemplate(object):
"""Factory class that produces objects that adhere to the Object interface on demand
@@ -13,13 +16,19 @@ class ObjectTemplate(object):
* Members, etc
etc.
"""
def __init__(self, objclass, symbol_name = None, size = None, **kwargs):
self._objclass = objclass
def __init__(self, object_class = None, symbol_name = None, size = None, **kwargs):
if not issubclass(object_class, interfaces.ObjectInterface):
raise TypeError("ObjectTemplate object_class must be a class, not " + str(type(object_class)))
if not isinstance(size, int):
raise TypeError("ObjectTemplate size must be numeric, not " + str(type(size)))
self._size = size
self._symbol_name = symbol_name
self._kwargs = kwargs
self._object_class = object_class
@property
def object_class(self):
return self._object_class
@property
def size(self):
@@ -30,12 +39,26 @@ class ObjectTemplate(object):
"""Returns the name of the symbol if one was provided"""
return self._symbol_name
def __call__(self, context, offset, layer_name, parent = None):
@property
def kwargs(self):
return copy.deepcopy(self._kwargs)
def __call__(self, context, layer_name, offset, parent = None):
"""Constructs the object
Returns: an object adhereing to the Object interface
"""
return self._objclass(context, layer_name, offset, self.symbol_name, self.size, parent, **self._kwargs)
return self._object_class(context = context, layer_name = layer_name, offset = offset, symbol_name = self.symbol_name, size = self.size, parent = parent, **self._kwargs)
def member_from_object_template(relative_offset, object_template):
"""Returns a MemberTemplate based upon an existing ObjectTemplate"""
if not isinstance(object_template, ObjectTemplate):
raise TypeError("object_template must be an ObjectTemplate, not " + str(type(object_template)))
return MemberTemplate(relative_offset = relative_offset,
object_class = object_template.object_class,
symbol_name = object_template.symbol_name,
size = object_template.size,
**object_template.kwargs)
class MemberTemplate(ObjectTemplate):
"""Factory class that produces members of Structs
@@ -43,13 +66,12 @@ class MemberTemplate(ObjectTemplate):
This is just like a normal ObjectTemplate, but contains the relative offset
fron the parent object.
"""
def __init__(self, objclass, symbol_name = None, size = None, relative_offset = None, *args, **kwargs):
def __init__(self, relative_offset, **kwargs):
super(MemberTemplate, self).__init__(**kwargs)
if not isinstance(relative_offset, int):
raise TypeError("MemberTemplate relative_offset must be numeric, not " + str(type(relative_offset)))
self._reloffset = relative_offset
ObjectTemplate.__init__(self, objclass, symbol_name, size, *args, **kwargs)
self._relative_offset = relative_offset
@property
def relative_offset(self):
return self._reloffset
return self._relative_offset
@@ -4261,7 +4261,6 @@ ntkrnlmp_types = {
'DeviceObject' : [ 0x4, ['pointer', ['_DEVICE_OBJECT']]],
} ],
'__unnamed_17fb' : [ 0x4, {
'Srb' : [ 0x0, ['pointer', ['_SCSI_REQUEST_BLOCK']]],
} ],
'__unnamed_17ff' : [ 0x10, {
'Length' : [ 0x0, ['unsigned long']],
@@ -5014,7 +5013,6 @@ ntkrnlmp_types = {
'OpenRoutine' : [ 0x2c, ['pointer', ['void']]],
'WriteRoutine' : [ 0x30, ['pointer', ['void']]],
'FinishRoutine' : [ 0x34, ['pointer', ['void']]],
'AdapterObject' : [ 0x38, ['pointer', ['_ADAPTER_OBJECT']]],
'MappedRegisterBase' : [ 0x3c, ['pointer', ['void']]],
'PortConfiguration' : [ 0x40, ['pointer', ['void']]],
'CrashDump' : [ 0x44, ['unsigned char']],