mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
Backported fixes
This commit is contained in:
Binary file not shown.
@@ -1,578 +0,0 @@
|
||||
#<pycode(py_idp)>
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# P R O C E S S O R M O D U L E S C O N S T A N T S
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# processor_t related constants
|
||||
|
||||
CUSTOM_INSN_ITYPE = 0x8000
|
||||
REG_SPOIL = 0x80000000
|
||||
|
||||
REAL_ERROR_FORMAT = -1 # not supported format for current .idp
|
||||
REAL_ERROR_RANGE = -2 # number too big (small) for store (mem NOT modifyed)
|
||||
REAL_ERROR_BADDATA = -3 # illegal real data for load (IEEE data not filled)
|
||||
|
||||
#
|
||||
# Check whether the operand is relative to stack pointer or frame pointer.
|
||||
# This function is used to determine how to output a stack variable
|
||||
# This function may be absent. If it is absent, then all operands
|
||||
# are sp based by default.
|
||||
# Define this function only if some stack references use frame pointer
|
||||
# instead of stack pointer.
|
||||
# returns flags:
|
||||
OP_FP_BASED = 0x00000000 # operand is FP based
|
||||
OP_SP_BASED = 0x00000001 # operand is SP based
|
||||
OP_SP_ADD = 0x00000000 # operand value is added to the pointer
|
||||
OP_SP_SUB = 0x00000002 # operand value is substracted from the pointer
|
||||
|
||||
# processor_t.id
|
||||
${PLFM_DECLS}
|
||||
|
||||
#
|
||||
# processor_t.flag
|
||||
#
|
||||
PR_SEGS = 0x000001 # has segment registers?
|
||||
PR_USE32 = 0x000002 # supports 32-bit addressing?
|
||||
PR_DEFSEG32 = 0x000004 # segments are 32-bit by default
|
||||
PR_RNAMESOK = 0x000008 # allow to user register names for location names
|
||||
PR_ADJSEGS = 0x000020 # IDA may adjust segments moving their starting/ending addresses.
|
||||
PR_DEFNUM = 0x0000C0 # default number representation:
|
||||
PRN_HEX = 0x000000 # hex
|
||||
PRN_OCT = 0x000040 # octal
|
||||
PRN_DEC = 0x000080 # decimal
|
||||
PRN_BIN = 0x0000C0 # binary
|
||||
PR_WORD_INS = 0x000100 # instruction codes are grouped 2bytes in binrary line prefix
|
||||
PR_NOCHANGE = 0x000200 # The user can't change segments and code/data attributes (display only)
|
||||
PR_ASSEMBLE = 0x000400 # Module has a built-in assembler and understands IDP_ASSEMBLE
|
||||
PR_ALIGN = 0x000800 # All data items should be aligned properly
|
||||
PR_TYPEINFO = 0x001000 # the processor module supports
|
||||
# type information callbacks
|
||||
# ALL OF THEM SHOULD BE IMPLEMENTED!
|
||||
PR_USE64 = 0x002000 # supports 64-bit addressing?
|
||||
PR_SGROTHER = 0x004000 # the segment registers don't contain
|
||||
# the segment selectors, something else
|
||||
PR_STACK_UP = 0x008000 # the stack grows up
|
||||
PR_BINMEM = 0x010000 # the processor module provides correct
|
||||
# segmentation for binary files
|
||||
# (i.e. it creates additional segments)
|
||||
# The kernel will not ask the user
|
||||
# to specify the RAM/ROM sizes
|
||||
PR_SEGTRANS = 0x020000 # the processor module supports
|
||||
# the segment translation feature
|
||||
# (it means it calculates the code
|
||||
# addresses using the map_code_ea() function)
|
||||
PR_CHK_XREF = 0x040000 # don't allow near xrefs between segments
|
||||
# with different bases
|
||||
PR_NO_SEGMOVE = 0x080000 # the processor module doesn't support move_segm()
|
||||
# (i.e. the user can't move segments)
|
||||
PR_USE_ARG_TYPES = 0x200000 # use ph.use_arg_types callback
|
||||
PR_SCALE_STKVARS = 0x400000 # use ph.get_stkvar_scale callback
|
||||
PR_DELAYED = 0x800000 # has delayed jumps and calls
|
||||
PR_ALIGN_INSN = 0x1000000 # allow ida to create alignment instructions
|
||||
# arbirtrarily. Since these instructions
|
||||
# might lead to other wrong instructions
|
||||
# and spoil the listing, IDA does not create
|
||||
# them by default anymore
|
||||
PR_PURGING = 0x2000000 # there are calling conventions which may
|
||||
# purge bytes from the stack
|
||||
PR_CNDINSNS = 0x4000000 # has conditional instructions
|
||||
PR_USE_TBYTE = 0x8000000 # BTMT_SPECFLT means _TBYTE type
|
||||
PR_DEFSEG64 = 0x10000000 # segments are 64-bit by default
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# instruc_t related constants
|
||||
|
||||
#
|
||||
# instruc_t.feature
|
||||
#
|
||||
CF_STOP = 0x00001 # Instruction doesn't pass execution to the next instruction
|
||||
CF_CALL = 0x00002 # CALL instruction (should make a procedure here)
|
||||
CF_CHG1 = 0x00004 # The instruction modifies the first operand
|
||||
CF_CHG2 = 0x00008 # The instruction modifies the second operand
|
||||
CF_CHG3 = 0x00010 # The instruction modifies the third operand
|
||||
CF_CHG4 = 0x00020 # The instruction modifies 4 operand
|
||||
CF_CHG5 = 0x00040 # The instruction modifies 5 operand
|
||||
CF_CHG6 = 0x00080 # The instruction modifies 6 operand
|
||||
CF_USE1 = 0x00100 # The instruction uses value of the first operand
|
||||
CF_USE2 = 0x00200 # The instruction uses value of the second operand
|
||||
CF_USE3 = 0x00400 # The instruction uses value of the third operand
|
||||
CF_USE4 = 0x00800 # The instruction uses value of the 4 operand
|
||||
CF_USE5 = 0x01000 # The instruction uses value of the 5 operand
|
||||
CF_USE6 = 0x02000 # The instruction uses value of the 6 operand
|
||||
CF_JUMP = 0x04000 # The instruction passes execution using indirect jump or call (thus needs additional analysis)
|
||||
CF_SHFT = 0x08000 # Bit-shift instruction (shl,shr...)
|
||||
CF_HLL = 0x10000 # Instruction may be present in a high level language function.
|
||||
|
||||
#
|
||||
# Set IDP options constants
|
||||
#
|
||||
IDPOPT_STR = 1 # string constant
|
||||
IDPOPT_NUM = 2 # number
|
||||
IDPOPT_BIT = 3 # bit, yes/no
|
||||
IDPOPT_FLT = 4 # float
|
||||
IDPOPT_I64 = 5 # 64bit number
|
||||
|
||||
IDPOPT_OK = 0 # ok
|
||||
IDPOPT_BADKEY = 1 # illegal keyword
|
||||
IDPOPT_BADTYPE = 2 # illegal type of value
|
||||
IDPOPT_BADVALUE = 3 # illegal value (bad range, for example)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
import ida_pro
|
||||
import ida_funcs
|
||||
import ida_segment
|
||||
import ida_ua
|
||||
class processor_t(IDP_Hooks):
|
||||
__idc_cvt_id__ = ida_idaapi.PY_ICID_OPAQUE
|
||||
|
||||
"""
|
||||
Base class for all processor module scripts
|
||||
|
||||
A processor_t instance is both an ida_idp.IDP_Hooks, and an
|
||||
ida_idp.IDB_Hooks at the same time: any method of those two classes
|
||||
can be overridden in your processor_t subclass (with the exception of
|
||||
'ida_idp.IDP_Hooks.ev_init' (replaced with processor_t.__init__),
|
||||
and 'ida_idp.IDP_Hooks.ev_term' (replaced with processor_t.__del__)).
|
||||
"""
|
||||
def __init__(self):
|
||||
IDP_Hooks.__init__(self, ida_idaapi.HBF_CALL_WITH_NEW_EXEC)
|
||||
self.idb_hooks = _processor_t_Trampoline_IDB_Hooks(self)
|
||||
|
||||
def get_idpdesc(self):
|
||||
"""
|
||||
This function must be present and should return the list of
|
||||
short processor names similar to the one in ph.psnames.
|
||||
This method can be overridden to return to the kernel a different IDP description.
|
||||
"""
|
||||
return '\x01'.join(map(lambda t: '\x01'.join(t), zip(self.plnames, self.psnames)))
|
||||
|
||||
def get_uFlag(self):
|
||||
"""Use this utility function to retrieve the 'uFlag' global variable"""
|
||||
return ida_ua.cvar.uFlag
|
||||
|
||||
def get_auxpref(self, insn):
|
||||
"""This function returns insn.auxpref value"""
|
||||
return insn.auxpref
|
||||
|
||||
def _get_idp_notifier_addr(self):
|
||||
return _ida_idp.get_idp_notifier_addr(self)
|
||||
|
||||
def _get_idp_notifier_ud_addr(self):
|
||||
return _ida_idp.get_idp_notifier_ud_addr(self)
|
||||
|
||||
def _get_idb_notifier_addr(self):
|
||||
return _ida_idp.get_idb_notifier_addr(self)
|
||||
|
||||
def _get_idb_notifier_ud_addr(self):
|
||||
return _ida_idp.get_idb_notifier_ud_addr(self.idb_hooks)
|
||||
|
||||
def _make_forced_value_wrapper(self, val, meth=None):
|
||||
def f(*args):
|
||||
if meth:
|
||||
meth(*args)
|
||||
return val
|
||||
return f
|
||||
|
||||
def _make_int_returning_wrapper(self, meth, intval=0):
|
||||
def f(*args):
|
||||
val = meth(*args)
|
||||
if val is None:
|
||||
val = intval
|
||||
return val
|
||||
return f
|
||||
|
||||
def _get_notify(self, what, unimp_val=0, imp_forced_val=None, add_prefix=True, mandatory_impl=None):
|
||||
"""
|
||||
This helper is used to implement backward-compatibility
|
||||
of pre IDA 7.3 processor_t interfaces.
|
||||
"""
|
||||
if add_prefix:
|
||||
what = "notify_%s" % what
|
||||
meth = getattr(self, what, None)
|
||||
if meth is None:
|
||||
if mandatory_impl:
|
||||
raise Exception("processor_t.%s() must be implemented" % mandatory_impl)
|
||||
meth = self._make_forced_value_wrapper(unimp_val)
|
||||
else:
|
||||
if imp_forced_val is not None:
|
||||
meth = self._make_forced_value_wrapper(imp_forced_val, meth)
|
||||
else:
|
||||
meth = self._make_int_returning_wrapper(meth)
|
||||
return meth
|
||||
|
||||
# The default implementations below are what guarantees that
|
||||
# pre IDA 7.3 processor_t subclasses, will continue working
|
||||
|
||||
def ev_newprc(self, *args):
|
||||
return self._get_notify("newprc")(*args)
|
||||
|
||||
def ev_newfile(self, *args):
|
||||
return self._get_notify("newfile")(*args)
|
||||
|
||||
def ev_oldfile(self, *args):
|
||||
return self._get_notify("oldfile")(*args)
|
||||
|
||||
def ev_newbinary(self, *args):
|
||||
return self._get_notify("newbinary")(*args)
|
||||
|
||||
def ev_endbinary(self, *args):
|
||||
return self._get_notify("endbinary")(*args)
|
||||
|
||||
def ev_set_idp_options(self, keyword, value_type, value, idb_loaded):
|
||||
res = self._get_notify("set_idp_options", unimp_val=None)(keyword, value_type, value)
|
||||
if res is None:
|
||||
return 0
|
||||
return 1 if res == IDPOPT_OK else -1
|
||||
|
||||
def ev_set_proc_options(self, *args):
|
||||
return self._get_notify("set_proc_options")(*args)
|
||||
|
||||
def ev_ana_insn(self, *args):
|
||||
rc = self._get_notify("ana", mandatory_impl="ev_ana_insn")(*args)
|
||||
return rc > 0
|
||||
|
||||
def ev_emu_insn(self, *args):
|
||||
rc = self._get_notify("emu", mandatory_impl="ev_emu_insn")(*args)
|
||||
return rc > 0
|
||||
|
||||
def ev_out_header(self, *args):
|
||||
return self._get_notify("out_header", imp_forced_val=1)(*args)
|
||||
|
||||
def ev_out_footer(self, *args):
|
||||
return self._get_notify("out_footer", imp_forced_val=1)(*args)
|
||||
|
||||
def ev_out_segstart(self, ctx, s):
|
||||
return self._get_notify("out_segstart", imp_forced_val=1)(ctx, s.start_ea)
|
||||
|
||||
def ev_out_segend(self, ctx, s):
|
||||
return self._get_notify("out_segend", imp_forced_val=1)(ctx, s.end_ea)
|
||||
|
||||
def ev_out_assumes(self, *args):
|
||||
return self._get_notify("out_assumes", imp_forced_val=1)(*args)
|
||||
|
||||
def ev_out_insn(self, *args):
|
||||
return self._get_notify("out_insn", mandatory_impl="ev_out_insn", imp_forced_val=True)(*args)
|
||||
|
||||
def ev_out_mnem(self, *args):
|
||||
return self._get_notify("out_mnem", add_prefix=False, imp_forced_val=1)(*args)
|
||||
|
||||
def ev_out_operand(self, *args):
|
||||
rc = self._get_notify("out_operand", mandatory_impl="ev_out_operand", imp_forced_val=1)(*args)
|
||||
return rc > 0
|
||||
|
||||
def ev_out_data(self, *args):
|
||||
return self._get_notify("out_data", imp_forced_val=1)(*args)
|
||||
|
||||
def ev_out_label(self, *args):
|
||||
return self._get_notify("out_label")(*args)
|
||||
|
||||
def ev_out_special_item(self, *args):
|
||||
return self._get_notify("out_special_item")(*args)
|
||||
|
||||
def ev_gen_regvar_def(self, ctx, v):
|
||||
return self._get_notify("gen_regvar_def")(ctx, v.canon, v.user, v.cmt)
|
||||
|
||||
def ev_gen_src_file_lnnum(self, *args):
|
||||
return self._get_notify("gen_src_file_lnnum")(*args)
|
||||
|
||||
def ev_creating_segm(self, s):
|
||||
sname = ida_segment.get_visible_segm_name(s)
|
||||
sclass = ida_segment.get_segm_class(s)
|
||||
return self._get_notify("creating_segm")(s.start_ea, sname, sclass)
|
||||
|
||||
def ev_moving_segm(self, s, to_ea, flags):
|
||||
sname = ida_segment.get_visible_segm_name(s)
|
||||
sclass = ida_segment.get_segm_class(s)
|
||||
return self._get_notify("moving_segm")(s.start_ea, sname, sclass, to_ea, flags)
|
||||
|
||||
def ev_coagulate(self, *args):
|
||||
return self._get_notify("coagulate")(*args)
|
||||
|
||||
def ev_undefine(self, *args):
|
||||
return self._get_notify("undefine")(*args)
|
||||
|
||||
def ev_treat_hindering_item(self, *args):
|
||||
return self._get_notify("treat_hindering_item")(*args)
|
||||
|
||||
def ev_rename(self, *args):
|
||||
return self._get_notify("rename")(*args)
|
||||
|
||||
def ev_is_far_jump(self, *args):
|
||||
rc = self._get_notify("is_far_jump", unimp_val=False)(*args)
|
||||
return 1 if rc else -1
|
||||
|
||||
def ev_is_sane_insn(self, *args):
|
||||
return self._get_notify("is_sane_insn")(*args)
|
||||
|
||||
def ev_is_call_insn(self, *args):
|
||||
return self._get_notify("is_call_insn")(*args)
|
||||
|
||||
def ev_is_ret_insn(self, *args):
|
||||
return self._get_notify("is_ret_insn")(*args)
|
||||
|
||||
def ev_may_be_func(self, *args):
|
||||
return self._get_notify("may_be_func")(*args)
|
||||
|
||||
def ev_is_basic_block_end(self, *args):
|
||||
return self._get_notify("is_basic_block_end")(*args)
|
||||
|
||||
def ev_is_indirect_jump(self, *args):
|
||||
return self._get_notify("is_indirect_jump")(*args)
|
||||
|
||||
def ev_is_insn_table_jump(self, *args):
|
||||
return self._get_notify("is_insn_table_jump")(*args)
|
||||
|
||||
def ev_is_switch(self, *args):
|
||||
rc = self._get_notify("is_switch")(*args)
|
||||
return 1 if rc else 0
|
||||
|
||||
def ev_create_switch_xrefs(self, *args):
|
||||
return self._get_notify("create_switch_xrefs", imp_forced_val=1)(*args)
|
||||
|
||||
def ev_is_align_insn(self, *args):
|
||||
return self._get_notify("is_align_insn")(*args)
|
||||
|
||||
def ev_is_alloca_probe(self, *args):
|
||||
return self._get_notify("is_alloca_probe")(*args)
|
||||
|
||||
def ev_is_sp_based(self, mode, insn, op):
|
||||
rc = self._get_notify("is_sp_based", unimp_val=None)(insn, op)
|
||||
if type(rc) == int:
|
||||
ida_pro.int_pointer.frompointer(mode).assign(rc)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def ev_can_have_type(self, *args):
|
||||
rc = self._get_notify("can_have_type")(*args)
|
||||
if rc is True:
|
||||
return 1
|
||||
elif rc is False:
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def ev_cmp_operands(self, *args):
|
||||
rc = self._get_notify("cmp_operands")(*args)
|
||||
if rc is True:
|
||||
return 1
|
||||
elif rc is False:
|
||||
return -1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def ev_get_operand_string(self, buf, insn, opnum):
|
||||
rc = self._get_notify("get_operand_string")(insn, opnum)
|
||||
if rc:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def ev_str2reg(self, *args):
|
||||
rc = self._get_notify("notify_str2reg", unimp_val=-1)(*args)
|
||||
return 0 if rc < 0 else rc + 1
|
||||
|
||||
def ev_get_autocmt(self, *args):
|
||||
return self._get_notify("get_autocmt")(*args)
|
||||
|
||||
def ev_func_bounds(self, _possible_return_code, pfn, max_func_end_ea):
|
||||
possible_return_code = ida_pro.int_pointer.frompointer(_possible_return_code)
|
||||
rc = self._get_notify("func_bounds", unimp_val=None)(
|
||||
possible_return_code.value(),
|
||||
pfn.start_ea,
|
||||
max_func_end_ea)
|
||||
if type(rc) == int:
|
||||
possible_return_code.assign(rc)
|
||||
return 0
|
||||
|
||||
def ev_verify_sp(self, pfn):
|
||||
return self._get_notify("verify_sp")(pfn.start_ea)
|
||||
|
||||
def ev_verify_noreturn(self, pfn):
|
||||
return self._get_notify("verify_noreturn")(pfn.start_ea)
|
||||
|
||||
def ev_create_func_frame(self, pfn):
|
||||
rc = self._get_notify("create_func_frame", imp_forced_val=1)(pfn.start_ea)
|
||||
if rc is True:
|
||||
return 1
|
||||
elif rc is False:
|
||||
return -1
|
||||
else:
|
||||
return rc
|
||||
|
||||
def ev_get_frame_retsize(self, frsize, pfn):
|
||||
rc = self._get_notify("get_frame_retsize", unimp_val=None)(pfn.start_ea)
|
||||
if type(rc) == int:
|
||||
ida_pro.int_pointer.frompointer(frsize).assign(rc)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def ev_coagulate_dref(self, from_ea, to_ea, may_define, _code_ea):
|
||||
code_ea = ida_pro.ea_pointer.frompointer(_code_ea)
|
||||
rc = self._get_notify("coagulate_dref")(from_ea, to_ea, may_define, code_ea.value())
|
||||
if rc == -1:
|
||||
return -1
|
||||
if rc != 0:
|
||||
code_ea.assign(rc)
|
||||
return 0
|
||||
|
||||
def ev_may_show_sreg(self, *args):
|
||||
return self._get_notify("may_show_sreg")(*args)
|
||||
|
||||
def ev_auto_queue_empty(self, *args):
|
||||
return self._get_notify("auto_queue_empty")(*args)
|
||||
|
||||
def ev_validate_flirt_func(self, *args):
|
||||
return self._get_notify("validate_flirt_func")(*args)
|
||||
|
||||
def ev_assemble(self, *args):
|
||||
return self._get_notify("assemble")(*args)
|
||||
|
||||
def ev_gen_map_file(self, nlines, fp):
|
||||
import ida_fpro
|
||||
qfile = ida_fpro.qfile_t_from_fp(fp)
|
||||
rc = self._get_notify("gen_map_file")(qfile)
|
||||
if rc > 0:
|
||||
ida_pro.int_pointer.frompointer(nlines).assign(rc)
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def ev_calc_step_over(self, target, ip):
|
||||
rc = self._get_notify("calc_step_over", unimp_val=None)(ip)
|
||||
if rc is not None and rc != ida_idaapi.BADADDR:
|
||||
ida_pro.ea_pointer.frompointer(target).assign(rc)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
# IDB hooks handling
|
||||
|
||||
def closebase(self, *args):
|
||||
self._get_notify("closebase")(*args)
|
||||
|
||||
def savebase(self, *args):
|
||||
self._get_notify("savebase")(*args)
|
||||
|
||||
def auto_empty(self, *args):
|
||||
self._get_notify("auto_empty")(*args)
|
||||
|
||||
def auto_empty_finally(self, *args):
|
||||
self._get_notify("auto_empty_finally")(*args)
|
||||
|
||||
def determined_main(self, *args):
|
||||
self._get_notify("determined_main")(*args)
|
||||
|
||||
def idasgn_loaded(self, *args):
|
||||
self._get_notify("load_idasgn")(*args)
|
||||
|
||||
def kernel_config_loaded(self, *args):
|
||||
self._get_notify("kernel_config_loaded")(*args)
|
||||
|
||||
def compiler_changed(self, *args):
|
||||
self._get_notify("set_compiler")(*args)
|
||||
|
||||
def segm_moved(self, from_ea, to_ea, size, changed_netmap):
|
||||
s = ida_segment.getseg(to_ea)
|
||||
sname = ida_segment.get_visible_segm_name(s)
|
||||
sclass = ida_segment.get_segm_class(s)
|
||||
self._get_notify("move_segm")(from_ea, to_ea, sname, sclass, changed_netmap)
|
||||
|
||||
def func_added(self, pfn):
|
||||
self._get_notify("add_func")(pfn.start_ea)
|
||||
|
||||
def set_func_start(self, *args):
|
||||
self._get_notify("set_func_start")(*args)
|
||||
|
||||
def set_func_end(self, *args):
|
||||
self._get_notify("set_func_end")(*args)
|
||||
|
||||
def deleting_func(self, pfn):
|
||||
self._get_notify("del_func")(pfn.start_ea)
|
||||
|
||||
def sgr_changed(self, *args):
|
||||
self._get_notify("setsgr")(*args)
|
||||
|
||||
def make_code(self, *args):
|
||||
self._get_notify("make_code")(*args)
|
||||
|
||||
def make_data(self, *args):
|
||||
self._get_notify("make_data")(*args)
|
||||
|
||||
def renamed(self, *args):
|
||||
self._get_notify("renamed")(*args)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
class __ph(object):
|
||||
id = property(lambda self: ph_get_id())
|
||||
cnbits = property(lambda self: ph_get_cnbits())
|
||||
dnbits = property(lambda self: ph_get_dnbits())
|
||||
flag = property(lambda self: ph_get_flag())
|
||||
icode_return = property(lambda self: ph_get_icode_return())
|
||||
instruc = property(lambda self: ph_get_instruc())
|
||||
instruc_end = property(lambda self: ph_get_instruc_end())
|
||||
instruc_start = property(lambda self: ph_get_instruc_start())
|
||||
reg_code_sreg = property(lambda self: ph_get_reg_code_sreg())
|
||||
reg_data_sreg = property(lambda self: ph_get_reg_data_sreg())
|
||||
reg_first_sreg = property(lambda self: ph_get_reg_first_sreg())
|
||||
reg_last_sreg = property(lambda self: ph_get_reg_last_sreg())
|
||||
regnames = property(lambda self: ph_get_regnames())
|
||||
segreg_size = property(lambda self: ph_get_segreg_size())
|
||||
tbyte_size = property(lambda self: ph_get_tbyte_size())
|
||||
version = property(lambda self: ph_get_version())
|
||||
|
||||
ph = __ph()
|
||||
|
||||
class _idp_cvar_t:
|
||||
ash = property(lambda self: get_ash())
|
||||
cvar = _idp_cvar_t()
|
||||
|
||||
#</pycode(py_idp)>
|
||||
|
||||
#<pycode_BC695(py_idp)>
|
||||
AS_NOTAB=0
|
||||
CUSTOM_CMD_ITYPE=CUSTOM_INSN_ITYPE
|
||||
InstrIsSet=has_insn_feature
|
||||
NEXTEAS_ANSWER_SIZE=0
|
||||
PR_FULL_HIFXP=0
|
||||
SETPROC_ALL=SETPROC_LOADER_NON_FATAL
|
||||
SETPROC_COMPAT=SETPROC_IDB
|
||||
SETPROC_FATAL=SETPROC_LOADER
|
||||
area_cmt_changed=range_cmt_changed
|
||||
changed_stkpnts=stkpnts_changed
|
||||
changed_struc=struc_align_changed
|
||||
changing_area_cmt=changing_range_cmt
|
||||
changing_struc=changing_struc_align
|
||||
func_tail_removed=func_tail_deleted
|
||||
get_reg_info2=get_reg_info
|
||||
ph_get_regCodeSreg=ph_get_reg_code_sreg
|
||||
ph_get_regDataSreg=ph_get_reg_data_sreg
|
||||
ph_get_regFirstSreg=ph_get_reg_first_sreg
|
||||
ph_get_regLastSreg=ph_get_reg_last_sreg
|
||||
removing_func_tail=deleting_func_tail
|
||||
segm_attrs_changed=segm_attrs_updated
|
||||
str2regf=str2reg
|
||||
def parse_reg_name(*args):
|
||||
if isinstance(args[1], reg_info_t): # 6.95: regname, reg_info_t
|
||||
regname, ri = args
|
||||
else: # 7.00: reg_info_t, regname
|
||||
ri, regname = args
|
||||
return _ida_idp.parse_reg_name(ri, regname)
|
||||
|
||||
def __call_IDP_Hooks_auto_queue_empty(cb, qtype):
|
||||
old_rc = cb(qtype)
|
||||
if old_rc == 0: # 6.95's queue not empty anymore
|
||||
rc = -1 # 7.0's queue not empty anymore
|
||||
else:
|
||||
rc = old_rc
|
||||
return rc
|
||||
|
||||
import ida_ida
|
||||
ida_ida.__wrap_695_hooks_callback(
|
||||
IDP_Hooks,
|
||||
"ev_auto_queue_empty",
|
||||
"auto_queue_empty",
|
||||
__call_IDP_Hooks_auto_queue_empty)
|
||||
|
||||
#</pycode_BC695(py_idp)>
|
||||
-313
@@ -1,313 +0,0 @@
|
||||
# @arnaud drop this file?
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
# Misc constants
|
||||
#
|
||||
UA_MAXOP = 8
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# instruc_t related constants
|
||||
|
||||
#
|
||||
# instruc_t.feature
|
||||
#
|
||||
CF_STOP = 0x00001 # Instruction doesn't pass execution to the next instruction
|
||||
CF_CALL = 0x00002 # CALL instruction (should make a procedure here)
|
||||
CF_CHG1 = 0x00004 # The instruction modifies the first operand
|
||||
CF_CHG2 = 0x00008 # The instruction modifies the second operand
|
||||
CF_CHG3 = 0x00010 # The instruction modifies the third operand
|
||||
CF_CHG4 = 0x00020 # The instruction modifies 4 operand
|
||||
CF_CHG5 = 0x00040 # The instruction modifies 5 operand
|
||||
CF_CHG6 = 0x00080 # The instruction modifies 6 operand
|
||||
CF_USE1 = 0x00100 # The instruction uses value of the first operand
|
||||
CF_USE2 = 0x00200 # The instruction uses value of the second operand
|
||||
CF_USE3 = 0x00400 # The instruction uses value of the third operand
|
||||
CF_USE4 = 0x00800 # The instruction uses value of the 4 operand
|
||||
CF_USE5 = 0x01000 # The instruction uses value of the 5 operand
|
||||
CF_USE6 = 0x02000 # The instruction uses value of the 6 operand
|
||||
CF_JUMP = 0x04000 # The instruction passes execution using indirect jump or call (thus needs additional analysis)
|
||||
CF_SHFT = 0x08000 # Bit-shift instruction (shl,shr...)
|
||||
CF_HLL = 0x10000 # Instruction may be present in a high level language function.
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# op_t related constants
|
||||
|
||||
#
|
||||
# op_t.type
|
||||
# Description Data field
|
||||
o_void = 0 # No Operand ----------
|
||||
o_reg = 1 # General Register (al,ax,es,ds...) reg
|
||||
o_mem = 2 # Direct Memory Reference (DATA) addr
|
||||
o_phrase = 3 # Memory Ref [Base Reg + Index Reg] phrase
|
||||
o_displ = 4 # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr
|
||||
o_imm = 5 # Immediate Value value
|
||||
o_far = 6 # Immediate Far Address (CODE) addr
|
||||
o_near = 7 # Immediate Near Address (CODE) addr
|
||||
o_idpspec0 = 8 # Processor specific type
|
||||
o_idpspec1 = 9 # Processor specific type
|
||||
o_idpspec2 = 10 # Processor specific type
|
||||
o_idpspec3 = 11 # Processor specific type
|
||||
o_idpspec4 = 12 # Processor specific type
|
||||
o_idpspec5 = 13 # Processor specific type
|
||||
# There can be more processor specific types
|
||||
|
||||
#
|
||||
# op_t.dtype
|
||||
#
|
||||
dt_byte = 0 # 8 bit
|
||||
dt_word = 1 # 16 bit
|
||||
dt_dword = 2 # 32 bit
|
||||
dt_float = 3 # 4 byte floating point
|
||||
dt_double = 4 # 8 byte floating point
|
||||
dt_tbyte = 5 # variable size (ph.tbyte_size) floating point
|
||||
dt_packreal = 6 # packed real format for mc68040
|
||||
dt_qword = 7 # 64 bit
|
||||
dt_byte16 = 8 # 128 bit
|
||||
dt_code = 9 # ptr to code (not used?)
|
||||
dt_void = 10 # none
|
||||
dt_fword = 11 # 48 bit
|
||||
dt_bitfild = 12 # bit field (mc680x0)
|
||||
dt_string = 13 # pointer to asciiz string
|
||||
dt_unicode = 14 # pointer to unicode string
|
||||
dt_ldbl = 15 # long double (which may be different from tbyte)
|
||||
dt_byte32 = 16 # 256 bit
|
||||
dt_byte64 = 17 # 512 bit
|
||||
dt_half = 18 # 2 byte floating point
|
||||
|
||||
#
|
||||
# op_t.flags
|
||||
#
|
||||
OF_NO_BASE_DISP = 0x80 # o_displ: base displacement doesn't exist meaningful only for o_displ type if set, base displacement (x.addr) doesn't exist.
|
||||
OF_OUTER_DISP = 0x40 # o_displ: outer displacement exists meaningful only for o_displ type if set, outer displacement (x.value) exists.
|
||||
PACK_FORM_DEF = 0x20 # !o_reg + dt_packreal: packed factor defined
|
||||
OF_NUMBER = 0x10 # can be output as number only if set, the operand can be converted to a number only
|
||||
OF_SHOW = 0x08 # should the operand be displayed? if clear, the operand is hidden and should not be displayed
|
||||
|
||||
#
|
||||
# insn_t.flags
|
||||
#
|
||||
INSN_MACRO = 0x01 # macro instruction
|
||||
INSN_MODMAC = 0x02 # macros: may modify the database to make room for the macro insn
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# asm_t related constants
|
||||
|
||||
#
|
||||
# asm_t.flag
|
||||
#
|
||||
AS_OFFST = 0x00000001 # offsets are 'offset xxx' ?
|
||||
AS_COLON = 0x00000002 # create colons after data names ?
|
||||
AS_UDATA = 0x00000004 # can use '?' in data directives
|
||||
|
||||
AS_2CHRE = 0x00000008 # double char constants are: "xy
|
||||
AS_NCHRE = 0x00000010 # char constants are: 'x
|
||||
AS_N2CHR = 0x00000020 # can't have 2 byte char consts
|
||||
|
||||
# ASCII directives:
|
||||
AS_1TEXT = 0x00000040 # 1 text per line, no bytes
|
||||
AS_NHIAS = 0x00000080 # no characters with high bit
|
||||
AS_NCMAS = 0x00000100 # no commas in ascii directives
|
||||
|
||||
AS_HEXFM = 0x00000E00 # format of hex numbers:
|
||||
ASH_HEXF0 = 0x00000000 # 34h
|
||||
ASH_HEXF1 = 0x00000200 # h'34
|
||||
ASH_HEXF2 = 0x00000400 # 34
|
||||
ASH_HEXF3 = 0x00000600 # 0x34
|
||||
ASH_HEXF4 = 0x00000800 # $34
|
||||
ASH_HEXF5 = 0x00000A00 # <^R > (radix)
|
||||
AS_DECFM = 0x00003000 # format of dec numbers:
|
||||
ASD_DECF0 = 0x00000000 # 34
|
||||
ASD_DECF1 = 0x00001000 # #34
|
||||
ASD_DECF2 = 0x00002000 # 34.
|
||||
ASD_DECF3 = 0x00003000 # .34
|
||||
AS_OCTFM = 0x0001C000 # format of octal numbers:
|
||||
ASO_OCTF0 = 0x00000000 # 123o
|
||||
ASO_OCTF1 = 0x00004000 # 0123
|
||||
ASO_OCTF2 = 0x00008000 # 123
|
||||
ASO_OCTF3 = 0x0000C000 # @123
|
||||
ASO_OCTF4 = 0x00010000 # o'123
|
||||
ASO_OCTF5 = 0x00014000 # 123q
|
||||
ASO_OCTF6 = 0x00018000 # ~123
|
||||
AS_BINFM = 0x000E0000 # format of binary numbers:
|
||||
ASB_BINF0 = 0x00000000 # 010101b
|
||||
ASB_BINF1 = 0x00020000 # ^B010101
|
||||
ASB_BINF2 = 0x00040000 # %010101
|
||||
ASB_BINF3 = 0x00060000 # 0b1010101
|
||||
ASB_BINF4 = 0x00080000 # b'1010101
|
||||
ASB_BINF5 = 0x000A0000 # b'1010101'
|
||||
|
||||
AS_UNEQU = 0x00100000 # replace undefined data items
|
||||
# with EQU (for ANTA's A80)
|
||||
AS_ONEDUP = 0x00200000 # One array definition per line
|
||||
AS_NOXRF = 0x00400000 # Disable xrefs during the output file generation
|
||||
AS_XTRNTYPE = 0x00800000 # Assembler understands type of extrn
|
||||
# symbols as ":type" suffix
|
||||
AS_RELSUP = 0x01000000 # Checkarg: 'and','or','xor' operations
|
||||
# with addresses are possible
|
||||
AS_LALIGN = 0x02000000 # Labels at "align" keyword
|
||||
# are supported.
|
||||
AS_NOCODECLN = 0x04000000 # don't create colons after code names
|
||||
AS_NOTAB = 0x08000000 # Disable tabulation symbols during the output file generation
|
||||
AS_NOSPACE = 0x10000000 # No spaces in expressions
|
||||
AS_ALIGN2 = 0x20000000 # .align directive expects an exponent rather than a power of 2
|
||||
# (.align 5 means to align at 32byte boundary)
|
||||
AS_ASCIIC = 0x40000000 # ascii directive accepts C-like
|
||||
# escape sequences (\n,\x01 and similar)
|
||||
AS_ASCIIZ = 0x80000000 # ascii directive inserts implicit
|
||||
# zero byte at the end
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# processor_t related constants
|
||||
|
||||
IDP_INTERFACE_VERSION = 76
|
||||
CUSTOM_INSN_ITYPE = 0x8000
|
||||
REG_SPOIL = 0x80000000
|
||||
|
||||
REAL_ERROR_FORMAT = -1 # not supported format for current .idp
|
||||
REAL_ERROR_RANGE = -2 # number too big (small) for store (mem NOT modifyed)
|
||||
REAL_ERROR_BADDATA = -3 # illegal real data for load (IEEE data not filled)
|
||||
|
||||
#
|
||||
# Check whether the operand is relative to stack pointer or frame pointer.
|
||||
# This function is used to determine how to output a stack variable
|
||||
# This function may be absent. If it is absent, then all operands
|
||||
# are sp based by default.
|
||||
# Define this function only if some stack references use frame pointer
|
||||
# instead of stack pointer.
|
||||
# returns flags:
|
||||
OP_FP_BASED = 0x00000000 # operand is FP based
|
||||
OP_SP_BASED = 0x00000001 # operand is SP based
|
||||
OP_SP_ADD = 0x00000000 # operand value is added to the pointer
|
||||
OP_SP_SUB = 0x00000002 # operand value is substracted from the pointer
|
||||
|
||||
#
|
||||
# processor_t.flag
|
||||
#
|
||||
PR_SEGS = 0x000001 # has segment registers?
|
||||
PR_USE32 = 0x000002 # supports 32-bit addressing?
|
||||
PR_DEFSEG32 = 0x000004 # segments are 32-bit by default
|
||||
PR_RNAMESOK = 0x000008 # allow to user register names for location names
|
||||
PR_ADJSEGS = 0x000020 # IDA may adjust segments moving their starting/ending addresses.
|
||||
PR_DEFNUM = 0x0000C0 # default number representation:
|
||||
PRN_HEX = 0x000000 # hex
|
||||
PRN_OCT = 0x000040 # octal
|
||||
PRN_DEC = 0x000080 # decimal
|
||||
PRN_BIN = 0x0000C0 # binary
|
||||
PR_WORD_INS = 0x000100 # instruction codes are grouped 2bytes in binrary line prefix
|
||||
PR_NOCHANGE = 0x000200 # The user can't change segments and code/data attributes (display only)
|
||||
PR_ASSEMBLE = 0x000400 # Module has a built-in assembler and understands IDP_ASSEMBLE
|
||||
PR_ALIGN = 0x000800 # All data items should be aligned properly
|
||||
PR_TYPEINFO = 0x001000 # the processor module supports
|
||||
# type information callbacks
|
||||
# ALL OF THEM SHOULD BE IMPLEMENTED!
|
||||
PR_USE64 = 0x002000 # supports 64-bit addressing?
|
||||
PR_SGROTHER = 0x004000 # the segment registers don't contain
|
||||
# the segment selectors, something else
|
||||
PR_STACK_UP = 0x008000 # the stack grows up
|
||||
PR_BINMEM = 0x010000 # the processor module provides correct
|
||||
# segmentation for binary files
|
||||
# (i.e. it creates additional segments)
|
||||
# The kernel will not ask the user
|
||||
# to specify the RAM/ROM sizes
|
||||
PR_SEGTRANS = 0x020000 # the processor module supports
|
||||
# the segment translation feature
|
||||
# (it means it calculates the code
|
||||
# addresses using the map_code_ea() function)
|
||||
PR_CHK_XREF = 0x040000 # don't allow near xrefs between segments
|
||||
# with different bases
|
||||
PR_NO_SEGMOVE = 0x080000 # the processor module doesn't support move_segm()
|
||||
# (i.e. the user can't move segments)
|
||||
PR_USE_ARG_TYPES = 0x200000 # use ph.use_arg_types callback
|
||||
PR_SCALE_STKVARS = 0x400000 # use ph.get_stkvar_scale callback
|
||||
PR_DELAYED = 0x800000 # has delayed jumps and calls
|
||||
PR_ALIGN_INSN = 0x1000000 # allow ida to create alignment instructions
|
||||
# arbirtrarily. Since these instructions
|
||||
# might lead to other wrong instructions
|
||||
# and spoil the listing, IDA does not create
|
||||
# them by default anymore
|
||||
PR_PURGING = 0x2000000 # there are calling conventions which may
|
||||
# purge bytes from the stack
|
||||
PR_CNDINSNS = 0x4000000 # has conditional instructions
|
||||
PR_USE_TBYTE = 0x8000000 # BTMT_SPECFLT means _TBYTE type
|
||||
PR_DEFSEG64 = 0x10000000 # segments are 64-bit by default
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
OOF_SIGNMASK = 0x0003 # sign symbol (+/-) output:
|
||||
OOFS_IFSIGN = 0x0000 # output sign if needed
|
||||
OOFS_NOSIGN = 0x0001 # don't output sign, forbid the user to change the sign
|
||||
OOFS_NEEDSIGN = 0x0002 # always out sign (+-)
|
||||
OOF_SIGNED = 0x0004 # output as signed if < 0
|
||||
OOF_NUMBER = 0x0008 # always as a number
|
||||
OOF_WIDTHMASK = 0x0070 # width of value in bits:
|
||||
OOFW_IMM = 0x0000 # take from x.dtype
|
||||
OOFW_8 = 0x0010 # 8 bit width
|
||||
OOFW_16 = 0x0020 # 16 bit width
|
||||
OOFW_24 = 0x0030 # 24 bit width
|
||||
OOFW_32 = 0x0040 # 32 bit width
|
||||
OOFW_64 = 0x0050 # 32 bit width
|
||||
OOF_ADDR = 0x0080 # output x.addr, otherwise x.value
|
||||
OOF_OUTER = 0x0100 # output outer operand
|
||||
OOF_ZSTROFF = 0x0200 # meaningful only if is_stroff(uFlag)
|
||||
# append a struct field name if
|
||||
# the field offset is zero?
|
||||
# if AFL_ZSTROFF is set, then this flag
|
||||
# is ignored.
|
||||
OOF_NOBNOT = 0x0400 # prohibit use of binary not
|
||||
OOF_SPACES = 0x0800 # do not suppress leading spaces
|
||||
# currently works only for floating point numbers
|
||||
OOF_ANYSERIAL = 0x1000 # if enum: select first available serial
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
class insn_t(object):
|
||||
def __init__(self, noperands = UA_MAXOP):
|
||||
self.auxpref = 0
|
||||
self.cs = 0
|
||||
self.ea = 0
|
||||
self.flags = 0
|
||||
self.insnpref = 0
|
||||
self.ip = 0
|
||||
self.itype = 0
|
||||
self.n = 0
|
||||
self.segpref = 0
|
||||
self.size = 0
|
||||
self.ops = []
|
||||
|
||||
# store the number of operands
|
||||
self.n = noperands
|
||||
|
||||
# create operands
|
||||
for i in range(0, noperands):
|
||||
op = op_t()
|
||||
op.n = i
|
||||
self.ops.append(op)
|
||||
setattr(self, 'Op%d' % (i+1), op)
|
||||
def __getitem__(self, i):
|
||||
return self.ops[i]
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
class op_t(object):
|
||||
def __init__(self):
|
||||
self.addr = 0
|
||||
self.dtype = 0
|
||||
self.flags = 0
|
||||
self.n = 0
|
||||
self.offb = 0
|
||||
self.offo = 0
|
||||
self.reg = 0
|
||||
self.specval = 0
|
||||
self.specflag1 = 0
|
||||
self.specflag2 = 0
|
||||
self.specflag3 = 0
|
||||
self.specflag4 = 0
|
||||
self.type = 0
|
||||
self.value = 0
|
||||
|
||||
# make sure reg and phrase have the same value
|
||||
def __setattr__(self, name, value):
|
||||
if name == 'reg' or name == 'phrase':
|
||||
object.__setattr__(self, 'reg', value)
|
||||
object.__setattr__(self, 'phrase', value)
|
||||
else:
|
||||
object.__setattr__(self, name, value)
|
||||
+156
-290
File diff suppressed because it is too large
Load Diff
+156
-290
File diff suppressed because it is too large
Load Diff
@@ -1,42 +0,0 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import re
|
||||
import string
|
||||
|
||||
try:
|
||||
from argparse import ArgumentParser
|
||||
except:
|
||||
print("Failed to import module 'argparse'. Upgrade to Python 2.7, copy argparse.py to this directory or try 'apt-get install python-argparse'")
|
||||
raise
|
||||
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("-i", "--input", required=True)
|
||||
parser.add_argument("-o", "--output", required=True)
|
||||
parser.add_argument("-d", "--decls", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.input) as fin:
|
||||
template = string.Template(fin.read())
|
||||
|
||||
with open(args.decls) as fin:
|
||||
raw = fin.read()
|
||||
pat = re.compile(r"^#\s*define\s+(PLFM_[A-Za-z0-9_]*)\s+([0-9x]*)\s*(.*)$")
|
||||
decls = []
|
||||
for line in raw.split("\n"):
|
||||
m = pat.match(line)
|
||||
if m:
|
||||
proc = m.group(1)
|
||||
value = m.group(2)
|
||||
cmt = None
|
||||
rest = m.group(3)
|
||||
rest_cmt = rest.find("///<")
|
||||
if rest_cmt > -1:
|
||||
cmt = rest[rest_cmt+4:].strip()
|
||||
decls.append("{:20s} = {:8s} # {:s}".format(proc, value, cmt or "?"))
|
||||
kvps = {
|
||||
"PLFM_DECLS" : "\n".join(decls)
|
||||
}
|
||||
|
||||
with open(args.output, "w") as fout:
|
||||
fout.write(template.substitute(kvps))
|
||||
|
||||
Reference in New Issue
Block a user