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))
def update_idb(self, delete_existing_members=True): sid = ida_struct.get_struc_id(self._name) sptr = ida_struct.get_struc(sid) if sid == idc.BADADDR: sid = ida_struct.add_struc(idc.BADADDR, self._name, 0) sptr = ida_struct.get_struc(sid) else: if delete_existing_members: ida_struct.del_struc_members(sptr, 0, 0xffffffff) for f in self._fields: ida_struct.add_struc_member(sptr, f.name, f.offset, (idc.FF_BYTE | idc.FF_DATA) & 0xFFFFFFFF, None, 1) member_name = "{}.{}".format(self._name, f.name) idc.SetType( idaapi.get_member_by_fullname(member_name)[0].id, f.type) ida_auto.auto_wait()
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))