mirror of
https://github.com/cemu-project/idapython.git
synced 2024-11-30 21:14:20 +01:00
idautils.py: added procregs to identify registers and modified DecodeInstruction().
It is now possible to identify the registers of a decoded instruction with: cmd = DecodeInstruction(here()) if cmd[0].is_reg(proc_regs.eax): print "EAX is used" or something like: if cmd[1].is_reg(proc_regs.al): print "al is used"
This commit is contained in:
parent
c21a932cec
commit
99c60a82de
@ -266,7 +266,7 @@ def FuncItems(start):
|
|||||||
|
|
||||||
def DecodeInstruction(ea):
|
def DecodeInstruction(ea):
|
||||||
"""
|
"""
|
||||||
Decodes an instruction and returns a insn_t like class
|
Decodes an instruction and returns an insn_t like class
|
||||||
|
|
||||||
@param ea: address to decode
|
@param ea: address to decode
|
||||||
|
|
||||||
@ -278,19 +278,30 @@ def DecodeInstruction(ea):
|
|||||||
insn = idaapi.get_current_instruction()
|
insn = idaapi.get_current_instruction()
|
||||||
if not insn:
|
if not insn:
|
||||||
return None
|
return None
|
||||||
class dup(object):
|
|
||||||
|
class _insn(object):
|
||||||
|
def __getitem__(self, index):
|
||||||
|
if index > len(self.Operands):
|
||||||
|
raise StopIteration
|
||||||
|
return self.Operands[index]
|
||||||
|
|
||||||
|
class _op(_reg_dtyp_t):
|
||||||
def __init__(self, op):
|
def __init__(self, op):
|
||||||
for x in dir(op):
|
_copy_obj(op, self)
|
||||||
if x.startswith("__") and x.endswith("__"):
|
_reg_dtyp_t.__init__(self, op.reg, op.dtyp)
|
||||||
continue
|
def is_reg(self, r):
|
||||||
setattr(self, x, getattr(op, x))
|
"""Checks if the operand is the given processor register"""
|
||||||
r = dup(insn)
|
return self.type == idaapi.o_reg and self == r
|
||||||
r.Operands = []
|
def has_reg(self, r):
|
||||||
|
"""Checks if the operand accesses the given processor register"""
|
||||||
|
return self.reg == r.reg
|
||||||
|
r = _copy_obj(insn, _insn())
|
||||||
|
r.Operands = [] # to hold the operands
|
||||||
for n in xrange(0, idaapi.UA_MAXOP):
|
for n in xrange(0, idaapi.UA_MAXOP):
|
||||||
t = idaapi.get_instruction_operand(insn, n)
|
t = idaapi.get_instruction_operand(insn, n)
|
||||||
if t.type == idaapi.o_void:
|
if t.type == idaapi.o_void:
|
||||||
break
|
break
|
||||||
r.Operands.append(dup(t))
|
r.Operands.append(_op(t))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
@ -469,6 +480,50 @@ def Assemble(ea, line):
|
|||||||
idc.Batch(old_batch)
|
idc.Batch(old_batch)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
def _copy_obj(src, dest):
|
||||||
|
"""
|
||||||
|
Copy non private/non callable attributes from a class instance to another
|
||||||
|
@param src: Source class to copy from
|
||||||
|
@param dest: If it is a string then it designates the new class type that will be created and copied to.
|
||||||
|
Otherwise dest should be an instance of another class
|
||||||
|
@return: A new instance or "dest"
|
||||||
|
"""
|
||||||
|
if type(dest) == types.StringType:
|
||||||
|
dest = new.classobj(dest, (), {})
|
||||||
|
for x in dir(src):
|
||||||
|
if x.startswith("__") and x.endswith("__"):
|
||||||
|
continue
|
||||||
|
t = getattr(src, x)
|
||||||
|
if callable(t):
|
||||||
|
continue
|
||||||
|
setattr(dest, x, t)
|
||||||
|
return dest
|
||||||
|
|
||||||
|
class _reg_dtyp_t(object):
|
||||||
|
"""
|
||||||
|
INTERNAL
|
||||||
|
This class describes a register's number and dtyp.
|
||||||
|
The equal operator is overloaded so that two instances can be tested for equality
|
||||||
|
"""
|
||||||
|
def __init__(self, reg, dtyp):
|
||||||
|
self.reg = reg
|
||||||
|
self.dtyp = dtyp
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return (self.reg == other.reg) and (self.dtyp == other.dtyp)
|
||||||
|
|
||||||
|
class _procregs(object):
|
||||||
|
"""Utility class allowing the users to identify registers in a decoded instruction"""
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
ri = idaapi.reg_info_t()
|
||||||
|
if not idaapi.parse_reg_name(attr, ri):
|
||||||
|
raise AttributeError()
|
||||||
|
r = _reg_dtyp_t(ri.reg, ord(idaapi.get_dtyp_by_size(ri.size)))
|
||||||
|
self.__dict__[attr] = r
|
||||||
|
return r
|
||||||
|
|
||||||
|
def __setattr__(self, attr, value):
|
||||||
|
raise AttributeError(attr)
|
||||||
|
|
||||||
class _cpu(object):
|
class _cpu(object):
|
||||||
"Simple wrapper around GetRegValue/SetRegValue"
|
"Simple wrapper around GetRegValue/SetRegValue"
|
||||||
@ -481,3 +536,4 @@ class _cpu(object):
|
|||||||
return idc.SetRegValue(value, name)
|
return idc.SetRegValue(value, name)
|
||||||
|
|
||||||
cpu = _cpu()
|
cpu = _cpu()
|
||||||
|
procregs = _procregs()
|
Loading…
Reference in New Issue
Block a user