def import_ida(json_file, bv, options): if json_file is None: return False, "No json file specified" imported = None try: f = open(json_file, "rb") imported = json.load(f) except Exception as e: return False, "Failed to parse json file {} {}".format(json_file, e) resolved_functions = imported["functions"] resolved_strings = imported["strings"] # TODO: import segments # TODO: Handle Conflicts if options.import_functions: log("Applying import data", options.verbose) for name, rec in resolved_functions.items(): bv.add_function(rec["start"]) func = bv.get_function_at(rec["start"]) if name != ("sub_%x" % rec["start"]): func.name = name if options.import_comments: if "comment" in rec: func.comment = rec["comment"] if "comments" in rec: for comment, addr in rec["comments"].items(): func.set_comment_at(addr, comment) if "can_return" in rec: func.can_return = rec["can_return"] bv.update_analysis_and_wait() if options.import_strings: log("Importing string types", options.verbose) for addr, (name, length, t, data_refs) in resolved_strings.items(): bv.define_user_data_var(int(addr), Type.array(Type.int(1, None, "char"), length)) if options.import_strings_names: bv.define_user_symbol(Symbol(SymbolType.DataSymbol, int(addr), name)) for ref in data_refs: # references to this data for block in bv.get_basic_blocks_at(ref): # find any references in code for i in block.get_disassembly_text(): # go through all the instructions in the block if i.address == ref: for token in i.tokens: if token.type == InstructionTextTokenType.PossibleAddressToken: print "setting token", i.address, token.value, token.operand, IntegerDisplayType.PointerDisplayType, block.arch block.function.set_int_display_type(i.address, token.value, token.operand, IntegerDisplayType.PointerDisplayType, block.arch) break log("Updating Analysis", options.verbose) bv.update_analysis_and_wait() return True, None
def vtable_ty(vfunc_count): try: vtable_struct = StructureBuilder.create() except NameError: vtable_struct = Structure() vtable_struct.append(signed_int_ty, 'top_offset') vtable_struct.append(base_type_info_ptr_ty, 'typeinfo') vtable_struct.append(Type.array(void_p_ty, vfunc_count), 'functions') return Type.structure_type(vtable_struct)
def fix_mangled_symbols(thread, view): for sym in view.symbols.values(): if thread.cancelled: break if not isinstance(sym, Symbol): continue if sym.short_name.startswith('?') and not sym.raw_name.startswith('?'): demangled_type, demangled_name = demangle_ms( view.arch, sym.short_name) if demangled_type is not None: new_symbol = Symbol( sym.type, sym.address, short_name=get_qualified_name(demangled_name), full_name=get_qualified_name(demangled_name), raw_name=sym.short_name, binding=sym.binding, namespace=sym.namespace, ordinal=sym.ordinal) view.undefine_user_symbol(sym) view.define_user_symbol(new_symbol) view.define_user_data_var(new_symbol.address, demangled_type) sym = new_symbol # Create vtables if 'vftable\'' in sym.full_name: create_vtable(view, None, sym.address) # Create strings if sym.raw_name.startswith('??_C@_'): view.undefine_user_symbol(sym) ascii_string = view.get_ascii_string_at(sym.address) if (ascii_string is not None) and (ascii_string.start == sym.address): view.define_user_data_var( sym.address, Type.array(Type.char(), ascii_string.length)) for func in view.functions: if thread.cancelled: break process_msvc_func(func)
def make_code(bv: BinaryView, start: int, end: int) -> None: if bv.get_basic_blocks_at(start): return if end - start <= 1: # find the next basic block, data variable, or segment/section end data_var = bv.get_next_data_var_after(start) if data_var is not None: end = data_var.address else: end = bv.end end = min(bv.get_next_basic_block_start_after(start), end) seg = bv.get_segment_at(start) if seg is not None: end = min(seg.end, end) section_ends = [s.end for s in bv.get_sections_at(start)] end = min(*section_ends, end) bv.define_data_var(start, Type.array(Type.int(1, False), end - start), f"CODE_{start:08x}")
def find_dynamically_linked_funcs(bv): platform_info = get_platform_info(bv) funcs_to_check = set() for lookup in platform_info["sym_lookups"]: for ref in bv.get_code_refs(lookup): ref.function.analysis_skip_override = FunctionAnalysisSkipOverride.NeverSkipFunctionAnalysis funcs_to_check.add(ref.function) bv.update_analysis() time.sleep(1) for f in funcs_to_check: mlil_ssa = f.medium_level_il.ssa_form for call in find_mlil_calls_to_targets(mlil_ssa, platform_info["sym_lookups"]): if len(call.params) < 2 or len(call.output.vars_written) < 1: continue symbol_name_addr = call.params[1].value if symbol_name_addr.type not in [ RegisterValueType.ConstantPointerValue, RegisterValueType.ConstantValue ]: continue output_var = call.output.vars_written[0] symbol_name = bv.get_ascii_string_at(symbol_name_addr.value).value #Add confidence to both the args and the return of zero symbol_type = Type.pointer(bv.arch, bv.parse_type_string("void foo()")[0]) if len(symbol_name) == 0: continue bv.define_user_data_var(symbol_name_addr.value, Type.array(Type.int(1), len(symbol_name))) output_name = symbol_name + "@DYN" f.create_user_var(output_var.var, symbol_type, output_name) propagate_var_name(f, mlil_ssa, output_var, output_name, symbol_type)
def vtable_ty(vfunc_count): vtable_struct = Structure() vtable_struct.append(signed_int_ty, 'top_offset') vtable_struct.append(base_type_info_ptr_ty, 'typeinfo') vtable_struct.append(Type.array(void_p_ty, vfunc_count), 'functions') return Type.structure_type(vtable_struct)
def char_array_ty(length): return Type.array(Type.int(1), strings[0].length)
# example: EnumerationTypeClass enum_type = EnumerationBuilder.create([], None, arch=arch) enum_type.append('RED', 0) enum_type.append('ORANGE', 1) enum_type.append('YELLOW', 2) enum_type.append('GREEN', 3) enum_type.append('BLUE', 4) enum_type.append('INDIGO', 5) enum_type.append('VIOLET', 6) typelib.add_named_type('MyEnumerationType', enum_type) # example: ArrayTypeClass # # unsigned char[256] typelib.add_named_type('MyArrayType', Type.array(Type.int(1), 256)) # example: FunctionTypeClass # # int ()(int, int, int) ret = Type.int(4) params = [Type.int(4), Type.int(4), Type.int(4)] ftype = Type.function(ret, params) typelib.add_named_type('MyFunctionType', ftype) #------------------------------------------------------------------------------ # PART2: Named Objects #------------------------------------------------------------------------------ # example: any external/imported functions named _MySuperComputation # are typed int _MySuperComputation(int, int)