Replace HexRaysCodeXplorer and HexraysInvertIf with HexRaysPyTools

This commit is contained in:
ecx86
2018-08-05 01:08:36 -04:00
parent 035b4ae117
commit 454ae02a36
22 changed files with 5639 additions and 0 deletions

279
plugins/HexRaysPyTools.py Normal file
View File

@@ -0,0 +1,279 @@
import logging
import HexRaysPyTools.Actions as Actions
import HexRaysPyTools.Core.Cache
from HexRaysPyTools.Core.TemporaryStructure import *
import HexRaysPyTools.Forms as Forms
import idaapi
import HexRaysPyTools.Core.NegativeOffsets as NegativeOffsets
import HexRaysPyTools.Core.Helper as Helper
import HexRaysPyTools.Core.Cache as Cache
import HexRaysPyTools.Core.Const as Const
from HexRaysPyTools.Core.SpaghettiCode import SpaghettiVisitor, SwapThenElseVisitor
from HexRaysPyTools.Core.StructXrefs import *
potential_negatives = {}
def hexrays_events_callback(*args):
global potential_negatives
hexrays_event = args[0]
if hexrays_event == idaapi.hxe_populating_popup:
form, popup, hx_view = args[1:]
item = hx_view.item # current ctree_item_t
if Actions.GuessAllocation.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.GuessAllocation.name, None)
if Actions.RecastItemRight.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.RecastItemRight.name, None)
if Actions.RecastItemLeft.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.RecastItemLeft.name, None)
if Actions.RenameOther.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.RenameOther.name, None)
if Actions.RenameInside.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.RenameInside.name, None)
if Actions.RenameOutside.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.RenameOutside.name, None)
if Actions.RenameUsingAssert.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.RenameUsingAssert.name, None)
if Actions.SwapThenElse.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.SwapThenElse.name, None)
if Actions.ShallowScanVariable.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.ShallowScanVariable.name, None)
idaapi.attach_action_to_popup(form, popup, Actions.DeepScanVariable.name, None)
idaapi.attach_action_to_popup(form, popup, Actions.RecognizeShape.name, None)
if Actions.CreateNewField.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.CreateNewField.name, None)
if Actions.FindFieldXrefs.check(item):
idaapi.attach_action_to_popup(form, popup, Actions.FindFieldXrefs.name, None)
if Actions.PropagateName.check(hx_view.cfunc, item):
idaapi.attach_action_to_popup(form, popup, Actions.PropagateName.name, None)
if item.citype == idaapi.VDI_FUNC:
# If we clicked on function
if not hx_view.cfunc.entry_ea == idaapi.BADADDR: # Probably never happen
idaapi.attach_action_to_popup(form, popup, Actions.AddRemoveReturn.name, None)
idaapi.attach_action_to_popup(form, popup, Actions.ConvertToUsercall.name, None)
if Actions.DeepScanReturn.check(hx_view):
idaapi.attach_action_to_popup(form, popup, Actions.DeepScanReturn.name, None)
elif item.citype == idaapi.VDI_LVAR:
# If we clicked on argument
local_variable = hx_view.item.get_lvar() # idaapi.lvar_t
if local_variable.is_arg_var:
idaapi.attach_action_to_popup(form, popup, Actions.RemoveArgument.name, None)
elif item.citype == idaapi.VDI_EXPR:
if item.e.op == idaapi.cot_num:
# number_format = item.e.n.nf # idaapi.number_format_t
# print "(number) flags: {0:#010X}, type_name: {1}, opnum: {2}".format(
# number_format.flags,
# number_format.type_name,
# number_format.opnum
# )
idaapi.attach_action_to_popup(form, popup, Actions.GetStructureBySize.name, None)
elif item.e.op == idaapi.cot_var:
# Check if we clicked on variable that is a pointer to a structure that is potentially part of
# containing structure
if item.e.v.idx in potential_negatives:
idaapi.attach_action_to_popup(form, popup, Actions.SelectContainingStructure.name, None)
if Actions.ResetContainingStructure.check(hx_view.cfunc.get_lvars()[item.e.v.idx]):
idaapi.attach_action_to_popup(form, popup, Actions.ResetContainingStructure.name, None)
elif hexrays_event == idaapi.hxe_double_click:
hx_view = args[1]
item = hx_view.item
if item.citype == idaapi.VDI_EXPR and item.e.op == idaapi.cot_memptr:
# Look if we double clicked on expression that is member pointer. Then get tinfo_t of the structure.
# After that remove pointer and get member name with the same offset
if item.e.x.op == idaapi.cot_memref and item.e.x.x.op == idaapi.cot_memptr:
vtable_tinfo = item.e.x.type.get_pointed_object()
method_offset = item.e.m
class_tinfo = item.e.x.x.x.type.get_pointed_object()
vtable_offset = item.e.x.x.m
elif item.e.x.op == idaapi.cot_memptr:
vtable_tinfo = item.e.x.type.get_pointed_object()
method_offset = item.e.m
class_tinfo = item.e.x.x.type.get_pointed_object()
vtable_offset = item.e.x.m
else:
func_offset = item.e.m
struct_tinfo = item.e.x.type.get_pointed_object()
func_ea = Helper.get_virtual_func_address(Helper.get_member_name(struct_tinfo, func_offset))
if func_ea:
idaapi.jumpto(func_ea)
return 0
func_name = Helper.get_member_name(vtable_tinfo, method_offset)
func_ea = Helper.get_virtual_func_address(func_name, class_tinfo, vtable_offset)
if func_ea:
idaapi.open_pseudocode(func_ea, 0)
return 1
elif hexrays_event == idaapi.hxe_maturity:
cfunc, level_of_maturity = args[1:]
if level_of_maturity == idaapi.CMAT_BUILT:
# print '=' * 40
# print '=' * 15, "LEVEL", level_of_maturity, '=' * 16
# print '=' * 40
# print cfunc
# First search for CONTAINING_RECORD made by Ida
visitor = NegativeOffsets.SearchVisitor(cfunc)
visitor.apply_to(cfunc.body, None)
negative_lvars = visitor.result
# Second get saved information from comments
lvars = cfunc.get_lvars()
for idx in xrange(len(lvars)):
result = NegativeOffsets.parse_lvar_comment(lvars[idx])
if result and result.tinfo.equals_to(lvars[idx].type().get_pointed_object()):
negative_lvars[idx] = result
# Third make an analysis of local variables that a structure pointers and have reference that pass
# through structure boundaries. This variables will be considered as potential pointers to substructure
# and will get a menu on right click that helps to select Containing Structure from different libraries
structure_pointer_variables = {}
for idx in set(range(len(lvars))) - set(negative_lvars.keys()):
if lvars[idx].type().is_ptr():
pointed_tinfo = lvars[idx].type().get_pointed_object()
if pointed_tinfo.is_udt():
structure_pointer_variables[idx] = pointed_tinfo
if structure_pointer_variables:
visitor = NegativeOffsets.AnalyseVisitor(structure_pointer_variables, potential_negatives)
visitor.apply_to(cfunc.body, None)
if negative_lvars:
visitor = NegativeOffsets.ReplaceVisitor(negative_lvars)
visitor.apply_to(cfunc.body, None)
elif level_of_maturity == idaapi.CMAT_TRANS1:
visitor = SwapThenElseVisitor(cfunc.entry_ea)
visitor.apply_to(cfunc.body, None)
elif level_of_maturity == idaapi.CMAT_TRANS2:
# print '=' * 40
# print '=' * 15, "LEVEL", level_of_maturity, '=' * 16
# print '=' * 40
# print cfunc
visitor = SpaghettiVisitor()
visitor.apply_to(cfunc.body, None)
elif level_of_maturity == idaapi.CMAT_FINAL:
StructXrefVisitor(cfunc).process()
return 0
class MyPlugin(idaapi.plugin_t):
# flags = idaapi.PLUGIN_HIDE
flags = 0
comment = "Plugin for automatic classes reconstruction"
help = "This is help"
wanted_name = "HexRaysPyTools"
wanted_hotkey = "Alt-F8"
@staticmethod
def init():
if not idaapi.init_hexrays_plugin():
print "[ERROR] Failed to initialize Hex-Rays SDK"
return idaapi.PLUGIN_SKIP
Cache.temporary_structure = TemporaryStructureModel()
# Actions.register(Actions.CreateVtable)
Actions.register(Actions.ShowGraph)
Actions.register(Actions.ShowClasses)
Actions.register(Actions.GetStructureBySize)
Actions.register(Actions.RemoveArgument)
Actions.register(Actions.AddRemoveReturn)
Actions.register(Actions.ConvertToUsercall)
Actions.register(Actions.ShallowScanVariable, Cache.temporary_structure)
Actions.register(Actions.DeepScanVariable, Cache.temporary_structure)
Actions.register(Actions.DeepScanReturn, Cache.temporary_structure)
Actions.register(Actions.DeepScanFunctions, Cache.temporary_structure)
Actions.register(Actions.RecognizeShape)
Actions.register(Actions.CreateNewField)
Actions.register(Actions.SelectContainingStructure, potential_negatives)
Actions.register(Actions.ResetContainingStructure)
Actions.register(Actions.RecastItemRight)
Actions.register(Actions.RecastItemLeft)
Actions.register(Actions.RenameOther)
Actions.register(Actions.RenameInside)
Actions.register(Actions.RenameOutside)
Actions.register(Actions.RenameUsingAssert)
Actions.register(Actions.SwapThenElse)
Actions.register(Actions.FindFieldXrefs)
Actions.register(Actions.PropagateName)
Actions.register(Actions.GuessAllocation)
idaapi.attach_action_to_menu('View/Open subviews/Local types', Actions.ShowClasses.name, idaapi.SETMENU_APP)
idaapi.install_hexrays_callback(hexrays_events_callback)
Const.init()
XrefStorage().open()
return idaapi.PLUGIN_KEEP
@staticmethod
def run(arg):
tform = idaapi.find_tform("Structure Builder")
if tform:
idaapi.switchto_tform(tform, True)
else:
Forms.StructureBuilder(Cache.temporary_structure).Show()
@staticmethod
def term():
if Cache.temporary_structure:
Cache.temporary_structure.clear()
# Actions.unregister(Actions.CreateVtable)
Actions.unregister(Actions.ShowGraph)
Actions.unregister(Actions.ShowClasses)
Actions.unregister(Actions.GetStructureBySize)
Actions.unregister(Actions.RemoveArgument)
Actions.unregister(Actions.AddRemoveReturn)
Actions.unregister(Actions.ConvertToUsercall)
Actions.unregister(Actions.ShallowScanVariable)
Actions.unregister(Actions.DeepScanVariable)
Actions.unregister(Actions.DeepScanReturn)
Actions.unregister(Actions.DeepScanFunctions)
Actions.unregister(Actions.RecognizeShape)
Actions.unregister(Actions.CreateNewField)
Actions.unregister(Actions.SelectContainingStructure)
Actions.unregister(Actions.ResetContainingStructure)
Actions.unregister(Actions.RecastItemRight)
Actions.unregister(Actions.RecastItemLeft)
Actions.unregister(Actions.RenameOther)
Actions.unregister(Actions.RenameInside)
Actions.unregister(Actions.RenameOutside)
Actions.unregister(Actions.RenameUsingAssert)
Actions.unregister(Actions.SwapThenElse)
Actions.unregister(Actions.FindFieldXrefs)
Actions.unregister(Actions.PropagateName)
Actions.unregister(Actions.GuessAllocation)
idaapi.term_hexrays_plugin()
XrefStorage().close()
def PLUGIN_ENTRY():
idaapi.notify_when(idaapi.NW_OPENIDB, Cache.init_demangled_names)
idaapi.notify_when(idaapi.NW_OPENIDB, Cache.init_imported_ea)
idaapi.notify_when(idaapi.NW_OPENIDB, Cache.reset_touched_functions)
Helper.extend_ida()
return MyPlugin()