diff --git a/HexRaysPyTools/callbacks/actions.py b/HexRaysPyTools/callbacks/actions.py index f19edd1..123de75 100644 --- a/HexRaysPyTools/callbacks/actions.py +++ b/HexRaysPyTools/callbacks/actions.py @@ -74,6 +74,31 @@ def update(self, ctx): return idaapi.AST_ENABLE_FOR_WIDGET return idaapi.AST_DISABLE_FOR_WIDGET +class HexRaysXrefAction(Action): + """ + Wrapper around Action. Represents Action which can be added to menu after right-clicking in Decompile window. + Has `check` method that should tell whether Action should be added to popup menu when different items + are right-clicked. + Children of this class can also be fired by hot-key without right-clicking if one provided in `hotkey` + static member. + """ + + def __init__(self): + super(HexRaysXrefAction, self).__init__() + + def activate(self, ctx): + # type: (idaapi.action_activation_ctx_t) -> None + raise NotImplementedError + + def check(self, hx_view): + # type: (idaapi.vdui_t) -> bool + raise NotImplementedError + + def update(self, ctx): + if ctx.widget_type == idaapi.BWN_PSEUDOCODE or ctx.widget_type == idaapi.BWN_STRUCTS : + return idaapi.AST_ENABLE_FOR_WIDGET + return idaapi.AST_DISABLE_FOR_WIDGET + class HexRaysPopupRequestHandler(HexRaysEventHandler): """ diff --git a/HexRaysPyTools/callbacks/struct_xref_representation.py b/HexRaysPyTools/callbacks/struct_xref_representation.py index e6dc357..39fff0e 100644 --- a/HexRaysPyTools/callbacks/struct_xref_representation.py +++ b/HexRaysPyTools/callbacks/struct_xref_representation.py @@ -1,4 +1,6 @@ +# encoding:utf-8 import idaapi +import ida_struct from . import actions import HexRaysPyTools.core.helper as helper @@ -6,26 +8,58 @@ import HexRaysPyTools.forms as forms -class FindFieldXrefs(actions.HexRaysPopupAction): +class FindFieldXrefs(actions.HexRaysXrefAction): description = "Field Xrefs" hotkey = "Ctrl+X" def __init__(self): super(FindFieldXrefs, self).__init__() - def check(self, hx_view): - return hx_view.item.citype == idaapi.VDI_EXPR and \ - hx_view.item.it.to_specific_type.op in (idaapi.cot_memptr, idaapi.cot_memref) + #def check(self, hx_view):#old + # return hx_view.item.citype == idaapi.VDI_EXPR and \ + # hx_view.item.it.to_specific_type.op in (idaapi.cot_memptr, idaapi.cot_memref) - def activate(self, ctx): - hx_view = idaapi.get_widget_vdui(ctx.widget) - if not self.check(hx_view): - return + def check(self,ctree_item): + return ctree_item.citype == idaapi.VDI_EXPR and \ + ctree_item.it.to_specific_type.op in (idaapi.cot_memptr, idaapi.cot_memref) + def activate(self, ctx): + ordinal = 0 + offset = 0 data = [] - offset = hx_view.item.e.m - struct_type = idaapi.remove_pointer(hx_view.item.e.x.type) - ordinal = helper.get_ordinal(struct_type) + struct_name='' + field_name='' + + + #print('activate widget_type: ',ctx.widget_type) + + if ctx.widget_type == idaapi.BWN_PSEUDOCODE:# pseudocode window + hx_view = idaapi.get_widget_vdui(ctx.widget)#vdui_t + item = hx_view.item + if not self.check(item): + return + offset = item.e.m + #print (item.e.x.type + #print (dir(item.e.x.type); + struct_type = idaapi.remove_pointer(item.e.x.type) + #print (struct_type + #print (dir(struct_type); + ordinal = helper.get_ordinal(struct_type)#ordinal Id + struct_name=struct_type.dstr() + field_name=helper.get_member_name(struct_type, offset) + + if ctx.widget_type == idaapi.BWN_STRUCTS:#struct window ctrl+x + #print (dir(ctx)); + #print (dir(ctx.chooser_selection)); + #print (dir(ctx.cur_struc));#struc_t * + #print (type(ctx.cur_struc)) + #print (dir(ctx.cur_strmem));#member_t * the current structure member + ordinal= ctx.cur_struc.ordinal + offset= ctx.cur_strmem.soff + struct_name = ida_struct.get_struc_name(ctx.cur_struc.id) + field_name = ida_struct.get_member_name(ctx.cur_strmem.id) + + result = struct_xrefs.XrefStorage().get_structure_info(ordinal, offset) for xref_info in result: data.append([ @@ -34,10 +68,9 @@ def activate(self, ctx): 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), + "Cross-references to {0}::{1}".format(struct_name, field_name), [["Function", 20 | idaapi.Choose.CHCOL_PLAIN], ["Type", 2 | idaapi.Choose.CHCOL_PLAIN], ["Line", 40 | idaapi.Choose.CHCOL_PLAIN]]