Пример #1
0
def expand_struct(struct_id, new_size):
    struct = ida_struct.get_struc(struct_id)
    if struct is None:
        logging.warning("Struct id 0x%x wasn't found", struct_id)
        return
    logging.debug(
        "Expanding struc %s 0x%x -> 0x%x",
        ida_struct.get_struc_name(struct_id),
        ida_struct.get_struc_size(struct_id),
        new_size,
    )
    if ida_struct.get_struc_size(struct_id) > new_size - WORD_LEN:
        return
    fix_list = []
    xrefs = idautils.XrefsTo(struct.id)
    for xref in xrefs:
        if xref.type == ida_xref.dr_R and xref.user == 0 and xref.iscode == 0:
            member, full_name, x_struct = ida_struct.get_member_by_id(xref.frm)
            if x_struct is not None:
                old_name = ida_struct.get_member_name(member.id)
                offset = member.soff
                marker_name = "marker_%d" % random.randint(0, 0xFFFFFF)
                idc.add_struc_member(
                    x_struct.id,
                    marker_name,
                    member.soff + new_size,
                    idaapi.FF_DATA | idaapi.FF_BYTE,
                    -1,
                    0,
                )
                logging.debug(
                    "Delete member (0x%x-0x%x)", member.soff, member.soff + new_size - 1
                )
                ida_struct.del_struc_members(
                    x_struct, member.soff, member.soff + new_size - 1
                )
                fix_list.append(
                    [
                        x_struct.id,
                        old_name,
                        offset,
                        idaapi.FF_STRUCT | idaapi.FF_DATA,
                        struct_id,
                        new_size,
                    ]
                )
            else:
                logging.warning("Xref wasn't struct_member 0x%x", xref.frm)

    ret = push_ptr_member_to_struct(
        ida_struct.get_struc(struct_id), None, None, new_size - WORD_LEN
    )
    logging.debug("Now fix args:")
    for fix_args in fix_list:
        ret = idc.add_struc_member(*fix_args)
        logging.debug("%s = %d", fix_args, ret)
        x_struct_id = fix_args[0]
        idc.del_struc_member(x_struct_id, ida_struct.get_struc_size(x_struct_id))
Пример #2
0
 def add_member(self, offset, name, size):
     if get_member_name(self._sid, 0) == "Dummy":
         del_struc_member(self._sid, 0)
     flag = {1: FF_BYTE, 2: FF_WORD, 4: FF_DWORD, 8: FF_QWORD}.get(size)
     if flag is None:
         raise ValueError("size")
     err_code = add_struc_member(self._sid, name, offset, flag | FF_DATA,
                                 -1, size)
     if err_code != 0:
         raise Exception("err_code = %d" % err_code)
Пример #3
0
            def write_vtbl_struct(self, vtbl_name, struct_member_names):
                struct_name = "{0}_struct".format(vtbl_name)
                sid = idc.get_struc_id(struct_name)
                if sid == idc.BADADDR:
                    # Doesn't exist
                    sid = idc.add_struc(-1, struct_name, is_union=0)
                else:
                    # Clear existing
                    member_offset = idc.get_first_member(sid)
                    while member_offset != idc.BADADDR:
                        idc.del_struc_member(sid, member_offset)
                        member_offset = idc.get_first_member(sid)

                for member_name in struct_member_names:
                    idc.add_struc_member(sid,
                                         member_name,
                                         offset=-1,
                                         flag=idc.FF_DATA | idc.FF_QWORD,
                                         typeid=-1,
                                         nbytes=8,
                                         reftype=idc.REF_OFF64)
                    member_offset = idc.get_last_member(sid)
                    member_id = idc.get_member_id(sid, member_offset)
                    idc.SetType(member_id, "void*")
Пример #4
0
def expand_struct(struct_id, new_size):
    struct = ida_struct.get_struc(struct_id)
    if struct is None:
        log.warning("Struct id 0x%X wasn't found", struct_id)
        return
    log.debug(
        "Expanding struc %s, size: 0x%X -> 0x%X",
        ida_struct.get_struc_name(struct_id),
        ida_struct.get_struc_size(struct_id),
        new_size,
    )
    if ida_struct.get_struc_size(struct_id) > new_size - WORD_LEN:
        return
    fix_list = []
    xrefs = idautils.XrefsTo(struct.id)
    for xref in xrefs:
        if xref.type == ida_xref.dr_R and xref.user == 0 and xref.iscode == 0:
            res = ida_struct.get_member_by_id(xref.frm)
            if not res or not res[0]:
                log.warning("Xref from %08X wasn't struct_member", xref.frm)
                continue
            member = res[0]
            x_struct = ida_struct.get_member_struc(ida_struct.get_member_fullname(member.id))
            assert x_struct
            old_name = ida_struct.get_member_name(member.id)
            offset = member.soff
            # FIXME: why use random here?
            marker_name = "marker_%d" % random.randint(0, 0xFFFFFF)
            # FIXME: check if add_struc_member actually added a member
            idc.add_struc_member(
                x_struct.id,
                marker_name,
                member.soff + new_size,
                idaapi.FF_DATA | idaapi.FF_BYTE,
                -1,
                0,
            )
            log.debug(
                "Delete member (0x%X-0x%X)",
                member.soff,
                member.soff + new_size - 1,
            )
            # FIXME: check if struc member actually deleted
            ida_struct.del_struc_members(x_struct, member.soff, member.soff + new_size - 1)
            fix_list.append(
                [
                    x_struct.id,
                    old_name,
                    offset,
                    idaapi.FF_STRUCT | idaapi.FF_DATA,
                    struct_id,
                    new_size,
                ]
            )

    ret = add_to_struct(ida_struct.get_struc(struct_id), None, None, new_size - WORD_LEN)
    log.debug("Now fix args:")
    for fix_args in fix_list:
        ret = idc.add_struc_member(*fix_args)
        log.debug("%s = %d", fix_args, ret)
        x_struct_id = fix_args[0]
        idc.del_struc_member(x_struct_id, ida_struct.get_struc_size(x_struct_id))
Пример #5
0
def resolve_type(like, die_offset, log_fp, alias=None):
    if die_offset is None:
        return 'void'
    type = like.get(str(die_offset))
    if type is None:
        return DEFAULT_TYPE
    kind = type[0]
    if kind in ('struct', 'union'):
        if type[1] is None:
            if alias is None:
                struct_name = '{}_{}'.format(kind, hex(die_offset))
            else:
                struct_name = alias
        else:
            struct_name = type[1]
        if (not _is_uname(str(struct_name)) or
                (get_struc_id(str(struct_name)) == BADADDR and
                 get_name_ea(BADADDR, str(struct_name)) != BADADDR)):
            struct_name = '_' + struct_name
        struct_id = get_struc_id(str(struct_name))
        if struct_id != BADADDR:
            if len(type) == 4:
                type.append(struct_id)
            return struct_name
        log_fp.write('{}: ...\n'.format(struct_name))
        log_fp.flush()
        struct_id = add_struc(BADADDR, str(struct_name), kind == 'union')
        log_fp.write('... id={}\n'.format(hex(struct_id)))
        log_fp.flush()
        if struct_id == BADADDR:
            return DEFAULT_TYPE
        type.append(struct_id)
        if kind == 'struct' and type[2] != 0:
            ret = add_end_member(struct_id, struct_name, type[2], log_fp)
            have_end_member = ret == 0
        else:
            have_end_member = False
        for member_type_die_offset, member_name, member_offset in type[3]:
            if member_name is None:
                if kind == 'struct':
                    field_n = member_offset
                else:
                    field_n = sum(1 for _ in StructMembers(struct_id))
                member_name = 'field_{:X}'.format(field_n)
            elif not _is_uname(str(member_name)):
                member_name = '_' + member_name
            member_type_str = str(resolve_type(
                like, member_type_die_offset, log_fp))
            member_size = get_type_size(like, member_type_die_offset)
            if have_end_member and member_offset + member_size == type[2]:
                del_struc_member(struct_id, type[2] - 1)
                have_end_member = False
            log_fp.write('{} {}.{}: ...\n'.format(
                member_type_str, struct_name, member_name))
            log_fp.flush()
            ret = add_struc_member(
                struct_id,
                str(member_name),
                member_offset,
                DEFAULT_TYPE_FLAGS,
                DEFAULT_TYPE_ID,
                DEFAULT_TYPE_SIZE,
            )
            log_fp.write('... ret={}\n'.format(ret))
            log_fp.flush()
            if ret == 0:
                member_id = get_name_ea(
                    BADADDR, '{}.{}'.format(struct_name, member_name))
                apply_type(member_id, parse_decl(member_type_str, 0))
        return struct_name
    if kind == 'typedef':
        return resolve_type(like, type[2], log_fp, type[1])
    if kind == 'pointer':
        return resolve_type(like, type[1], log_fp) + '*'
    if kind == 'base':
        if type[1]:
            return '__int' + str(type[2] * 8)
        else:
            return 'unsigned __int' + str(type[2] * 8)
    if kind in ('const', 'volatile'):
        return resolve_type(like, type[1], log_fp)
    if kind == 'array':
        return '{}[{}]'.format(resolve_type(like, type[1], log_fp), type[2])
    return DEFAULT_TYPE