Beispiel #1
0
 def setBitfield(self, isBF=True):
     if isBF and idc.IsBitfield(self.id):
         return
     if not isBF and not idc.IsBitfield(self.id):
         return
     if isBF:
         self.clear()
     idc.SetEnumBf(self.id, 1 if isBF else 0)
Beispiel #2
0
 def yacheck_enums(self):
     values = yaunit.load('enums')
     for flag in flags:
         for prefix, enum_width, is_bitfield, num_fields in tests:
             name, ea, values = str(values[0][0]), values[0][1], values[1:]
             eid = idc.GetEnum(name)
             self.assertNotEqual(eid, idaapi.BADADDR)
             self.assertEqual(idc.GetEnumFlag(eid), flag)
             self.assertEqual(idc.GetEnumName(eid), name)
             self.assertEqual(idc.IsBitfield(eid), is_bitfield)
             self.assertEqual(idc.GetEnumCmt(eid, False), prefix + 'cmt')
             self.assertEqual(idc.GetEnumCmt(eid, True),  prefix + 'rpt')
             if enum_width != 0:
                 self.assertEqual(idc.GetEnumWidth(eid), enum_width)
             n = 0
             for value, bmask in walk_enum(eid):
                 self.assertLessEqual(n, num_fields)
                 v = 1 << n if is_bitfield else n
                 self.assertEqual(value, value, v)
                 cid = idc.GetConstEx(eid, v, 0, bmask)
                 self.assertNotEqual(cid, idaapi.BADADDR)
                 field = '%s_%d' % (name, n)
                 self.assertEqual(idc.GetConstName(cid), field)
                 # FIXME comments are not working
                 #self.assertEqual(idc.GetConstCmt(cid, False), field + 'cmt')
                 #self.assertEqual(idc.GetConstCmt(cid, True),  field + 'rpt')
                 n += 1
             self.assertEqual(n, num_fields)
             if ea != None:
                 self.assertEqual(idaapi.get_enum_id(ea, 1)[0], eid)
Beispiel #3
0
def get_constant_id(enumid, value):
    """ Return id of constant for specific value in enum. """
    constid = idc.GetConstEx(enumid, value, 0, -1)
    if constid != idaapi.BADADDR and not idc.IsBitfield(enumid):
        return constid

    for bm in get_bitmasks(enumid):
        constid = idc.GetConstEx(enumid, value, 0, bm)
        if constid != idaapi.BADADDR:
            return constid
    return idaapi.BADADDR
Beispiel #4
0
    def make_enum_member(self, object_version, value):
        name = object_version.get_name()
        object_id = object_version.get_id()

        enum_object_id = object_version.get_parent_object_id()

        enum_id = 0
        try:
            enum_id = self.enum_ids[enum_object_id]
        except:
            return

        self.hash_provider.put_hash_enum_member(idc.GetEnumName(enum_id), name,
                                                value, object_id)

        # create member
        if not idc.IsBitfield(enum_id):
            bmask = -1
        else:
            bmask = object_version.get_object_flags()

        member_id = idc.GetConstEx(enum_id, value, 0, bmask)
        if member_id == idc.BADADDR:
            idc.AddConstEx(enum_id, name, value, bmask)
            member_id = idc.GetConstEx(enum_id, value, 0, bmask)
        else:
            if idc.SetConstName(member_id, name) == 0:
                logger.error("Failed to set const name for enum_id")

        # apply comments
        try:
            repeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(True))
            idc.SetConstCmt(member_id, repeatable_headercomment, 1)
        except KeyError:
            pass

        try:
            nonrepeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(True))
            idc.SetConstCmt(member_id, nonrepeatable_headercomment, 0)
        except KeyError:
            pass

        self.enum_member_ids[(idc.GetEnumName(enum_id), name,
                              value)] = (member_id, object_id)
Beispiel #5
0
    def make_enum(self, object_version, address):
        enum_name = object_version.get_name()
        object_id = object_version.get_id()

        # build flags
        bitfield = False
        flags = object_version.get_object_flags()
        if flags & 0x1 == 0x1:
            bitfield = True
        flags = flags & ~0x1

        try:
            enum_width = object_version.get_size()
        except KeyError:
            enum_width = None

        # check if enum already exists
        enum_id = idc.GetEnum(enum_name)
        enum_xrefs_ids = object_version.get_xrefed_ids()
        logger.debug(
            "%s:%d : Check here that enum_xrefs_ids is a set(YaToolObjectId) and correctly used"
            % (__file__, inspect.currentframe().f_lineno))
        if enum_id != idc.BADADDR:
            # enum already exists, deleting all members
            for (const_id, const_value,
                 bmask) in YaToolIDATools.enum_member_iterate_all(enum_id):
                if bmask == idc.BADADDR:
                    bmask = -1
                const_name = idc.GetConstName(const_id)

                if (enum_name, const_name,
                        const_value) not in self.enum_member_ids:
                    idc.DelConstEx(enum_id, const_value, 0, bmask)
                elif self.hash_provider.get_enum_member_id(
                        enum_id, enum_name, const_id, const_name,
                        const_value) not in enum_xrefs_ids:
                    logger.debug("deleting not found constant : %s/%s" %
                                 (enum_name, const_name))
                    idc.DelConstEx(enum_id, const_value, 0, bmask)
            """
            if the enum "bitfield" state has changed : change it!
            We can't access the functions
            """
            if idc.IsBitfield(enum_id) != bitfield:
                idaapi.set_enum_bf(enum_id, bitfield)
        else:
            # create enum
            # SetEnumFlag return "'module' object has no attribute 'set_enum_flag'".
            enum_id = idc.AddEnum(address, enum_name, flags)

        if enum_width is not None:
            idc.SetEnumWidth(enum_id, enum_width)

        if bitfield:
            idc.SetEnumBf(enum_id, 1)

        # process comment
        try:
            repeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(True))
            idc.SetEnumCmt(enum_id, repeatable_headercomment, 1)
        except KeyError:
            pass
        try:
            nonrepeatable_headercomment = self.sanitize_comment_to_ascii(
                object_version.get_header_comment(False))
            idc.SetEnumCmt(enum_id, nonrepeatable_headercomment, 0)
        except KeyError:
            pass

        self.enum_ids[object_id] = enum_id

        self.hash_provider.put_hash_struc_or_enum(enum_id, object_id)

        logger.debug("adding enum id %s : '0x%.016X'" %
                     (self.hash_provider.hash_to_string(object_id), enum_id))
Beispiel #6
0
 def enum_bf_changed(self, tid):
     bf_flag = 1 if idc.IsBitfield(tid) else 0
     self._send_event(EnumBfChangedEvent(tid, bf_flag))
     return 0
Beispiel #7
0
 def enum_bf_changed(self, id):
     bf_flag = 1 if idc.IsBitfield(id) else 0
     self._send_event(EnumBfChangedEvent(idaapi.get_enum_name(id), bf_flag))
     return 0