Beispiel #1
0
    def struc_member_changed(self, sptr, mptr):
        #print(f"struc member changed: {sptr.id}, {mptr.id}")

        # struct pointer is actually a stack frame
        if sptr.is_frame():
            stack_frame = sptr
            func_addr = idaapi.get_func_by_frame(stack_frame.id)
            try:
                all_var_info = compat.get_func_stack_var_info(func_addr)
                stack_var_info = all_var_info[compat.ida_to_angr_stack_offset(
                    func_addr, mptr.soff)]
            except KeyError:
                l.debug(
                    f"Failed to track an internal changing stack var: {mptr.id}."
                )
                return 0

            # find the properties of the changed stack var
            angr_offset = compat.ida_to_angr_stack_offset(
                func_addr, stack_var_info.stack_offset)
            size = stack_var_info.size
            type_str = stack_var_info.type

            new_name = stack_var_info.name  #ida_struct.get_member_name(mptr.id)

            # do the change on a new thread
            sv = StackVariable(angr_offset, StackOffsetType.IDA, new_name,
                               type_str, size, func_addr)
            self.binsync_state_change(self.controller.push_artifact, sv)
        else:
            self.ida_struct_changed(sptr.id)

        return 0
Beispiel #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
Beispiel #3
0
def get_func_stack_var_info(func_addr) -> typing.Dict[int, StackVariable]:
    try:
        decompilation = ida_hexrays.decompile(func_addr)
    except ida_hexrays.DecompilationFailure:
        l.debug(
            "Decompiling too many functions too fast! Slow down and try that operation again."
        )
        return {}

    stack_var_info = {}

    for var in decompilation.lvars:
        if not var.is_stk_var():
            continue

        size = var.width
        name = var.name

        ida_offset = var.location.stkoff() - decompilation.get_stkoff_delta()
        bs_offset = ida_to_angr_stack_offset(func_addr, ida_offset)
        type_str = str(var.type())
        stack_var_info[bs_offset] = StackVariable(ida_offset,
                                                  StackOffsetType.IDA, name,
                                                  type_str, size, func_addr)

    return stack_var_info
Beispiel #4
0
    def handle_stack_var_retyped(self, func, offset, old_type, new_type):
        decompilation = self.controller.decompile_function(func)
        stack_var = self.controller.find_stack_var_in_codegen(decompilation, offset)

        self.controller.schedule_job(
            self.controller.push_artifact,
            StackVariable(offset, StackOffsetType.ANGR, stack_var.name, new_type, stack_var.size, func.addr),
        )
        return False
Beispiel #5
0
    def handle_stack_var_renamed(self, func, offset, old_name, new_name):
        decompilation = self.controller.decompile_function(func)
        stack_var = self.controller.find_stack_var_in_codegen(decompilation, offset)
        var_type = AngrBinSyncController.stack_var_type_str(decompilation, stack_var)

        self.controller.schedule_job(
            self.controller.push_artifact,
            StackVariable(offset, StackOffsetType.ANGR, new_name, var_type, stack_var.size, func.addr)
        )
        return False
Beispiel #6
0
    def push_stack_variable(self,
                            bn_func: binaryninja.Function,
                            stack_var: binaryninja.function.Variable,
                            state: State = None):
        if stack_var.source_type != VariableSourceType.StackVariableSourceType:
            raise TypeError("Unexpected source type %s of the variable %r." %
                            (stack_var.source_type, stack_var))

        type_str = stack_var.type.get_string_before_name()
        size = stack_var.type.width
        v = StackVariable(stack_var.storage, StackOffsetType.BINJA,
                          stack_var.name, type_str, size, bn_func.start)
        state.set_stack_variable(bn_func.start, stack_var.storage, v)
Beispiel #7
0
    def struc_member_renamed(self, sptr, mptr):
        #print(f"struc member renamed: {sptr.id}: {mptr.id}")
        """
        Handles renaming of two things:
        1. Global Structs
        2. Stack Variables

        :param sptr:    Struct Pointer
        :param mptr:    Member Pointer
        :return:
        """
        # struct pointer is actually a stack frame
        if sptr.is_frame():
            stack_frame = sptr
            func_addr = idaapi.get_func_by_frame(stack_frame.id)
            try:
                stack_var_info = compat.get_func_stack_var_info(func_addr)[
                    compat.ida_to_angr_stack_offset(func_addr, mptr.soff)]
            except KeyError:
                l.debug(
                    f"Failed to track an internal changing stack var: {mptr.id}."
                )
                return 0

            # find the properties of the changed stack var
            angr_offset = compat.ida_to_angr_stack_offset(
                func_addr, stack_var_info.stack_offset)
            size = stack_var_info.size
            type_str = stack_var_info.type

            # TODO: correct this fix in the get_func_stack_var_info
            new_name = ida_struct.get_member_name(mptr.id)

            # do the change on a new thread
            sv = StackVariable(angr_offset, StackOffsetType.IDA, new_name,
                               type_str, size, func_addr)
            self.binsync_state_change(self.controller.push_artifact, sv)

        # an actual struct
        else:
            self.ida_struct_changed(sptr.id)

        return 0
Beispiel #8
0
    def push_stack_variable(self,
                            func_addr,
                            stack_offset,
                            name,
                            type_str,
                            size,
                            user=None,
                            state=None):
        # Update last pushed values
        last_push_time = int(time.time())
        last_push_func = compat.ida_func_addr(func_addr)
        func_name = compat.get_func_name(last_push_func)

        # convert longs to ints
        stack_offset = int(stack_offset)
        func_addr = int(func_addr)
        size = int(size)

        v = StackVariable(stack_offset, StackOffsetType.IDA, name, type_str,
                          size, func_addr)
        state.set_stack_variable(func_addr, stack_offset, v)

        self._client.last_push(last_push_func, last_push_time, func_name)