Beispiel #1
0
def _populate_vtable_struct(sid, classinfo):
    """Populate the ::vtable struct."""
    # For each ancestor from root down to us (inclusive), add our ::vmethods struct.
    for ci in classinfo.ancestors(inclusive=True):
        # Get the offset at which the ::vmethods for ci will be.
        offset = 0
        if ci.superclass:
            offset = ci.superclass.vtable_nmethods * idau.WORD_SIZE
        # The size is ci's vtable length minus the offset.
        vmethods_size = ci.vtable_nmethods * idau.WORD_SIZE - offset
        # If the vmethods_size is 0, skip this entry. Otherwise we get weird
        # "struct->til conversion failed" errors.
        if vmethods_size == 0:
            continue
        # Get the sid for ci's ::vmethods.
        vmethods_sid = idau.struct_open(ci.classname + '::vmethods')
        if vmethods_sid is None:
            _log(0, 'Could not find {}::vmethods', ci.classname)
            return False
        # Add this ::vmethods slice to the ::vtable struct.
        ret = idau.struct_add_struct(sid, ci.classname, offset, vmethods_sid)
        if ret != 0:
            _log(0, 'Could not add {}::vmethods to {}::vtable', ci.classname,
                 classinfo.classname)
            return False
    return True
Beispiel #2
0
def _populate_wrapper_struct__slices(sid, classinfo):
    """Fill in the members of the wrapper struct."""
    # First add the vtable pointer.
    offset = 0
    vtable_ptr_type = '{}::vtable *'.format(classinfo.classname)
    ret = idau.struct_add_ptr(sid, 'vtable', offset, type=vtable_ptr_type)
    if ret not in (0, idc.STRUC_ERROR_MEMBER_OFFSET):
        _log(0, 'Could not create {}.vtable: {}', classinfo.classname, ret)
        return False
    # Now add all the ::fields structs.
    offset += idau.WORD_SIZE
    for ci in classinfo.ancestors(inclusive=True):
        # Get the sid of the ::fields struct.
        fields_sid = idau.struct_open(ci.classname + '::fields')
        if fields_sid is None:
            _log(0, 'Could not find {}::fields', ci.classname)
            return False
        # If this is a 0-length struct (no fields), skip it.
        size = idc.GetStrucSize(fields_sid)
        if size == 0:
            continue
        # If this is already in the wrapper struct, skip it. This avoids weird
        # STRUC_ERROR_MEMBER_VARLAST errors.
        if idc.GetMemberOffset(sid, ci.classname) != -1:
            continue
        # Add the ::fields struct to the wrapper.
        ret = idau.struct_add_struct(sid, ci.classname, offset, fields_sid)
        if ret != 0:
            _log(0, 'Could not create {}.{}: {}', classinfo.classname,
                 ci.classname, ret)
            return False
        offset += size
    return True
Beispiel #3
0
def _populate_wrapper_struct__unions(sid, classinfo):
    """Fill in the members of the wrapper struct."""
    # First add the vtable pointer.
    vtable_ptr_type = '{}::vtable *'.format(classinfo.classname)
    ret = idau.struct_add_ptr(sid, 'vtable', -1, type=vtable_ptr_type)
    if ret not in (0, idc.STRUC_ERROR_MEMBER_NAME):
        _log(0, 'Could not create {}.vtable: {}', classinfo.classname, ret)
        return False
    # Now add all the ::fields structs.
    for ci in classinfo.ancestors(inclusive=True):
        # Get the sid of the ::fields struct.
        fields_sid = idau.struct_open(ci.classname + '::fields')
        if fields_sid is None:
            _log(0, 'Could not find {}::fields', ci.classname)
            return False
        # Add the ::fields struct to the wrapper. Ignore STRUC_ERROR_MEMBER_UNIVAR if the ::fields
        # struct has length 0.
        ret = idau.struct_add_struct(sid, ci.classname, -1, fields_sid)
        if ret not in (0, idc.STRUC_ERROR_MEMBER_NAME, idc.STRUC_ERROR_MEMBER_UNIVAR):
            _log(0, 'Could not create {}.{}: {}', classinfo.classname, ci.classname, ret)
            return False
    return True