Esempio n. 1
0
def add_enums(function):
    """ Add standard enums from parsed MSDN documentation for all imported
    library calls and their arguments.

    Arguments:
    function -- function object
    """
    enum_count = 0
    for argument in function.arguments:
        # Add standard enums
        if not argument.enums:
            g_logger.debug(' No standard constants available for %s' %
                           argument.name)
        else:
            for enum in argument.enums:
                g_logger.debug('  Importing enum %s for argument %s' %
                               (enum, argument.name))
                if idc.Til2Idb(-1, enum) != idaapi.BADADDR:
                    g_logger.debug('  ' + enum + ' ' + hex(idc.GetEnum(enum)) +
                                   ' added successfully')
                    enum_count = enum_count + 1
                else:
                    g_logger.debug('  Could not add ' + enum)

        if not argument.constants:
            # No constants for this argument
            continue

        argument.name = argument.name.encode('utf-8')
        function.name = function.name.encode('utf-8')

        # Add constant descriptions
        for constant in argument.constants:
            constant.name = constant.name.encode('utf-8')

            if constant.name == 'NULL':
                # Create unique name, so we can add descriptive comment to it
                constant.name = 'NULL_{}_{}'.format(argument.name,
                                                    function.name)
                # Add custom enum for NULL values if it does not exist yet
                enumid = idc.GetEnum(NULL_ENUM_NAME)
                if enumid == idaapi.BADADDR:
                    enumid = idc.AddEnum(-1, NULL_ENUM_NAME, idaapi.hexflag())
                idc.AddConstEx(enumid, constant.name, 0, -1)
                constid = idc.GetConstByName(constant.name)
                idc.SetConstCmt(constid, format_comment(constant.description),
                                False)
            else:
                constid = idc.GetConstByName(constant.name)
                if constid:
                    if idc.SetConstCmt(constid,
                                       format_comment(constant.description),
                                       False):
                        g_logger.debug('    Description added for %s' %
                                       constant.name)
                    else:
                        g_logger.debug('    No description added for %s' %
                                       constant.name)
    return enum_count
Esempio n. 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)
Esempio n. 3
0
 def get_struc_enum_id_for_name(self, name):
     item_id = idc.GetStrucIdByName(name)
     if item_id == idc.BADADDR:
         item_id = idc.GetEnum(name)
         if item_id == idc.BADADDR:
             logger.error("no struc or enum id for name : %s", name)
             return None
     return self.get_struc_enum_object_id(item_id, name)
Esempio n. 4
0
def rename_constant(arg_ea, fct_name, arg_name, arg_enums):
    """ Rename constants to values from standard enumerations. """
    instruction = idc.GetMnem(arg_ea)
    if instruction == 'push':
        op_num = 0
    elif instruction == 'mov':
        op_num = 1
    else:
        raise RenamingException('Constant: unhandled instruction ' +
                                instruction)

    op_val = idc.GetOperandValue(arg_ea, op_num)
    # NULL
    if op_val == 0:
        targetid = idc.GetConstByName('NULL_{}_{}'.format(arg_name, fct_name))
        serial = 0
        enumid = idc.GetEnum(NULL_ENUM_NAME)
        constid = idc.GetConstEx(enumid, 0, serial, -1)
        while constid != idaapi.BADADDR:
            if constid == targetid:
                idc.OpEnumEx(arg_ea, op_num, enumid, serial)
                return
            serial = serial + 1
            constid = idc.GetConstEx(enumid, 0, serial, -1)

    # All other constants
    op_type = idc.GetOpType(arg_ea, op_num)
    if op_type == idaapi.o_imm:
        # only one choice
        if len(arg_enums) == 1:
            enumid = idc.GetEnum(arg_enums[0])
            idc.OpEnumEx(arg_ea, op_num, enumid, 0)
            return

        for enum in arg_enums:
            enumid = idc.GetEnum(enum)
            constid = get_constant_id(enumid, op_val)
            if constid == idaapi.BADADDR:
                # Not in this enum
                continue
            else:
                # Found the right enum
                idc.OpEnumEx(arg_ea, op_num, enumid, 0)
                return
Esempio n. 5
0
 def __init__(self, name, canCreate=False):
     if isinstance(name, (int, long)):
         name = str(name)
     self.name = name
     self.id = idc.GetEnum(name)
     self._vals = None
     self._names = None
     if self.id == idc.BADADDR:
         try:
             self.id = int(name)
             self.name = idc.GetEnumName(self.id)
         except Exception:
             self.name = None
             self.id = None
     if not self.name:
         if not canCreate:
             raise Enum.EnumNotFoundError(name)
         self.id = idc.AddEnum(idc.GetEnumQty(), name, 0)
Esempio n. 6
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))