예제 #1
0
파일: controller.py 프로젝트: angr/binsync
    def active_context(self):
        out = self.bridge.server.context()
        if not out:
            return Function(0, 0, header=FunctionHeader("", 0))

        return Function(out['func_addr'],
                        0,
                        header=FunctionHeader(out["name"], out['func_addr']))
예제 #2
0
    def function(self, addr) -> Optional[Function]:
        """
        TODO: fix how types and offsets are set

        @param addr:
        @return:
        """
        bn_func = self.bv.get_function_at(addr)
        if not bn_func:
            return None

        func = Function(bn_func.start, bn_func.total_bytes)
        func_header = FunctionHeader(
            bn_func.name,
            func.addr,
            ret_type=bn_func.return_type.get_string_before_name(),
            args={
                idx: FunctionArgument(idx, param.name, str(param.type),
                                      param.type.width)
                for idx, param in enumerate(bn_func.function_type.parameters)
            })
        stack_vars = {
            v.storage: StackVariable(v.storage, StackOffsetType.BINJA, v.name,
                                     str(v.type), v.type.width, func.addr)
            for v in bn_func.stack_layout
            if v.source_type == VariableSourceType.StackVariableSourceType
        }
        func.header = func_header
        func.stack_vars = stack_vars

        return func
예제 #3
0
파일: test_state.py 프로젝트: angr/binsync
    def test_nonconflicting_funcs(self):
        state1 = binsync.State("user1")
        state2 = binsync.State("user2")

        # setup top
        func1 = FunctionHeader("user1_func",
                               0x400000,
                               ret_type="int *",
                               args={})
        func2 = FunctionHeader("main", func1.addr, ret_type="long *", args={})

        state1.set_function_header(func1)
        state2.set_function_header(func2)
        state1.functions[func1.addr].size = 0x100
        state2.functions[func1.addr].size = 0x100

        stack_vars1 = {
            0x0: StackVariable(0, 3, "v0", "int", 4, func1.addr),
            0x4: StackVariable(4, 3, "my_var", "int", 4, func1.addr)
        }
        stack_vars2 = {
            0x0: StackVariable(0, 3, "v0", "int", 4, func1.addr),
            0x4: StackVariable(4, 3, "v4", "long", 8, func1.addr),
            0x8: StackVariable(8, 3, "v8", "long", 8, func1.addr)
        }

        for stack_vars_info in [(stack_vars1, state1), (stack_vars2, state2)]:
            state = stack_vars_info[1]
            stack_vars = stack_vars_info[0]
            for off, var in stack_vars.items():
                state.set_stack_variable(var)

        func1, func2 = state1.get_function(0x400000), state2.get_function(
            0x400000)
        merge_func = func1.nonconflict_merge(func2)

        self.assertEqual(merge_func.name, "user1_func")
        self.assertEqual(merge_func.header.ret_type, "int *")
        self.assertEqual(merge_func.stack_vars[0].name, "v0")
        self.assertEqual(merge_func.stack_vars[4].name, "my_var")
        self.assertEqual(merge_func.stack_vars[4].type, "int")
        self.assertEqual(merge_func.stack_vars[8].name, "v8")
예제 #4
0
 def push_function_header(self,
                          addr,
                          new_name,
                          ret_type=None,
                          args=None,
                          user=None,
                          state=None):
     func_header = FunctionHeader(new_name,
                                  addr,
                                  ret_type=ret_type,
                                  args=args)
     return state.set_function_header(func_header)
예제 #5
0
def conv_func_binja_to_binsync(binja_func):

    #
    # header: name, ret type, args
    #

    args = {
        i: FunctionArgument(i, parameter.name,
                            parameter.type.get_string_before_name(),
                            parameter.type.width)
        for i, parameter in enumerate(binja_func.parameter_vars)
    }

    sync_header = FunctionHeader(
        binja_func.name,
        binja_func.start,
        ret_type=binja_func.return_type.get_string_before_name(),
        args=args)

    #
    # stack vars
    #

    binja_stack_vars = {
        v.storage: v
        for v in binja_func.stack_layout
        if v.source_type == VariableSourceType.StackVariableSourceType
    }
    sorted_stack = sorted(binja_func.stack_layout, key=lambda x: x.storage)
    var_sizes = {}

    for off, var in binja_stack_vars.items():
        i = sorted_stack.index(var)
        if i + 1 >= len(sorted_stack):
            var_sizes[var] = 0
        else:
            var_sizes[var] = var.storage - sorted_stack[i].storage

    bs_stack_vars = {
        off:
        binsync.StackVariable(off, binsync.StackOffsetType.BINJA, var.name,
                              var.type.get_string_before_name(),
                              var_sizes[var], binja_func.start)
        for off, var in binja_stack_vars.items()
    }

    size = binja_func.address_ranges[0].end - binja_func.address_ranges[0].start
    return Function(binja_func.start,
                    size,
                    header=sync_header,
                    stack_vars=bs_stack_vars)
예제 #6
0
    def handle_func_arg_retyped(self, func, offset, old_type, new_type):
        decompilation = self.controller.decompile_function(func)
        func_args = AngrBinSyncController.get_func_args(decompilation)
        func_type = decompilation.cfunc.functy.returnty.c_repr()
        bs_args = {
            i: binsync.FunctionArgument(i, var_info[0].name, var_info[1], var_info[0].size)
            for i, var_info in func_args.items()
        }

        self.controller.schedule_job(
            self.controller.push_artifact,
            FunctionHeader(func.name, func.addr, ret_type=func_type, args=bs_args)
        )
        return False
예제 #7
0
    def symbol_updated(self, view, sym):
        if self._controller.sync_lock.locked():
            return

        if sym.type == SymbolType.FunctionSymbol:
            func = view.get_function_at(sym.address)
            bs_func = conv_func_binja_to_binsync(func)
            self._controller.schedule_job(
                self._controller.push_artifact,
                FunctionHeader(sym.name,
                               sym.address,
                               ret_type=bs_func.header.ret_type,
                               args=bs_func.header.args))

        elif sym.type == SymbolType.DataSymbol:
            pass
예제 #8
0
    def active_context(self):
        curr_view = self._workspace.view_manager.current_tab
        if not curr_view:
            return None

        try:
            func = curr_view.function
        except NotImplementedError:
            return None

        if func is None or func.am_obj is None:
            return None

        return binsync.data.Function(func.addr,
                                     0,
                                     header=FunctionHeader(
                                         func.name, func.addr))
예제 #9
0
    def active_context(self):
        all_contexts = UIContext.allContexts()
        if not all_contexts:
            return None

        ctx = all_contexts[0]
        handler = ctx.contentActionHandler()
        if handler is None:
            return None

        actionContext = handler.actionContext()
        func = actionContext.function
        if func is None:
            return None

        return binsync.data.Function(func.start,
                                     0,
                                     header=FunctionHeader(
                                         func.name, func.start))
예제 #10
0
파일: controller.py 프로젝트: angr/binsync
    def function(self, addr) -> Optional[Function]:
        """
        TODO: add support for stack variables and function args

        @param addr:
        @return:
        """
        try:
            _func = self._instance.kb.functions[addr]
        except KeyError:
            return None

        func = Function(_func.addr, _func.size)
        func_header = FunctionHeader(_func.name,
                                     _func.addr,
                                     ret_type=_func.prototype.c_repr())

        func.header = func_header
        return func
예제 #11
0
파일: hooks.py 프로젝트: angr/binsync
    def renamed(self, ea, new_name, local_name):
        # #print("renamed(ea = %x, new_name = %s, local_name = %d)" % (ea, new_name, local_name))
        if ida_struct.is_member_id(ea) or ida_struct.get_struc(
                ea) or ida_enum.get_enum_name(ea):
            return 0

        ida_func = idaapi.get_func(ea)
        # global var renaming
        if ida_func is None:
            size = idaapi.get_item_size(ea)
            self.binsync_state_change(self.controller.push_artifact,
                                      GlobalVariable(ea, new_name, size=size))

        # function name renaming
        elif ida_func.start_ea == ea:
            # grab the name instead from ida
            name = idc.get_func_name(ida_func.start_ea)
            self.binsync_state_change(self.controller.push_artifact,
                                      FunctionHeader(name, ida_func.start_ea))

        return 0
예제 #12
0
파일: compat.py 프로젝트: angr/binsync
def function_header(ida_cfunc) -> FunctionHeader:
    func_addr = ida_cfunc.entry_ea

    # collect the function arguments
    func_args = {}
    for idx, arg in enumerate(ida_cfunc.arguments):
        size = arg.width
        name = arg.name
        type_str = str(arg.type())
        func_args[idx] = FunctionArgument(idx, name, type_str, size)

    # collect the header ret_type and name
    func_name = get_func_name(func_addr)
    try:
        ret_type_str = str(ida_cfunc.type.get_rettype())
    except Exception:
        ret_type_str = ""

    ida_function_info = FunctionHeader(func_name,
                                       func_addr,
                                       ret_type=ret_type_str,
                                       args=func_args,
                                       last_change=int(time()))
    return ida_function_info
예제 #13
0
파일: test_state.py 프로젝트: angr/binsync
    def test_func_diffing(self):
        state1 = binsync.State("user1")
        state2 = binsync.State("user2")

        # setup top
        func1 = FunctionHeader("func",
                               0x400000,
                               ret_type="int *",
                               args={
                                   0: FunctionArgument(0, "a1", "int", 4),
                                   1: FunctionArgument(1, "a2", "long", 8)
                               })
        func2 = FunctionHeader("func_changed",
                               func1.addr,
                               ret_type="long *",
                               args={
                                   0: FunctionArgument(0, "a1", "int", 4),
                                   1: FunctionArgument(1, "a2", "int", 4)
                               })

        state1.set_function_header(func1)
        state2.set_function_header(func2)
        state1.functions[func1.addr].size = 0x100
        state2.functions[func1.addr].size = 0x150

        stack_vars1 = {
            0x0: StackVariable(0, 3, "v0", "int", 4, func1.addr),
            0x4: StackVariable(4, 3, "v4", "int", 4, func1.addr)
        }
        stack_vars2 = {
            0x0: StackVariable(0, 3, "v0", "int", 4, func1.addr),
            0x4: StackVariable(4, 3, "v4", "long", 8, func1.addr),
            0x8: StackVariable(8, 3, "v8", "long", 8, func1.addr)
        }

        for stack_vars_info in [(stack_vars1, state1), (stack_vars2, state2)]:
            stack_vars, state = stack_vars_info[:]
            for off, var in stack_vars.items():
                state.set_stack_variable(var)

        func1 = state1.get_function(func1.addr)
        func2 = state2.get_function(func1.addr)

        diff_dict = func1.diff(func2)
        header_diff = diff_dict["header"]
        vars_diff = diff_dict["stack_vars"]

        # size should not match
        self.assertNotEqual(func1.size, func2.size)
        self.assertEqual(diff_dict["size"]["before"], func1.size)
        self.assertEqual(diff_dict["size"]["after"], func2.size)

        # names should not match
        self.assertEqual(header_diff["name"]["before"], func1.name)
        self.assertEqual(header_diff["name"]["after"], func2.name)

        # arg1 should match
        self.assertFalse(header_diff["args"][0])

        # arg2 should not match
        self.assertNotEqual(header_diff["args"][1]["type_str"]["before"],
                            header_diff["args"][1]["type_str"]["after"])

        # v4 and v8 should differ
        offsets = [0, 4, 8]
        for off in offsets:
            var_diff = vars_diff[off]
            if off == 0:
                self.assertFalse(var_diff)
            if off == 0x4:
                self.assertNotEqual(var_diff["size"]["before"],
                                    var_diff["size"]["after"])
            elif off == 0x8:
                self.assertIsNone(var_diff["addr"]["before"])
                self.assertEqual(var_diff["addr"]["after"], func1.addr)

        print(json.dumps(diff_dict, sort_keys=False, indent=4))
예제 #14
0
 def handle_function_renamed(self, func, old_name, new_name):
     self.controller.schedule_job(
         self.controller.push_artifact,
         FunctionHeader(new_name, func.addr)
     )
     return False