def struc_renamed(self, struct): sid = struct.id idx = idc.GetStrucIdx(sid) sname = idc.GetStrucName(sid) self.ctrl._handle_action({ 'action': 'struct_renamed', 'struct': idx, 'sname': sname }) return 0
def struc_cmt_changed(self, sid): idx = idc.GetStrucIdx(sid) sname = idc.GetStrucName(sid) cmt = idc.GetEnumCmt(sid, 0) self.ctrl._handle_action({ 'action': 'struct_cmt_changed', 'struct': idx, 'sname': sname, 'cmt': cmt }) return 0
def struc_member_deleted(self, struct, mid, moff): sid = struct.id idx = idc.GetStrucIdx(sid) sname = idc.GetStrucName(sid) self.ctrl._handle_action({ 'action': 'struct_member_deleted', 'struct': idx, 'sname': sname, 'member': mid, 'off': moff }) return 0
def struc_expanded(self, struct): sid = struct.id sname = idc.GetStrucName(sid) size = idc.GetStrucSize(sid) idx = idc.GetStrucIdx(sid) self.ctrl._handle_action({ 'action': 'struct_expanded', 'struct': idx, 'sname': sname, 'size': size }) return 0
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
def struc_member_renamed(self, struct, membr): sid = struct.id mid = membr.id moff = membr.soff idx = idc.GetStrucIdx(sid) sname = idc.GetStrucName(sid) mname = idc.GetMemberName(sid, moff) self.ctrl._handle_action({ 'action': 'struct_member_renamed', 'struct': idx, 'member': mid, 'sname': sname, 'mname': mname, 'off': moff }) return 0
def struc_cmt_changed(self, struc, *args): self.pre_hook() if LOG_IDB_EVENTS: self.debug_event("struc_cmt_changed for id 0x%08X (%s)" % (struc, idaapi.get_struc_name(struc))) sidx = idc.GetStrucIdx(struc) if sidx is None or sidx == idc.BADADDR or not sidx: # this is either a stackframe, or a member of a structure fullname = idaapi.get_struc_name(struc) if "." in fullname: # it is a member id, retreive the struc id st = idaapi.get_member_struc(fullname) struc = st.id else: # it is a stackframe id pass hooks.ida.struc_updated(struc) return idaapi.IDB_Hooks.struc_cmt_changed(self, struc, *args)
def add_auto_comment(self, ea, text): if ea is not None: prefix = "" if idaapi.get_struc(ea) is not None: if idc.GetStrucIdx(ea) == idc.BADADDR: prefix = "stackframe '%s'" % idc.GetFunctionName( idaapi.get_func_by_frame(ea)) else: prefix = "structure '%s'" % idc.GetStrucName(ea) elif idc.GetEnumIdx(ea) != idc.BADADDR: prefix = "enum '%s'" % idc.GetEnumName(ea) else: foffset = idc.GetFuncOffset(ea) if foffset is None: prefix = yatools.ea_to_hex(ea) else: prefix = "%s,%s" % (yatools.ea_to_hex(ea), foffset) self.auto_comments.add((prefix, text)) else: self.auto_comments.add(("", text))
def struc_member_created(self, struct, membr): sid = struct.id mid = membr.id moff = membr.soff flag = membr.flag size = idc.GetMemberSize(sid, moff) sname = idc.GetStrucName(sid) mname = idc.GetMemberName(sid, moff) idx = idc.GetStrucIdx(sid) self.ctrl._handle_action({ 'action': 'struct_member_created', 'struct': idx, 'member': mid, 'sname': sname, 'mname': mname, 'off': moff, 'flag': flag, 'size': size }) return 0
def save_strucs(self, ida_model, memory_exporter): """ Structures : export modified structures and delete those who have been deleted """ for struc_id in self.structures_to_process: sidx = idc.GetStrucIdx(struc_id) if sidx is None or sidx == idc.BADADDR: # it is a deleted structure or a stackframe # in this last case we need to export the parent (function) eaFunc = idaapi.get_func_by_frame(struc_id) if eaFunc != idc.BADADDR: # OK, it is a stackframe ida_model.accept_struct(memory_exporter, eaFunc, struc_id) ida_model.accept_ea(memory_exporter, eaFunc) else: # it is a deleted structure ida_model.delete_struct(memory_exporter, struc_id) else: ida_model.accept_struct(memory_exporter, idc.BADADDR, struc_id) logger.debug("Walking members") """ Structure members : update modified ones, and remove deleted ones We iterate over members : -if the parent struc has been deleted, delete the member -otherwise, detect if the member has been updated or removed -updated : accept struc_member + accept_struct if not already exported! -removed : accept struc_member_deleted """ for (struc_id, member_set) in self.strucmember_to_process.iteritems(): ida_struc = idaapi.get_struc(struc_id) logger.debug("Walking struc 0x%08X" % struc_id) sidx = idc.GetStrucIdx(struc_id) is_stackframe = False struc_deleted = False if sidx is None or sidx == idc.BADADDR: f = idaapi.get_func_by_frame(struc_id) if f is not None and f != idc.BADADDR: is_stackframe = True else: struc_deleted = True stackframe_func_addr = idc.BADADDR if is_stackframe: eaFunc = idaapi.get_func_by_frame(struc_id) stackframe_func_addr = eaFunc ida_model.accept_function(memory_exporter, eaFunc) if struc_deleted: # The structure has been deleted : we need to delete the members # Note: at first sight, it is not a stackframe # TODO: handle function->stackframe deletion here for (member_id, offset) in member_set: ida_model.delete_struct_member(memory_exporter, idc.BADADDR, struc_id, offset) else: # The structure or stackframe has been modified for (member_id, offset) in member_set: ida_member = idaapi.get_member(ida_struc, offset) if ida_member is None: new_member_id = -1 else: new_member_id = ida_member.id if new_member_id == -1: # the member has been deleted : delete it ida_model.delete_struct_member(memory_exporter, stackframe_func_addr, struc_id, offset) elif offset > 0 and idc.GetMemberId( struc_id, offset - 1) == new_member_id: # the member was deleted, and replaced by a member starting above it ida_model.delete_struct_member(memory_exporter, stackframe_func_addr, struc_id, offset) else: # the member has just been modified ida_model.accept_struct_member(memory_exporter, stackframe_func_addr, ida_member.id)
def save_strucs(self, memory_exporter): """ Structures : export modified structures and delete those who have been deleted """ for struc_id in self.structures_to_process: self.ida_model.clear_exported_struc_enum_id(struc_id) sidx = idc.GetStrucIdx(struc_id) if sidx is None or sidx == idc.BADADDR: # it is a deleted structure or a stackframe # in this last case we need to export the parent (function) eaFunc = idaapi.get_func_by_frame(struc_id) if eaFunc != idc.BADADDR: # OK, it is a stackframe self.ida_model.accept_struc( memory_exporter, 0, struc_id, ya.OBJECT_TYPE_STACKFRAME, ya.OBJECT_TYPE_STACKFRAME_MEMBER, stackframe_func_addr=eaFunc) self.ida_model.accept_ea(memory_exporter, 0, eaFunc) else: # it is a deleted structure self.ida_model.accept_deleted_struc(memory_exporter, struc_id) else: self.ida_model.accept_struc(memory_exporter, 0, struc_id) logger.debug("Walking members") """ Structure members : update modified ones, and remove deleted ones We iterate over members : -if the parent struc has been deleted, delete the member -otherwise, detect if the member has been updated or removed -updated : accept struc_member + accept_struc if not already exported! -removed : accept struc_member_deleted """ for (struc_id, member_set) in self.strucmember_to_process.iteritems(): ida_struc = idaapi.get_struc(struc_id) logger.debug("Walking struc 0x%08X" % struc_id) sidx = idc.GetStrucIdx(struc_id) is_stackframe = False struc_deleted = False if sidx is None or sidx == idc.BADADDR: f = idaapi.get_func_by_frame(struc_id) if f is not None and f != idc.BADADDR: is_stackframe = True else: struc_deleted = True if is_stackframe: strucmember_type = ya.OBJECT_TYPE_STACKFRAME_MEMBER struc_name = None struc_type = ya.OBJECT_TYPE_STACKFRAME eaFunc = idaapi.get_func_by_frame(struc_id) stackframe_func_addr = eaFunc func = idaapi.get_func(eaFunc) self.ida_model.accept_function(memory_exporter, 0, eaFunc, func) else: strucmember_type = ya.OBJECT_TYPE_STRUCT_MEMBER struc_type = ya.OBJECT_TYPE_STRUCT stackframe_func_addr = None if not struc_deleted: struc_name = idc.GetStrucName(struc_id) if struc_deleted: # The structure has been deleted : we need to delete the members # Note: at first sight, it is not a stackframe # TODO: handle function->stackframe deletion here for (member_id, offset) in member_set: self.ida_model.accept_deleted_strucmember(memory_exporter, struc_id, None, offset) else: # The structure or stackframe has been modified is_union = ida_struc.is_union() for (member_id, offset) in member_set: ida_member = idaapi.get_member(ida_struc, offset) if ida_member is None: new_member_id = -1 else: new_member_id = ida_member.id logger.debug("exporting member %s at offset 0x%02X (mid=0x%016X)" % (strucmember_type, offset, member_id)) self.ida_model.clear_exported_struc_member_id(new_member_id) if new_member_id == -1: # the member has been deleted : delete it self.ida_model.accept_deleted_strucmember( memory_exporter, struc_id, struc_name, offset, struc_type, strucmember_type) elif offset > 0 and idc.GetMemberId(struc_id, offset - 1) == new_member_id: # the member was deleted, and replaced by a member starting above it self.ida_model.accept_deleted_strucmember( memory_exporter, struc_id, struc_name, offset, struc_type, strucmember_type) elif new_member_id != member_id: # the member has been deleted and later recreated name = idaapi.get_member_name(new_member_id) self.ida_model.accept_struc_member( memory_exporter, 0, ida_struc, struc_id, is_union, offset, struc_name, name, struc_type, strucmember_type, stackframe_func_addr=stackframe_func_addr) else: # the member has just been modified name = idaapi.get_member_name(new_member_id) logger.debug("exporting member %s (%s) at offset 0x%02X (mid=0x%016X)" % (strucmember_type, name, offset, member_id)) self.ida_model.accept_struc_member( memory_exporter, 0, ida_struc, struc_id, is_union, offset, struc_name, name, struc_type, strucmember_type, stackframe_func_addr=stackframe_func_addr)