Exemple #1
0
    def dump():
        ret = []
        for addr, name in idautils.Names():
            flags = ida_bytes.get_flags(addr)
            # The 'a' heuristic is fairly bad but we need to filter out IDA's default
            # naming for strings
            if ida_bytes.has_dummy_name(flags) or ida_bytes.has_auto_name(flags) or not ida_bytes.is_data(flags) or name[0] == 'a':
                continue

            # Sometimes the auto-generated names don't actually usually have the
            # right flags set, so skip these auto-looking names.
            if any(name.startswith(s) for s in ['byte_', 'word_', 'dword_', 'unk_', 'jpt_']):
                continue

            sz = ida_bytes.get_item_size(addr)

            if ida_bytes.is_struct(flags):
                ti = ida_nalt.opinfo_t()
                ida_bytes.get_opinfo(ti, addr, 0, flags)
                typ = ida_struct.get_struc_name(ti.tid)
            else:
                typ = None
			
            ret.append(filter_none({
                'address': addr,
                'name': name,
                'type': typ,
                'sz': sz,
                'flags': flags,
            }))

        return ret
Exemple #2
0
    def struc_member_changed(self, sptr, mptr):
        extra = {}

        sname = ida_struct.get_struc_name(sptr.id)
        soff = 0 if mptr.unimem() else mptr.soff
        flag = mptr.flag
        mt = ida_nalt.opinfo_t()
        is_not_data = ida_struct.retrieve_member_info(mt, mptr)
        if is_not_data:
            if flag & ida_bytes.off_flag():
                extra['target'] = mt.ri.target
                extra['base'] = mt.ri.base
                extra['tdelta'] = mt.ri.tdelta
                extra['flags'] = mt.ri.flags
                self._send_event(
                    StrucMemberChangedEvent(sname, soff, mptr.eoff, flag,
                                            extra))
            # Is it really possible to create an enum?
            elif flag & ida_bytes.enum_flag():
                extra['serial'] = mt.ec.serial
                self._send_event(
                    StrucMemberChangedEvent(sname, soff, mptr.eoff, flag,
                                            extra))
            elif flag & ida_bytes.stru_flag():
                extra['id'] = mt.tid
                if flag & ida_bytes.strlit_flag():
                    extra['strtype'] = mt.strtype
                self._send_event(
                    StrucMemberChangedEvent(sname, soff, mptr.eoff, flag,
                                            extra))
        else:
            self._send_event(
                StrucMemberChangedEvent(sname, soff, mptr.eoff, flag, extra))
        return 0
Exemple #3
0
    def member_data(self, member):
        d = {}
        # TODO: variable size bool
        # TODO: retrieve_member_info - get operand type member info
        d['name'] = ida_struct.get_member_name(member.id)
        d['size'] = ida_struct.get_member_size(member)
        d['flag'] = member.flag
        d['offset'] = member.soff
        d['comment'] = ida_struct.get_member_cmt(member.id, False)
        d['repeatable_comment'] = ida_struct.get_member_cmt(member.id, True)

        if member.has_ti():
            tinfo = ida_typeinf.tinfo_t()
            ida_struct.get_member_tinfo(tinfo, member)
            d['type_info_serialize'] = tinfo.serialize()
            d['type_info'] = str(tinfo)

        oi = ida_nalt.opinfo_t()
        ida_struct.retrieve_member_info(oi, member)
        # TODO: Do things with OI

        sptr = ida_struct.get_sptr(member)
        if sptr:
            struct_name = ida_struct.get_struc_name(sptr.id)
            d['struct_name'] = struct_name
            d['struct_uuid'] = StructureAnnotation.depend(self, struct_name)
        return d
Exemple #4
0
    def struc_member_changed(self, sptr, mptr):
        extra = {}

        sname = ida_struct.get_struc_name(sptr.id)
        soff = 0 if mptr.unimem() else mptr.soff
        flag = mptr.flag
        mt = ida_nalt.opinfo_t()
        is_not_data = ida_struct.retrieve_member_info(mt, mptr)
        if is_not_data:
            if flag & ida_bytes.off_flag():
                extra["target"] = mt.ri.target
                extra["base"] = mt.ri.base
                extra["tdelta"] = mt.ri.tdelta
                extra["flags"] = mt.ri.flags
                self._send_packet(
                    evt.StrucMemberChangedEvent(sname, soff, mptr.eoff, flag,
                                                extra))
            elif flag & ida_bytes.enum_flag():
                extra["serial"] = mt.ec.serial
                self._send_packet(
                    evt.StrucMemberChangedEvent(sname, soff, mptr.eoff, flag,
                                                extra))
            elif flag & ida_bytes.stru_flag():
                extra["struc_name"] = ida_struct.get_struc_name(mt.tid)
                if flag & ida_bytes.strlit_flag():
                    extra["strtype"] = mt.strtype
                self._send_packet(
                    evt.StrucMemberChangedEvent(sname, soff, mptr.eoff, flag,
                                                extra))
        else:
            self._send_packet(
                evt.StrucMemberChangedEvent(sname, soff, mptr.eoff, flag,
                                            extra))
        return 0
Exemple #5
0
 def apply(self):
     func_frame = self.func_frame_pointer
     if self.new:
         ida_struct.add_struc_member(func_frame, self.data, self.offset, 0,
                                     ida_nalt.opinfo_t(), self.var_size)
     else:
         ida_struct.set_member_name(func_frame, self.offset, self.data)
     return True
Exemple #6
0
def push_ptr_member_to_struct(
    struct, member_name, member_type, offset=BADADDR, overwrite=False
):
    mt = None
    flag = idaapi.FF_DWORD
    member_size = WORD_LEN
    if member_type is not None and (member_type.is_struct() or member_type.is_union()):
        logging.debug("Is struct!")
        substruct = extract_struct_from_tinfo(member_type)
        if substruct is not None:
            flag = idaapi.FF_STRUCT
            mt = ida_nalt.opinfo_t()
            mt.tid = substruct.id
            logging.debug(
                f"Is struct: {ida_struct.get_struc_name(substruct.id)}/{substruct.id}"
            )
            member_size = ida_struct.get_struc_size(substruct.id)
            member_type = None
    elif WORD_LEN == 4:
        flag = idaapi.FF_DWORD
    elif WORD_LEN == 8:
        flag = idaapi.FF_QWORD

    new_member_name = member_name
    if overwrite and ida_struct.get_member(struct, offset):
        logging.debug("Overwriting!")
        ret_val = ida_struct.set_member_name(struct, offset, member_name)
        i = 0
        while ret_val == ida_struct.STRUC_ERROR_MEMBER_NAME:
            new_member_name = "%s_%d" % (member_name, i)
            i += 1
            if i > 250:
                return
            ret_val = ida_struct.set_member_name(struct, offset, new_member_name)

    else:
        ret_val = ida_struct.add_struc_member(
            struct, new_member_name, offset, flag, mt, member_size
        )
        i = 0
        while ret_val == ida_struct.STRUC_ERROR_MEMBER_NAME:
            new_member_name = "%s_%d" % (member_name, i)
            i += 1
            if i > 250:
                return
            ret_val = ida_struct.add_struc_member(
                struct, new_member_name, offset, flag, mt, member_size
            )
        if ret_val != 0:
            logging.debug(f"ret_val: {ret_val}")
    member_ptr = ida_struct.get_member_by_name(struct, new_member_name)
    if member_ptr is None:
        logging.debug("member is None")
    if member_type is not None and member_ptr is not None:
        ida_struct.set_member_tinfo(
            struct, member_ptr, 0, member_type, idaapi.TINFO_DEFINITE
        )
    return member_ptr
Exemple #7
0
def get_member_params(member_tif, is_offs):
    """@return: tuple(flag, mt, member_size)"""

    substruct_ptr = get_struc_from_tinfo(member_tif)
    if substruct_ptr:
        flag = idaapi.FF_STRUCT
        mt = ida_nalt.opinfo_t()
        mt.tid = substruct_ptr.id
        member_size = ida_struct.get_struc_size(substruct_ptr.id)
    else:
        flag = idaapi.FF_QWORD if WORD_LEN == 8 else idaapi.FF_DWORD
        mt = None
        member_size = WORD_LEN

    if is_offs:
        flag |= idaapi.FF_0OFF
        mt = ida_nalt.opinfo_t()
        r = ida_nalt.refinfo_t()
        r.init(ida_nalt.get_reftype_by_size(WORD_LEN) | ida_nalt.REFINFO_NOBASE)
        mt.ri = r

    return flag, mt, member_size
Exemple #8
0
    def op_type_changed(self, ea, n):
        flags = ida_bytes.get_flags(ea)
        self.log("op_type_changed(ea=0x%08X, n=%d). Flags now: 0x%08X" % (ea, n, flags))

        buf = ida_nalt.opinfo_t()
        opi = ida_bytes.get_opinfo(buf, ea, n, flags)
        if opi:
            if ida_bytes.is_struct(flags):
                self.log("New struct: 0x%08X (name=%s)" % (
                    opi.tid,
                    ida_struct.get_struc_name(opi.tid)))
            elif ida_bytes.is_strlit(flags):
                encidx = ida_nalt.get_str_encoding_idx(opi.strtype)
                if encidx == ida_nalt.STRENC_DEFAULT:
                    encidx = ida_nalt.get_default_encoding_idx(ida_nalt.get_strtype_bpu(opi.strtype))
                encname = ida_nalt.get_encoding_name(encidx)
                strlen = ida_bytes.get_max_strlit_length(
                    ea,
                    opi.strtype,
                    ida_bytes.ALOPT_IGNHEADS | ida_bytes.ALOPT_IGNCLT)
                raw = ida_bytes.get_strlit_contents(ea, strlen, opi.strtype) or b""
                self.log("New strlit: 0x%08X, raw hex=%s (encoding=%s)" % (
                    opi.strtype,
                    binascii.hexlify(raw),
                    encname))
            elif ida_bytes.is_off(flags, n):
                self.log("New offset: refinfo={target=0x%08X, base=0x%08X, tdelta=0x%08X, flags=0x%X}" % (
                    opi.ri.target,
                    opi.ri.base,
                    opi.ri.tdelta,
                    opi.ri.flags))
            elif ida_bytes.is_enum(flags, n):
                self.log("New enum: 0x%08X (enum=%s), serial=%d" % (
                    opi.ec.tid,
                    ida_enum.get_enum_name(opi.ec.tid),
                    opi.ec.serial))
                pass
            elif ida_bytes.is_stroff(flags, n):
                parts = []
                for i in range(opi.path.len):
                    tid = opi.path.ids[i]
                    parts.append("0x%08X (name=%s)" % (tid, ida_struct.get_struc_name(tid)))
                self.log("New stroff: path=[%s] (len=%d, delta=0x%08X)" % (
                    ", ".join(parts),
                    opi.path.len,
                    opi.path.delta))
            elif ida_bytes.is_custom(flags) or ida_bytes.is_custfmt(flags, n):
                self.log("New custom data type") # unimplemented
        else:
            print("Cannot retrieve opinfo_t")
 def __call__(self):
     mt = ida_nalt.opinfo_t()
     if ida_bytes.is_struct(self.flag):
         mt.tid = self.extra['id']
     if ida_bytes.is_off0(self.flag) or ida_bytes.is_off1(self.flag):
         mt.ri = ida_nalt.refinfo_t(self.extra['flags'], self.extra['base'],
                                    self.extra['target'],
                                    self.extra['tdelta'])
     if ida_bytes.is_strlit(self.flag):
         mt.strtype = self.extra['strtype']
     struc = ida_struct.get_struc_id(Event.encode(self.sname))
     sptr = ida_struct.get_struc(struc)
     ida_struct.set_member_type(sptr, self.soff, self.flag, mt,
                                self.eoff - self.soff)
Exemple #10
0
 def __call__(self):
     mt = ida_nalt.opinfo_t()
     if ida_bytes.is_struct(self.flag):
         mt.tid = self.extra["id"]
     if ida_bytes.is_off0(self.flag) or ida_bytes.is_off1(self.flag):
         mt.ri = ida_nalt.refinfo_t(
             self.extra["flags"],
             self.extra["base"],
             self.extra["target"],
             self.extra["tdelta"],
         )
     if ida_bytes.is_strlit(self.flag):
         mt.strtype = self.extra["strtype"]
     struc = ida_struct.get_struc_id(Event.encode(self.sname))
     sptr = ida_struct.get_struc(struc)
     ida_struct.set_member_type(sptr, self.soff, self.flag, mt,
                                self.eoff - self.soff)
Exemple #11
0
 def struc_member_created(self, sptr, mptr):
     extra = {}
     sname = ida_struct.get_struc_name(sptr.id)
     fieldname = ida_struct.get_member_name(mptr.id)
     offset = 0 if mptr.unimem() else mptr.soff
     flag = mptr.flag
     nbytes = mptr.eoff if mptr.unimem() else mptr.eoff - mptr.soff
     mt = ida_nalt.opinfo_t()
     is_not_data = ida_struct.retrieve_member_info(mt, mptr)
     if is_not_data:
         if flag & ida_bytes.off_flag():
             extra["target"] = mt.ri.target
             extra["base"] = mt.ri.base
             extra["tdelta"] = mt.ri.tdelta
             extra["flags"] = mt.ri.flags
             self._send_packet(
                 evt.StrucMemberCreatedEvent(
                     sname, fieldname, offset, flag, nbytes, extra
                 )
             )
         # Is it really possible to create an enum?
         elif flag & ida_bytes.enum_flag():
             extra["serial"] = mt.ec.serial
             self._send_packet(
                 evt.StrucMemberCreatedEvent(
                     sname, fieldname, offset, flag, nbytes, extra
                 )
             )
         elif flag & ida_bytes.stru_flag():
             extra["id"] = mt.tid
             if flag & ida_bytes.strlit_flag():
                 extra["strtype"] = mt.strtype
             self._send_packet(
                 evt.StrucMemberCreatedEvent(
                     sname, fieldname, offset, flag, nbytes, extra
                 )
             )
     else:
         self._send_packet(
             evt.StrucMemberCreatedEvent(
                 sname, fieldname, offset, flag, nbytes, extra
             )
         )
     return 0
Exemple #12
0
 def implement(self):
     id_of_struct = ida_struct.get_struc_id(str(self._id))
     sturct_obj = ida_struct.get_struc(long(id_of_struct))
     flags = 0
     size = 0
     if self._value == "db":
         flags = ida_bytes.FF_BYTE
         size = 1
     elif self._value == "dw":
         flags = ida_bytes.FF_WORD
         size = 2
     elif self._value == "dd":
         flags = ida_bytes.FF_DWORD
         size = 4
     elif self._value == "dq":
         flags = ida_bytes.QWORD
         size = 8
     ida_struct.set_member_type(sturct_obj, int(self._offset), flags,
                                ida_nalt.opinfo_t(), size)
Exemple #13
0
def _is_address_of_struct_field(ea):
    prev_head_ea = idc.prev_head(ea)

    if is_invalid_ea(prev_head_ea):
        return False

    prev_item_size = idc.get_item_size(prev_head_ea)
    if ea >= (prev_head_ea + prev_item_size):
        return False

    # Try to get a type for the last item head.
    flags = ida_bytes.get_full_flags(ea)
    ti = ida_nalt.opinfo_t()
    oi = ida_bytes.get_opinfo(ti, ea, 0, flags)
    if not oi:
        return False

    # Get the size of the struct, and keep going if the suze of the previous
    # item is a multiple of the struct's size (e.g. one struct or an array
    # of that struct).
    struct_size = idc.get_struc_size(oi.tid)
    if not struct_size or 0 != (prev_item_size % struct_size):
        return False

    # Figure out the offset of `ea` within its structure, which may belong to
    # an array of structures, and then check if that offset is associated with
    # a named field.
    arr_index = int((ea - prev_head_ea) / struct_size)
    struct_begin_ea = (arr_index & struct_size) + prev_head_ea
    off_in_struct = ea - struct_begin_ea
    if not idc.get_member_name(oi.tid, off_in_struct):
        return False

    field_begin_ea = struct_begin_ea + off_in_struct
    if field_begin_ea != ea:
        return False

    field_size = idc.get_member_size(oi.tid, off_in_struct)
    if not field_size:
        return False

    return True
Exemple #14
0
def _is_address_of_struct_field(ea):
  prev_head_ea = idc.prev_head(ea)

  if is_invalid_ea(prev_head_ea):
    return False

  prev_item_size = idc.get_item_size(prev_head_ea)
  if ea >= (prev_head_ea + prev_item_size):
    return False

  # Try to get a type for the last item head.
  flags = ida_bytes.get_full_flags(ea)
  ti = ida_nalt.opinfo_t()
  oi = ida_bytes.get_opinfo(ti, ea, 0, flags)
  if not oi:
    return False

  # Get the size of the struct, and keep going if the suze of the previous
  # item is a multiple of the struct's size (e.g. one struct or an array
  # of that struct).
  struct_size = idc.get_struc_size(oi.tid)
  if not struct_size or 0 != (prev_item_size % struct_size):
    return False

  # Figure out the offset of `ea` within its structure, which may belong to
  # an array of structures, and then check if that offset is associated with
  # a named field.
  arr_index = int((ea - prev_head_ea) / struct_size)
  struct_begin_ea = (arr_index & struct_size) + prev_head_ea
  off_in_struct = ea - struct_begin_ea
  if not idc.get_member_name(oi.tid, off_in_struct):
    return False

  field_begin_ea = struct_begin_ea + off_in_struct
  if field_begin_ea != ea:
    return False

  field_size = idc.GetMemberSize(oi.tid, off_in_struct)
  if not field_size:
    return False

  return True
Exemple #15
0
    def struc_member_changed(self, sptr, mptr):
        print("struc member changed")
        extra = {}

        sname = ida_struct.get_struc_name(sptr.id)
        soff = 0 if mptr.unimem() else mptr.soff
        flag = mptr.flag
        mt = ida_nalt.opinfo_t()
        is_not_data = ida_struct.retrieve_member_info(mt, mptr)
        if is_not_data:
            if flag & ida_bytes.off_flag():
                extra["target"] = mt.ri.target
                extra["base"] = mt.ri.base
                extra["tdelta"] = mt.ri.tdelta
                extra["flags"] = mt.ri.flags
            elif flag & ida_bytes.enum_flag():
                extra["serial"] = mt.ec.serial
            elif flag & ida_bytes.stru_flag():
                extra["struc_name"] = ida_struct.get_struc_name(mt.tid)
                if flag & ida_bytes.strlit_flag():
                    extra["strtype"] = mt.strtype
        return 0
Exemple #16
0
    def dump():
        ret = []
        for addr, name in idautils.Names():
            flags = ida_bytes.get_flags(addr)
            if ida_bytes.has_dummy_name(flags) or ida_bytes.has_auto_name(
                    flags) or not ida_bytes.is_data(flags):
                print('skip auto:', name)
                continue

            # Sometimes the auto-generated names don't actually usually have the
            # right flags set, so skip these auto-looking names.
            if any(
                    name.startswith(s)
                    for s in ['byte_', 'word_', 'dword_', 'unk_', 'jpt_']):
                continue

            # print('%08x' % addr, '%08x' % flags, name,
            # ida_bytes.is_data(flags))

            sz = ida_bytes.get_item_size(addr)

            if ida_bytes.is_struct(flags):
                ti = ida_nalt.opinfo_t()
                ida_bytes.get_opinfo(ti, addr, 0, flags)
                # itemsize = ida_bytes.get_data_elsize(addr, flags, ti)
                typ = ida_struct.get_struc_name(ti.tid)
            else:
                # itemsize = ida_bytes.get_item_size(addr)
                typ = None

            ret.append({
                'address': addr,
                'name': name,
                'type': typ,
                'sz': sz,
                'flags': flags,
            })

        return ret
Exemple #17
0
 def __call__(self):
     mt = ida_nalt.opinfo_t()
     if ida_bytes.is_struct(self.flag):
         mt.tid = self.extra["id"]
     if ida_bytes.is_off0(self.flag) or ida_bytes.is_off1(self.flag):
         mt.ri = ida_nalt.refinfo_t(
             self.extra["flags"],
             self.extra["base"],
             self.extra["target"],
             self.extra["tdelta"],
         )
     if ida_bytes.is_strlit(self.flag):
         mt.strtype = self.extra["strtype"]
     struc = ida_struct.get_struc_id(self.sname)
     sptr = ida_struct.get_struc(struc)
     ida_struct.add_struc_member(
         sptr,
         self.fieldname,
         self.offset,
         self.flag,
         mt,
         self.nbytes,
     )
Exemple #18
0
 def struc_member_created(self, sptr, mptr):
     print("struc member created")
     extra = {}
     sname = ida_struct.get_struc_name(sptr.id)
     fieldname = ida_struct.get_member_name(mptr.id)
     offset = 0 if mptr.unimem() else mptr.soff
     flag = mptr.flag
     nbytes = mptr.eoff if mptr.unimem() else mptr.eoff - mptr.soff
     mt = ida_nalt.opinfo_t()
     is_not_data = ida_struct.retrieve_member_info(mt, mptr)
     if is_not_data:
         if flag & ida_bytes.off_flag():
             extra["target"] = mt.ri.target
             extra["base"] = mt.ri.base
             extra["tdelta"] = mt.ri.tdelta
             extra["flags"] = mt.ri.flags
         # Is it really possible to create an enum?
         elif flag & ida_bytes.enum_flag():
             extra["serial"] = mt.ec.serial
         elif flag & ida_bytes.stru_flag():
             extra["struc_name"] = ida_struct.get_struc_name(mt.tid)
             if flag & ida_bytes.strlit_flag():
                 extra["strtype"] = mt.strtype
     return 0
Exemple #19
0
def add_to_struct(
    struct,
    member_name,
    member_type=None,
    offset=BADADDR,
    is_offset=False,
    overwrite=False,
):
    mt = None
    flag = idaapi.FF_DWORD
    member_size = WORD_LEN
    if member_type is not None and (member_type.is_struct()
                                    or member_type.is_union()):
        logging.debug("Is struct!")
        substruct = extract_struct_from_tinfo(member_type)
        if substruct is not None:
            flag = idaapi.FF_STRUCT
            mt = ida_nalt.opinfo_t()
            mt.tid = substruct.id
            logging.debug(
                f"Is struct: {ida_struct.get_struc_name(substruct.id)}/{substruct.id}"
            )
            member_size = ida_struct.get_struc_size(substruct.id)
    elif WORD_LEN == 4:
        flag = idaapi.FF_DWORD
    elif WORD_LEN == 8:
        flag = idaapi.FF_QWORD
    if is_offset:
        flag |= idaapi.FF_0OFF
        mt = ida_nalt.opinfo_t()
        r = ida_nalt.refinfo_t()
        r.init(
            ida_nalt.get_reftype_by_size(WORD_LEN) | ida_nalt.REFINFO_NOBASE)
        mt.ri = r

    new_member_name = member_name
    member_ptr = ida_struct.get_member(struct, offset)
    if overwrite and member_ptr:
        if ida_struct.get_member_name(member_ptr.id) != member_name:
            logging.debug("Overwriting!")
            ret_val = ida_struct.set_member_name(struct, offset, member_name)
            i = 0
            while ret_val == ida_struct.STRUC_ERROR_MEMBER_NAME:
                new_member_name = "%s_%d" % (member_name, i)
                i += 1
                if i > 250:
                    logging.debug("failed change name")
                    return
                ret_val = ida_struct.set_member_name(struct, offset,
                                                     new_member_name)

    else:
        ret_val = ida_struct.add_struc_member(struct, new_member_name, offset,
                                              flag, mt, member_size)
        i = 0
        while ret_val == ida_struct.STRUC_ERROR_MEMBER_NAME:
            new_member_name = "%s_%d" % (member_name, i)
            i += 1
            if i > 250:
                return
            ret_val = ida_struct.add_struc_member(struct, new_member_name,
                                                  offset, flag, mt,
                                                  member_size)
        if ret_val != 0:
            logging.debug(f"ret_val: {ret_val}")
        member_ptr = ida_struct.get_member_by_name(struct, new_member_name)
    if member_type is not None and member_ptr is not None:
        ida_struct.set_member_tinfo(struct, member_ptr, 0, member_type,
                                    idaapi.TINFO_DEFINITE)
    return member_ptr