Files
idapython-src/pywraps/py_hexrays.py
T
2016-08-09 10:01:18 +02:00

420 lines
13 KiB
Python

# -----------------------------------------------------------------------
#<pycode(py_hexrays)>
import ida_funcs
hexrays_failure_t.__str__ = lambda self: str(self.str)
# ---------------------------------------------------------------------
class DecompilationFailure(Exception):
""" Raised on a decompilation error.
The associated hexrays_failure_t object is stored in the
'info' member of this exception. """
def __init__(self, info):
Exception.__init__(self, 'Decompilation failed: %s' % (str(info), ))
self.info = info
return
# ---------------------------------------------------------------------
def decompile(ea, hf=None):
if isinstance(ea, (int, long)):
func = ida_funcs.get_func(ea)
if not func: return
elif type(ea) == ida_funcs.func_t:
func = ea
else:
raise RuntimeError('arg 1 of decompile expects either ea_t or cfunc_t argument')
if hf is None:
hf = hexrays_failure_t()
ptr = _decompile(func, hf)
if ptr.__deref__() is None:
raise DecompilationFailure(hf)
return ptr
# ---------------------------------------------------------------------
# stringify all string types
#qtype.__str__ = qtype.c_str
#qstring.__str__ = qstring.c_str
#citem_cmt_t.__str__ = citem_cmt_t.c_str
# ---------------------------------------------------------------------
# listify all list types
import ida_idaapi
ida_idaapi._listify_types(
cinsnptrvec_t,
ctree_items_t,
qvector_lvar_t,
qvector_carg_t,
qvector_ccase_t,
hexwarns_t,
history_t,
lvar_saved_infos_t)
def citem_to_specific_type(self):
""" cast the citem_t object to its more specific type, either cexpr_t or cinsn_t. """
if self.op >= cot_empty and self.op <= cot_last:
return self.cexpr
elif self.op >= cit_empty and self.op < cit_end:
return self.cinsn
raise RuntimeError('unknown op type %s' % (repr(self.op), ))
citem_t.to_specific_type = property(citem_to_specific_type)
""" array used for translating cinsn_t->op type to their names. """
cinsn_t.op_to_typename = {}
for k in dir(_ida_hexrays):
if k.startswith('cit_'):
cinsn_t.op_to_typename[getattr(_ida_hexrays, k)] = k[4:]
""" array used for translating cexpr_t->op type to their names. """
cexpr_t.op_to_typename = {}
for k in dir(_ida_hexrays):
if k.startswith('cot_'):
cexpr_t.op_to_typename[getattr(_ida_hexrays, k)] = k[4:]
def property_op_to_typename(self):
return self.op_to_typename[self.op]
cinsn_t.opname = property(property_op_to_typename)
cexpr_t.opname = property(property_op_to_typename)
def cexpr_operands(self):
""" return a dictionary with the operands of a cexpr_t. """
if self.op >= cot_comma and self.op <= cot_asgumod or \
self.op >= cot_lor and self.op <= cot_fdiv or \
self.op == cot_idx:
return {'x': self.x, 'y': self.y}
elif self.op == cot_tern:
return {'x': self.x, 'y': self.y, 'z': self.z}
elif self.op in [cot_fneg, cot_neg, cot_sizeof] or \
self.op >= cot_lnot and self.op <= cot_predec:
return {'x': self.x}
elif self.op == cot_cast:
return {'type': self.type, 'x': self.x}
elif self.op == cot_call:
return {'x': self.x, 'a': self.a}
elif self.op in [cot_memref, cot_memptr]:
return {'x': self.x, 'm': self.m}
elif self.op == cot_num:
return {'n': self.n}
elif self.op == cot_fnum:
return {'fpc': self.fpc}
elif self.op == cot_str:
return {'string': self.string}
elif self.op == cot_obj:
return {'obj_ea': self.obj_ea}
elif self.op == cot_var:
return {'v': self.v}
elif self.op == cot_helper:
return {'helper': self.helper}
raise RuntimeError('unknown op type %s' % self.opname)
cexpr_t.operands = property(cexpr_operands)
def cinsn_details(self):
""" return the details pointer for the cinsn_t object depending on the value of its op member. \
this is one of the cblock_t, cif_t, etc. objects. """
if self.op not in self.op_to_typename:
raise RuntimeError('unknown item->op type')
opname = self.opname
if opname == 'empty':
return self
if opname in ['break', 'continue']:
return None
return getattr(self, 'c' + opname)
cinsn_t.details = property(cinsn_details)
def cblock_iter(self):
iter = self.begin()
for i in range(self.size()):
yield iter.cur
iter.next()
return
cblock_t.__iter__ = cblock_iter
cblock_t.__len__ = cblock_t.size
# cblock.find(cinsn_t) -> returns the iterator positioned at the given item
def cblock_find(self, item):
iter = self.begin()
for i in range(self.size()):
if iter.cur == item:
return iter
iter.next()
return
cblock_t.find = cblock_find
# cblock.index(cinsn_t) -> returns the index of the given item
def cblock_index(self, item):
iter = self.begin()
for i in range(self.size()):
if iter.cur == item:
return i
iter.next()
return
cblock_t.index = cblock_index
# cblock.at(int) -> returns the item at the given index index
def cblock_at(self, index):
iter = self.begin()
for i in range(self.size()):
if i == index:
return iter.cur
iter.next()
return
cblock_t.at = cblock_at
# cblock.remove(cinsn_t)
def cblock_remove(self, item):
iter = self.find(item)
self.erase(iter)
return
cblock_t.remove = cblock_remove
# cblock.insert(index, cinsn_t)
def cblock_insert(self, index, item):
pos = self.at(index)
iter = self.find(pos)
self.insert(iter, item)
return
cblock_t.insert = cblock_insert
cfuncptr_t.__str__ = lambda self: str(self.__deref__())
import ida_typeinf
def cfunc_type(self):
""" Get the function's return type tinfo_t object. """
tif = ida_typeinf.tinfo_t()
result = self.get_func_type(tif)
if not result:
return
return tif
cfunc_t.type = property(cfunc_type)
cfuncptr_t.type = property(lambda self: self.__deref__().type)
cfunc_t.arguments = property(lambda self: [o for o in self.lvars if o.is_arg_var])
cfuncptr_t.arguments = property(lambda self: self.__deref__().arguments)
cfunc_t.lvars = property(cfunc_t.get_lvars)
cfuncptr_t.lvars = property(lambda self: self.__deref__().lvars)
cfunc_t.warnings = property(cfunc_t.get_warnings)
cfuncptr_t.warnings = property(lambda self: self.__deref__().warnings)
cfunc_t.pseudocode = property(cfunc_t.get_pseudocode)
cfuncptr_t.pseudocode = property(lambda self: self.__deref__().get_pseudocode())
cfunc_t.eamap = property(cfunc_t.get_eamap)
cfuncptr_t.eamap = property(lambda self: self.__deref__().get_eamap())
cfunc_t.boundaries = property(cfunc_t.get_boundaries)
cfuncptr_t.boundaries = property(lambda self: self.__deref__().get_boundaries())
#pragma SWIG nowarn=+503
lvar_t.used = property(lvar_t.used)
lvar_t.typed = property(lvar_t.typed)
lvar_t.mreg_done = property(lvar_t.mreg_done)
lvar_t.has_nice_name = property(lvar_t.has_nice_name)
lvar_t.is_unknown_width = property(lvar_t.is_unknown_width)
lvar_t.has_user_info = property(lvar_t.has_user_info)
lvar_t.has_user_name = property(lvar_t.has_user_name)
lvar_t.has_user_type = property(lvar_t.has_user_type)
lvar_t.is_result_var = property(lvar_t.is_result_var)
lvar_t.is_arg_var = property(lvar_t.is_arg_var)
lvar_t.is_fake_var = property(lvar_t.is_fake_var)
lvar_t.is_overlapped_var = property(lvar_t.is_overlapped_var)
lvar_t.is_floating_var = property(lvar_t.is_floating_var)
lvar_t.is_spoiled_var = property(lvar_t.is_spoiled_var)
lvar_t.is_mapdst_var = property(lvar_t.is_mapdst_var)
# dictify all dict-like types
def _map___getitem__(self, key):
""" Returns the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of key should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
return self.second(self.find(key))
def _map___setitem__(self, key, value):
""" Returns the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if not isinstance(value, self.valuetype):
raise KeyError('type of `value` should be ' + repr(self.valuetype) + ' but got ' + type(value))
self.insert(key, value)
return
def _map___delitem__(self, key):
""" Removes the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
self.erase(self.find(key))
return
def _map___contains__(self, key):
""" Returns true if the specified key exists in the . """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if self.find(key) != self.end():
return True
return False
def _map_clear(self):
self.clear()
return
def _map_copy(self):
ret = {}
for k in self.iterkeys():
ret[k] = self[k]
return ret
def _map_get(self, key, default=None):
if key in self:
return self[key]
return default
def _map_iterkeys(self):
iter = self.begin()
while iter != self.end():
yield self.first(iter)
iter = self.next(iter)
return
def _map_itervalues(self):
iter = self.begin()
while iter != self.end():
yield self.second(iter)
iter = self.next(iter)
return
def _map_iteritems(self):
iter = self.begin()
while iter != self.end():
yield (self.first(iter), self.second(iter))
iter = self.next(iter)
return
def _map_keys(self):
return list(self.iterkeys())
def _map_values(self):
return list(self.itervalues())
def _map_items(self):
return list(self.iteritems())
def _map_has_key(self, key):
return key in self
def _map_pop(self, key):
""" Sets the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
ret = self[key]
del self[key]
return ret
def _map_popitem(self):
""" Sets the value associated with the provided key. """
if len(self) == 0:
raise KeyError('key not found')
key = self.keys()[0]
return (key, self.pop(key))
def _map_setdefault(self, key, default=None):
""" Sets the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key in self:
return self[key]
self[key] = default
return default
def _map_as_dict(maptype, name, keytype, valuetype):
maptype.keytype = keytype
maptype.valuetype = valuetype
for fctname in ['begin', 'end', 'first', 'second', 'next', \
'find', 'insert', 'erase', 'clear', 'size']:
fct = getattr(_ida_hexrays, name + '_' + fctname)
setattr(maptype, '__' + fctname, fct)
maptype.__len__ = maptype.size
maptype.__getitem__ = maptype.at
maptype.begin = lambda self, *args: self.__begin(self, *args)
maptype.end = lambda self, *args: self.__end(self, *args)
maptype.first = lambda self, *args: self.__first(*args)
maptype.second = lambda self, *args: self.__second(*args)
maptype.next = lambda self, *args: self.__next(*args)
maptype.find = lambda self, *args: self.__find(self, *args)
maptype.insert = lambda self, *args: self.__insert(self, *args)
maptype.erase = lambda self, *args: self.__erase(self, *args)
maptype.clear = lambda self, *args: self.__clear(self, *args)
maptype.size = lambda self, *args: self.__size(self, *args)
maptype.__getitem__ = _map___getitem__
maptype.__setitem__ = _map___setitem__
maptype.__delitem__ = _map___delitem__
maptype.__contains__ = _map___contains__
maptype.clear = _map_clear
maptype.copy = _map_copy
maptype.get = _map_get
maptype.iterkeys = _map_iterkeys
maptype.itervalues = _map_itervalues
maptype.iteritems = _map_iteritems
maptype.keys = _map_keys
maptype.values = _map_values
maptype.items = _map_items
maptype.has_key = _map_has_key
maptype.pop = _map_pop
maptype.popitem = _map_popitem
maptype.setdefault = _map_setdefault
#_map_as_dict(user_labels_t, 'user_labels', (int, long), qstring)
_map_as_dict(user_cmts_t, 'user_cmts', treeloc_t, citem_cmt_t)
_map_as_dict(user_numforms_t, 'user_numforms', operand_locator_t, number_format_t)
_map_as_dict(user_iflags_t, 'user_iflags', citem_locator_t, (int, long))
import ida_pro
_map_as_dict(user_unions_t, 'user_unions', (int, long), ida_pro.intvec_t)
_map_as_dict(eamap_t, 'eamap', long, cinsnptrvec_t)
#_map_as_dict(boundaries_t, 'boundaries', cinsn_t, areaset_t)
#</pycode(py_hexrays)>