def method_kdbg_offset( self, context: interfaces.context.ContextInterface, vlayer: layers.intel.Intel, progress_callback: constants.ProgressCallback = None ) -> ValidKernelsType: vollog.debug( "Kernel base determination - using KDBG structure for kernel offset" ) valid_kernels = {} # type: ValidKernelsType physical_layer_name = self.get_physical_layer_name(context, vlayer) physical_layer = context.layers[physical_layer_name] results = physical_layer.scan(context, scanners.BytesScanner(b"KDBG"), progress_callback=progress_callback) seen = set() # type: Set[int] for result in results: # TODO: Identify the specific structure we're finding and document this a bit better pointer = context.object("pdbscan!unsigned long long", offset=result + 8, layer_name=physical_layer_name) address = pointer & vlayer.address_mask if address in seen: continue seen.add(address) valid_kernels = self.check_kernel_offset(context, vlayer, address, progress_callback) if valid_kernels: break return valid_kernels
def method_module_offset(self, context: interfaces.context.ContextInterface, vlayer: layers.intel.Intel, progress_callback: constants.ProgressCallback = None) -> ValidKernelsType: """Method for finding a suitable kernel offset based on a module table.""" vollog.debug("Kernel base determination - searching layer module list structure") valid_kernels = {} # type: ValidKernelsType # If we're here, chances are high we're in a Win10 x64 image with kernel base randomization virtual_layer_name = vlayer.name physical_layer_name = self.get_physical_layer_name(context, vlayer) physical_layer = context.layers[physical_layer_name] # TODO: On older windows, this might be \WINDOWS\system32\nt rather than \SystemRoot\system32\nt results = physical_layer.scan(context, scanners.BytesScanner(b"\\SystemRoot\\system32\\nt"), progress_callback = progress_callback) seen = set() # type: Set[int] # Because this will launch a scan of the virtual layer, we want to be careful for result in results: # TODO: Identify the specific structure we're finding and document this a bit better pointer = context.object("pdbscan!unsigned long long", offset = (result - 16 - int(vlayer.bits_per_register / 8)), layer_name = physical_layer_name) address = pointer & vlayer.address_mask if address in seen: continue seen.add(address) valid_kernels = self.check_kernel_offset(context, vlayer, address, progress_callback) if valid_kernels: break return valid_kernels
def _generator(self, tasks): is_32bit = not symbols.symbol_table_is_64bit(self.context, self.config["darwin"]) if is_32bit: pack_format = "I" bash_json_file = "bash32" else: pack_format = "Q" bash_json_file = "bash64" bash_table_name = BashIntermedSymbols.create(self.context, self.config_path, "linux", bash_json_file) ts_offset = self.context.symbol_space.get_type( bash_table_name + constants.BANG + "hist_entry").relative_child_offset("timestamp") for task in tasks: task_name = utility.array_to_string(task.p_comm) if task_name not in ["bash", "sh", "dash"]: continue proc_layer_name = task.add_process_layer() if proc_layer_name is None: continue proc_layer = self.context.layers[proc_layer_name] bang_addrs = [] # find '#' values on the heap for address in proc_layer.scan( self.context, scanners.BytesScanner(b"#"), sections=task.get_process_memory_sections( self.context, self.config['darwin'], rw_no_file=True)): bang_addrs.append(struct.pack(pack_format, address)) history_entries = [] for address, _ in proc_layer.scan( self.context, scanners.MultiStringScanner(bang_addrs), sections=task.get_process_memory_sections( self.context, self.config['darwin'], rw_no_file=True)): hist = self.context.object(bash_table_name + constants.BANG + "hist_entry", offset=address - ts_offset, layer_name=proc_layer_name) if hist.is_valid(): history_entries.append(hist) for hist in sorted(history_entries, key=lambda x: x.get_time_as_integer()): yield (0, (int(task.p_pid), task_name, hist.get_time_object(), hist.get_command()))
def _generator(self): service_table_name = self.create_service_table( self.context, self.config["nt_symbols"], self.config_path) relative_tag_offset = self.context.symbol_space.get_type( service_table_name + constants.BANG + "_SERVICE_RECORD").relative_child_offset("Tag") filter_func = pslist.PsList.create_name_filter(["services.exe"]) is_vista_or_later = SvcScan.is_vista_or_later( context=self.context, symbol_table=self.config["nt_symbols"]) if is_vista_or_later: service_tag = b"serH" else: service_tag = b"sErv" seen = [] for task in pslist.PsList.list_processes( context=self.context, layer_name=self.config['primary'], symbol_table=self.config['nt_symbols'], filter_func=filter_func): try: proc_layer_name = task.add_process_layer() except exceptions.InvalidAddressException: continue layer = self.context.layers[proc_layer_name] for offset in layer.scan( context=self.context, scanner=scanners.BytesScanner(needle=service_tag), sections=vadyarascan.VadYaraScan.get_vad_maps(task)): if not is_vista_or_later: service_record = self.context.object( service_table_name + constants.BANG + "_SERVICE_RECORD", offset=offset - relative_tag_offset, layer_name=proc_layer_name) if not service_record.is_valid(): continue yield (0, self.get_record_tuple(service_record)) else: service_header = self.context.object( service_table_name + constants.BANG + "_SERVICE_HEADER", offset=offset, layer_name=proc_layer_name) if not service_header.is_valid(): continue # since we walk the s-list backwards, if we've seen # an object, then we've also seen all objects that # exist before it, thus we can break at that time. for service_record in service_header.ServiceRecord.traverse( ): if service_record in seen: break seen.append(service_record) yield (0, self.get_record_tuple(service_record))