def main(target: str, delphi_version: int): # Just disable some features for large binaries opts = { 'analysis.mode': 'full', 'analysis.linearSweep.autorun': False, 'analysis.linearSweep.controlFlowGraph': False, } bv = BinaryViewType.get_view_of_file_with_options(target, options=opts) if bv is None: print(f'Invalid binary path: {target}') exit(-1) BNLogger.init_console() BNLogger.log('File loaded') BNLogger.log('-----------------------------') BNLogger.log('Searching for VMT...') analyzer = DelphiAnalyzer(bv, delphi_version) analyzer.update_analysis_and_wait(lambda vmt: analyze_callback(vmt, bv)) bv.update_analysis_and_wait() BNLogger.log(f'Saving database: `{target}.bndb`...') bv.create_database(f'{target}.bndb')
def run_fs_test(fpath): bv = BinaryViewType.get_view_of_file(fpath) bv.update_analysis_and_wait() fs_finder = FormatStringFinder(bv, False) fs_finder.find_format_strings() # ==================== # Prepare what should be found success = True printf_like_funcs = [x for x in bv.symbols if x.startswith("PRINTF_LIKE")] vuln_funcs = [x for x in bv.symbols if x.startswith("VULN")] safe_funcs = [x for x in bv.symbols if x.startswith("SAFE")] def test_helper(should_be_found, found, msg_type): nonlocal success for i in should_be_found: if i not in found: log_error(f"'{i}' was not detected as a {msg_type}.") success = False else: log_info(f"'{i}' successfully detected as a {msg_type}.") # ==================== # Check that every printf like function was found found_printf_like_funcs = [x.name for x in fs_finder.new_printf_like_funcs] test_helper(printf_like_funcs, found_printf_like_funcs, "printf like function") # ==================== # Check that all safe/vuln results are in safe/vuln functions found_vuln_funcs = [ x.ref.function.name for x in fs_finder.results if x.is_vuln ] found_safe_funcs = [ x.ref.function.name for x in fs_finder.results if not x.is_vuln ] test_helper(vuln_funcs, found_vuln_funcs, "vuln function") test_helper(safe_funcs, found_safe_funcs, "safe function") bv.file.close() return success
def __init__(self, filename: Optional[str] = None, debug_root: Optional[str] = None, debug_file: Optional[str] = None, binary_view: Optional[BinaryView] = None, logger=None): if filename is None and binary_view is None: raise ValueError('Must specify either a filename or binary view.') self.model: AnalysisModel self.binary_view: BinaryView self.debug_root = debug_root self.debug_file = debug_file if binary_view is None: bv = BinaryViewType.get_view_of_file(filename, update_analysis=True) if bv is None: raise Exception( f'Unable to get binary view for file: {filename}') self.binary_view = bv else: self.binary_view = binary_view if self.binary_view.arch is None: raise Exception('The binary view has no valid architecture.') # Create the root module with the binary name as the module name. if filename is None: filename = self.binary_view.file.original_filename assert (isinstance(filename, str)) binary_name = os.path.basename(filename) debug_source = filename if self.debug_file is not None: debug_source = self.debug_file m = AnalysisModel.from_dwarf(debug_source, self.debug_root, name=binary_name, logger=logger) self.model = m if m else AnalysisModel(binary_name) self.mapping = BinjaMap(self.binary_view)
def main(target: str, delphi_version: int): # Just disable some features for large binaries opts = { 'analysis.mode': 'controlFlow', 'analysis.linearSweep.autorun': False, 'analysis.linearSweep.controlFlowGraph': False, } bv = BinaryViewType.get_view_of_file_with_options(target, options=opts) if bv is None: print(f'Invalid binary path: {target}') exit(-1) BNLogger.init_console() BNLogger.log('File loaded') BNLogger.log('Searching for VMT...') analyzer = DelphiAnalyzer(bv, delphi_version) analyzer.update_analysis_and_wait() BNLogger.log('Creating Graph...') vmt_map = {vmt.start: vmt for vmt in analyzer.vmt_list} create_graph(vmt_map)
possible_sizes = size_param.possible_values # Dataflow won't combine multiple possible values from # shifted bytes, so any value we care about will be # undetermined at this point. This might change in the future? if possible_sizes.type != RegisterValueType.UndeterminedValue: return False model = ByteSwapModeler(size_param, bv.address_size) return model.is_byte_swap() if __name__ == '__main__': filename = sys.argv[1] bv = BinaryViewType.get_view_of_file(filename) bv.update_analysis_and_wait() print "{} loaded...".format(filename) memcpy_refs = [ (ref.function, ref.address) for ref in bv.get_code_refs(bv.symbols['_memcpy'].address) ] print 'Checking {} memcpy calls'.format(len(memcpy_refs)) dangerous_calls = [] for function, addr in tqdm(memcpy_refs): call_instr = function.get_low_level_il_at(addr).medium_level_il
def open_bv(path, **kw): # Note: This is now a context manager, hurrah! return BinaryViewType.get_view_of_file(path, **kw)
print("[*] Syntax: {} <path to analysis directory> <output file>".format( sys.argv[0])) exit(0) # parse arguments analysis_directory = sys.argv[1] output_file_path = sys.argv[2] # global ngrams counter ngrams = Counter() # set n as default to 3 n = 3 # walk over all binaries in the provided directory for binary_file_path in glob.glob(f"{analysis_directory}/*"): print(f"Analyzing file {binary_file_path}.") # init binary ninja bv = BinaryViewType.get_view_of_file(binary_file_path) # wait until analysis finishes bv.update_analysis_and_wait() # count ngrams ngrams.update(calc_global_ngrams(bv, n)) # prepare output string -- the most common 1k ngrams in a set output_string = pformat({k for k, v in ngrams.most_common(1000)}) # write output file with open(output_file_path, 'w') as output_file: output_file.write(output_string) output_file.close()