def get_symbol(self, name: str) -> interfaces.symbols.SymbolInterface: """Returns the symbol given by the symbol name.""" if self._symbol_cache.get(name, None): return self._symbol_cache[name] symbol = self._json_object['symbols'].get(name, None) if not symbol: raise exceptions.SymbolError(name, self.name, f"Unknown symbol: {name}") address = symbol['address'] if self.config.get('symbol_mask', 0): address = address & self.config['symbol_mask'] symbol_type = None if 'type' in symbol: symbol_type = self._interdict_to_template(symbol['type']) self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name, address = address, type = symbol_type) return self._symbol_cache[name]
def get_type(self, type_name: str) -> interfaces.objects.Template: """Takes a symbol name and resolves it. This method ensures that all referenced templates (including self-referential templates) are satisfied as ObjectTemplates """ # Traverse down any resolutions if type_name not in self._resolved: self._resolved[type_name] = self._weak_resolve( SymbolType.TYPE, type_name) # type: ignore self._iterative_resolve([type_name]) if isinstance(self._resolved[type_name], objects.templates.ReferenceTemplate): table_name = None index = type_name.find(constants.BANG) if index > 0: table_name, type_name = type_name[:index], type_name[index + 1:] raise exceptions.SymbolError( type_name, table_name, f"Unresolvable symbol requested: {type_name}") return self._resolved[type_name]
def get_symbol(self, name: str) -> interfaces.symbols.SymbolInterface: """Returns the symbol given by the symbol name.""" if self._symbol_cache.get(name, None): return self._symbol_cache[name] symbol = self._json_object['symbols'].get(name, None) if not symbol: raise exceptions.SymbolError(name, self.name, f"Unknown symbol: {name}") symbol_type = None if 'type' in symbol: symbol_type = self._interdict_to_template(symbol['type']) symbol_constant_data = None if 'constant_data' in symbol: symbol_constant_data = base64.b64decode(symbol.get('constant_data')) # Mask the addresses if necessary address = symbol['address'] + self.config.get('symbol_shift', 0) if self.config.get('symbol_mask', 0): address = address & self.config['symbol_mask'] self._symbol_cache[name] = interfaces.symbols.SymbolInterface(name = name, address = address, type = symbol_type, constant_data = symbol_constant_data) return self._symbol_cache[name]
def find_port_pools(cls, context: interfaces.context.ContextInterface, layer_name: str, net_symbol_table: str, tcpip_symbol_table: str, tcpip_module_offset: int) -> Tuple[int, int]: """Finds the given image's port pools. Older Windows versions (presumably < Win10 build 14251) use driver symbols called `UdpPortPool` and `TcpPortPool` which point towards the pools. Newer Windows versions use `UdpCompartmentSet` and `TcpCompartmentSet`, which we first have to translate into the port pool address. See also: http://redplait.blogspot.com/2016/06/tcpip-port-pools-in-fresh-windows-10.html Args: context: The context to retrieve required elements (layers, symbol tables) from layer_name: The name of the layer on which to operate net_symbol_table: The name of the table containing the tcpip types tcpip_module_offset: This memory dump's tcpip.sys image offset tcpip_symbol_table: The name of the table containing the tcpip driver symbols Returns: The tuple containing the address of the UDP and TCP port pool respectively. """ if "UdpPortPool" in context.symbol_space[tcpip_symbol_table].symbols: # older Windows versions upp_symbol = context.symbol_space.get_symbol(tcpip_symbol_table + constants.BANG + "UdpPortPool").address upp_addr = context.object(net_symbol_table + constants.BANG + "pointer", layer_name=layer_name, offset=tcpip_module_offset + upp_symbol) tpp_symbol = context.symbol_space.get_symbol(tcpip_symbol_table + constants.BANG + "TcpPortPool").address tpp_addr = context.object(net_symbol_table + constants.BANG + "pointer", layer_name=layer_name, offset=tcpip_module_offset + tpp_symbol) elif "UdpCompartmentSet" in context.symbol_space[ tcpip_symbol_table].symbols: # newer Windows versions since 10.14xxx ucs = context.symbol_space.get_symbol(tcpip_symbol_table + constants.BANG + "UdpCompartmentSet").address tcs = context.symbol_space.get_symbol(tcpip_symbol_table + constants.BANG + "TcpCompartmentSet").address ucs_offset = context.object(net_symbol_table + constants.BANG + "pointer", layer_name=layer_name, offset=tcpip_module_offset + ucs) tcs_offset = context.object(net_symbol_table + constants.BANG + "pointer", layer_name=layer_name, offset=tcpip_module_offset + tcs) ucs_obj = context.object(net_symbol_table + constants.BANG + "_INET_COMPARTMENT_SET", layer_name=layer_name, offset=ucs_offset) upp_addr = ucs_obj.InetCompartment.ProtocolCompartment.PortPool tcs_obj = context.object(net_symbol_table + constants.BANG + "_INET_COMPARTMENT_SET", layer_name=layer_name, offset=tcs_offset) tpp_addr = tcs_obj.InetCompartment.ProtocolCompartment.PortPool else: # this branch should not be reached. raise exceptions.SymbolError( "UdpPortPool", tcpip_symbol_table, f"Neither UdpPortPool nor UdpCompartmentSet found in {tcpip_symbol_table} table" ) vollog.debug( f"Found PortPools @ 0x{upp_addr:x} (UDP) && 0x{tpp_addr:x} (TCP)") return upp_addr, tpp_addr
def get_enumeration(self, name: str) -> objects.Template: raise exceptions.SymbolError(name, self.name, "NativeTables never hold enumerations")
def get_symbol(self, name: str) -> SymbolInterface: raise exceptions.SymbolError(name, self.name, "NativeTables never hold symbols")