Repository URL to install this package:
Version:
9.1~250226-5.fc43 ▾
|
"""
summary: list instruction registers
description:
Shows a list of direct references to a register from the
current instruction.
level: advanced
"""
import ida_pro
import ida_hexrays
import ida_kernwin
import ida_funcs
import ida_bytes
import ida_lines
def collect_block_xrefs(out, mlist, blk, ins, find_uses):
p = ins
while p and not mlist.empty():
use = blk.build_use_list(p, ida_hexrays.MUST_ACCESS); # things used by the insn
_def = blk.build_def_list(p, ida_hexrays.MUST_ACCESS); # things defined by the insn
plst = use if find_uses else _def
if mlist.has_common(plst):
if not p.ea in out:
out.append(p.ea) # this microinstruction seems to use our operand
mlist.sub(_def)
p = p.next if find_uses else p.prev
def collect_xrefs(out, ctx, mop, mlist, du, find_uses):
# first collect the references in the current block
start = ctx.topins.next if find_uses else ctx.topins.prev;
collect_block_xrefs(out, mlist, ctx.blk, start, find_uses)
# then find references in other blocks
serial = ctx.blk.serial; # block number of the operand
bc = du[serial] # chains of that block
voff = ida_hexrays.voff_t(mop)
ch = bc.get_chain(voff) # chain of the operand
if not ch:
return # odd
for bn in ch:
b = ctx.mba.get_mblock(bn)
ins = b.head if find_uses else b.tail
tmp = ida_hexrays.mlist_t()
tmp.add(mlist)
collect_block_xrefs(out, tmp, b, ins, find_uses)
class xref_chooser_t(ida_kernwin.Choose):
def __init__(self, xrefs, t, n, ea, gco):
ida_kernwin.Choose.__init__(
self,
t,
[["Type", 3], ["Address", 16], ["Instruction", 60]])
self.xrefs = xrefs
self.ndefs = n
self.curr_ea = ea
self.gco = gco
self.items = [ self._make_item(idx) for idx in range(len(xrefs)) ]
def OnGetSize(self):
return len(self.items)
def OnGetLine(self, n):
return self.items[n]
def _make_item(self, idx):
ea = self.xrefs[idx]
both_mask = ida_hexrays.GCO_USE|ida_hexrays.GCO_DEF
both = (self.gco.flags & both_mask) == both_mask
if ea == self.curr_ea and both:
type_str = "use/def"
elif idx < self.ndefs:
type_str = "def"
else:
type_str = "use"
insn = ida_lines.generate_disasm_line(ea, ida_lines.GENDSM_REMOVE_TAGS)
return [type_str, "%08x" % ea, insn]
def show_xrefs(ea, gco, xrefs, ndefs):
title = "xrefs to %s at %08x" % (gco.name, ea)
xc = xref_chooser_t(xrefs, title, ndefs, ea, gco)
i = xc.Show(True)
if i >= 0:
ida_kernwin.jumpto(xrefs[i])
if ida_hexrays.init_hexrays_plugin():
ea = ida_kernwin.get_screen_ea()
pfn = ida_funcs.get_func(ea)
w = ida_kernwin.warning
if pfn:
F = ida_bytes.get_flags(ea)
if ida_bytes.is_code(F):
gco = ida_hexrays.gco_info_t()
if ida_hexrays.get_current_operand(gco):
# generate microcode
hf = ida_hexrays.hexrays_failure_t()
mbr = ida_hexrays.mba_ranges_t(pfn)
mba = ida_hexrays.gen_microcode(
mbr,
hf,
None,
ida_hexrays.DECOMP_WARNINGS | ida_hexrays.DECOMP_NO_CACHE,
ida_hexrays.MMAT_PREOPTIMIZED)
if mba:
merr = mba.build_graph()
if merr == ida_hexrays.MERR_OK:
ncalls = mba.analyze_calls(ida_hexrays.ACFL_GUESS)
if ncalls < 0:
print("%08x: failed to determine some calling conventions", pfn.start_ea)
mlist = ida_hexrays.mlist_t()
if gco.append_to_list(mlist, mba):
ctx = ida_hexrays.op_parent_info_t()
mop = mba.find_mop(ctx, ea, gco.is_def(), mlist)
if mop:
xrefs = ida_pro.eavec_t()
ndefs = 0
graph = mba.get_graph()
ud = graph.get_ud(ida_hexrays.GC_REGS_AND_STKVARS)
du = graph.get_du(ida_hexrays.GC_REGS_AND_STKVARS)
if gco.is_use():
collect_xrefs(xrefs, ctx, mop, mlist, ud, False)
ndefs = xrefs.size()
if ea not in xrefs:
xrefs.append(ea)
if gco.is_def():
if ea not in xrefs:
xrefs.append(ea)
ndefs = len(xrefs)
collect_xrefs(xrefs, ctx, mop, mlist, du, True)
show_xrefs(ea, gco, xrefs, ndefs)
else:
w("Could not find the operand in the microcode, sorry")
else:
w("Failed to represent %s as microcode list" % gco.name)
else:
w("%08x: %s" % (errea, ida_hexrays.get_merror_desc(merr, mba)))
else:
w("%08x: %s" % (hf.errea, hf.str))
else:
w("Could not find a register or stkvar in the current operand")
else:
w("Please position the cursor on an instruction")
else:
w("Please position the cursor within a function")
else:
print('vds12: Hex-rays is not available.')