Skip to content

Commit d3ce45b

Browse files
committed
feat: Add more recasts
1) `var_1 = var_2` when variables have different types but Ida doesn't think so (for now works only for left side recast) 2) `(TYPE *)&something`
1 parent 6966ff3 commit d3ce45b

File tree

1 file changed

+42
-10
lines changed

1 file changed

+42
-10
lines changed

HexRaysPyTools/Actions.py

+42-10
Original file line numberDiff line numberDiff line change
@@ -518,29 +518,52 @@ def check(cfunc, ctree_item):
518518
if expression:
519519
expression = expression.to_specific_type
520520
if expression.op == idaapi.cot_asg and \
521-
expression.x.op in (idaapi.cot_var, idaapi.cot_obj, idaapi.cot_memptr, idaapi.cot_memref) \
522-
and expression.y.op == idaapi.cot_cast:
521+
expression.x.op in (idaapi.cot_var, idaapi.cot_obj, idaapi.cot_memptr, idaapi.cot_memref):
522+
523+
right_expr = expression.y
524+
right_tinfo = right_expr.x.type if right_expr.op == idaapi.cot_cast else right_expr.type
525+
526+
# Check if both left and right parts of expression are of the same types.
527+
# If no then we can recast then.
528+
if right_tinfo.dstr() == expression.x.type.dstr():
529+
return
530+
523531
if expression.x.op == idaapi.cot_var:
524532
variable = cfunc.get_lvars()[expression.x.v.idx]
525533
idaapi.update_action_label(RecastItemLeft.name, 'Recast Variable "{0}"'.format(variable.name))
526-
return RECAST_LOCAL_VARIABLE, expression.y.x.type, variable
534+
return RECAST_LOCAL_VARIABLE, right_tinfo, variable
527535
elif expression.x.op == idaapi.cot_obj:
528536
idaapi.update_action_label(RecastItemLeft.name, 'Recast Global')
529-
return RECAST_GLOBAL_VARIABLE, expression.y.x.type, expression.x.obj_ea
537+
return RECAST_GLOBAL_VARIABLE, right_tinfo, expression.x.obj_ea
530538
elif expression.x.op == idaapi.cot_memptr:
531539
idaapi.update_action_label(RecastItemLeft.name, 'Recast Field')
532-
return RECAST_STRUCTURE, expression.x.x.type.get_pointed_object().dstr(), expression.x.m, expression.y.x.type
540+
return RECAST_STRUCTURE, expression.x.x.type.get_pointed_object().dstr(), expression.x.m, right_tinfo
533541
elif expression.x.op == idaapi.cot_memref:
534542
idaapi.update_action_label(RecastItemLeft.name, 'Recast Field')
535-
return RECAST_STRUCTURE, expression.x.x.type.dstr(), expression.x.m, expression.y.x.type
543+
return RECAST_STRUCTURE, expression.x.x.type.dstr(), expression.x.m, right_tinfo
536544

537545
elif expression.op == idaapi.cit_return:
546+
547+
idaapi.update_action_label(RecastItemLeft.name, "Recast Return")
538548
child = child or expression.creturn.expr
549+
539550
if child.op == idaapi.cot_cast:
540-
idaapi.update_action_label(RecastItemLeft.name, "Recast Return")
541551
return RECAST_RETURN, child.x.type, None
542552

553+
func_tinfo = idaapi.tinfo_t()
554+
cfunc.get_func_type(func_tinfo)
555+
rettype = func_tinfo.get_rettype()
556+
557+
print func_tinfo.get_rettype().dstr(), child.type.dstr()
558+
if func_tinfo.get_rettype().dstr() != child.type.dstr():
559+
return RECAST_RETURN, child.type, None
560+
543561
elif expression.op == idaapi.cot_call:
562+
563+
if expression.x.op == idaapi.cot_memptr:
564+
# TODO: Recast arguments of virtual functions
565+
return
566+
544567
if child and child.op == idaapi.cot_cast:
545568
if child.cexpr.x.op == idaapi.cot_memptr:
546569
idaapi.update_action_label(RecastItemLeft.name, 'Recast Virtual Function')
@@ -642,23 +665,32 @@ def check(cfunc, ctree_item):
642665
if ctree_item.citype == idaapi.VDI_EXPR:
643666

644667
expression = ctree_item.it
668+
645669
while expression and expression.op != idaapi.cot_cast:
646670
expression = expression.to_specific_type
647671
expression = cfunc.body.find_parent_of(expression)
648672
if expression:
649673
expression = expression.to_specific_type
674+
675+
if expression.x.op == idaapi.cot_ref:
676+
new_type = expression.type.get_pointed_object()
677+
expression = expression.x
678+
else:
679+
new_type = expression.type
680+
650681
if expression.x.op == idaapi.cot_var:
682+
651683
variable = cfunc.get_lvars()[expression.x.v.idx]
652684
idaapi.update_action_label(RecastItemRight.name, 'Recast Variable "{0}"'.format(variable.name))
653-
return RECAST_LOCAL_VARIABLE, expression.type, variable
685+
return RECAST_LOCAL_VARIABLE, new_type, variable
654686

655687
elif expression.x.op == idaapi.cot_obj:
656688
idaapi.update_action_label(RecastItemRight.name, 'Recast Global')
657-
return RECAST_GLOBAL_VARIABLE, expression.type, expression.x.obj_ea
689+
return RECAST_GLOBAL_VARIABLE, new_type, expression.x.obj_ea
658690

659691
elif expression.x.op == idaapi.cot_call:
660692
idaapi.update_action_label(RecastItemRight.name, "Recast Return")
661-
return RECAST_RETURN, expression.type, expression.x.x.obj_ea
693+
return RECAST_RETURN, new_type, expression.x.x.obj_ea
662694

663695

664696
class RenameInside(idaapi.action_handler_t):

0 commit comments

Comments
 (0)