# ----------------------------------------------------------------------- # 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) #