Example #1
0
    def xrefs_to(self):
        """
        Retrieves the xrefs to the stack variable.

        NOTE: This code is very SWIGGY because IDA did not properly expose this functionality.

        :raises ValueError: if frame_id, stack_offset, or string_reference was not provided.
            This is needed to determine what function to use.
        """
        if self._xrefs_to is None:
            if not self.string_reference:
                raise ValueError('Unable to get xrefs without string_reference.')
            if not (self.frame_id and self.stack_offset):
                raise ValueError('Unable to get xrefs without frame_id and stack_offset')
            xrefs = idaapi.xreflist_t()
            frame = idaapi.get_frame(self.frame_id)
            func = idaapi.get_func(self.string_reference)
            member = idaapi.get_member(frame, self.stack_offset)
            idaapi.build_stkvar_xrefs(xrefs, func, member)
            self._xrefs_to = [ref.ea for ref in xrefs]
        return self._xrefs_to
Example #2
0
    def refs(self):
        """Return the (address, opnum, type) of all the references (code & data) to this structure within the database.
        If `opnum` is None, then the `address` has the structure applied to it.
        If `opnum` is defined, then the instruction at `address` references a field that is the specified structure.
        """
        x, sid = idaapi.xrefblk_t(), self.id

        # grab first reference to structure
        ok = x.first_to(sid, 0)
        if not ok:
            return []

        # collect rest of it's references
        refs = [(x.frm, x.iscode, x.type)]
        while x.next_to():
            refs.append((x.frm, x.iscode, x.type))

        # calculate the high-byte which is used to differentiate an address from a structure
        bits = math.trunc(math.ceil(math.log(idaapi.BADADDR) / math.log(2.0)))
        highbyte = 0xff << (bits - 8)

        # iterate through figuring out if sid is applied to an address or another structure
        res = []
        for ref, _, _ in refs:
            # structure (probably a frame member)
            if ref & highbyte == highbyte:
                # get sptr, mptr
                name = idaapi.get_member_fullname(ref)
                mptr, _ = idaapi.get_member_by_fullname(name)
                if not isinstance(mptr, idaapi.member_t):
                    cls = self.__class__
                    raise TypeError(
                        "{:s} : Unexpected type {!r} for netnode '{:s}'".
                        format('.'.join((__name__, cls.__name__)),
                               mptr.__class__, name))
                sptr = idaapi.get_sptr(mptr)

                # get frame, func_t
                frname, _ = name.split('.', 2)
                frid = internal.netnode.get(frname)
                ea = idaapi.get_func_by_frame(frid)
                f = idaapi.get_func(ea)

                # now find all xrefs to member within function
                xl = idaapi.xreflist_t()
                idaapi.build_stkvar_xrefs(xl, f, mptr)

                # now we can add it
                for xr in xl:
                    ea, opnum, state = xr.ea, int(
                        xr.opnum), instruction.op_state(ea, opnum)
                    res.append(
                        interface.OREF(ea, opnum,
                                       interface.ref_t.of_state(state)))
                continue

            # address
            res.append(interface.OREF(ref, None, interface.ref_t.of_state(
                '*')))  # using '*' to describe being applied to the an address

        return res
Example #3
0
    def refs(self):
        '''Return the (address, opnum, type) of all the references to this member within the database.'''
        mid = self.id

        # calculate the high-byte which is used to determine an address from a structure
        bits = int(math.ceil(math.log(idaapi.BADADDR) / math.log(2.0)))
        highbyte = 0xff << (bits - 8)

        # if structure is a frame..
        if internal.netnode.name.get(self.__owner.id).startswith('$ '):
            name, mptr = self.fullname, self.ptr
            sptr = idaapi.get_sptr(mptr)

            # get frame, func_t
            frname, _ = name.split('.', 2)
            frid = internal.netnode.get(frname)
            ea = idaapi.get_func_by_frame(frid)
            f = idaapi.get_func(ea)

            # now find all xrefs to member within function
            xl = idaapi.xreflist_t()
            idaapi.build_stkvar_xrefs(xl, f, mptr)

            # now we can add it
            res = []
            for xr in xl:
                ea, opnum = xr.ea, int(xr.opnum)
                res.append(
                    interface.OREF(
                        ea, opnum,
                        interface.ref_t(xr.type,
                                        instruction.op_state(ea,
                                                             opnum))))  # FIXME
            return res

        # otherwise, it's a structure..which means we need to specify the member to get refs for
        x = idaapi.xrefblk_t()
        ok = x.first_to(mid, 0)
        if not ok:
            return []

        # collect all references available
        refs = [(x.frm, x.iscode, x.type)]
        while x.next_to():
            refs.append((x.frm, x.iscode, x.type))

        # now figure out which operand has the structure member applied to it
        res = []
        for ea, _, t in refs:
            ops = ((idx, internal.netnode.sup.get(ea, 0xf + idx))
                   for idx in range(idaapi.UA_MAXOP)
                   if internal.netnode.sup.get(ea, 0xf + idx) is not None)
            ops = ((idx,
                    interface.node.sup_opstruct(
                        val,
                        idaapi.get_inf_structure().is_64bit()))
                   for idx, val in ops)
            ops = (idx for idx, ids in ops if self.__owner.id in ids)  # sanity
            res.extend(
                interface.OREF(ea, int(op), interface.ref_t.of(t))
                for op in ops)
        return res