def activate(self, ctx): hx_view = idaapi.get_widget_vdui(ctx.widget) if not self.check(hx_view): return data = [] offset = hx_view.item.e.m struct_type = idaapi.remove_pointer(hx_view.item.e.x.type) ordinal = helper.get_ordinal(struct_type) result = struct_xrefs.XrefStorage().get_structure_info(ordinal, offset) for xref_info in result: data.append([ idaapi.get_short_name(xref_info.func_ea) + "+" + hex(int(xref_info.offset)), xref_info.type, xref_info.line ]) field_name = helper.get_member_name(struct_type, offset) chooser = forms.MyChoose( data, "Cross-references to {0}::{1}".format(struct_type.dstr(), field_name), [["Function", 20 | idaapi.CHCOL_PLAIN], ["Type", 2 | idaapi.CHCOL_PLAIN], ["Line", 40 | idaapi.CHCOL_PLAIN]] ) idx = chooser.Show(True) if idx == -1: return xref = result[idx] idaapi.open_pseudocode(xref.func_ea + xref.offset, False)
def visit_expr(self, expression): # Checks if expression is reference by pointer or by value if expression.op == idaapi.cot_memptr: struct_type = expression.x.type.get_pointed_object() elif expression.op == idaapi.cot_memref: struct_type = expression.x.type else: return 0 # Getting information about structure, field offset, address and one line corresponding to code ordinal = helper.get_ordinal(struct_type) field_offset = expression.m ea = self.__find_ref_address(expression) usage_type = self.__get_type(expression) if ea == idaapi.BADADDR or not ordinal: logger.warning( "Failed to parse at address {0}, ordinal - {1}, type - {2}". format(helper.to_hex(ea), ordinal, struct_type.dstr())) one_line = self.__get_line() occurrence_offset = ea - self.__function_address xref_info = (occurrence_offset, one_line, usage_type) # Saving results if ordinal not in self.__result: self.__result[ordinal] = {field_offset: [xref_info]} elif field_offset not in self.__result[ordinal]: self.__result[ordinal][field_offset] = [xref_info] else: self.__result[ordinal][field_offset].append(xref_info) return 0