Esempio n. 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.is_union(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.add_struc_member(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
Esempio n. 2
0
def struct_open(name, create=False, union=None):
    """Get the SID of the IDA struct with the given name, optionally creating it."""
    sid = ida_struct.get_struc_id(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.is_union(sid))
        if union != is_union:
            return None
    return sid
Esempio n. 3
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 = ida_struct.get_struc_id(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 ida_struct.get_struc_name(sid) is None:
            raise ValueError('Invalid struc id {}'.format(sid))
    # Iterate through the members and add them to the struct.
    union = idc.is_union(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, ida_struct.get_struc_size(sid))
    return struct
Esempio n. 4
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.is_union(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