Initial commit
This commit is contained in:
111
force_lvar_width.py
Normal file
111
force_lvar_width.py
Normal file
@@ -0,0 +1,111 @@
|
||||
""" Forcibly change the width of an lvar.
|
||||
Useful for making an lvar smaller (which Hex-Rays does not let you do apparently)
|
||||
Tags (for search engines):
|
||||
IDA Pro Hex-Rays make stack variable smaller force variable size decrease width delete variable split up break up variable into smaller
|
||||
"""
|
||||
|
||||
import idautils
|
||||
import idaapi
|
||||
import idc
|
||||
import ida_hexrays
|
||||
|
||||
import traceback
|
||||
|
||||
force_width_actname = "forcelvarwidth:forcewidth"
|
||||
|
||||
class force_width_action_handler_t(idaapi.action_handler_t):
|
||||
def __init__(self, callback_info):
|
||||
idaapi.action_handler_t.__init__(self)
|
||||
self.callback_info = callback_info
|
||||
|
||||
def activate(self, ctx):
|
||||
vdui = idaapi.get_widget_vdui(ctx.widget)
|
||||
self.callback_info.gui_action_callback(vdui)
|
||||
return 1
|
||||
|
||||
def update(self, ctx):
|
||||
return idaapi.AST_ENABLE_FOR_WIDGET if \
|
||||
ctx.widget_type == idaapi.BWN_PSEUDOCODE else \
|
||||
idaapi.AST_DISABLE_FOR_WIDGET
|
||||
|
||||
|
||||
class hexrays_callback_info(object):
|
||||
|
||||
def __init__(self):
|
||||
self.vu = None
|
||||
return
|
||||
|
||||
def load(self):
|
||||
return
|
||||
|
||||
def save(self):
|
||||
return
|
||||
|
||||
def do_force_width(self, cfunc, insn):
|
||||
|
||||
if insn.opname != 'if':
|
||||
return False
|
||||
|
||||
cif = insn.details
|
||||
|
||||
if not cif.ithen or not cif.ielse:
|
||||
return False
|
||||
|
||||
idaapi.qswap(cif.ithen, cif.ielse)
|
||||
cond = idaapi.cexpr_t(cif.expr)
|
||||
notcond = idaapi.lnot(cond)
|
||||
|
||||
cif.expr.swap(notcond)
|
||||
|
||||
return True
|
||||
|
||||
def gui_action_callback(self, vu):
|
||||
|
||||
cfunc = vu.cfunc.__deref__()
|
||||
|
||||
if not vu.get_current_item(idaapi.USE_KEYBOARD):
|
||||
print "Force lvar width: you don't have anything selected"
|
||||
return False
|
||||
|
||||
badlv = vu.item.get_lvar()
|
||||
if not badlv:
|
||||
print "Force lvar width: you don't have an lvar selected"
|
||||
return False
|
||||
|
||||
new_width = idc.AskLong(badlv.width, "Enter the new width for " + badlv.name)
|
||||
if new_width == None: # cancelled
|
||||
print "Force lvar width: operation cancelled"
|
||||
return False
|
||||
|
||||
if new_width <= 0:
|
||||
print "Force lvar width: not allowed. Non-positive width will crash IDA"
|
||||
return False
|
||||
|
||||
badlv.set_width(new_width)
|
||||
print 'Set the type in IDA (Y) for it to apply'
|
||||
idaapi.process_ui_action('hx:SetType')
|
||||
|
||||
# vu.refresh_ctext()
|
||||
print 'Force lvar width: OK.'
|
||||
return True
|
||||
|
||||
def event_callback(self, event, *args):
|
||||
|
||||
if event == idaapi.hxe_populating_popup:
|
||||
widget, phandle, vu = args
|
||||
res = idaapi.attach_action_to_popup(vu.ct, None, force_width_actname)
|
||||
|
||||
return 0
|
||||
|
||||
if idaapi.init_hexrays_plugin():
|
||||
i = hexrays_callback_info()
|
||||
idaapi.register_action(
|
||||
idaapi.action_desc_t(
|
||||
force_width_actname,
|
||||
"Force lvar width",
|
||||
force_width_action_handler_t(i),
|
||||
"Shift-W"))
|
||||
idaapi.install_hexrays_callback(i.event_callback)
|
||||
else:
|
||||
print 'Force lvar width: hexrays is not available.'
|
||||
|
||||
Reference in New Issue
Block a user