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)
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)
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
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)
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))
def enum_bf_changed(self, tid): bf_flag = 1 if idc.IsBitfield(tid) else 0 self._send_event(EnumBfChangedEvent(tid, bf_flag)) return 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