示例#1
0
def _create_class_structs__slices(classinfo, endmarkers=True):
    """Create the IDA structs for a C++ class."""
    classname = classinfo.classname
    # Open or create the structs.
    sidf = idau.struct_open(classname + '::fields', create=True)
    sid = idau.struct_open(classname, create=True)
    if sid is None or sidf is None:
        _log(0, 'Could not create class structs for {}', classname)
        return None
    assert all(not idc.IsUnion(s) for s in (sidf, sid))
    # Calculate the size of the ::fields struct.
    if classinfo.superclass:
        # If we have a superclass, our fields start after our superclass's fields end.
        fields_start = classinfo.superclass.class_size
    else:
        # If we don't have a superclass, our fields start after our vtable.
        fields_start = idau.WORD_SIZE
    fields_size = classinfo.class_size - fields_start
    # Add an ::end member to the fields struct if requested.
    if endmarkers:
        ret = idc.AddStrucMember(sidf, classname + '::end', fields_size,
                                 idc.FF_UNK, -1, 0)
        if ret not in (0, idc.STRUC_ERROR_MEMBER_NAME,
                       idc.STRUC_ERROR_MEMBER_OFFSET):
            # If that didn't work that's too bad, but continue anyway.
            _log(0, 'Could not create {}::end', classname)
    return sid, sidf, fields_start
示例#2
0
def get_object_id_of_union_member_id(hash_provider, member_id):
    try:
        return union_member_object_ids[member_id]
    except KeyError:

        idx = idc.GetFirstStrucIdx()
        while idx != idc.BADADDR:
            struc_id = idc.GetStrucId(idx)
            if idc.IsUnion(struc_id):

                offset = idc.GetFirstMember(struc_id)

                while offset != idc.BADADDR:
                    smember_id = idc.GetMemberId(struc_id, offset)
                    if smember_id == member_id:
                        name = idc.GetMemberName(struc_id, offset)
                        if name is not None:
                            struc_name = idc.GetStrucName(struc_id)
                            logger.debug("found member id 0x%016X in union %s/%s" % (member_id, struc_name, name))
                            return hash_provider.get_struc_member_id_for_name(struc_name, offset)

                    # next member
                    offset = idc.GetStrucNextOff(struc_id, offset)
            idx = idc.GetNextStrucIdx(idx)

        logger.error("Could not find member id 0x%016X in unions" % member_id)

        return None
示例#3
0
def struct_open(name, create=False, union=None):
    """Get the SID of the IDA struct with the given name, optionally creating it."""
    sid = idc.GetStrucIdByName(name)
    if sid == idc.BADADDR:
        if not create:
            return None
        sid = struct_create(name, union=bool(union))
    elif union is not None:
        is_union = bool(idc.IsUnion(sid))
        if union != is_union:
            return None
    return sid
示例#4
0
文件: hooks.py 项目: Spl3en/ipad
 def struc_created(self, struct):
     ### we have to maintain our own struct db
     ## becuse ida sux...
     sname = idc.GetStrucName(struct)
     union = idc.IsUnion(struct)
     idx = idc.GetStrucIdx(struct)
     self.ctrl._handle_action({
         'action': 'struct_created',
         'struct': idx,
         'sname': sname,
         'union': union
     })
     self.ctrl.db.struct_add(struct, idx)
     return 0
示例#5
0
def read_struct(ea, struct=None, sid=None, members=None, asobject=False):
    """Read a structure from the given address.

    This function reads the structure at the given address and converts it into a dictionary or
    accessor object.

    Arguments:
        ea: The linear address of the start of the structure.

    Options:
        sid: The structure ID of the structure type to read.
        struct: The name of the structure type to read.
        members: A list of the names of the member fields to read. If members is None, then all
            members are read. Default is None.
        asobject: If True, then the struct is returned as a Python object rather than a dict.

    One of sid and struct must be specified.
    """
    # Handle sid/struct.
    if struct is not None:
        sid2 = idc.GetStrucIdByName(struct)
        if sid2 == idc.BADADDR:
            raise ValueError('Invalid struc name {}'.format(struct))
        if sid is not None and sid2 != sid:
            raise ValueError('Invalid arguments: sid={}, struct={}'.format(
                sid, struct))
        sid = sid2
    else:
        if sid is None:
            raise ValueError('Invalid arguments: sid={}, struct={}'.format(
                sid, struct))
        if idc.GetStrucName(sid) is None:
            raise ValueError('Invalid struc id {}'.format(sid))
    # Iterate through the members and add them to the struct.
    union = idc.IsUnion(sid)
    struct = {}
    for offset, name, size in idautils.StructMembers(sid):
        if members is not None and name not in members:
            continue
        _read_struct_member(struct, sid, union, ea, offset, name, size,
                            asobject)
    if asobject:
        struct = objectview(struct, ea, idc.GetStrucSize(sid))
    return struct
示例#6
0
    def make_struc(self, object_version, address):
        name = object_version.get_name()
        object_id = object_version.get_id()
        size = object_version.get_size()

        struc_id = idc.GetStrucIdByName(name)
        if struc_id == idc.BADADDR:
            try:
                is_union = object_version.get_object_flags()
            except KeyError:
                is_union = 0

            struc_id = idc.AddStrucEx(0, name, is_union)
            # add a dummy field.
            # This is necessary to avoid an error is idc.SetType(struc*) is used on another struc
            # member
            # TODO not for empty strucs
            if is_union:
                idc.AddStrucMember(struc_id, "yaco_filler", 0, idc.FF_BYTE, 0,
                                   1)

        else:

            is_union = idc.IsUnion(struc_id)
        #             if(is_union):
        #                 pass
        #             else:
        #                 self.clear_struc_fields(struc_id, object_version['xrefs'], is_union)

        if not is_union or is_union == 0:
            self.clear_struc_fields(
                struc_id, size,
                object_version.get_xrefed_id_map().iterkeys(), False)
        else:
            self.union_ids.add(struc_id)

        if DEBUG_EXPORTER:
            logger.debug(
                "adding struc id %s : '0x%.016X' (%s)" %
                (self.hash_provider.hash_to_string(object_id), struc_id, name))
        self.struc_ids[object_id] = struc_id
        _yatools_ida_exporter.set_struct_id(object_id, struc_id)

        self.hash_provider.put_hash_struc_or_enum(struc_id, object_id)
示例#7
0
def get_struc_id_from_member_if(member_id):
    try:
        return member_struc_ids[member_id]
    except KeyError:

        idx = idc.GetFirstStrucIdx()
        while idx != idc.BADADDR:
            struc_id = idc.GetStrucId(idx)
            if idc.IsUnion(struc_id):
                offset = idc.GetFirstMember(struc_id)

                while offset != idc.BADADDR:
                    smember_id = idc.GetMemberId(struc_id, offset)
                    if smember_id == member_id:
                        member_struc_ids[member_id] = struc_id
                        return struc_id
                    offset = idc.GetStrucNextOff(struc_id, offset)
            idx = idc.GetNextStrucIdx(idx)
        logger.error("Could not find struc id from member id 0x%08X (name=%s)" %
                     (member_id, idaapi.get_struc_name(member_id)))
        return None
示例#8
0
def _set_class_style(style):
    """Set the global class style."""
    global _style_was_set, _create_class_structs, _populate_class_structs
    assert style in (CLASS_SLICES, CLASS_UNIONS)
    # Check the current style based on OSObject, a class that should always exist.
    sid = idau.struct_open('OSObject')
    want_union = style == CLASS_UNIONS
    if sid is None:
        # No global style has been set.
        idau.struct_create('OSObject', union=want_union)
    else:
        # A style already exists. Check that the requested style matches.
        is_union = bool(idc.IsUnion(sid))
        if is_union != want_union:
            raise ValueError('Incompatible style {}', style)
    # Set the appropriate functions based on the style.
    if style == CLASS_SLICES:
        _create_class_structs = _create_class_structs__slices
        _populate_class_structs = _populate_class_structs__slices
    else:
        _create_class_structs = _create_class_structs__unions
        _populate_class_structs = _populate_class_structs__unions
示例#9
0
 def is_union(self):
     return idc.IsUnion(self.sid)