mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
154 lines
5.7 KiB
Python
154 lines
5.7 KiB
Python
"""
|
|
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.')
|
|
|