Ejemplo n.º 1
0
def members(id):
    """Yields the members of the structure identified by ``id``.
    Each iteration yields the ((offset,size),(name,comment,repeatable-comment)) of each member.
    """

    st = idaapi.get_struc(id)
    if not st:
        # empty structure
        return

    size = idaapi.get_struc_size(st)

    offset = 0
    for i in range(st.memqty):
        m = st.get_member(i)
        ms = idaapi.get_member_size(m)

        left, right = m.soff, m.eoff

        if offset < left:
            yield (offset, left - offset), (idaapi.get_member_name(m.id),
                                            idaapi.get_member_cmt(m.id, 0),
                                            idaapi.get_member_cmt(m.id, 1))
            offset = left

        yield (offset, ms), (idaapi.get_member_name(m.id),
                             idaapi.get_member_cmt(m.id, 0),
                             idaapi.get_member_cmt(m.id, 1))
        offset += ms
    return
Ejemplo n.º 2
0
    def renaming_struc_member(self, sptr, mptr, newname):
        """
        Handles renaming of two things:
        1. Global Structs
        2. Stack Variables

        :param sptr:    Struct Pointer
        :param mptr:    Member Pointer
        :param newname: New Member Name
        :return:
        """

        sname = ida_struct.get_struc_name(sptr.id)
        s_type = compat.parse_struct_type(sname)

        # stack offset variable
        if isinstance(s_type, int):
            func_addr = s_type

            # compute stack frame for offset
            frame = idaapi.get_frame(func_addr)
            frame_size = idc.get_struc_size(frame)
            last_member_size = idaapi.get_member_size(
                frame.get_member(frame.memqty - 1))

            # stack offset
            stack_offset = mptr.soff - frame_size + last_member_size
            size = idaapi.get_member_size(mptr)
            type_str = self.controller._get_type_str(mptr.flag)

            # do the change on a new thread
            self.controller.make_controller_cmd(
                self.controller.push_stack_variable, func_addr, stack_offset,
                newname, type_str, size)

        # actual struct
        elif isinstance(s_type, str):
            print("Not implemented")

        else:
            print("Error: bad parsing")

        return 0
Ejemplo n.º 3
0
def ida_to_angr_stack_offset(func_addr, ida_stack_off):
    frame = idaapi.get_frame(func_addr)
    if not frame:
        return ida_stack_off

    frame_size = idc.get_struc_size(frame)
    last_member_size = idaapi.get_member_size(
        frame.get_member(frame.memqty - 1))
    angr_stack_off = ida_stack_off - frame_size + last_member_size
    return angr_stack_off
Ejemplo n.º 4
0
    def by_offset(self, offset):
        '''Return the member at the specified ``offset``.'''
        min, max = map(lambda sz: sz + self.baseoffset,
                       (idaapi.get_struc_first_offset(self.owner.ptr),
                        idaapi.get_struc_last_offset(self.owner.ptr)))

        mptr = idaapi.get_member(self.owner.ptr, max - self.baseoffset)
        msize = idaapi.get_member_size(mptr)
        if (offset < min) or (offset >= max + msize):
            raise LookupError(
                "{:s}.instance({:s}).members.by_offset : Requested offset {:+#x} not within bounds ({:#x},{:#x})"
                .format(__name__, self.owner.name, offset, min, max + msize))

        mem = idaapi.get_member(self.owner.ptr, offset - self.baseoffset)
        if mem is None:
            raise LookupError(
                "{:s}.instance({:s}).members.by_offset : Unable to find member at offset : {:+#x}"
                .format(__name__, self.owner.name, offset))

        index = self.index(mem)
        return self[index]
Ejemplo n.º 5
0
def members(id):
    st = idaapi.get_struc(id)
    if not st:
        # empty structure
        return

    size = idaapi.get_struc_size(st)

    offset = 0
    for i in range(st.memqty):
        m = st.get_member(i)
        ms = idaapi.get_member_size(m)

        left,right = m.soff,m.eoff

        if offset < left:
            yield (offset,left-offset), (None,None)
            offset = left

        yield (offset,ms),(idaapi.get_member_name(m.id), idaapi.get_member_cmt(m.id, 1))
        offset += ms
    return
Ejemplo n.º 6
0
def members(id):
    """Return the ((offset,size),(name,comment)) of each member within the specified structure"""
    st = idaapi.get_struc(id)
    if not st:
        # empty structure
        return

    size = idaapi.get_struc_size(st)

    offset = 0
    for i in range(st.memqty):
        m = st.get_member(i)
        ms = idaapi.get_member_size(m)

        left, right = m.soff, m.eoff

        if offset < left:
            yield (offset, left - offset), (None, None)
            offset = left

        yield (offset, ms), (idaapi.get_member_name(m.id),
                             idaapi.get_member_cmt(m.id, 1))
        offset += ms
    return
Ejemplo n.º 7
0
 def size(self):
     return idaapi.get_member_size(self.ptr)
Ejemplo n.º 8
0
 def size(self):
     return idaapi.get_member_size(self.ptr)
Ejemplo n.º 9
0
 def size(self):
     '''Return the size of the member.'''
     return idaapi.get_member_size(self.ptr)
Ejemplo n.º 10
0
    def fill_function(self, ida_func, user=None, state=None):
        """
        Grab all relevant information from the specified user and fill the @ida_func.
        """

        # == function name === #
        _func = self.pull_function(ida_func, user=user, state=state)
        if _func is None:
            return

        if compat.get_func_name(ida_func.start_ea) != _func.name:
            compat.set_ida_func_name(ida_func.start_ea, _func.name)

        # === comments === #
        # set the func comment
        func_comment = self.pull_comment(_func.addr, user=user, state=state)
        if func_comment is None:
            func_comment = ""
            #idc.set_func_cmt(_func.addr, func_comment, 1)
            #compat.set_ida_comment(_func.addr, func_comment, 1, func_cmt=True)

        # set the disassembly comments
        func_cmt_end = "\n"
        for start_ea, end_ea in idautils.Chunks(ida_func.start_ea):
            for head in idautils.Heads(start_ea, end_ea):
                if head == _func.addr:
                    continue

                comment = self.pull_comment(head, user=user, state=state)
                if comment is not None:
                    func_cmt_end += f"\n{hex(head)}: {comment}"
                    #compat.set_decomp_comments(_func.addr, {head: comment})
                    #compat.set_ida_comment(head, comment, 0, func_cmt=False)
        func_comment += func_cmt_end
        compat.set_ida_comment(_func.addr, func_comment, 1, func_cmt=True)

        # === stack variables === #
        existing_stack_vars = {}
        frame = idaapi.get_frame(ida_func.start_ea)
        if frame is None or frame.memqty <= 0:
            _l.debug(
                "Function %#x does not have an associated function frame. Skip variable name sync-up.",
                ida_func.start_ea)
            return

        frame_size = idc.get_struc_size(frame)
        last_member_size = idaapi.get_member_size(
            frame.get_member(frame.memqty - 1))

        for i in range(frame.memqty):
            member = frame.get_member(i)
            stack_offset = member.soff - frame_size + last_member_size
            existing_stack_vars[stack_offset] = member

        for offset, stack_var in self.pull_stack_variables(
                ida_func, user=user, state=state).items():
            ida_offset = stack_var.get_offset(StackOffsetType.IDA)
            # skip if this variable already exists
            if ida_offset in existing_stack_vars:
                type_str = self._get_type_str(
                    existing_stack_vars[ida_offset].flag)
            else:
                type_str = None

            if ida_offset in existing_stack_vars:
                if idc.get_member_name(frame.id, existing_stack_vars[ida_offset].soff) == stack_var.name \
                        and type_str is not None \
                        and stack_var.type == type_str:
                    continue
                # rename the existing variable
                idaapi.set_member_name(frame,
                                       existing_stack_vars[ida_offset].soff,
                                       stack_var.name)
                # TODO: retype the existing variable

        # ===== update the psuedocode ==== #
        compat.refresh_pseudocode_view(_func.addr)