A brief tl;dr code sample on how to map, rename and re-type variables programmatically in python.
see github for the rest of the code. don't expect this to work on IDA 6.x, though maybe it will. i've never tried.
import re
from itertools import islice
import ida_hexrays
import idaapi
import idautils
import idc
def map_lvar(src, dst, ea):
func = idaapi.get_func(ea)
if func:
ea = func.start_ea
vu = idaapi.open_pseudocode(ea, 0)
lvars1 = [n for n in vu.cfunc.lvars if n.name == src]
lvars2 = [n for n in vu.cfunc.lvars if n.name == dst]
if len(lvars1) == 1 and len(lvars2) == 1:
print("mapping {} to {}".format(lvars1[0].name, lvars2[0].name))
# we might need to change the lvar type?
vu.set_lvar_type(lvars1[0], lvars2[0].type())
vu.map_lvar(lvars1[0], lvars2[0])
else:
print("couldn't find one of the vars {} or {}".format(src, dst))
def set_lvar_type(src, t, ea):
func = idaapi.get_func(ea)
if func:
ea = func.start_ea
vu = idaapi.open_pseudocode(ea, 0)
# names = [n.name for n in vu.cfunc.lvars]
lvars = [n for n in vu.cfunc.lvars if n.name == src]
if len(lvars) == 1:
print("changing type of {} to {}".format(lvars[0].name, t))
vu.set_lvar_type(lvars[0], t)
else:
print("couldn't find var {}".format(src))
def rename_lvar(src, dst, ea):
def make_unique_name(name, taken):
if name not in taken:
return name
fmt = "%s_%%i" % name
for i in range(3, 1024):
tmpName = fmt % i
if tmpName not in taken:
return tmpName
return "i_give_up"
func = idaapi.get_func(ea)
if func:
ea = func.start_ea
vu = idaapi.open_pseudocode(ea, 0)
names = [n.name for n in vu.cfunc.lvars]
if dst in names:
dst = make_unique_name(dst, names)
lvars = [n for n in vu.cfunc.lvars if n.name == src]
if len(lvars) == 1:
print("renaming {} to {}".format(lvars[0].name, dst))
vu.rename_lvar(lvars[0], dst, 1)
# how to close the view without a widget object?
# idautils.close_pseudocode (nope)
# ida_kerwin.close_widget (nope)
else:
print("couldn't find var {}".format(src))