Beispiel #1
0
    def init(self):
        self.platform = Platform['8049_rb0mb0']

        length = len(self.parent_view)

        try:
            # create the data memory segment and section
            self.add_auto_segment(
                0, 128, 0, 0, SegmentFlag.SegmentContainsData
                | SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)
            self.add_auto_section(
                '.ram', 0, 128, SectionSemantics.ReadWriteDataSectionSemantics)

            # create the program memory segment, section and entry point
            self.add_auto_segment(
                self.CODE_OFFSET, length, 0, length,
                SegmentFlag.SegmentContainsCode
                | SegmentFlag.SegmentContainsData | SegmentFlag.SegmentReadable
                | SegmentFlag.SegmentExecutable)
            self.add_auto_section(
                '.rom', self.CODE_OFFSET, length,
                SectionSemantics.ReadOnlyCodeSectionSemantics)
            self.add_entry_point(self.CODE_OFFSET)

            self.define_auto_symbol_and_var_or_function(
                Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 0,
                       'reset'), None, self.platform)
            self.define_auto_symbol_and_var_or_function(
                Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 3,
                       'interrupt'), None, self.platform)
            self.define_auto_symbol_and_var_or_function(
                Symbol(SymbolType.FunctionSymbol, self.CODE_OFFSET | 7,
                       'timer'), None, self.platform)

            # working registers
            for n in range(8):
                self.define_auto_symbol_and_var_or_function(
                    Symbol(SymbolType.DataSymbol, n, 'R{}'.format(n)),
                    Type.int(1, False), self.platform)
                self.define_auto_symbol_and_var_or_function(
                    Symbol(SymbolType.DataSymbol, n + 24, 'R{}\''.format(n)),
                    Type.int(1, False), self.platform)

            # stack registers
            for n in range(8):
                self.define_auto_symbol_and_var_or_function(
                    Symbol(SymbolType.DataSymbol, n * 2 + 8, 'S{}'.format(n)),
                    Type.int(2, False), self.platform)

            return True

        except:
            log_error(traceback.format_exc())
            return False
Beispiel #2
0
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
Beispiel #3
0
def load_svd(bv, svd_file=None):
    if not svd_file:
        svd_file = get_open_filename_input("SVD File")
    if isinstance(svd_file, str):
        svd_file = bytes(svd_file, encoding="utf-8")
    if not os.access(svd_file, os.R_OK):
        log_error(f"SVD Browser: Unable to open {svd_file}")
        return
    log_info(f"SVD Loader: Loading {svd_file}")
    device = parse(svd_file)
    peripherals = device['peripherals'].values()
    base_peripherals = [p for p in peripherals if 'derives' not in p]
    derived_peripherals = [p for p in peripherals if 'derives' in p]

    def register_peripheral(p, struct_type):
        bv.add_user_section(p['name'], p['base'], p['size'],
                            SectionSemantics.ReadWriteDataSectionSemantics)
        bv.add_user_segment(
            p['base'], p['size'], 0, 0, SegmentFlag.SegmentContainsData
            | SegmentFlag.SegmentReadable | SegmentFlag.SegmentWritable)
        bv.define_data_var(p['base'], struct_type)
        bv.define_user_symbol(
            Symbol(SymbolType.ImportedDataSymbol, p['base'], p['name']))

    for p in base_peripherals:
        s = Structure()
        for r in p['registers'].values():
            if r['size'] is None:
                s.insert(r['offset'], Type.int(4, False), r['name'])
            else:
                s.insert(r['offset'], Type.int(int(r['size'] / 8), False),
                         r['name'])
        struct_type = Type.structure_type(s)
        bv.define_user_type(p['name'], struct_type)
        register_peripheral(p, struct_type)

    for p in derived_peripherals:
        struct_type = bv.get_type_by_name(
            device['peripherals'][p['derives']]['name'])
        register_peripheral(p, struct_type)
Beispiel #4
0
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}")
Beispiel #5
0
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 ty_from_demangler_node(node, cv_qual=frozenset(), arg_count_hint=None):
        if node.kind == 'builtin':
            if node.value in ty_for_cxx_builtin:
                return ty_for_cxx_builtin[node.value]
            else:
                return None
        elif node.kind in ['name', 'qual_name']:
            named_ty_ref = NamedTypeReference(name=str(node))
            return Type.named_type(named_ty_ref)
        elif node.kind in ['pointer', 'lvalue', 'rvalue']:
            pointee_ty = ty_from_demangler_node(node.value)
            if pointee_ty is None:
                return None
            is_const = ('const' in cv_qual)
            is_volatile = ('volatile' in cv_qual)
            if node.kind == 'pointer':
                return Type.pointer(arch, pointee_ty, is_const, is_volatile)
            elif node.kind == 'lvalue':
                return Type.pointer(
                    arch,
                    pointee_ty,
                    is_const,
                    is_volatile,
                    ref_type=ReferenceType.ReferenceReferenceType)
            elif node.kind == 'rvalue':
                return Type.pointer(arch,
                                    pointee_ty,
                                    is_const,
                                    is_volatile,
                                    ref_type=ReferenceType.RValueReferenceType)
        elif node.kind == 'cv_qual':
            return ty_from_demangler_node(node.value, cv_qual=node.qual)
        elif node.kind == 'func':
            is_ctor_dtor = False
            if node.name and node.name.kind == 'qual_name':
                qual_name = node.name.value
                if qual_name[-1].kind in ['ctor', 'dtor']:
                    is_ctor_dtor = True

            if is_ctor_dtor:
                ret_ty = Type.void()
            elif node.ret_ty is not None:
                ret_ty = ty_from_demangler_node(node.ret_ty)
                if ret_ty is None:
                    return None
            else:
                ret_ty = Type.int(arch.default_int_size).with_confidence(0)

            arg_nodes = list(node.arg_tys)
            arg_tys = []

            var_arg = False
            if arg_nodes[-1].kind == 'builtin' and arg_nodes[-1].value == '...':
                arg_nodes.pop()
                var_arg = True
            elif arg_nodes[0].kind == 'builtin' and arg_nodes[
                    0].value == 'void':
                arg_nodes = arg_nodes[1:]

            this_arg = False
            if node.name and node.name.kind == 'qual_name':
                qual_name = node.name.value
                if is_ctor_dtor or (arg_count_hint is not None
                                    and len(arg_nodes) == arg_count_hint - 1):
                    this_arg = True
                    this_node = Node('qual_name', qual_name[:-1])
                    this_ty = ty_from_demangler_node(this_node)
                    if this_ty is None:
                        return None
                    arg_tys.append(Type.pointer(arch, this_ty))

            for arg_node in arg_nodes:
                arg_ty = ty_from_demangler_node(arg_node)
                if arg_ty is None:
                    return None
                arg_tys.append(arg_ty)

            ty = Type.function(ret_ty, arg_tys, variable_arguments=var_arg)
            if arg_count_hint is not None:
                # toplevel invocation, so return whether we inferred a this argument
                return this_arg, ty
            else:
                return ty
        else:
            log.log_warn("Cannot convert demangled AST {} to a type".format(
                repr(node)))
 def char_array_ty(length):
     return Type.array(Type.int(1), strings[0].length)
def analyze_cxx_abi(view, start=None, length=None, task=None):
    platform = view.platform
    arch = platform.arch

    void_p_ty = Type.pointer(arch, Type.void())
    char_p_ty = Type.pointer(arch, Type.int(1))
    unsigned_int_ty = Type.int(arch.default_int_size, False)
    signed_int_ty = Type.int(arch.default_int_size, True)

    base_type_info_ty = Type.named_type(
        NamedTypeReference(name='std::type_info'))
    base_type_info_ptr_ty = Type.pointer(arch, base_type_info_ty)

    def char_array_ty(length):
        return Type.array(Type.int(1), strings[0].length)

    def type_info_ty(kind=None):
        type_info_struct = Structure()
        type_info_struct.append(void_p_ty, 'vtable')
        type_info_struct.append(char_p_ty, 'name')
        if kind == 'si_class':
            type_info_struct.append(base_type_info_ptr_ty, 'base_type')
        return Type.structure_type(type_info_struct)

    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)

    if platform.name.startswith("windows-"):
        long_size = arch.default_int_size
    else:
        long_size = arch.address_size

    if arch.name.startswith('x86'):
        char_signed = True
    else:
        char_signed = False  # not always true

    short_size = 2  # not always true
    long_long_size = 8  # not always true

    ty_for_cxx_builtin = {
        'void': Type.void(),
        'wchar_t': Type.int(2, sign=char_signed, altname='wchar_t'),
        'bool': Type.bool(),
        'char': Type.int(1, sign=char_signed),
        'signed char': Type.int(1, sign=True),
        'unsigned char': Type.int(1, sign=False),
        'short': Type.int(short_size, sign=True),
        'unsigned short': Type.int(short_size, sign=False),
        'int': Type.int(arch.default_int_size, sign=True),
        'unsigned int': Type.int(arch.default_int_size, sign=False),
        'long': Type.int(long_size, sign=True),
        'unsigned long': Type.int(long_size, sign=False),
        'long long': Type.int(long_long_size, sign=True),
        'unsigned long long': Type.int(long_long_size, sign=False),
        '__int128': Type.int(16, sign=True),
        'unsigned __int128': Type.int(16, sign=False),
        'float': Type.float(4),
        'double': Type.float(8),
        '__float80': Type.float(10),
        '__float128': Type.float(16),
        'char32_t': Type.int(4, sign=char_signed, altname='char32_t'),
        'char16_t': Type.int(2, sign=char_signed, altname='char16_t'),
    }

    def ty_from_demangler_node(node, cv_qual=frozenset(), arg_count_hint=None):
        if node.kind == 'builtin':
            if node.value in ty_for_cxx_builtin:
                return ty_for_cxx_builtin[node.value]
            else:
                return None
        elif node.kind in ['name', 'qual_name']:
            named_ty_ref = NamedTypeReference(name=str(node))
            return Type.named_type(named_ty_ref)
        elif node.kind in ['pointer', 'lvalue', 'rvalue']:
            pointee_ty = ty_from_demangler_node(node.value)
            if pointee_ty is None:
                return None
            is_const = ('const' in cv_qual)
            is_volatile = ('volatile' in cv_qual)
            if node.kind == 'pointer':
                return Type.pointer(arch, pointee_ty, is_const, is_volatile)
            elif node.kind == 'lvalue':
                return Type.pointer(
                    arch,
                    pointee_ty,
                    is_const,
                    is_volatile,
                    ref_type=ReferenceType.ReferenceReferenceType)
            elif node.kind == 'rvalue':
                return Type.pointer(arch,
                                    pointee_ty,
                                    is_const,
                                    is_volatile,
                                    ref_type=ReferenceType.RValueReferenceType)
        elif node.kind == 'cv_qual':
            return ty_from_demangler_node(node.value, cv_qual=node.qual)
        elif node.kind == 'func':
            is_ctor_dtor = False
            if node.name and node.name.kind == 'qual_name':
                qual_name = node.name.value
                if qual_name[-1].kind in ['ctor', 'dtor']:
                    is_ctor_dtor = True

            if is_ctor_dtor:
                ret_ty = Type.void()
            elif node.ret_ty is not None:
                ret_ty = ty_from_demangler_node(node.ret_ty)
                if ret_ty is None:
                    return None
            else:
                ret_ty = Type.int(arch.default_int_size).with_confidence(0)

            arg_nodes = list(node.arg_tys)
            arg_tys = []

            var_arg = False
            if arg_nodes[-1].kind == 'builtin' and arg_nodes[-1].value == '...':
                arg_nodes.pop()
                var_arg = True
            elif arg_nodes[0].kind == 'builtin' and arg_nodes[
                    0].value == 'void':
                arg_nodes = arg_nodes[1:]

            this_arg = False
            if node.name and node.name.kind == 'qual_name':
                qual_name = node.name.value
                if is_ctor_dtor or (arg_count_hint is not None
                                    and len(arg_nodes) == arg_count_hint - 1):
                    this_arg = True
                    this_node = Node('qual_name', qual_name[:-1])
                    this_ty = ty_from_demangler_node(this_node)
                    if this_ty is None:
                        return None
                    arg_tys.append(Type.pointer(arch, this_ty))

            for arg_node in arg_nodes:
                arg_ty = ty_from_demangler_node(arg_node)
                if arg_ty is None:
                    return None
                arg_tys.append(arg_ty)

            ty = Type.function(ret_ty, arg_tys, variable_arguments=var_arg)
            if arg_count_hint is not None:
                # toplevel invocation, so return whether we inferred a this argument
                return this_arg, ty
            else:
                return ty
        else:
            log.log_warn("Cannot convert demangled AST {} to a type".format(
                repr(node)))

    reader = BinaryReader(view)

    def read(size):
        if size == 4:
            return reader.read32()
        elif size == 8:
            return reader.read64()
        else:
            assert False

    symbols = view.get_symbols(start, length)
    if task:
        task.set_total(len(symbols))

    mangled_re = re.compile('_?_Z')

    demangler_failures = 0
    for symbol in symbols:
        if task and not task.advance():
            break

        if not mangled_re.match(symbol.raw_name):
            continue

        is_data = (symbol.type == SymbolType.DataSymbol)
        is_code = (symbol.type in [
            SymbolType.FunctionSymbol, SymbolType.ImportedFunctionSymbol
        ])

        raw_name, suffix = symbol.raw_name, ''
        if '@' in raw_name:
            match = re.match(r'^(.+?)(@.+)$', raw_name)
            raw_name, suffix = match.group(1), match.group(2)

        try:
            name_ast = parse_mangled(raw_name)
            if name_ast is None:
                log.log_warn(
                    "Demangler failed to recognize {}".format(raw_name))
                demangler_failures += 1
        except NotImplementedError as e:
            log.log_warn("Demangler feature missing on {}: {}".format(
                raw_name, str(e)))
            demangler_failures += 1

        if name_ast:
            if name_ast.kind == 'func':
                short_name = str(name_ast.name)
            else:
                short_name = str(name_ast)
            symbol = Symbol(symbol.type,
                            symbol.address,
                            short_name=short_name + suffix,
                            full_name=str(name_ast) + suffix,
                            raw_name=symbol.raw_name)
        else:
            symbol = Symbol(symbol.type,
                            symbol.address,
                            short_name=symbol.raw_name,
                            full_name=None,
                            raw_name=symbol.raw_name)
        view.define_auto_symbol(symbol)

        if name_ast is None:
            continue

        elif is_data and name_ast.kind == 'typeinfo_name':
            strings = view.get_strings(symbol.address, 1)
            if not strings:
                continue

            view.define_data_var(symbol.address, char_array_ty(length))

        elif is_data and name_ast.kind == 'typeinfo':
            reader.offset = symbol.address + arch.address_size * 2

            kind = None

            # heuristic: is this is an abi::__si_class_type_info?
            base_or_flags = read(arch.default_int_size)
            base_symbol = view.get_symbol_at(base_or_flags)
            if base_symbol and base_symbol.raw_name.startswith('_ZTI'):
                kind = 'si_class'

            view.define_data_var(symbol.address, type_info_ty(kind))

        elif is_data and name_ast.kind == 'vtable':
            vtable_addr = symbol.address

            reader.offset = vtable_addr + arch.address_size * 2
            while True:
                vfunc_count = 0
                check_next = True
                while True:
                    vfunc_ptr_symbol = view.get_symbol_at(reader.offset)
                    if vfunc_ptr_symbol and vfunc_ptr_symbol.raw_name.startswith(
                            '_Z'):
                        # any C++ symbol definitely terminates the vtable
                        check_next = False
                        break

                    # heuristic: existing function
                    vfunc_addr = read(arch.address_size)
                    if view.get_function_at(vfunc_addr):
                        vfunc_count += 1
                        continue

                    # explicitly reject null pointers; in position-independent code
                    # address zero can belong to the executable segment
                    if vfunc_addr == 0:
                        check_next = False
                        break

                    # heuristic: pointer to executable memory
                    vfunc_segment = view.get_segment_at(vfunc_addr)
                    if vfunc_addr != 0 and vfunc_segment and vfunc_segment.executable:
                        view.add_function(vfunc_addr)
                        vfunc_count += 1

                        log.log_info(
                            'Discovered function at {:#x} via {}'.format(
                                vfunc_addr, symbol.full_name
                                or symbol.short_name))
                        changed = True
                        continue

                    # we've fell off the end of the vtable
                    break

                view.define_data_var(vtable_addr, vtable_ty(vfunc_count))

                if check_next:
                    # heuristic: can another vtable follow this one? let's see if it has typeinfo,
                    # since that should be always true for when we have a virtual base
                    typeinfo_ptr = read(arch.address_size)
                    typeinfo_ptr_symbol = view.get_symbol_at(typeinfo_ptr)
                    if typeinfo_ptr_symbol and typeinfo_ptr_symbol.raw_name.startswith(
                            '_ZTI'):
                        vtable_addr = reader.offset - 2 * arch.address_size

                        # documentat it with a symbol
                        secondary_symbol_name = '{}_secondary_{:x}'.format(
                            symbol.short_name, vtable_addr - symbol.address)
                        secondary_symbol = Symbol(
                            SymbolType.DataSymbol,
                            vtable_addr,
                            short_name=secondary_symbol_name)
                        view.define_auto_symbol(secondary_symbol)
                        continue

                break

        elif is_code and name_ast.kind == 'func':
            func = view.get_function_at(symbol.address)
            demangled = ty_from_demangler_node(
                name_ast, arg_count_hint=len(func.function_type.parameters))
            if demangled is not None:
                this_arg, ty = demangled
                func.apply_auto_discovered_type(ty)

    view.update_analysis()

    if demangler_failures:
        log.log_warn('{} demangler failures'.format(demangler_failures))
Beispiel #9
0
class Intel8086(Architecture):
    name = "8086"
    endianness = Endianness.LittleEndian

    default_int_size = 2
    address_size = 3

    stack_pointer = 'sp'
    regs = {
        # General
        'ax': RegisterInfo('ax', 2, 0),
        'al': RegisterInfo('ax', 1, 0),
        'ah': RegisterInfo('ax', 1, 1),
        'cx': RegisterInfo('cx', 2, 0),
        'cl': RegisterInfo('cx', 1, 0),
        'ch': RegisterInfo('cx', 1, 1),
        'bx': RegisterInfo('bx', 2, 0),
        'bl': RegisterInfo('bx', 1, 0),
        'bh': RegisterInfo('bx', 1, 1),
        'dx': RegisterInfo('dx', 2, 0),
        'dl': RegisterInfo('dx', 1, 0),
        'dh': RegisterInfo('dx', 1, 1),
        'sp': RegisterInfo('sp', 2),
        'bp': RegisterInfo('bp', 2),
        'si': RegisterInfo('si', 2),
        'di': RegisterInfo('di', 2),
        # Segment
        'cs': RegisterInfo('cs', 2),
        'ds': RegisterInfo('ds', 2),
        'es': RegisterInfo('es', 2),
        'ss': RegisterInfo('ss', 2),
        # Instruction pointer
        'ip': RegisterInfo('ip', 2)
    }
    flags = [
        # Status
        'c',  # carry
        'p',  # parity
        'a',  # aux carry
        'z',  # zero
        's',  # sign
        'o',  # overflow
        # Control
        'i',  # interrupt
        'd',  # direction
        't',  # trap
    ]
    flag_roles = {
        'c': FlagRole.CarryFlagRole,
        'p': FlagRole.OddParityFlagRole,
        'a': FlagRole.HalfCarryFlagRole,
        'z': FlagRole.ZeroFlagRole,
        's': FlagRole.NegativeSignFlagRole,
        't': FlagRole.SpecialFlagRole,
        'i': FlagRole.SpecialFlagRole,
        'd': FlagRole.SpecialFlagRole,
        'o': FlagRole.OverflowFlagRole,
    }
    flag_write_types = [
        '',
        '*',
        '!c',
        'co',
    ]
    flags_written_by_flag_write_type = {
        '*': ['c', 'p', 'a', 'z', 's', 'o'],
        '!c': ['p', 'a', 'z', 's', 'o'],
        'co': ['c', 'o'],
    }
    flags_required_for_flag_condition = {
        LowLevelILFlagCondition.LLFC_E: ['z'],
        LowLevelILFlagCondition.LLFC_NE: ['z'],
        LowLevelILFlagCondition.LLFC_SLT: ['s', 'o'],
        LowLevelILFlagCondition.LLFC_ULT: ['c'],
        LowLevelILFlagCondition.LLFC_SLE: ['z', 's', 'o'],
        LowLevelILFlagCondition.LLFC_ULE: ['c', 'z'],
        LowLevelILFlagCondition.LLFC_SGE: ['s', 'o'],
        LowLevelILFlagCondition.LLFC_UGE: ['c'],
        LowLevelILFlagCondition.LLFC_SGT: ['z', 's', 'o'],
        LowLevelILFlagCondition.LLFC_UGT: ['c', 'z'],
        LowLevelILFlagCondition.LLFC_NEG: ['s'],
        LowLevelILFlagCondition.LLFC_POS: ['s'],
        LowLevelILFlagCondition.LLFC_O: ['o'],
        LowLevelILFlagCondition.LLFC_NO: ['o'],
    }

    intrinsics = {
        'outb': IntrinsicInfo([Type.int(2), Type.int(1)], []),
        'outw': IntrinsicInfo([Type.int(2), Type.int(2)], []),
        'inb': IntrinsicInfo([Type.int(1)], [Type.int(2)]),
        'inw': IntrinsicInfo([Type.int(2)], [Type.int(2)]),
    }

    def get_instruction_info(self, data, addr):
        decoded = mc.decode(data, addr)
        if decoded:
            info = InstructionInfo()
            decoded.analyze(info, addr)
            return info

    def get_instruction_text(self, data, addr):
        decoded = mc.decode(data, addr)
        if decoded:
            encoded = data[:decoded.total_length()]
            recoded = mc.encode(decoded, addr)
            if encoded != recoded:
                log_error("Instruction roundtrip error")
                log_error("".join([str(x) for x in decoded.render(addr)]))
                log_error("Orig: {}".format(encoded.hex()))
                log_error("New:  {}".format(recoded.hex()))

            return decoded.render(addr), decoded.total_length()

    def get_instruction_low_level_il(self, data, addr, il):
        decoded = mc.decode(data, addr)
        if decoded:
            decoded.lift(il, addr)
            return decoded.total_length()

    def convert_to_nop(self, data, addr):
        return b'\x90' * len(data)

    def is_always_branch_patch_available(self, data, addr):
        decoded = mc.decode(data, addr)
        if decoded:
            return isinstance(decoded, mc.instr.jmp.JmpCond)

    def always_branch(self, data, addr):
        branch = mc.decode(data, addr)
        branch = branch.to_always()
        return mc.encode(branch, addr)

    def is_invert_branch_patch_available(self, data, addr):
        decoded = mc.decode(data, addr)
        if decoded:
            return isinstance(decoded, mc.instr.jmp.JmpCond)

    def invert_branch(self, data, addr):
        branch = mc.decode(data, addr)
        branch = branch.to_inverted()
        return mc.encode(branch, addr)
Beispiel #10
0
typelib.add_platform(binaryninja.Platform['mac-x86_64'])
typelib.add_alternate_name('libtest.so')

#------------------------------------------------------------------------------
# PART1: Named Types
#------------------------------------------------------------------------------

# example: VoidTypeClass
typelib.add_named_type('MyVoidType', Type.void())

# example: BoolTypeClass
typelib.add_named_type('MyBoolType', Type.bool())

# example: IntegerTypeClass
typelib.add_named_type('MyCharType', Type.char())
typelib.add_named_type('MyIntType', Type.int(4, True))
typelib.add_named_type('MyUnsignedIntType', Type.int(4, False))

# example: FloatTypeClass
typelib.add_named_type('MyFloatType', Type.float(4))

# example: PointerTypeClass
# char *
typelib.add_named_type('MyPointerType', Type.pointer(arch, Type.char()))

# example of typedef to primitive type
# typedef int MyTypedefType;
typelib.add_named_type('MyTypedefType', Type.int(4))


# example of typedef to typedef