3
3
import re
4
4
5
5
import idaapi
6
+ import idc
6
7
7
8
import HexRaysPyTools .Forms as Forms
8
9
import HexRaysPyTools .Core .Const as Const
9
10
import HexRaysPyTools .Core .Helper as Helper
10
11
from HexRaysPyTools .Core .StructureGraph import StructureGraph
11
12
from HexRaysPyTools .Core .TemporaryStructure import VirtualTable , TemporaryStructureModel
12
- from HexRaysPyTools .Core .VariableScanner import ShallowSearchVisitor , DeepSearchVisitor
13
+ from HexRaysPyTools .Core .VariableScanner import ShallowSearchVisitor , DeepSearchVisitor , VariableLookupVisitor
13
14
from HexRaysPyTools .Core .Helper import FunctionTouchVisitor
14
15
15
16
RECAST_LOCAL_VARIABLE = 0
@@ -83,7 +84,7 @@ def choose_til():
83
84
if library_num != - 1 :
84
85
selected_library = list_type_library [library_num ][0 ]
85
86
max_ordinal = idaapi .get_ordinal_qty (selected_library )
86
- if max_ordinal == idaapi .BADNODE :
87
+ if max_ordinal == idaapi .BADORD :
87
88
TypeLibrary .enable_library_ordinals (library_num - 1 )
88
89
max_ordinal = idaapi .get_ordinal_qty (selected_library )
89
90
print "[DEBUG] Maximal ordinal of lib {0} = {1}" .format (selected_library .name , max_ordinal )
@@ -95,7 +96,7 @@ def import_type(library, name):
95
96
if library .name != idaapi .cvar .idati .name :
96
97
last_ordinal = idaapi .get_ordinal_qty (idaapi .cvar .idati )
97
98
type_id = idaapi .import_type (library , - 1 , name ) # tid_t
98
- if type_id != idaapi .BADNODE :
99
+ if type_id != idaapi .BADORD :
99
100
return last_ordinal
100
101
return None
101
102
@@ -280,6 +281,7 @@ def activate(self, ctx):
280
281
scanner .process ()
281
282
for field in scanner .candidates :
282
283
self .temporary_structure .add_row (field )
284
+ scanner .clear ()
283
285
284
286
def update (self , ctx ):
285
287
if ctx .form_title [0 :10 ] == "Pseudocode" :
@@ -300,6 +302,9 @@ def __init__(self, temporary_structure):
300
302
def activate (self , ctx ):
301
303
hx_view = idaapi .get_tform_vdui (ctx .form )
302
304
variable = hx_view .item .get_lvar () # lvar_t
305
+ self .scan (hx_view , variable )
306
+
307
+ def scan (self , hx_view , variable ):
303
308
if variable and filter (lambda x : x .equals_to (variable .type ()), Const .LEGAL_TYPES ):
304
309
definition_address = variable .defea
305
310
# index = list(hx_view.cfunc.get_lvars()).index(variable)
@@ -313,6 +318,61 @@ def activate(self, ctx):
313
318
scanner .process ()
314
319
for field in scanner .candidates :
315
320
self .temporary_structure .add_row (field )
321
+ scanner .clear ()
322
+
323
+ def update (self , ctx ):
324
+ if ctx .form_title [0 :10 ] == "Pseudocode" :
325
+ return idaapi .AST_ENABLE_FOR_FORM
326
+ return idaapi .AST_DISABLE_FOR_FORM
327
+
328
+
329
+ class DeepScanReturn (idaapi .action_handler_t ):
330
+
331
+ name = "my:DeepScanReturn"
332
+ description = "Deep Scan Returned Variables"
333
+ hotkey = None
334
+
335
+ def __init__ (self , temporary_structure ):
336
+ self .temporary_structure = temporary_structure
337
+ idaapi .action_handler_t .__init__ (self )
338
+
339
+ @staticmethod
340
+ def check (ctx ):
341
+ hx_view = idaapi .get_tform_vdui (ctx .form )
342
+ return hx_view .cfunc .get_rettype ().equals_to (Const .VOID_TINFO )
343
+
344
+ def activate (self , ctx ):
345
+ hx_view = idaapi .get_tform_vdui (ctx .form )
346
+ address = hx_view .cfunc .entry_ea
347
+
348
+ xref_ea = idaapi .get_first_cref_to (address )
349
+ xrefs = set ()
350
+ while xref_ea != idaapi .BADADDR :
351
+ xref_func_ea = idc .GetFunctionAttr (xref_ea , idc .FUNCATTR_START )
352
+ if xref_func_ea != idaapi .BADADDR :
353
+ xrefs .add (xref_func_ea )
354
+ else :
355
+ print "[Warning] Function not found at 0x{0:08X}" .format (xref_ea )
356
+ xref_ea = idaapi .get_next_cref_to (address , xref_ea )
357
+
358
+ for func_ea in xrefs :
359
+ visitor = VariableLookupVisitor (address )
360
+
361
+ try :
362
+ cfunc = idaapi .decompile (func_ea )
363
+ if cfunc :
364
+ FunctionTouchVisitor (cfunc ).process ()
365
+ visitor .apply_to (cfunc .body , None )
366
+ for idx in visitor .result :
367
+ scanner = DeepSearchVisitor (cfunc , 0 , idx )
368
+ scanner .process ()
369
+ for field in scanner .candidates :
370
+ self .temporary_structure .add_row (field )
371
+
372
+ except idaapi .DecompilationFailure :
373
+ print "[Warning] Failed to decompile function at 0x{0:08X}" .format (xref_ea )
374
+
375
+ DeepSearchVisitor .clear ()
316
376
317
377
def update (self , ctx ):
318
378
if ctx .form_title [0 :10 ] == "Pseudocode" :
@@ -693,6 +753,51 @@ def check(cfunc, ctree_item):
693
753
return RECAST_RETURN , new_type , expression .x .x .obj_ea
694
754
695
755
756
+ class RenameOther (idaapi .action_handler_t ):
757
+ name = "my:RenameOther"
758
+ description = "Take other name"
759
+ hotkey = "Ctrl+N"
760
+
761
+ def __init__ (self ):
762
+ idaapi .action_handler_t .__init__ (self )
763
+
764
+ @staticmethod
765
+ def check (cfunc , ctree_item ):
766
+ if ctree_item .citype != idaapi .VDI_EXPR :
767
+ return
768
+
769
+ expression = ctree_item .it .to_specific_type
770
+ if expression .op != idaapi .cot_var :
771
+ return
772
+
773
+ parent = cfunc .body .find_parent_of (expression ).to_specific_type
774
+ if parent .op != idaapi .cot_asg :
775
+ return
776
+
777
+ other = parent .theother (expression )
778
+ if other .op != idaapi .cot_var :
779
+ return
780
+
781
+ this_lvar = ctree_item .get_lvar ()
782
+ other_lvar = cfunc .get_lvars ()[other .v .idx ]
783
+ if (other_lvar .has_user_name or other_lvar .is_arg_var and re .search ("a\d*$" , other_lvar .name ) is None ) \
784
+ and this_lvar .name .lstrip ('_' ) != other_lvar .name .lstrip ('_' ):
785
+ return '_' + other_lvar .name , this_lvar
786
+
787
+ def activate (self , ctx ):
788
+ hx_view = idaapi .get_tform_vdui (ctx .form )
789
+ result = self .check (hx_view .cfunc , hx_view .item )
790
+
791
+ if result :
792
+ name , lvar = result
793
+ hx_view .rename_lvar (lvar , name , True )
794
+
795
+ def update (self , ctx ):
796
+ if ctx .form_title [0 :10 ] == "Pseudocode" :
797
+ return idaapi .AST_ENABLE_FOR_FORM
798
+ return idaapi .AST_DISABLE_FOR_FORM
799
+
800
+
696
801
class RenameInside (idaapi .action_handler_t ):
697
802
name = "my:RenameInto"
698
803
description = "Rename inside argument"
@@ -717,8 +822,8 @@ def check(cfunc, ctree_item):
717
822
func_tinfo = parent .x .type .get_pointed_object ()
718
823
func_data = idaapi .func_type_data_t ()
719
824
func_tinfo .get_func_details (func_data )
720
- if arg_index < func_tinfo .get_nargs () and lvar .name != func_data [arg_index ].name :
721
- return func_tinfo , parent .x .obj_ea , arg_index , lvar .name
825
+ if arg_index < func_tinfo .get_nargs () and lvar .name . lstrip ( '_' ) != func_data [arg_index ].name :
826
+ return func_tinfo , parent .x .obj_ea , arg_index , lvar .name . lstrip ( '_' )
722
827
723
828
def activate (self , ctx ):
724
829
hx_view = idaapi .get_tform_vdui (ctx .form )
0 commit comments