issue #306 - _POOL_HEADER class based on OS

This commit is contained in:
Dave Lassalle
2020-08-22 22:27:46 +01:00
committed by ikelos
parent 288a017178
commit 09ca2ecb40
3 changed files with 40 additions and 5 deletions
@@ -85,11 +85,11 @@ class PoolHeaderScanner(interfaces.layers.ScannerInterface):
if constraint.page_type is not None:
checks_pass = False
if (constraint.page_type & PoolType.FREE) and header.PoolType == 0:
if (constraint.page_type & PoolType.FREE) and header.is_free_pool():
checks_pass = True
elif (constraint.page_type & PoolType.PAGED) and header.PoolType % 2 == 0 and header.PoolType > 0:
elif (constraint.page_type & PoolType.NONPAGED) and header.is_nonpaged_pool():
checks_pass = True
elif (constraint.page_type & PoolType.NONPAGED) and header.PoolType % 2 == 1:
elif (constraint.page_type & PoolType.PAGED) and header.is_paged_pool:
checks_pass = True
if not checks_pass:
@@ -202,6 +202,9 @@ class PoolScanner(plugins.PluginInterface):
fallback_checks = [("_OBJECT_HEADER", "TypeIndex", True),
("_HANDLE_TABLE", "HandleCount", True)])
is_vista_or_later = os_distinguisher(version_check = lambda x: x >= (6, 0),
fallback_checks = [("KdCopyDataBlock", None, True)])
def _generator(self):
symbol_table = self.config["nt_symbols"]
@@ -445,13 +448,19 @@ class PoolScanner(plugins.PluginInterface):
else:
pool_header_json_filename = "poolheader-x86"
is_vista_or_later = cls.is_vista_or_later(context, symbol_table)
if is_vista_or_later:
class_type = extensions.pool.POOL_HEADER_VISTA
else:
class_type = extensions.pool.POOL_HEADER
new_table_name = intermed.IntermediateSymbolTable.create(
context = context,
config_path = configuration.path_join(context.symbol_space[symbol_table].config_path, "poolheader"),
sub_path = "windows",
filename = pool_header_json_filename,
table_mapping = {'nt_symbols': symbol_table},
class_types = {'_POOL_HEADER': extensions.pool.POOL_HEADER})
class_types = {'_POOL_HEADER': class_type})
module = context.module(new_table_name, layer_name, offset = 0)
return module
@@ -36,7 +36,10 @@ class WindowsKernelIntermedSymbols(intermed.IntermediateSymbolTable):
# This doesn't exist in very specific versions of windows
try:
self.set_type_class('_POOL_HEADER', pool.POOL_HEADER)
if self.get_type("_POOL_TRACKER_BIG_PAGES").has_member("PoolType"):
self.set_type_class('_POOL_HEADER', pool.POOL_HEADER_VISTA)
else:
self.set_type_class('_POOL_HEADER', pool.POOL_HEADER)
except ValueError:
pass
@@ -165,6 +165,29 @@ class POOL_HEADER(objects.StructType):
pass
return headers, sizes
def is_free_pool(self):
return self.PoolType == 0
def is_paged_pool(self):
return self.PoolType % 2 == 0 and self.PoolType > 0
def is_nonpaged_pool(self):
return self.PoolType % 2 == 1
class POOL_HEADER_VISTA(POOL_HEADER):
"""A kernel pool allocation header, updated for Vista and later.
Exists at the base of the allocation and provides a tag that we can
scan for.
"""
def is_paged_pool(self):
return self.PoolType % 2 == 1
def is_nonpaged_pool(self):
return self.PoolType % 2 == 0 and self.PoolType > 0
class POOL_TRACKER_BIG_PAGES(objects.StructType):
"""A kernel big page pool tracker."""