def find_aslr(cls, context: interfaces.context.ContextInterface, symbol_table: str, layer_name: str, progress_callback: constants.ProgressCallback = None) \ -> Tuple[int, int]: """Determines the offset of the actual DTB in physical space and its symbol offset.""" init_task_symbol = symbol_table + constants.BANG + 'init_task' init_task_json_address = context.symbol_space.get_symbol( init_task_symbol).address swapper_signature = rb"swapper(\/0|\x00\x00)\x00\x00\x00\x00\x00\x00" module = context.module(symbol_table, layer_name, 0) address_mask = context.symbol_space[symbol_table].config.get( 'symbol_mask', None) task_symbol = module.get_type('task_struct') comm_child_offset = task_symbol.relative_child_offset('comm') for offset in context.layers[layer_name].scan( scanner=scanners.RegExScanner(swapper_signature), context=context, progress_callback=progress_callback): init_task_address = offset - comm_child_offset init_task = module.object(object_type='task_struct', offset=init_task_address, absolute=True) if init_task.pid != 0: continue elif init_task.has_member( 'state') and init_task.state.cast('unsigned int') != 0: continue # This we get for free aslr_shift = init_task.files.cast( 'long unsigned int') - module.get_symbol('init_files').address kaslr_shift = init_task_address - cls.virtual_to_physical_address( init_task_json_address) if address_mask: aslr_shift = aslr_shift & address_mask if aslr_shift & 0xfff != 0 or kaslr_shift & 0xfff != 0: continue vollog.debug( "Linux ASLR shift values determined: physical {:0x} virtual {:0x}" .format(kaslr_shift, aslr_shift)) return kaslr_shift, aslr_shift # We don't throw an exception, because we may legitimately not have an ASLR shift, but we report it vollog.debug( "Scanners could not determine any ASLR shifts, using 0 for both") return 0, 0
def _scan_generator(cls, context, layer_name, progress_callback): darwin_signature = rb"Darwin Kernel Version \d{1,3}\.\d{1,3}\.\d{1,3}: [^\x00]+\x00" for offset in context.layers[layer_name].scan(scanner = scanners.RegExScanner(darwin_signature), context = context, progress_callback = progress_callback): banner = context.layers[layer_name].read(offset, 128) idx = banner.find(b"\x00") if idx != -1: banner = banner[:idx] yield offset, banner
def locate_banners(cls, context: interfaces.context.ContextInterface, layer_name: str): """Identifies banners from a memory image""" layer = context.layers[layer_name] for offset in layer.scan( context=context, scanner=scanners.RegExScanner( rb"(Linux version|Darwin Kernel Version) [0-9]+\.[0-9]+\.[0-9]+" )): data = layer.read(offset, 0xfff) data_index = data.find(b'\x00') if data_index > 0: data = data[:data_index].strip() failed = [ char for char in data if char not in b' #()+,;/-.0123456789:@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~' ] if not failed: yield format_hints.Hex(offset), str(data, encoding='latin-1', errors='?')