IDAPython for IDA 6.95: Initial commit

This commit is contained in:
Arnaud Diederen
2016-08-09 10:01:18 +02:00
parent c04b70e0e5
commit 62ddab8db6
197 changed files with 11206 additions and 12091 deletions
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
+165 -7
View File
@@ -95,6 +95,7 @@
'IDP_Hooks_add_dref',
'IDP_Hooks_add_func',
'IDP_Hooks_adjust_libfunc_ea',
'IDP_Hooks_adjust_refinfo',
'IDP_Hooks_assemble',
'IDP_Hooks_auto_empty',
'IDP_Hooks_auto_empty_finally',
@@ -140,7 +141,6 @@
'IDP_Hooks_get_func_cvtarg_map',
'IDP_Hooks_get_jump_target',
'IDP_Hooks_get_macro_insn_head',
'IDP_Hooks_get_operand_info',
'IDP_Hooks_get_operand_string',
'IDP_Hooks_get_reg_info2',
'IDP_Hooks_get_reg_name',
@@ -164,7 +164,6 @@
'IDP_Hooks_kernel_config_loaded',
'IDP_Hooks_load_idasgn',
'IDP_Hooks_loader',
'IDP_Hooks_loader_elf_machine',
'IDP_Hooks_loader_finished',
'IDP_Hooks_make_code',
'IDP_Hooks_make_data',
@@ -179,7 +178,6 @@
'IDP_Hooks_newfile',
'IDP_Hooks_newprc',
'IDP_Hooks_newseg',
'IDP_Hooks_obsolete_get_operand_info',
'IDP_Hooks_obsolete_makemicro',
'IDP_Hooks_oldfile',
'IDP_Hooks_out_3byte',
@@ -283,6 +281,7 @@
'_askseg',
'_askseg__varargs__',
'_decompile',
'_kludge_use_TPopupMenu',
'a2funcoff',
'accepts_udts',
'action_ctx_base_t_action_get',
@@ -341,6 +340,7 @@
'add_const',
'add_cref',
'add_custom_viewer_popup_item',
'add_custom_viewer_popup_item__SWIG_1',
'add_dref',
'add_encoding',
'add_entry',
@@ -416,6 +416,7 @@
'append_func_tail',
'append_name',
'append_struct_fields2',
'append_tinfo_covered',
'append_varloc',
'apply_callee_tinfo',
'apply_cdecl',
@@ -557,6 +558,7 @@
'argloc_t_is_custom',
'argloc_t_is_ea',
'argloc_t_is_fragmented',
'argloc_t_is_mixed_scattered',
'argloc_t_is_reg',
'argloc_t_is_reg1',
'argloc_t_is_reg2',
@@ -992,10 +994,9 @@
'calc_reference_target',
'calc_stkvar_struc_offset',
'calc_switch_cases',
'calc_switch_cases__SWIG_0',
'calc_switch_cases__SWIG_1',
'calc_target',
'calc_thunk_func_target',
'calc_tinfo_gaps',
'calc_type_size',
'calc_varloc_info',
'calcexpr',
@@ -1456,6 +1457,7 @@
'cinsn_t_creturn_get',
'cinsn_t_cswitch_get',
'cinsn_t_cwhile_get',
'cinsn_t_is_epilog',
'cinsn_t_is_ordinary_flow',
'cinsn_t_new_insn',
'cinsn_t_print1',
@@ -1540,6 +1542,7 @@
'citem_t_print1',
'citem_t_swap',
'cleanup_appcall',
'cleanup_name',
'cleanup_varloc',
'clearBreak',
'clear_cached_cfuncs',
@@ -1599,7 +1602,8 @@
'codeflag',
'compact_til',
'compare',
'compare__SWIG_0',
'compare',
'compare',
'compare__SWIG_1',
'compare__SWIG_12',
'compare__SWIG_13',
@@ -1621,6 +1625,7 @@
'compare__SWIG_28',
'compare__SWIG_29',
'compare__SWIG_3',
'compare__SWIG_3',
'compare__SWIG_30',
'compare__SWIG_4',
'compare__SWIG_5',
@@ -1657,6 +1662,7 @@
'convert_argloc_to_varloc',
'convert_encoding',
'convert_pt_flags_to_hti',
'convert_to_user_call',
'convert_varloc_to_argloc',
'copy_srareas',
'copy_tinfo_t',
@@ -1672,6 +1678,7 @@
'create_helper__varargs__',
'create_insn',
'create_memory_linput',
'create_menu',
'create_numbered_type_name',
'create_numbered_type_reference',
'create_source_viewer',
@@ -1679,6 +1686,7 @@
'create_switch_xrefs',
'create_tform',
'create_tinfo',
'create_toolbar',
'create_typedef',
'create_typedef__SWIG_0',
'create_typedef__SWIG_1',
@@ -2113,6 +2121,10 @@
'delete_lvar_uservec_t',
'delete_lvars_t',
'delete_member_t',
'delete_memreg_info_t',
'delete_memreg_infos_t',
'delete_menu',
'delete_microcode_filter_t',
'delete_module_info_t',
'delete_netnode',
'delete_node_info_t',
@@ -2140,6 +2152,7 @@
'delete_refinfo_t',
'delete_reg_info_t',
'delete_regarg_t',
'delete_reginfovec_t',
'delete_regobj_t',
'delete_regobjs_t',
'delete_regval_t',
@@ -2178,6 +2191,7 @@
'delete_til_t',
'delete_tinfo_t',
'delete_tinfo_visitor_t',
'delete_toolbar',
'delete_treeloc_t',
'delete_twinpos_t',
'delete_type_attr_t',
@@ -2188,6 +2202,9 @@
'delete_type_visitor_t',
'delete_typedef_type_data_t',
'delete_uchar_array',
'delete_udc_filter_t',
'delete_udcall_map_iterator_t',
'delete_udcall_t',
'delete_udt_member_t',
'delete_udt_type_data_t',
'delete_udtmembervec_t',
@@ -2299,9 +2316,11 @@
'disown_ctree_visitor_t',
'disown_enum_member_visitor_t',
'disown_highlighter_cbs_t',
'disown_microcode_filter_t',
'disown_struct_field_visitor_t',
'disown_text_sink_t',
'disown_tinfo_visitor_t',
'disown_udc_filter_t',
'disown_user_lvar_modifier_t',
'display_complex_call_chart',
'display_copyright_warning',
@@ -2906,6 +2925,7 @@
'get_c_header_path',
'get_c_macros',
'get_call_tev_callee',
'get_chooser_data',
'get_chooser_obj',
'get_cmt',
'get_colored_demangled_name',
@@ -3077,6 +3097,7 @@
'get_hidden_area_num',
'get_hidden_area_qty',
'get_highlighted_identifier',
'get_ida_subdirs',
'get_idainfo_by_type',
'get_idainfo_by_type2',
'get_idainfo_by_type3',
@@ -3230,6 +3251,7 @@
'get_reg_name',
'get_reg_val',
'get_reg_vals',
'get_registered_actions',
'get_ret_tev_return',
'get_root_filename',
'get_running_notification',
@@ -3318,7 +3340,6 @@
'get_tev_info',
'get_tev_memory_info',
'get_tev_qty',
'get_tev_reg_mem',
'get_tev_reg_mem_ea',
'get_tev_reg_mem_qty',
'get_tev_reg_val',
@@ -3561,6 +3582,7 @@
'idainfo_is_64bit',
'idainfo_is_dll',
'idainfo_is_flat_off32',
'idainfo_is_hard_float',
'idainfo_is_mem_aligned4',
'idainfo_is_snapshot',
'idainfo_lenxref_get',
@@ -3799,6 +3821,7 @@
'install_command_interpreter',
'install_extlang',
'install_hexrays_callback',
'install_microcode_filter',
'instant_dbgopts_t__pass_get',
'instant_dbgopts_t__pass_set',
'instant_dbgopts_t_attach_get',
@@ -4193,6 +4216,7 @@
'load_loader_module',
'load_plugin',
'load_til',
'load_til2',
'load_til__SWIG_0',
'load_til__SWIG_1',
'load_til_header',
@@ -4491,7 +4515,50 @@
'member_t_soff_get',
'member_t_soff_set',
'member_t_unimem',
'memreg_info_t_ea_get',
'memreg_info_t_ea_set',
'memreg_info_t_get_bytes',
'memreg_infos_t___getitem__',
'memreg_infos_t___len__',
'memreg_infos_t___setitem__',
'memreg_infos_t_at',
'memreg_infos_t_back',
'memreg_infos_t_back__SWIG_0',
'memreg_infos_t_back__SWIG_1',
'memreg_infos_t_begin',
'memreg_infos_t_begin__SWIG_0',
'memreg_infos_t_begin__SWIG_1',
'memreg_infos_t_capacity',
'memreg_infos_t_clear',
'memreg_infos_t_empty',
'memreg_infos_t_end',
'memreg_infos_t_end__SWIG_0',
'memreg_infos_t_end__SWIG_1',
'memreg_infos_t_erase',
'memreg_infos_t_erase__SWIG_0',
'memreg_infos_t_erase__SWIG_1',
'memreg_infos_t_extract',
'memreg_infos_t_front',
'memreg_infos_t_front__SWIG_0',
'memreg_infos_t_front__SWIG_1',
'memreg_infos_t_grow',
'memreg_infos_t_inject',
'memreg_infos_t_insert',
'memreg_infos_t_pop_back',
'memreg_infos_t_push_back',
'memreg_infos_t_push_back__SWIG_0',
'memreg_infos_t_push_back__SWIG_1',
'memreg_infos_t_qclear',
'memreg_infos_t_reserve',
'memreg_infos_t_resize',
'memreg_infos_t_resize__SWIG_0',
'memreg_infos_t_resize__SWIG_1',
'memreg_infos_t_size',
'memreg_infos_t_swap',
'memreg_infos_t_truncate',
'micro_err_format',
'microcode_filter_t_apply',
'microcode_filter_t_match',
'modify_user_lvars',
'module_info_t_base_get',
'module_info_t_base_set',
@@ -4634,6 +4701,8 @@
'new_argloc_t__SWIG_0',
'new_argloc_t__SWIG_1',
'new_argpart_t',
'new_argpart_t__SWIG_0',
'new_argpart_t__SWIG_1',
'new_array_parameters_t',
'new_array_type_data_t',
'new_asm_t',
@@ -4841,6 +4910,11 @@
'new_lvar_uservec_t',
'new_lvars_t',
'new_member_t',
'new_memreg_info_t',
'new_memreg_infos_t',
'new_memreg_infos_t__SWIG_0',
'new_memreg_infos_t__SWIG_1',
'new_microcode_filter_t',
'new_module_info_t',
'new_netnode',
'new_netnode__SWIG_0',
@@ -4888,6 +4962,9 @@
'new_refinfo_t',
'new_reg_info_t',
'new_regarg_t',
'new_reginfovec_t',
'new_reginfovec_t__SWIG_0',
'new_reginfovec_t__SWIG_1',
'new_regobj_t',
'new_regobjs_t',
'new_regval_t',
@@ -4954,6 +5031,9 @@
'new_typedef_type_data_t__SWIG_0',
'new_typedef_type_data_t__SWIG_1',
'new_uchar_array',
'new_udc_filter_t',
'new_udcall_map_iterator_t',
'new_udcall_t',
'new_udt_member_t',
'new_udt_type_data_t',
'new_udtmembervec_t',
@@ -5198,6 +5278,7 @@
'parse_decls',
'parse_reg_name',
'parse_types2',
'parse_user_call',
'partial_type_num',
'patch_byte',
'patch_long',
@@ -5798,6 +5879,52 @@
'regarg_t_reg_set',
'regarg_t_type_get',
'regarg_t_type_set',
'reginfovec_t___eq__',
'reginfovec_t___getitem__',
'reginfovec_t___len__',
'reginfovec_t___ne__',
'reginfovec_t___setitem__',
'reginfovec_t__del',
'reginfovec_t_add_unique',
'reginfovec_t_at',
'reginfovec_t_back',
'reginfovec_t_back__SWIG_0',
'reginfovec_t_back__SWIG_1',
'reginfovec_t_begin',
'reginfovec_t_begin__SWIG_0',
'reginfovec_t_begin__SWIG_1',
'reginfovec_t_capacity',
'reginfovec_t_clear',
'reginfovec_t_empty',
'reginfovec_t_end',
'reginfovec_t_end__SWIG_0',
'reginfovec_t_end__SWIG_1',
'reginfovec_t_erase',
'reginfovec_t_erase__SWIG_0',
'reginfovec_t_erase__SWIG_1',
'reginfovec_t_extract',
'reginfovec_t_find',
'reginfovec_t_find__SWIG_0',
'reginfovec_t_find__SWIG_1',
'reginfovec_t_front',
'reginfovec_t_front__SWIG_0',
'reginfovec_t_front__SWIG_1',
'reginfovec_t_grow',
'reginfovec_t_has',
'reginfovec_t_inject',
'reginfovec_t_insert',
'reginfovec_t_pop_back',
'reginfovec_t_push_back',
'reginfovec_t_push_back__SWIG_0',
'reginfovec_t_push_back__SWIG_1',
'reginfovec_t_qclear',
'reginfovec_t_reserve',
'reginfovec_t_resize',
'reginfovec_t_resize__SWIG_0',
'reginfovec_t_resize__SWIG_1',
'reginfovec_t_size',
'reginfovec_t_swap',
'reginfovec_t_truncate',
'register_action',
'register_addon',
'register_and_attach_to_menu',
@@ -5924,6 +6051,7 @@
'resolve_typedef2',
'restore_database_snapshot',
'restore_user_cmts',
'restore_user_defined_calls',
'restore_user_iflags',
'restore_user_labels',
'restore_user_lvar_settings',
@@ -5952,6 +6080,7 @@
'save_tinfo',
'save_trace_file',
'save_user_cmts',
'save_user_defined_calls',
'save_user_iflags',
'save_user_labels',
'save_user_lvar_settings',
@@ -6127,6 +6256,7 @@
'set_const_cmt',
'set_const_name',
'set_custom_data_type_ids',
'set_custom_fixup_ex',
'set_custom_viewer_qt_aware',
'set_dbg_default_options',
'set_dbg_options',
@@ -6541,6 +6671,8 @@
'tinfo_t___ne__',
'tinfo_t___str__',
'tinfo_t__print',
'tinfo_t_append_covered',
'tinfo_t_calc_gaps',
'tinfo_t_calc_purged_bytes',
'tinfo_t_calc_score',
'tinfo_t_calc_udt_aligns',
@@ -6717,6 +6849,7 @@
'tinfo_t_set_const',
'tinfo_t_set_declalign',
'tinfo_t_set_modifiers',
'tinfo_t_set_named_type',
'tinfo_t_set_numbered_type',
'tinfo_t_set_volatile',
'tinfo_t_swap',
@@ -6797,6 +6930,30 @@
'uchar_array___setitem__',
'uchar_array_cast',
'uchar_array_frompointer',
'udc_filter_t_apply',
'udc_filter_t_init',
'udc_filter_t_match',
'udcall_map_begin',
'udcall_map_clear',
'udcall_map_end',
'udcall_map_erase',
'udcall_map_find',
'udcall_map_first',
'udcall_map_free',
'udcall_map_insert',
'udcall_map_iterator_t___eq__',
'udcall_map_iterator_t___ne__',
'udcall_map_iterator_t_x_get',
'udcall_map_iterator_t_x_set',
'udcall_map_new',
'udcall_map_next',
'udcall_map_prev',
'udcall_map_second',
'udcall_map_size',
'udcall_t_name_get',
'udcall_t_name_set',
'udcall_t_tif_get',
'udcall_t_tif_set',
'udt_member_t___eq__',
'udt_member_t___lt__',
'udt_member_t___ne__',
@@ -6833,6 +6990,7 @@
'udt_type_data_t_effalign_get',
'udt_type_data_t_effalign_set',
'udt_type_data_t_is_cppobj',
'udt_type_data_t_is_last_baseclass',
'udt_type_data_t_is_msstruct',
'udt_type_data_t_is_unaligned',
'udt_type_data_t_is_union_get',
-4
View File
@@ -1,4 +0,0 @@
#ifndef _BASETSD_H
#define _BASETSD_H
/* Microsoft free compilers seem to lack this file and Python needs it */
#endif
+4 -3
View File
@@ -40,6 +40,7 @@ parser.add_argument("--swig-inc", type=str, help="Path(s) to the SWIG includes d
parser.add_argument("--with-hexrays", help="Build Hex-Rays decompiler bindings (requires the 'hexrays.hpp' header to be present in the SDK's include/ directory)", default=False, action="store_true")
parser.add_argument("--debug", help="Build debug version of the plugin", default=False, action="store_true")
parser.add_argument("--python-home", help="Python home, where the 'include' directory can be found", default=None)
parser.add_argument("-j", "--parallel", action="store_true", help="Build in parallel", default=False)
parser.add_argument("-v", "--verbose", help="Verbose mode", default=False, action="store_true")
args = parser.parse_args()
@@ -58,6 +59,8 @@ def run(proc_argv, env=None):
def main():
argv = ["make"]
if args.parallel:
argv.append("-j")
env = os.environ.copy()
env["OUT_OF_TREE_BUILD"] = "1"
if args.swig_bin:
@@ -79,9 +82,7 @@ def main():
if "__EA64__" in env:
del env["__EA64__"]
print "\n### Building EAsize=%d(bit) version of the plugin" % (64 if ea64 else 32)
run(argv + ["dist"], env=env) # 'dist' depends on build phases
print "\n### Packaging"
run(argv + ["package"], env=env)
run(argv, env=env)
# -----------------------------------------------------------------------
if __name__ == "__main__":
-312
View File
@@ -1,312 +0,0 @@
from __future__ import with_statement
import sys, optparse, re, pprint
ignorable_api_contents = [
"qwait"
]
class TextStream:
def __init__(self, text):
self.text = text
self.point = 0
self.maxpoint = len(self.text)
self.line_nr = 0
self.char_nr = 0
self.curline = None
def line(self):
pt = self.point
self.advance_to_newline()
return self.text[pt : self.point]
def char(self):
c, self.point = self.text[self.point], self.point + 1
if c == '\n':
self.line_nr += 1
self.char_nr = 0
return c
def advance_to_newline(self):
p = self.point
while self.text[p] != '\n':
p += 1
p += 1
self.line_nr += 1
self.char_nr = 0
self.point = p
def empty(self):
return self.point >= self.maxpoint
if __name__ == "__main__":
p = optparse.OptionParser(description='Check the generated idaapi_include.cpp file')
p.add_option('-v', "--verbose", dest="verbose", action="store_true")
p.add_option('-f', "--file", dest="path", type="string")
p.add_option('-x', "--with-hexrays", dest="with_hexrays", action="store_true")
p.add_option('-r', "--report-contents", dest="report_contents", type="string")
opts, _ = p.parse_args(sys.argv[1:])
api_contents = {
"functions" : []
}
if not opts.path:
p.print_help()
sys.exit(1)
functions_coherence_base = {
#
# qstrvec_t: Specialized, internal, clink'ed object.
#
"_wrap_qstrvec_t_assign" : {
"mustcall" : "qstrvec_t_assign"
},
"_wrap_qstrvec_t_addressof" : {
"mustcall" : "qstrvec_t_addressof"
},
"_wrap_qstrvec_t_set" : {
"mustcall" : "qstrvec_t_set"
},
"_wrap_qstrvec_t_from_list" : {
"mustcall" : "qstrvec_t_from_list"
},
"_wrap_qstrvec_t_size" : {
"mustcall" : "qstrvec_t_size"
},
"_wrap_qstrvec_t_get" : {
"mustcall" : "qstrvec_t_get"
},
"_wrap_qstrvec_t_add" : {
"mustcall" : "qstrvec_t_add"
},
"_wrap_qstrvec_t_clear" : {
"mustcall" : "qstrvec_t_clear"
},
"_wrap_qstrvec_t_insert" : {
"mustcall" : "qstrvec_t_insert"
},
"_wrap_qstrvec_t_remove" : {
"mustcall" : "qstrvec_t_remove"
},
#
# Misc.
#
"_wrap_areacb_t_get_type" : {
"mustcall" : "get_type",
},
"_wrap_tinfo_t_deserialize__SWIG_2" : {
"mustcall" : "tinfo_t_deserialize__SWIG_2",
},
"_wrap_get_bpt_group" : {
"mustcall" : "PyString_FromStringAndSize",
},
"_wrap_get_jumptable_info" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_get_array_parameters" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_read_dbg_memory" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_write_dbg_memory" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_get_grp_bpts" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_generic_linput_t_read" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_generic_linput64_t_read64" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_linput_buffer_t_read" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_get_ptr_object_size" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_tag_strlen" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_get_next_member_idx" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
"_wrap_get_prev_member_idx" : {
"string" : "resultobj = PyLong_FromLongLong(result)",
},
# char[ANY] out typemap
"_wrap_idainfo_tag_get" : {
"nostring" : " --size;",
},
# char[ANY] varout typemap
"Swig_var_database_idb_get" : {
"nostring" : " --size;",
},
}
functions_coherence_hexrays = {
"_wrap_cfuncptr_t___str__" : {
"mustcall" : ["cfunc_t___str__", "PyString_FromStringAndSize"],
},
"_wrap_cfunc_t___str__" : {
"mustcall" : ["cfunc_t___str__", "PyString_FromStringAndSize"],
},
"_wrap_hexrays_failure_t_desc" : {
"mustcall" : "PyString_FromStringAndSize",
},
"_wrap_vd_failure_t_desc" : {
"mustcall" : "PyString_FromStringAndSize",
},
"_wrap_create_field_name" : {
"mustcall" : "PyString_FromStringAndSize",
},
"delete_qrefcnt_t_Sl_cfunc_t_Sg_" : {
"mustcall" : "hexrays_deregister_python_cfuncptr_t_instance",
},
"_wrap__decompile" : {
"mustcall" : "hexrays_register_python_cfuncptr_t_instance",
},
"_wrap_vdui_t_cfunc_get" : {
"mustcall" : "hexrays_register_python_cfuncptr_t_instance",
},
#
# qvector<simpleline_t>
#
"_wrap_strvec_t___len__" : {
"mustcall" : "qvector_Sl_simpleline_t_Sg____len__",
},
"_wrap_strvec_t___setitem__" : {
"mustcall" : "qvector_Sl_simpleline_t_Sg____setitem__",
},
"_wrap_strvec_t___getitem__" : {
"mustcall" : "qvector_Sl_simpleline_t_Sg____getitem__",
},
#
# vdui_t::cfunc
#
"_wrap_vdui_t_cfunc_get" : {
"string" : "SWIGTYPE_p_qrefcnt_tT_cfunc_t_t", # proper typemap must be used
},
}
functions_coherence = functions_coherence_base.copy()
if opts.with_hexrays:
functions_coherence.update(functions_coherence_hexrays)
# Mark all functions as not-spotted.
for fname in functions_coherence.keys():
chk = functions_coherence[fname]
chk["spotted"] = False
# Read and go through lines
with open(opts.path, "r") as f:
ts = TextStream(f.read())
def dbg(msg):
if opts.verbose:
print("DEBUG: %s" % msg)
def is_fundecl(line):
if len(line) <= 2:
return False
if line[0:1].isspace():
return False
if line[len(line)-1:] != "{":
return False
if line.find("(") == -1 or line.find(")") == -1:
return False
return True
def collect_funbody_lines(ts):
pt = ts.point
braces_cnt = 1
while True:
c = ts.char()
if c == "{":
braces_cnt = braces_cnt + 1
elif c == "}":
braces_cnt = braces_cnt - 1
if braces_cnt == 0:
break;
# TODO: Skip strings!
return ts.text[pt : ts.point].split("\n")
api_fname_regex = re.compile(".*PyObject \\*_wrap_([^\\(]*)\\(.*\\).*")
# Process lines
STATE_UNKNOWN = 0
STATE_IN_FUN = 1
state = STATE_UNKNOWN
while not ts.empty():
line = ts.line().rstrip()
# dbg("Line: '%s'" % line)
if is_fundecl(line):
# dbg("Entering function (from line %d: '%s')" % (ts.line_nr, line))
state = STATE_IN_FUN
funstart = line
match = api_fname_regex.match(funstart)
if match:
fname = match.group(1)
if fname not in ignorable_api_contents:
api_contents["functions"].append(fname)
funlines = collect_funbody_lines(ts)
# Do we care about this function?
check_for = None
for fname in functions_coherence.keys():
if funstart.find(fname + "(") > -1:
check_for = fname
break
if check_for:
dbg("Checking function at line %d: '%s'" % (ts.line_nr, check_for))
chk = functions_coherence[check_for]
chk["spotted"] = True
def look_for_stuff(stuff, isFuncall, lookForPresence=True):
if isinstance(stuff, str):
stuff = [stuff]
for bit in stuff:
found = False
bit_pat = ("%s(" % bit) if isFuncall else bit
dbg("Thing to look for: '%s'" % bit_pat)
for funline in funlines:
# dbg("Testing line: '%s'" % funline)
if funline.find(bit_pat) > -1:
found = True
break
if lookForPresence:
if not found:
raise Exception("Couldn't find '%s', from function '%s' (lines: %s)" %
(bit_pat, check_for, "\n".join([""] + funlines)))
else:
if found:
raise Exception("Did find unwanted '%s', from function '%s' (lines: %s)" %
(bit_pat, check_for, "\n".join([""] + funlines)))
if "mustcall" in chk:
look_for_stuff(chk["mustcall"], True)
if "string" in chk:
look_for_stuff(chk["string"], False)
if "nostring" in chk:
look_for_stuff(chk["nostring"], False, lookForPresence=False)
# Ensure all functions were spotted.
for fname in functions_coherence.keys():
chk = functions_coherence[fname]
if not chk["spotted"]:
raise Exception("Couldn't spot function '%s'" % fname)
# Report contents
if opts.report_contents:
# NB: we use "wb" here so that the endlines
# are written as-is, in Unix format
# and so 'diff' does not report bogus changes
# against the file from repository
with open(opts.report_contents, "wb") as f:
api_contents["functions"].sort()
f.write(pprint.pformat(api_contents))
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
-18
View File
@@ -1,18 +0,0 @@
import idaapi
def cb(*args):
print("Callback called!")
return 1
try:
ex_addmenu_item_ctx
idaapi.del_menu_item(ex_addmenu_item_ctx)
print("Menu removed")
del ex_addmenu_item_ctx
except:
ex_addmenu_item_ctx = idaapi.add_menu_item("Search/", "X", "", 0, cb, tuple("hello world"))
if ex_addmenu_item_ctx is None:
print("Failed to add menu!")
del ex_addmenu_item_ctx
else:
print("Menu added successfully. Run the script again to delete the menu")
Regular → Executable
+2
View File
@@ -50,6 +50,7 @@ Form Test
{FormChangeCb}
This is a string: +{cStr1}+
This is an address: +{cAddr1}+
This is some HTML: +{cHtml1}+
Escape\{control}
This is a string: '{cStr2}'
@@ -85,6 +86,7 @@ The end!
""", {
'cStr1': Form.StringLabel("Hello"),
'cStr2': Form.StringLabel("StringTest"),
'cHtml1': Form.StringLabel("<span style='color: red'>Is this red?<span>", tp=Form.FT_HTML_LABEL),
'cAddr1': Form.NumericLabel(0x401000, Form.FT_ADDR),
'cVal1' : Form.NumericLabel(99, Form.FT_HEX),
'iStr1': Form.StringInput(),
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
+5 -4
View File
@@ -1,5 +1,6 @@
from idaapi import PluginForm
from PyQt4 import QtCore, QtGui
from PyQt5 import QtCore, QtGui, QtWidgets
import sip
class MyPluginFormClass(PluginForm):
@@ -15,12 +16,12 @@ class MyPluginFormClass(PluginForm):
def PopulateForm(self):
# Create layout
layout = QtGui.QVBoxLayout()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(
QtGui.QLabel("Hello from <font color=red>PyQt</font>"))
QtWidgets.QLabel("Hello from <font color=red>PyQt</font>"))
layout.addWidget(
QtGui.QLabel("Hello from <font color=blue>IDAPython</font>"))
QtWidgets.QLabel("Hello from <font color=blue>IDAPython</font>"))
self.parent.setLayout(layout)
-34
View File
@@ -1,34 +0,0 @@
from idaapi import PluginForm
from PySide import QtGui, QtCore
class MyPluginFormClass(PluginForm):
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPySideWidget(form)
self.PopulateForm()
def PopulateForm(self):
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(
QtGui.QLabel("Hello from <font color=red>PySide</font>"))
layout.addWidget(
QtGui.QLabel("Hello from <font color=blue>IDAPython</font>"))
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
pass
plg = MyPluginFormClass()
plg.Show("PySide hello world")
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
+93
View File
@@ -0,0 +1,93 @@
"""
This is a crude (and not very pythonic) reimplementation of the example
hexrays plugin 'hexrays_sample6.cpp', shipped with the Hex-Rays decompiler.
It modifies the decompilation output: removes some space characters.
"""
import idautils
import idc
import ida_hexrays
import ida_lines
def dbg(msg):
#print msg
pass
def is_cident_char(c):
return c.isalnum() or c == '_'
def my_tag_skipcodes(l, storage):
n = ida_lines.tag_skipcodes(l)
dbg("Skipping %d chars ('%s')" % (n, l[0:n]))
storage.append(l[0:n])
return l[n:]
def remove_spaces(sl):
dbg("*" * 80)
l = sl.line
out = []
def push(c):
dbg("Appending '%s'" % c)
out.append(c)
# skip initial spaces, do not compress them
while True:
l = my_tag_skipcodes(l, out)
if not l:
break
c = l[0]
if not c.isspace():
break
push(c)
l = l[1:]
# remove all spaces except in string and char constants
delim = None # if not None, then we are skipping until 'delim'
last = None # last seen character
while True:
# go until comments
dbg("-" * 60)
nchars = ida_lines.tag_advance(l, 1)
push(l[0:nchars])
l = l[nchars:]
l = my_tag_skipcodes(l, out)
if not l:
break
if l.startswith("//"):
push(l)
break
c = l[0]
dbg("c: '%s', last: '%s', l: '%s'" % (c, last, l))
if delim:
# we're inside a literal.
if c == delim:
delim = None # literal ended
elif c == '"' or c == "'":
delim = c # string/char literal started
elif c.isspace():
end = l.lstrip()
nptr = my_tag_skipcodes(end, out)
dbg("end: '%s', nptr: '%s'" % (end, nptr))
# do not concatenate idents
if not is_cident_char(last) or not is_cident_char(nptr[0]):
l = end
c = l[0] if l else ''
dbg("new l: '%s'" % l)
last = l[0] if l else ''
sl.line = "".join(out)
def cb(event, *args):
if event == ida_hexrays.hxe_func_printed:
cf = args[0]
for sl in cf.get_pseudocode():
remove_spaces(sl);
return 0
if ida_hexrays.init_hexrays_plugin():
ida_hexrays.install_hexrays_callback(cb)
else:
print 'remove spaces: hexrays is not available.'
-4
View File
@@ -1,4 +0,0 @@
// This file just includes the correct idaapi_include.cpp file
// We need it because we can not compile a file from a subdirectory
#include <idaapi_include.cpp>
+5 -5
View File
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug64|Win32">
<Configuration>Debug64</Configuration>
@@ -27,25 +27,25 @@
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
+307 -174
View File
@@ -27,25 +27,17 @@ all:
else
PROC=python
STRIPOBJS=idaapi.cpp
API_CONTENTS=api_contents.txt
PYDOC_INJECTIONS=pydoc_injections.txt
IDA_INCLUDE=../../include
STAGING=./staging
ST_SWIG=$(STAGING)/swig
ST_SDK=$(STAGING)/idasdk
ST_PYW=$(STAGING)/pywraps
ST_PARSED_HEADERS=$(STAGING)/parsed_notifications/xml
# ATM, 'dist' in in staging/, but that will change since
# staging directories will be $(SYSDIR)-dependent
DIST=$(STAGING)/dist
DIST=$(F)dist
ifdef __NT__
SYSNAME=win
MSRUNTIME=/MD
else
.NOTPARALLEL:
endif
ifdef __LINUX__
SYSNAME=linux
@@ -62,11 +54,103 @@ ifdef __MAC__
DEFS=-D__MAC__
endif
O1=idaapi
ADDITIONAL_GOALS=pyfiles config $(TEST_IDC)
# O1=idaapi
# __USE_RTTI__=1
DONT_ERASE_LIB=1
__USE_RTTI__=1
include ../plugin.mak
PLUGIN_SCRIPT=
ifdef __LINUX__
OUTDLLOPTS=-Wl,-soname,$(notdir $(BINARY))
else
ifdef __MAC__
OUTDLLOPTS=-Wl,-install_name,@executable_path/plugins/$(notdir $(BINARY))
endif
endif
ST_SWIG=$(F)swig
ifeq ($(OUT_OF_TREE_BUILD),)
ST_SDK=$(F)idasdk
else
ST_SDK=$(IDA_INCLUDE)
endif
ST_PYW=$(F)pywraps
ST_WRAP=$(F)wrappers
ST_PARSED_HEADERS_NOXML=$(F)parsed_notifications
ST_PARSED_HEADERS=$(ST_PARSED_HEADERS_NOXML)/xml
ST_API_CONTENTS=$(F)api_contents.txt.new
ST_PYDOC_INJECTIONS=$(F)pydoc_injections.txt
# output directory for python scripts
DEPLOY_PYDIR=$(R)python
DEPLOY_INIT_PY=$(DEPLOY_PYDIR)/init.py
DEPLOY_IDC_PY=$(DEPLOY_PYDIR)/idc.py
DEPLOY_IDAUTILS_PY=$(DEPLOY_PYDIR)/idautils.py
ifeq ($(OUT_OF_TREE_BUILD),)
TEST_IDC=test_idc
DBLZIP_SCRIPT:=$(abspath ../../ida/build/dblzip.py)
PKGBIN_SCRIPT:=$(abspath ../../ida/build/pkgbin.py)
endif
#
SDK_SOURCES=$(wildcard $(IDA_INCLUDE)/*.h) $(wildcard $(IDA_INCLUDE)/*.hpp)
ifeq ($(OUT_OF_TREE_BUILD),)
ST_SDK_TARGETS=$(SDK_SOURCES:$(IDA_INCLUDE)/%=$(ST_SDK)/%)
else
ST_SDK_TARGETS=$(SDK_SOURCES)
endif
PYTHON_DYNLOAD=$(BIN_PATH)../python/lib/python2.7/lib-dynload
DEPLOY_LIBDIR=$(PYTHON_DYNLOAD)/ida_$(ADRSIZE)
$(DEPLOY_LIBDIR):
-@if [ ! -d "$(DEPLOY_LIBDIR)" ] ; then mkdir -p 2>/dev/null $(DEPLOY_LIBDIR) ; fi
$(DEPLOY_PYDIR):
-@if [ ! -d "$(DEPLOY_PYDIR)" ] ; then mkdir -p 2>/dev/null $(DEPLOY_PYDIR) ; fi
ifdef __NT__
MODULE_SFX=.pyd
else
MODULE_SFX=.so
endif
# We are building 'MODULES_NAMES' from subvars because it appears some versions
# of make do not deal too well with '\'s, and introduce spaces, which later is
# problematic when substituting ' ' for ',' & passing modules list to scripts
MNAMES_0=allins area auto bytes dbg diskio entry enum expr fixup
MNAMES_1=fpro frame funcs gdl graph hexrays ida idaapi idd idp ints
MNAMES_2=kernwin lines loader moves nalt name netnode offset pro queue
MNAMES_3=registry search segment srarea strlist struct typeinf ua xref
MODULES_NAMES=$(MNAMES_0) $(MNAMES_1) $(MNAMES_2) $(MNAMES_3)
MODULES=$(MODULES_NAMES:%=$(F)_ida_%$(MODULE_SFX))
DEPLOYED_MODULES=$(MODULES_NAMES:%=$(DEPLOY_LIBDIR)/_ida_%$(MODULE_SFX))
MODULES_OBJECTS=$(MODULES_NAMES:%=$(F)%$(O))
ALL_ST_SWIG=$(foreach mod,$(MODULES_NAMES),$(ST_SWIG)/$(mod).i)
ALL_ST_WRAP_CPP=$(foreach mod,$(MODULES_NAMES),$(ST_WRAP)/$(mod).cpp)
ALL_ST_WRAP_PY=$(foreach mod,$(MODULES_NAMES),$(ST_WRAP)/ida_$(mod).py)
PYTHON_MODULES=$(MODULES_NAMES:%=$(DEPLOY_PYDIR)/ida_%.py)
ifdef __NT__
MODULE_LINKIDA=
CREATE_IMPLIB=$(RS)lib32.bat
IDAPYTHON_IMPLIB_DEF=$(F)idapython_implib.def
IDAPYTHON_IMPLIB_DEF_IN=tools/idapython_implib.def.in
IDAPYTHON_IMPLIB_PATH=$(F)python.lib
BINARY_LINKOPTS=/def:$(IDAPYTHON_IMPLIB_DEF) /IMPLIB:$(IDAPYTHON_IMPLIB_PATH)
RESFILES=$(IDAPYTHON_IMPLIB_DEF)
else
MODULE_LINKIDA=-L$(R) $(LINKIDA) $(BINARY)
endif
all: objdir pyfiles config $(DEPLOYED_MODULES) $(PYTHON_MODULES) $(ST_API_CONTENTS) $(IDAPYTHON_IMPLIB) $(ST_PYDOC_INJECTIONS) #$(TEST_IDC)
# used python version
PYTHON_VERSION_MAJOR?=2
@@ -75,8 +159,8 @@ PYTHON_VERSION_MINOR?=7
# IDAPython version
IDAPYTHON_VERSION_MAJOR=6
IDAPYTHON_VERSION_MINOR=9
IDAPYTHON_VERSION_PATCH=0
PACKAGE_NAME=idapython-$(IDAPYTHON_VERSION_MAJOR).$(IDAPYTHON_VERSION_MINOR).$(IDAPYTHON_VERSION_PATCH)-python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)-$(SYSNAME).zip
IDAPYTHON_VERSION_PATCH=5
PACKAGE_NAME=idapython-$(IDAPYTHON_VERSION_MAJOR).$(IDAPYTHON_VERSION_MINOR).$(IDAPYTHON_VERSION_PATCH)-python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)-$(SYSNAME)
# HIJACK the $(I) variable to point to our staging SDK
@@ -87,19 +171,6 @@ ifdef __CODE_CHECKER__
OBJS:=$(filter-out $(OBJ1),$(OBJS))
endif
# output directory for python scripts
ifeq ($(OUT_OF_TREE_BUILD),)
SCRIPTDIR=$(R)python
DEPLOY_INIT_PY=$(SCRIPTDIR)/init.py
DEPLOY_IDC_PY=$(SCRIPTDIR)/idc.py
DEPLOY_IDAUTILS_PY=$(SCRIPTDIR)/idautils.py
DEPLOY_PYTHON_CFG=$(C)python.cfg
TEST_IDC=test_idc
else
SCRIPTDIR=python
endif
ifdef __NT__ # os and compiler specific flags
ifneq ($(UCRT_INCLUDE),)
I_UCRT_INCLUDE=/I$(UCRT_INCLUDE)
@@ -114,16 +185,18 @@ endif
endif
_SWIGFLAGS=-D__NT__ -DWIN32 -D_USRDLL -I$(PYTHON_DIR)/include
SWIGINCLUDES?= # nothing
OSFLAGS=$(_SWIGFLAGS) -UNO_OBSOLETE_FUNCS
# FIXME: Cannot enable the .cfg file ATM, because there's just too many errors if I do.
PLATFORM_CFLAGS=$(_SWIGFLAGS) -UNO_OBSOLETE_FUNCS
else # unix/mac
ifdef __LINUX__
# use the precompiled 2.7
ifeq ($(OUT_OF_TREE_BUILD),)
PYDIR=$(shell pwd)/precompiled
# assign right away, so it won't be eval'd 10301829 times
PYDIR:=$(shell pwd)/precompiled
PYLIBDIR=$(PYDIR)
# copy these files to IDA's directory
PYLIBFILES=$(shell find precompiled/lib -type f)
PRECOMPILED_COPY=$(R)$(PYTHONLIBNAME) $(patsubst precompiled/%,$(SCRIPTDIR)/%,$(PYLIBFILES))
PYLIBFILES:=$(shell find precompiled/lib -type f)
PRECOMPILED_COPY=$(R)$(PYTHONLIBNAME) $(patsubst precompiled/%,$(DEPLOY_PYDIR)/%,$(PYLIBFILES))
else
PYDIR=$(IDAPYTHON_PYTHONHOME)
PYLIBDIR=$(PYDIR)/lib
@@ -138,40 +211,50 @@ else # unix/mac
MACDEFINES=-DMACSDKVER=$(MACSDKVER)
endif
IDAPYTHON_CFLAGS=-w -g
OSFLAGS=$(SYS) -g $(PYTHON32_INCLUDE) $(ARCH_CFLAGS) $(PIC) -UNO_OBSOLETE_FUNCS # gcc flags
PLATFORM_CFLAGS=$(SYS) -g $(PYTHON32_INCLUDE) $(ARCH_CFLAGS) $(PIC) -UNO_OBSOLETE_FUNCS # gcc flags
_SWIGFLAGS=$(DEFS)
SWIGINCLUDES?=-I$(SWIGDIR)share/swig/$(SWIG_VERSION)/python -I$(SWIGDIR)share/swig/$(SWIG_VERSION)
endif
SWIGFLAGS=$(_SWIGFLAGS) $(SWIGINCLUDES)
# Apparently that's not needed, but I don't understand why ATM, since doc says:
# ...Then, only modules compiled with SWIG_TYPE_TABLE set to myprojectname
# will share type information. So if your project has three modules, all three
# should be compiled with -DSWIG_TYPE_TABLE=myprojectname, and then these
# three modules will share type information. But any other project's
# types will not interfere or clash with the types in your module.
DEF_TYPE_TABLE=-DSWIG_TYPE_TABLE=idaapi
SWIGFLAGS=$(_SWIGFLAGS) $(SWIGINCLUDES) $(DEF_TYPE_TABLE)
ADDITIONAL_LIBS=$(PYTHONLIB)
PUBTREE_DIR=$(F)/public_tree
.PHONY: pyfiles docs $(TEST_IDC) staging_dirs clean check_python dist dist_dirs dist_cfg package
.PHONY: pyfiles docs $(TEST_IDC) staging_dirs clean check_python package public_tree
config: $(C)python.cfg
clean:
rm -rf $(STAGING)/ obj/
rm -rf obj/
pyfiles: $(SCRIPTDIR)/idautils.py \
$(SCRIPTDIR)/idc.py \
$(SCRIPTDIR)/init.py \
$(SCRIPTDIR)/idaapi.py
pyfiles: $(DEPLOY_PYDIR)/idautils.py \
$(DEPLOY_PYDIR)/idc.py \
$(DEPLOY_PYDIR)/init.py \
$(DEPLOY_PYDIR)/idaapi.py
GENHOOKS=tools/genhooks/
_SPACE := $(null) #
_COMMA := ,
$(DEPLOY_INIT_PY): python/init.py
$(DEPLOY_INIT_PY): python/init.py | $(DEPLOY_PYDIR)
$(CP) $? $@
$(DEPLOY_IDC_PY): python/idc.py
$(DEPLOY_IDC_PY): python/idc.py | $(DEPLOY_PYDIR)
$(CP) $? $@
$(DEPLOY_IDAUTILS_PY): python/idautils.py
$(DEPLOY_IDAUTILS_PY): python/idautils.py | $(DEPLOY_PYDIR)
$(CP) $? $@
$(SCRIPTDIR)/idaapi.py: $(F)idaapi.py
$(PYTHON) inject_pydoc.py swig/ $? $@
$(DEPLOY_PYDIR)/idaapi.py: python/idaapi.py tools/genidaapi.py | $(DEPLOY_PYDIR)
$(PYTHON) tools/genidaapi.py -i $< -o $@ -m $(subst $(_SPACE),$(_COMMA),$(MODULES_NAMES))
$(SCRIPTDIR)/lib/%: precompiled/lib/%
$(DEPLOY_PYDIR)/lib/%: precompiled/lib/%
mkdir -p $(@D)
cp $< $@
@chmod +w $@
@@ -184,41 +267,37 @@ $(R)$(PYTHONLIBNAME): $(PYDIR)/$(PYTHONLIBNAME)
# -------------------------------------------------------------------------
# Hooks generation
$(ST_PARSED_HEADERS)/structprocessor__t.xml: $(I)idp.hpp $(GENHOOKS)doxy_gen_notifs.cfg | $(ST_SDK_TARGETS)
@$(DOXYGEN_BIN) $(GENHOOKS)doxy_gen_notifs.cfg
$(ST_PARSED_HEADERS)/dbg_8hpp.xml: $(I)dbg.hpp $(GENHOOKS)doxy_gen_notifs.cfg | $(ST_SDK_TARGETS)
@$(DOXYGEN_BIN) $(GENHOOKS)doxy_gen_notifs.cfg
$(ST_PARSED_HEADERS)/kernwin_8hpp.xml: $(I)kernwin.hpp $(GENHOOKS)doxy_gen_notifs.cfg | $(ST_SDK_TARGETS)
@$(DOXYGEN_BIN) $(GENHOOKS)doxy_gen_notifs.cfg
$(ST_PARSED_HEADERS)/namespaceidb__event.xml: $(I)kernwin.hpp $(GENHOOKS)doxy_gen_notifs.cfg | $(ST_SDK_TARGETS)
@$(DOXYGEN_BIN) $(GENHOOKS)doxy_gen_notifs.cfg
# http://stackoverflow.com/questions/11032280/specify-doxygen-parameters-through-command-line
GENERATED_HEADERS=$(ST_PARSED_HEADERS)/headers_generated.marker
$(GENERATED_HEADERS): $(I)idp.hpp $(I)dbg.hpp $(I)kernwin.hpp $(GENHOOKS)doxy_gen_notifs.cfg $(ST_SDK_TARGETS)
ifeq ($(OUT_OF_TREE_BUILD),)
@( cat $(GENHOOKS)doxy_gen_notifs.cfg; echo "OUTPUT_DIRECTORY=$(ST_PARSED_HEADERS_NOXML)" ) | $(DOXYGEN_BIN) -
else
(cd $(F) && unzip ../../out_of_tree/parsed_notifications.zip)
endif
@touch $@
#
staging_dirs:
-@if [ ! -d "$(ST_SDK)" ] ; then mkdir -p 2>/dev/null $(ST_SDK) ; fi
-@if [ ! -d "$(ST_SWIG)" ] ; then mkdir -p 2>/dev/null $(ST_SWIG) ; fi
-@if [ ! -d "$(ST_PYW)" ] ; then mkdir -p 2>/dev/null $(ST_PYW) ; fi
-@if [ ! -d "$(ST_WRAP)" ] ; then mkdir -p 2>/dev/null $(ST_WRAP) ; fi
-@if [ ! -d "$(ST_PARSED_HEADERS)" ] ; then mkdir -p 2>/dev/null $(ST_PARSED_HEADERS) ; fi
# -------------------------------------------------------------------------
# Rules for preparing 'staging/idasdk/*.h[pp]'
# obj/.../idasdk/*.h[pp]
#
SDK_SOURCES=$(wildcard $(IDA_INCLUDE)/*.h) $(wildcard $(IDA_INCLUDE)/*.hpp)
ST_SDK_TARGETS=$(SDK_SOURCES:$(IDA_INCLUDE)/%=$(ST_SDK)/%)
$(ST_SDK)/%.h: $(IDA_INCLUDE)/%.h | staging_dirs
@$(CP) $^ $@ && chmod +rw $@
$(ST_SDK)/%.hpp: $(IDA_INCLUDE)/%.hpp | staging_dirs
@$(CP) $^ $@ && chmod +rw $@
ifeq ($(OUT_OF_TREE_BUILD),)
$(ST_SDK)/%.h: $(IDA_INCLUDE)/%.h | staging_dirs $(PRECOMPILED_COPY)
$(PYTHON) ../../bin/update_sdk.py -filter-file -input $^ -output $@
$(ST_SDK)/%.hpp: $(IDA_INCLUDE)/%.hpp | staging_dirs $(PRECOMPILED_COPY)
$(PYTHON) ../../bin/update_sdk.py -filter-file -input $^ -output $@
endif
# -------------------------------------------------------------------------
# Rules for preparing 'staging/pywraps/*'
# obj/.../pywraps/*
#
PYW_SOURCES=$(wildcard pywraps/*.hpp) $(wildcard pywraps/*.py)
ST_PYW_TARGETS=$(PYW_SOURCES:pywraps/%=$(ST_PYW)/%)
$(ST_PYW)/%.hpp: pywraps/%.hpp | staging_dirs
@$(CP) $^ $@ && chmod +rw $@
$(ST_PYW)/%.py: pywraps/%.py | staging_dirs
@@ -226,121 +305,190 @@ $(ST_PYW)/%.py: pywraps/%.py | staging_dirs
ifneq ($(OUT_OF_TREE_BUILD),)
# envvar HAS_HEXRAYS must have been set by build.py if needed
# envvar HAS_HEXRAYS must have been set by build.py if needed
else
HAS_HEXRAYS=1 # force hexrays bindings
endif
# force hexrays bindings
HAS_HEXRAYS=1
# These require special care, as they will have to be injected w/ hooks -- this
# only happens if we are sitting in the hexrays source tree; when published to
# the outside world, the pywraps must already contain the injected code.
$(ST_PYW)/py_idp.hpp: pywraps/py_idp.hpp \
# These require special care, as they will have to be injected w/ hooks -- this
# only happens if we are sitting in the hexrays source tree; when published to
# the outside world, the pywraps must already contain the injected code.
$(ST_PYW)/py_idp.hpp: pywraps/py_idp.hpp \
$(I)idp.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_idphooks.py \
$(ST_PARSED_HEADERS)/structprocessor__t.xml | staging_dirs $(SDK_SOURCES)
$(GENERATED_HEADERS) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/structprocessor__t.xml -e idp_notify \
-r int -n 0 -m hookgenIDP -q "processor_t::" \
-R $(GENHOOKS)recipe_idphooks.py
$(ST_PYW)/py_idbhooks.hpp: pywraps/py_idbhooks.hpp \
$(ST_PYW)/py_idp_idbhooks.hpp: pywraps/py_idp_idbhooks.hpp \
$(I)idp.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_idbhooks.py \
$(ST_PARSED_HEADERS)/namespaceidb__event.xml | staging_dirs $(SDK_SOURCES)
$(GENERATED_HEADERS) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/namespaceidb__event.xml -e event_code_t \
-r int -n 0 -m hookgenIDB -q "idb_event::" \
-R $(GENHOOKS)recipe_idbhooks.py
$(ST_PYW)/py_dbg.hpp: pywraps/py_dbg.hpp \
$(ST_PYW)/py_dbg.hpp: pywraps/py_dbg.hpp \
$(I)dbg.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_dbghooks.py \
$(ST_PARSED_HEADERS)/dbg_8hpp.xml | staging_dirs $(SDK_SOURCES)
$(GENERATED_HEADERS) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/dbg_8hpp.xml -e dbg_notification_t \
-r void -n 0 -m hookgenDBG \
-R $(GENHOOKS)recipe_dbghooks.py
$(ST_PYW)/py_kernwin.hpp: pywraps/py_kernwin.hpp \
$(ST_PYW)/py_kernwin.hpp: pywraps/py_kernwin.hpp \
$(I)kernwin.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_uihooks.py \
$(ST_PARSED_HEADERS)/kernwin_8hpp.xml | staging_dirs $(SDK_SOURCES)
$(GENERATED_HEADERS) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/kernwin_8hpp.xml -e ui_notification_t \
-r void -n 0 -m hookgenUI \
-R $(GENHOOKS)recipe_uihooks.py \
-d "ui_dbg_,ui_obsolete" -D "ui:" -s "ui_"
endif # OUT_OF_TREE_BUILD
ifneq ($(HAS_HEXRAYS),)
WITH_HEXRAYS=-DWITH_HEXRAYS
WITH_HEXRAYS_CHKAPI=--with-hexrays
endif
CFLAGS= $(CCOPT) $(PLATFORM_CFLAGS) $(MSRUNTIME) -D__EXPR_SRC -I. -I$(ST_SWIG) -I$(ST_SDK) -I$(F) \
-DVER_MAJOR="1" -DVER_MINOR="7" -DVER_PATCH="0" -D__IDP__ \
-DUSE_STANDARD_FILE_FUNCTIONS $(IDAPYTHON_CFLAGS) \
$(SWITCH64) $(ARCH_CFLAGS) $(WITH_HEXRAYS) $(DEF_TYPE_TABLE)
# -------------------------------------------------------------------------
# Rules for preparing 'staging/swig/*.i'
#
# Note: At the time we define those rules, we cannot go and look in
# staging/pywraps/ just yet, as those will/might not have been deployed at
# that point (i.e., when building from scratch.)
# Thus, we must find the dependencies in pywraps/, and then re-route them to
# staging/pywraps/
SWIG_SOURCES=$(wildcard swig/*.i)
ST_SWIG_TARGETS=$(SWIG_SOURCES:swig/%.i=$(ST_SWIG)/%.i)
find-pywraps-deps = $(wildcard pywraps/py_$(subst .i,,$(notdir $1)).*)
define make-deploy-swig-file-rule
$1: $(subst staging/,,$1) $(addprefix staging/,$(call find-pywraps-deps,$1)) | $(ST_PYW_TARGETS)
@$(PYTHON) tools/deploy.py --pywraps $(ST_PYW) --template $$(subst staging/,,$$@) --output $$@ --module $$(subst .i,,$$(notdir $$@))
ST_SWIG_HEADER=$(ST_SWIG)/header.i
$(ST_SWIG)/header.i: tools/deploy/header.i.in tools/genswigheader.py $(ST_SDK_TARGETS) | staging_dirs
$(PYTHON) tools/genswigheader.py -i $< -o $@ -m $(subst $(_SPACE),$(_COMMA),$(MODULES_NAMES)) -s $(ST_SDK)
ifdef __NT__
$(IDAPYTHON_IMPLIB_DEF): $(IDAPYTHON_IMPLIB_DEF_IN)
sed s/%LIBNAME%/$(notdir $(BINARY))/ < $? > $@
endif
find-pywraps-deps = $(wildcard pywraps/py_$(subst .i,,$(notdir $1))*.*)
# Some .i files depend on some other .i files in order to be parseable by SWiG
# (e.g., srarea.i imports area.i). Declare the list of such dependencies here
# so they will be picked by the auto-generated rules.
SWIG_IFACE_bytes=area
SWIG_IFACE_dbg=idd
SWIG_IFACE_frame=area
SWIG_IFACE_funcs=area
SWIG_IFACE_gdl=area
SWIG_IFACE_hexrays=typeinf
SWIG_IFACE_segment=area
SWIG_IFACE_srarea=area
SWIG_IFACE_typeinf=idp
define make-module-rules
# Note: apparently make cannot work well when a given recipe generates multiple files
# http://stackoverflow.com/questions/19822435/multiple-targets-from-one-recipe-and-parallel-execution
# Consequently, rules such as this:
#
# $(ST_WRAP)/ida_$1.py: $(ST_WRAP)/$1.cpp
#
# i.e., that do nothing but rely on the generation of another file,
# will not work in // execution. Thus, we will rely exclusively on
# the presence of the generated .cpp file, and not other generated
# files.
# ../../bin/x86_linux_gcc/python/ida_$1.py (note: dep. on .cpp. See note above.)
$(DEPLOY_PYDIR)/ida_$1.py: $(ST_WRAP)/$1.cpp | $(DEPLOY_PYDIR) tools/inject_pydoc.py
$(PYTHON) tools/inject_pydoc.py \
-i $(ST_WRAP)/ida_$1.py \
-w $(ST_SWIG)/$1.i \
-o $$@ \
-v > $(ST_WRAP)/ida_$1.pydoc_injection 2>&1
# obj/x86_linux_gcc/swig/X.i
$(ST_SWIG)/$1.i: $(addprefix $(F),$(call find-pywraps-deps,$1)) swig/$1.i $(ST_SWIG_HEADER) $(SWIG_IFACE_$1:%=$(ST_SWIG)/%.i) $(ST_SWIG_HEADER) tools/deploy.py
$(PYTHON) tools/deploy.py --pywraps $(ST_PYW) --template $$(subst $(F),,$$@) --output $$@ --module $$(subst .i,,$$(notdir $$@)) --interface-dependencies=$(subst $(_SPACE),$(_COMMA),$(SWIG_IFACE_$1))
# obj/x86_linux_gcc/wrappers/X.cpp
$(ST_WRAP)/$1.cpp: $(ST_SWIG)/$1.i
$(SWIG) -modern $(WITH_HEXRAYS) -python -threads -c++ -shadow \
$(MACDEFINES) -D__GNUC__ $(SWIGFLAGS) $(SWITCH64) -I$(ST_SWIG) \
-outdir $(ST_WRAP) -o $$@ -I$(ST_SDK) $$<
@$(PYTHON) tools/patch_constants.py --file $(ST_WRAP)/$1.cpp
ifdef __NT__
@$(PYTHON) tools/patch_directors_cc.py --file $(ST_WRAP)/$1.h
endif
# The copying of the .py will preserve attributes (including timestamps).
# And, since we have patched $1.cpp, it'll be more recent than ida_$1.py,
# and make would keep copying the .py file at each invocation.
# To prevent that, let's make the source .py file more recent than .cpp.
@touch $(ST_WRAP)/ida_$1.py
# obj/x86_linux_gcc/X.o32
$(F)$1$(O): $(ST_WRAP)/$1.cpp
ifdef __CODE_CHECKER__
touch $$@
else
$(CXX) $(CFLAGS) $(MSRUNTIME) $(NORTTI) -DPLUGIN_SUBMODULE -DSWIG_DIRECTOR_NORTTI -c $(OBJSW)$$@ $(ST_WRAP)/$1.cpp
ifndef __NT__
ifeq ($(OUT_OF_TREE_BUILD),)
@$(STRIPSYM_TOOL) $$@ $(STRIPSYMS) > /dev/null || ($(RM) $$@; false)
endif
endif
endif
# obj/x86_linux_gcc/_ida_X.so
$(F)_ida_$1$(MODULE_SFX): $(F)$1$(O) $(BINARY) $(IDAPYTHON_IMPLIB_DEF)
ifdef __NT__
$(LINKER) $(LINKOPTS) /OPT:ICF /OPT:REF /INCREMENTAL:NO /STUB:../../plugins/stub /OUT:$$@ $$< $(IDALIB) user32.lib $(ADDITIONAL_LIBS) $(IDAPYTHON_IMPLIB_PATH)
else
$(CCL) $(OUTDLL) $(OUTSW)$$@ $$< $(MODULE_LINKIDA) $(PLUGIN_SCRIPT) $(ADDITIONAL_LIBS) $(STDLIBS)
endif
# ../../bin/x86_linux_gcc/python/lib/lib-dynload/ida_32/_ida_X.so
$(DEPLOY_LIBDIR)/_ida_$1$(MODULE_SFX): $(F)_ida_$1$(MODULE_SFX) | $(DEPLOY_LIBDIR)
@$(CP) $$< $$@
endef
$(foreach tgt,$(ST_SWIG_TARGETS),$(eval $(call make-deploy-swig-file-rule,$(tgt))))
$(foreach mod,$(MODULES_NAMES),$(eval $(call make-module-rules,$(mod))))
$(ST_API_CONTENTS): $(ALL_ST_WRAP_CPP)
$(PYTHON) tools/chkapi.py $(WITH_HEXRAYS_CHKAPI) -i $(subst $(_SPACE),$(_COMMA),$(ALL_ST_WRAP_CPP)) -p $(subst $(_SPACE),$(_COMMA),$(ALL_ST_WRAP_PY)) -r $(ST_API_CONTENTS)
@(diff -w $(API_CONTENTS) $(ST_API_CONTENTS)) > /dev/null || \
(echo "API CONTENTS CHANGED! update api_contents.txt or fix the API" && \
echo "(New API: $(ST_API_CONTENTS)) ***" && \
(diff -U 1 -w $(API_CONTENTS) $(ST_API_CONTENTS) && false))
# Check that doc injection is stable
PYDOC_INJECTIONS_RESULTS=$(MODULES_NAMES:%=$(ST_WRAP)/ida_%.pydoc_injection)
$(ST_PYDOC_INJECTIONS): $(PYTHON_MODULES)
cat $(PYDOC_INJECTIONS_RESULTS) > $@
@(diff -w $(PYDOC_INJECTIONS) $(ST_PYDOC_INJECTIONS)) > /dev/null || \
(echo "PYDOC INJECTION CHANGED! update $(PYDOC_INJECTIONS) or fix .. what needs fixing" && \
echo "(New API: $(ST_PYDOC_INJECTIONS)) ***" && \
(diff -U 1 -w $(PYDOC_INJECTIONS) $(ST_PYDOC_INJECTIONS) && false))
# Require a strict SWiG version (other versions might generate different code.)
SWIG_VERSION_ACTUAL=$(shell $(SWIG) -version | awk "/SWIG Version [0-9.]+/ { if (match(\$$0, /([0-9.]+)/)) { print substr(\$$0, RSTART, RLENGTH); } }")
# idaapi.py is created together with idaapi_include.cpp
$(F)idaapi.py: | $(F)idaapi_include.cpp
# idaapi_include.h is created together with idaapi_include.cpp
patched_idaapi_include_h: patch_directors_cc.py | $(F)idaapi_include.h
ifdef __NT__
@$(PYTHON) patch_directors_cc.py -f $(F)idaapi_include.h
endif
# ST_WRAP_FILES=$(MODULES_NAMES:%=$(ST_WRAP)/%.cpp) $(MODULES_NAMES:%=$(ST_WRAP)/%.h) $(MODULES_NAMES:%=$(ST_WRAP)/ida_%.py)
# .PRECIOUS: $(ST_WRAP_FILES) $(MODULES_OBJECTS)
.PRECIOUS: $(ST_API_CONTENTS) $(ST_PYDOC_INJECTIONS)
$(F)idaapi_include.h: | $(F)idaapi_include.cpp
$(F)idaapi_include.cpp: $(PRECOMPILED_COPY) \
$(ST_SDK_TARGETS) \
$(ST_PYW_TARGETS) \
$(ST_SWIG_TARGETS) \
pywraps.hpp | objdir
@ ! (grep __EA64__ swig/* | grep -v typeconv.i) || \
(echo "ERROR: __EA64__ macro is foribidden in swig subdirectory (to ensure the same api for both ida versions)" && false)
ifneq ($(SWIG_VERSION_ACTUAL),$(SWIG_VERSION))
$(error Expected SWIG version "$(SWIG_VERSION)", but got "$(SWIG_VERSION_ACTUAL)" (from $(SWIG)))
endif
$(SWIG) -modern $(WITH_HEXRAYS) -python -threads -c++ -shadow \
$(MACDEFINES) -D__GNUC__ $(SWIGFLAGS) $(SWITCH64) -I$(ST_SWIG) \
-outdir $(F) -o $@ -I$(ST_SDK) $(ST_SWIG)/idaapi.i || \
{ $(RM) $(F)idaapi_include.*; exit 1 ;}
$(PYTHON) chkapi.py $(WITH_HEXRAYS_CHKAPI) -f $@ -r $(API_CONTENTS).new
@(diff $(API_CONTENTS) $(API_CONTENTS).new) > /dev/null || \
(rm -f $@ $(F)idaapi_include.h && \
echo "API CONTENTS CHANGED! update api_contents.txt or fix the API" && \
echo "(New API: $(API_CONTENTS).new) ***" && \
(diff -U 1 -w $(API_CONTENTS) $(API_CONTENTS).new && false))
# Python version
CFLAGS= $(CCOPT) $(OSFLAGS) -D__EXPR_SRC -I. -I$(ST_SWIG) -I$(ST_SDK) -I$(F) \
-DVER_MAJOR="1" -DVER_MINOR="7" -DVER_PATCH="0" -D__IDP__ \
-DUSE_STANDARD_FILE_FUNCTIONS $(IDAPYTHON_CFLAGS) \
$(SWITCH64) $(ARCH_CFLAGS) $(WITH_HEXRAYS)
DOCS_MODULES=$(MODULES_NAMES:%=ida_%)
tools/docs/hrdoc.cfg: tools/docs/hrdoc.cfg.in
sed s/%IDA_MODULES%/"$(DOCS_MODULES)"/ < $? > $@
# the html files are produced in docs\hr-html directory
docs: hrdoc.py hrdoc.cfg hrdoc.css
idaq -Shrdoc.py -t
docs: tools/docs/hrdoc.py tools/docs/hrdoc.cfg tools/docs/hrdoc.css
ifndef __NT__
TVHEADLESS=1 $(R)idal -Stools/docs/hrdoc.py -t > /dev/null
else
$(R)idaq -Stools/docs/hrdoc.py -t
endif
# Test that all functions that are present in ftable.cpp
# are present in idc.py (and therefore made available by
@@ -367,52 +515,37 @@ ifneq ($(wildcard ../../tests),)
(echo "ERROR: The IDAPython IDC interface is incomplete. IDA log:" && cat $(F)idctest.log && false)
endif
dist_dirs:
-@if [ ! -d "$(DIST)/plugins" ] ; then mkdir -p 2>/dev/null $(DIST)/plugins ; fi
DIST_OTHER_SOURCES=python.cfg README.md AUTHORS.txt CHANGES.txt COPYING.txt STATUS.txt
DIST_OTHER_TARGETS=$(DIST_OTHER_SOURCES:%=$(DIST)/%)
$(DIST)/%: % | dist_dirs
@$(CP) $^ $@ && chmod +rw $@
DIST_BINARY=$(DIST)/plugins/$(PROC)$(PLUGIN)
$(DIST_BINARY): $(BINARY) | dist_dirs
$(CP) $? $@
ifdef __LINUX__
strip $@
else
ifdef __MAC__
strip -x $@
endif
package:
ifeq ($(OUT_OF_TREE_BUILD),)
-@if [ ! -d "$(DIST)" ] ; then mkdir -p 2>/dev/null $(DIST) ; fi
$(PYTHON) $(PKGBIN_SCRIPT) \
--input-binary-tree $(R) \
--output-dir $(DIST) \
--confirmed \
--component plugins/idapython
(cd $(DIST) && $(PYTHON) $(DBLZIP_SCRIPT) --once --output ../../../obj/$(PACKAGE_NAME))
endif
dist: $(BINARY) pyfiles $(DIST_OTHER_TARGETS) $(DIST_BINARY) dist_cfg | dist_dirs
# rsync -a docs $(DIST)/
rsync -a examples $(DIST)/
rsync -a python $(DIST)/
package:
(cd $(DIST) && zip -r ../../$(PACKAGE_NAME) *)
public_tree: all
ifeq ($(OUT_OF_TREE_BUILD),)
-@if [ ! -d "$(PUBTREE_DIR)/out_of_tree" ] ; then mkdir -p 2>/dev/null $(PUBTREE_DIR)/out_of_tree ; fi
rsync -a --exclude=obj/ \
--exclude=precompiled/ \
--exclude=repl.py \
--exclude=test_idc.py \
--exclude=RELEASE.md \
. $(PUBTREE_DIR)
(cd $(F) && zip -r ../../$(PUBTREE_DIR)/out_of_tree/parsed_notifications.zip parsed_notifications)
endif
echo_modules:
@echo $(MODULES_NAMES)
# MAKEDEP dependency list ------------------
$(F)idaapi$(O) : $(F)idaapi_include.cpp $(I)allins.hpp $(I)area.hpp \
$(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp $(I)dbg.hpp \
$(I)diskio.hpp $(I)entry.hpp $(I)enum.hpp $(I)err.h \
$(I)expr.hpp $(I)fixup.hpp $(I)fpro.h $(I)frame.hpp \
$(I)funcs.hpp $(I)gdl.hpp $(I)graph.hpp $(I)ida.hpp \
$(I)idd.hpp $(I)idp.hpp $(I)ieee.h $(I)ints.hpp \
$(I)kernwin.hpp $(I)lines.hpp $(I)llong.hpp \
$(I)loader.hpp $(I)moves.hpp $(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h $(I)queue.hpp \
$(I)search.hpp $(I)segment.hpp $(I)sistack.hpp \
$(I)srarea.hpp $(I)strlist.hpp $(I)struct.hpp \
$(I)typeinf.hpp $(I)ua.hpp $(I)xref.hpp \
idaapi.cpp pywraps.hpp | patched_idaapi_include_h $(ST_SDK_TARGETS)
$(F)python$(O) : $(I)area.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)diskio.hpp $(I)expr.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)kernwin.hpp $(I)lines.hpp \
$(I)llong.hpp $(I)loader.hpp $(I)nalt.hpp \
$(I)netnode.hpp $(I)pro.h $(I)segment.hpp $(I)ua.hpp \
$(I)xref.hpp python.cpp pywraps.hpp | $(ST_SDK_TARGETS)
$(I)xref.hpp python.cpp pywraps.hpp pywraps.cpp | $(ST_SDK_TARGETS)
endif
Binary file not shown.
-80
View File
@@ -1,80 +0,0 @@
import os, shutil, sys, optparse
if __name__ == "__main__":
p = optparse.OptionParser(description='Patch calling conventions for some functions, so it builds on windows')
p.add_option('-v', "--verbose", dest="verbose", action="store_true")
p.add_option('-f', "--file", dest="path", type="string", help="File name, without extension.")
opts, _ = p.parse_args(sys.argv[1:])
if not opts.path:
p.print_help()
sys.exit(1)
patches = [
# text_sink_t
"virtual int idaapi print",
# user_lvar_modifier_t
"virtual bool idaapi modify_lvars",
# ctree_visitor_t
"virtual int idaapi visit_insn",
"virtual int idaapi visit_expr",
"virtual int idaapi leave_insn",
"virtual int idaapi leave_expr",
# ctree_parentee_t
"virtual int idaapi visit_insn",
"virtual int idaapi visit_expr",
"virtual int idaapi leave_insn",
"virtual int idaapi leave_expr",
# cfunc_parentee_t
"virtual int idaapi visit_insn",
"virtual int idaapi visit_expr",
"virtual int idaapi leave_insn",
"virtual int idaapi leave_expr",
# enum_member_visitor_t
"virtual int idaapi visit_enum_member",
# struct_field_visitor_t
"virtual int idaapi visit_field",
# tinfo_visitor_t
"virtual int idaapi visit_type",
# aloc_visitor_t
"virtual int idaapi visit_location",
# const_aloc_visitor_t
"virtual int idaapi visit_location",
# area_visitor2_t
"virtual int idaapi visit_area",
# highlighter_cbs_t
"virtual void idaapi set_style",
"virtual int32 idaapi prev_block_state",
"virtual int32 idaapi cur_block_state",
"virtual void idaapi set_block_state",
]
path = opts.path
outlines = []
outpath = "%s.cc" % path
with open(path, "r") as f:
lines = f.readlines()
for line in lines:
for patch in patches:
from_text = patch.replace("idaapi ", "")
if line.find(from_text) > -1:
line = line.replace(from_text, patch)
patches.remove(patch)
break
outlines.append(line)
with open(outpath, "w") as f:
f.writelines(outlines)
shutil.move(outpath, path)
+214
View File
@@ -0,0 +1,214 @@
### Processing allins.i
### Processing area.i
### Processing auto.i
### Processing bytes.i
fix_fun: found info for visit_patched_bytes
fix_fun: found info for nextthat
fix_fun: found info for get_many_bytes
fix_fun: found info for get_ascii_contents2
fix_fun: found info for get_ascii_contents
fix_fun: found info for register_custom_data_type
fix_fun: found info for unregister_custom_data_type
fix_fun: found info for register_custom_data_format
fix_fun: found info for unregister_custom_data_format
fix_fun: found info for get_custom_data_format
fix_fun: found info for get_custom_data_type
### Processing dbg.i
fix_fun: found info for get_manual_regions
fix_fun: found info for dbg_is_loaded
fix_fun: found info for refresh_debugger_memory
fix_fun: found info for move_bpt_to_grp
fix_fun: found info for internal_get_sreg_base
### Processing diskio.i
fix_fun: found info for enumerate_files
### Processing entry.i
### Processing enum.i
### Processing expr.i
### Processing fixup.i
### Processing fpro.i
fix_class: found info for qfile_t
fix_method: found info for __init__
fix_method: found info for opened
fix_method: found info for open
fix_method: found info for tmpfile
fix_method: found info for seek
fix_method: found info for tell
fix_method: found info for readbytes
fix_method: found info for read
fix_method: found info for gets
fix_method: found info for writebytes
fix_method: found info for write
fix_method: found info for flush
fix_method: found info for put_char
### Processing frame.i
fix_fun: found info for add_stkvar3
fix_fun: found info for get_stkvar
### Processing funcs.i
fix_fun: found info for get_fchunk_referer
fix_fun: found info for get_idasgn_desc
fix_fun: found info for get_idasgn_desc_with_matches
fix_fun: found info for get_func_cmt
### Processing gdl.i
### Processing graph.i
### Processing hexrays.i
### Processing ida.i
### Processing idaapi.i
fix_fun: found info for get_inf_structure
fix_fun: found info for set_script_timeout
fix_fun: found info for disable_script_timeout
fix_fun: found info for enable_extlang_python
fix_fun: found info for notify_when
fix_class: found info for loader_input_t
fix_method: found info for __init__
fix_method: found info for open
fix_method: found info for set_linput
fix_method: found info for from_fp
fix_method: found info for open_memory
fix_method: found info for seek
fix_method: found info for tell
fix_method: found info for getz
fix_method: found info for gets
fix_method: found info for read
fix_method: found info for opened
fix_method: found info for readbytes
fix_method: found info for file2base
fix_method: found info for get_char
### Processing idd.i
fix_fun: found info for dbg_get_registers
fix_fun: found info for dbg_get_thread_sreg_base
fix_fun: found info for dbg_read_memory
fix_fun: found info for dbg_write_memory
fix_fun: found info for dbg_get_name
fix_fun: found info for dbg_get_memory_info
fix_fun: found info for dbg_can_query
### Processing idp.i
fix_fun: found info for AssembleLine
fix_fun: found info for assemble
fix_fun: found info for ph_get_id
fix_fun: found info for ph_get_version
fix_fun: found info for ph_get_flag
fix_fun: found info for ph_get_cnbits
fix_fun: found info for ph_get_dnbits
fix_fun: found info for ph_get_regFirstSreg
fix_fun: found info for ph_get_regLastSreg
fix_fun: found info for ph_get_segreg_size
fix_fun: found info for ph_get_regCodeSreg
fix_fun: found info for ph_get_regDataSreg
fix_fun: found info for ph_get_high_fixup_bits
fix_fun: found info for ph_get_icode_return
fix_fun: found info for ph_get_instruc_start
fix_fun: found info for ph_get_instruc_end
fix_fun: found info for ph_get_tbyte_size
fix_fun: found info for ph_get_instruc
fix_fun: found info for ph_get_regnames
fix_fun: found info for ph_get_operand_info
fix_class: found info for IDP_Hooks
fix_method: found info for hook
fix_method: found info for unhook
fix_method: found info for assemble
fix_method: found info for rename
fix_method: found info for closebase
fix_method: found info for load_idasgn
fix_method: found info for may_be_func
fix_method: found info for is_sane_insn
fix_method: found info for custom_ana
fix_method: found info for custom_out
fix_method: found info for custom_emu
fix_method: found info for custom_outop
fix_method: found info for custom_mnem
fix_method: found info for undefine
fix_method: found info for make_code
fix_method: found info for make_data
fix_method: found info for is_call_insn
fix_method: found info for is_ret_insn
fix_method: found info for savebase
fix_method: found info for renamed
fix_method: found info for add_func
fix_method: found info for del_func
### Processing ints.i
### Processing kernwin.i
fix_fun: found info for register_timer
fix_fun: found info for unregister_timer
fix_fun: found info for choose_idasgn
fix_fun: found info for get_highlighted_identifier
fix_fun: found info for umsg
fix_fun: found info for msg
fix_fun: found info for asktext
fix_fun: found info for str2ea
fix_fun: found info for str2user
fix_fun: found info for process_ui_action
fix_fun: found info for del_menu_item
fix_fun: found info for del_hotkey
fix_fun: found info for add_hotkey
fix_fun: found info for add_menu_item
fix_fun: found info for execute_sync
fix_fun: found info for execute_ui_requests
fix_class: found info for UI_Hooks
fix_method: found info for hook
fix_method: found info for unhook
fix_method: found info for saving
fix_method: found info for saved
fix_method: found info for term
fix_method: found info for get_ea_hint
fix_method: found info for preprocess
fix_method: found info for postprocess
fix_method: found info for updating_actions
fix_method: found info for updated_actions
fix_method: found info for populating_tform_popup
fix_method: found info for finish_populating_tform_popup
fix_fun: found info for set_nav_colorizer
fix_fun: found info for call_nav_colorizer
fix_fun: found info for set_dock_pos
fix_fun: found info for free_custom_icon
fix_fun: found info for is_idaq
fix_fun: found info for readsel2
### Processing lines.i
fix_fun: found info for set_user_defined_prefix
fix_fun: found info for tag_remove
fix_fun: found info for generate_disassembly
### Processing loader.i
fix_fun: found info for mem2base
fix_fun: found info for load_plugin
fix_fun: found info for run_plugin
### Processing moves.i
### Processing nalt.i
fix_fun: found info for get_import_module_name
fix_fun: found info for get_switch_info_ex
fix_fun: found info for set_switch_info_ex
fix_fun: found info for del_switch_info_ex
fix_fun: found info for enum_import_names
### Processing name.i
### Processing netnode.i
### Processing offset.i
### Processing pro.i
### Processing queue.i
### Processing registry.i
### Processing search.i
### Processing segment.i
### Processing srarea.i
### Processing strlist.i
### Processing struct.i
### Processing typeinf.i
fix_fun: found info for calc_type_size
fix_fun: found info for apply_type
fix_fun: found info for print_type
fix_fun: found info for unpack_object_from_bv
fix_fun: found info for pack_object_to_idb
fix_fun: found info for pack_object_to_bv
fix_fun: found info for get_named_type
fix_fun: found info for apply_type_to_stkarg
### Processing ua.i
fix_fun: found info for init_output_buffer
fix_fun: found info for term_output_buffer
fix_fun: found info for decode_preceding_insn
fix_fun: found info for OutValue
fix_fun: found info for OutImmChar
fix_fun: found info for ua_stkvar2
fix_fun: found info for ua_add_off_drefs
fix_fun: found info for ua_add_off_drefs2
fix_fun: found info for out_name_expr
fix_fun: found info for construct_macro
### Processing xref.i
fix_fun: found info for create_switch_xrefs
fix_fun: found info for calc_switch_cases
fix_fun: found info for create_switch_table
+4
View File
@@ -8,3 +8,7 @@ REMOVE_CWD_SYS_PATH = YES
// Script timeout (in seconds)
// (A value of 0 disables the timeout)
SCRIPT_TIMEOUT = 3
// Should the plugin automatically load a backward-compatibility-providing
// 'idaapi' wrapper module?
AUTOIMPORT_COMPAT_IDAAPI = YES
+304 -216
View File
@@ -32,13 +32,8 @@
#include <kernwin.hpp>
#include <ida_highlighter.hpp>
#ifdef WITH_HEXRAYS
//-V::730 Not all members of a class are initialized inside the constructor
#include <hexrays.hpp>
hexdsp_t *hexdsp = NULL;
#endif
#include "pywraps.hpp"
#include "pywraps.cpp"
//-------------------------------------------------------------------------
// Defines and constants
@@ -54,7 +49,6 @@ hexdsp_t *hexdsp = NULL;
#define S_IDAPYTHON "IDAPython"
#define S_INIT_PY "init.py"
static const char S_IDC_ARGS_VARNAME[] = "ARGV";
static const char S_MAIN[] = "__main__";
static const char S_IDC_RUNPYTHON_STATEMENT[] = "RunPythonStatement";
static const char S_IDAPYTHON_DATA_NODE[] = "IDAPython_Data";
@@ -80,9 +74,9 @@ static char g_idapython_dir[QMAXPATH];
//-------------------------------------------------------------------------
// Prototypes and forward declarations
// Alias to SWIG_Init
//lint -esym(526,init_idaapi) not defined
extern "C" void init_idaapi(void);
// // Alias to SWIG_Init
// //lint -esym(526,init_idaapi) not defined
// extern "C" void init_idaapi(void);
// Plugin run() callback
void idaapi run(int arg);
@@ -117,40 +111,186 @@ int tracefunc(PyObject *obj, _frame *frame, int what, PyObject *arg)
//-------------------------------------------------------------------------
// Helper routines to make Python script execution breakable from IDA
static int ninsns = 0; // number of times trace function was called
static bool box_displayed; // has the wait box been displayed?
static time_t start_time; // the start time of the execution
static int script_timeout = 2;
static bool g_ui_ready = false;
static bool g_alert_auto_scripts = true;
static bool g_remove_cwd_sys_path = false;
static bool g_use_local_python = false;
static bool g_autoimport_compat_idaapi = true;
static void end_execution(void);
static void begin_execution(void);
// Allowing the user to interrupt a script is not entirely trivial.
// Imagine the following script, that is run in an IDB that uses
// an IDAPython processor module (important!) :
// ---
// while True:
// gen_disasm_text(ea, ea + 4, dtext, False)
// ---
// This script will call the processor module's out/outop functions in
// order to generate the text. If the processor module behaves
// correctly (i.e., doesn't take forever to generate said text), if the
// user presses 'Cancel' once the wait dialog box shows, what we want
// to cancel is _this_ script above: we don't want to interrupt the
// processor module while it's doing its thing!
// In order to do that, we will have to remember the time-of-entry of
// various entry points:
// - IDAPython_extlang_compile_file
// - IDAPython_RunStatement
// - ... and more importantly in this case:
// - IDAPython_extlang_call_method (called by the IDA kernel to generate text)
//
// Of course, in case the processor module's out/outop misbehaves, we still
// want the ability to cancel that operation. The following code allows for
// that, too.
//-------------------------------------------------------------------------
struct exec_entry_t
{
time_t etime;
exec_entry_t() { etime = time(NULL); }
};
DECLARE_TYPE_AS_MOVABLE(exec_entry_t);
typedef qvector<exec_entry_t> exec_entries_t;
//-------------------------------------------------------------------------
struct execution_t
{
exec_entries_t entries;
int timeout;
uint32 steps_before_action;
bool waitdialog_shown;
execution_t()
: timeout(2),
steps_before_action(0),
waitdialog_shown(false)
{
reset_steps();
}
void reset_steps();
void push();
void pop();
bool can_interrupt_current(time_t now) const;
void stop_tracking();
void sync_to_present_time();
void maybe_hide_waitdialog();
static int on_trace(PyObject *obj, _frame *frame, int what, PyObject *arg);
};
static execution_t execution;
//#define LOG_EXEC 1
#ifdef LOG_EXEC
#define LEXEC(Format, ...) msg("IDAPython exec: " Format, __VA_ARGS__)
#else
#define LEXEC(Format, ...)
#endif
//-------------------------------------------------------------------------
void execution_t::reset_steps()
{
// we want to trace/check the time about every 10 steps. But we don't
// want it to be exactly 10 steps, or we might never make important
// checks because the tracing happens always at the wrong point.
// E.g., imagine the following loop:
// ---
// while True:
// gen_disasm_text(ea, ea + 4, dtext, False)
// ---
// If we never hit the 'trace' callback while in the 'while True' loop
// but always when performing the call to the processor module's 'out/outop'
// then the loop will never stop. That was happening on windows (optimized.)
steps_before_action = 1 + rand() % 20;
}
//-------------------------------------------------------------------------
void execution_t::push()
{
if ( entries.empty() )
PyEval_SetTrace(execution_t::on_trace, NULL);
entries.push_back();
LEXEC("push() (now: %d entries)\n", int(entries.size()));
}
//-------------------------------------------------------------------------
void execution_t::pop()
{
entries.pop_back();
if ( entries.empty() )
stop_tracking();
LEXEC("pop() (now: %d entries)\n", int(entries.size()));
}
//-------------------------------------------------------------------------
void execution_t::stop_tracking()
{
PyEval_SetTrace(NULL, NULL);
maybe_hide_waitdialog();
}
//-------------------------------------------------------------------------
void execution_t::sync_to_present_time()
{
time_t now = time(NULL);
for ( size_t i = 0, n = entries.size(); i < n; ++i )
entries[i].etime = now;
maybe_hide_waitdialog();
}
//-------------------------------------------------------------------------
void execution_t::maybe_hide_waitdialog()
{
if ( waitdialog_shown )
{
hide_wait_box();
waitdialog_shown = false;
}
}
//-------------------------------------------------------------------------
bool execution_t::can_interrupt_current(time_t now) const
{
LEXEC("can_interrupt_current(): nentries: %d\n", int(entries.size()));
if ( entries.empty() || timeout <= 0 )
return false;
const exec_entry_t &last = entries.back();
bool can = (now - last.etime) > timeout;
LEXEC("can_interrupt_current(): last: %d, now: %d (-> %d)\n",
int(last.etime), int(now), can);
return can;
}
//------------------------------------------------------------------------
// This callback is called on various interpreter events
static int break_check(PyObject *obj, _frame *frame, int what, PyObject *arg)
int execution_t::on_trace(PyObject *obj, _frame *frame, int what, PyObject *arg)
{
if ( wasBreak() )
{
// User pressed Cancel in the waitbox; send KeyboardInterrupt exception
PyErr_SetString(PyExc_KeyboardInterrupt, "User interrupted");
return -1;
}
else if ( !box_displayed && ++ninsns > 10 )
{
// We check the timer once every 10 calls
ninsns = 0;
LEXEC("on_trace() (steps=%d, nentries=%d)\n",
int(execution.steps_before_action), int(execution.entries.size()));
// we don't want to query for time at every trace event
if ( execution.steps_before_action-- > 0 )
return 0;
// Timeout disabled or elapsed?
if ( script_timeout != 0 && (time(NULL) - start_time > script_timeout) )
execution.reset_steps();
time_t now = time(NULL);
LEXEC("on_trace()::now: %d\n", int(now));
bool can_interrupt = execution.can_interrupt_current(now);
if ( can_interrupt )
{
LEXEC("on_trace()::can_interrupt. Waitdialog shown? %d\n",
int(execution.waitdialog_shown));
if ( execution.waitdialog_shown )
{
box_displayed = true;
if ( wasBreak() )
{
LEXEC("on_trace()::INTERRUPTING\n");
PyErr_SetString(PyExc_KeyboardInterrupt, "User interrupted");
return -1;
}
}
else
{
LEXEC("on_trace()::showing wait dialog\n");
show_wait_box("Running Python script");
execution.waitdialog_shown = true;
}
}
#ifdef ENABLE_PYTHON_PROFILING
return tracefunc(obj, frame, what, arg);
#else
@@ -162,84 +302,50 @@ static int break_check(PyObject *obj, _frame *frame, int what, PyObject *arg)
#endif
}
//------------------------------------------------------------------------
static void reset_execution_time()
//-------------------------------------------------------------------------
//lint -esym(1788, new_execution_t) is referenced only by its constructor or destructor
struct new_execution_t
{
start_time = time(NULL);
ninsns = 0;
}
//------------------------------------------------------------------------
// Prepare for Python execution
static void begin_execution()
{
if ( !g_ui_ready || script_timeout == 0 )
return;
PYW_GIL_CHECK_LOCKED_SCOPE();
end_execution();
reset_execution_time();
PyEval_SetTrace(break_check, NULL);
}
//---------------------------------------------------------------------------
static void hide_script_waitbox()
{
if ( box_displayed )
bool created;
new_execution_t()
{
hide_wait_box();
box_displayed = false;
created = g_ui_ready && execution.timeout > 0;
if ( created )
{
PYW_GIL_CHECK_LOCKED_SCOPE();
execution.push();
}
}
}
//------------------------------------------------------------------------
// Called after Python execution finishes
static void end_execution()
{
hide_script_waitbox();
PYW_GIL_CHECK_LOCKED_SCOPE();
#ifdef ENABLE_PYTHON_PROFILING
PyEval_SetTrace(tracefunc, NULL);
#else
PyEval_SetTrace(NULL, NULL);
#endif
}
//-------------------------------------------------------------------------
pycall_res_t::pycall_res_t(PyObject *pyo)
: result(pyo)
{
PYGLOG("return code: %p\n", result.o);
}
//-------------------------------------------------------------------------
pycall_res_t::~pycall_res_t()
{
if ( PyErr_Occurred() )
PyErr_Print();
}
~new_execution_t()
{
if ( created )
{
PYW_GIL_CHECK_LOCKED_SCOPE();
execution.pop();
}
}
};
//-------------------------------------------------------------------------
//lint -esym(714,disable_script_timeout) Symbol not referenced
void disable_script_timeout()
idaman void ida_export disable_script_timeout()
{
// Clear timeout
script_timeout = 0;
execution.timeout = 0;
// Uninstall the trace function and hide the waitbox (if it was shown)
end_execution();
execution.stop_tracking();
}
//-------------------------------------------------------------------------
//lint -esym(714,set_script_timeout) Symbol not referenced
int set_script_timeout(int timeout)
idaman int ida_export set_script_timeout(int timeout)
{
// Update the timeout
qswap(timeout, script_timeout);
qswap(timeout, execution.timeout);
// Reset the execution time and hide the waitbox (so it is shown again after timeout elapses)
reset_execution_time();
hide_script_waitbox();
execution.sync_to_present_time();
return timeout;
}
@@ -347,16 +453,17 @@ static bool idaapi IDAPython_extlang_run_statements(
{
errbuf[0] = '\0';
PyErr_Clear();
begin_execution();
newref_t result(PyRun_String(
str,
Py_file_input,
globals,
globals));
end_execution();
ok = result != NULL && !PyErr_Occurred();
if ( !ok )
handle_python_error(errbuf, errbufsize);
{
new_execution_t exec;
newref_t result(PyRun_String(
str,
Py_file_input,
globals,
globals));
ok = result != NULL && !PyErr_Occurred();
if ( !ok )
handle_python_error(errbuf, errbufsize);
}
}
if ( !ok && errbuf[0] == '\0' )
qstrncpy(errbuf, "internal error", errbufsize);
@@ -384,9 +491,10 @@ static error_t idaapi idc_runpythonstatement(
//--------------------------------------------------------------------------
static const cfgopt_t opts[] =
{
cfgopt_t("SCRIPT_TIMEOUT", &script_timeout, 0, INT_MAX),
cfgopt_t("SCRIPT_TIMEOUT", &execution.timeout, 0, INT_MAX),
cfgopt_t("ALERT_AUTO_SCRIPTS", &g_alert_auto_scripts, true),
cfgopt_t("REMOVE_CWD_SYS_PATH", &g_remove_cwd_sys_path, true),
cfgopt_t("AUTOIMPORT_COMPAT_IDAAPI", &g_autoimport_compat_idaapi, true),
};
//-------------------------------------------------------------------------
@@ -397,11 +505,11 @@ static bool check_python_dir()
{
S_IDC_MODNAME ".py",
S_INIT_PY,
"idaapi.py",
"ida_idaapi.py",
"idautils.py"
};
char filepath[QMAXPATH];
for ( size_t i=0; i<qnumber(script_files); i++ )
for ( size_t i=0; i < qnumber(script_files); i++ )
{
qmakepath(filepath, sizeof(filepath), g_idapython_dir, script_files[i], NULL);
if ( !qfileexist(filepath) )
@@ -417,14 +525,11 @@ static bool check_python_dir()
#ifdef __LINUX__
qmakepath(filepath, sizeof(filepath), g_idapython_dir, "lib", "python27.zip", NULL);
if ( qfileexist(filepath) )
#else
qmakepath(filepath, sizeof(filepath), g_idapython_dir, "lib", NULL);
if ( qisdir(filepath) )
#endif
{
deb(IDA_DEBUG_PLUGIN, "Found \"%s\"; assuming local Python.\n", filepath);
g_use_local_python = true;
}
#endif // __LINUX__
return true;
}
@@ -490,9 +595,10 @@ void IDAPython_RunStatement(void)
if ( asktext(sizeof(statement), statement, statement, "ACCEPT TABS\nEnter Python expressions") != NULL )
{
begin_execution();
PyRun_SimpleString(statement);
end_execution();
{
new_execution_t exec;
PyRun_SimpleString(statement);
}
// Store the statement to the database
history.setblob(statement, strlen(statement) + 1, 0, 'A');
@@ -547,7 +653,7 @@ static bool IDAPython_ExecFile(
ref_t py_execscript(get_idaapi_attr(idaapi_script));
if ( py_execscript == NULL )
{
qsnprintf(errbuf, errbufsz, "Could not find idaapi.%s ?!", idaapi_script);
qsnprintf(errbuf, errbufsz, "Could not find %s.%s ?!", S_IDA_IDAAPI_MODNAME, idaapi_script);
return false;
}
@@ -627,14 +733,15 @@ static bool IDAPython_ExecFile(
// Execute the Python script from the plugin
static bool RunScript(const char *script)
{
begin_execution();
char errbuf[MAXSTR];
bool ok = IDAPython_ExecFile(script, errbuf, sizeof(errbuf));
bool ok;
{
new_execution_t exec;
ok = IDAPython_ExecFile(script, errbuf, sizeof(errbuf));
}
if ( !ok )
warning("IDAPython: error executing '%s':\n%s", script, errbuf);
end_execution();
return ok;
}
@@ -648,7 +755,7 @@ static bool parse_py_modname(
char *modname,
char *attrname,
size_t sz,
const char *defmod = S_IDAAPI_MODNAME)
const char *defmod = S_IDA_IDAAPI_MODNAME)
{
const char *p = strchr(full_name, '.');
if ( p == NULL )
@@ -808,10 +915,8 @@ bool idaapi IDAPython_extlang_compile_file(
size_t errbufsize)
{
PYW_GIL_GET;
begin_execution();
bool ok = IDAPython_ExecFile(filename, errbuf, errbufsize);
end_execution();
return ok;
new_execution_t exec;
return IDAPython_ExecFile(filename, errbuf, errbufsize);
}
//-------------------------------------------------------------------------
@@ -823,14 +928,16 @@ static bool idaapi IDAPython_extlang_loadprocmod(
size_t errbufsize)
{
PYW_GIL_GET;
begin_execution();
bool ok = IDAPython_ExecFile(filename, errbuf, errbufsize, S_IDAAPI_LOADPROCMOD, procobj, true);
bool ok;
{
new_execution_t exec;
ok = IDAPython_ExecFile(filename, errbuf, errbufsize, S_IDAAPI_LOADPROCMOD, procobj, true);
}
if ( ok && procobj->is_zero() )
{
errbuf[0] = '\0';
ok = false;
}
end_execution();
return ok;
}
@@ -842,10 +949,8 @@ static bool idaapi IDAPython_extlang_unloadprocmod(
size_t errbufsize)
{
PYW_GIL_GET;
begin_execution();
bool ok = IDAPython_ExecFile(filename, errbuf, errbufsize, S_IDAAPI_UNLOADPROCMOD);
end_execution();
return ok;
new_execution_t exec;
return IDAPython_ExecFile(filename, errbuf, errbufsize, S_IDAAPI_UNLOADPROCMOD);
}
//-------------------------------------------------------------------------
@@ -1076,9 +1181,10 @@ bool idaapi IDAPython_extlang_calcexpr(
ref_t result;
if ( ok )
{
begin_execution();
result = newref_t(PyRun_String(expr, Py_eval_input, globals, globals));
end_execution();
{
new_execution_t exec;
result = newref_t(PyRun_String(expr, Py_eval_input, globals, globals));
}
ok = return_python_result(rv, result, errbuf, errbufsize);
}
return ok;
@@ -1105,7 +1211,8 @@ bool idaapi IDAPython_extlang_call_method(
// Behave like run()
else if ( idc_obj == NULL && method_name != NULL )
{
return IDAPython_extlang_run(method_name, nargs, args, result, errbuf, errbufsize);
new_execution_t exec;
return IDAPython_extlang_run(method_name, nargs, args, result, errbuf, errbufsize);
}
// Holds conversion status of input object
@@ -1135,8 +1242,11 @@ bool idaapi IDAPython_extlang_call_method(
if ( !ok )
break;
newref_t py_res(PyObject_CallObject(py_method.o, pargs.empty() ? NULL : pargs[0].o));
ok = return_python_result(result, py_res, errbuf, errbufsize);
{
new_execution_t exec;
newref_t py_res(PyObject_CallObject(py_method.o, pargs.empty() ? NULL : pargs[0].o));
ok = return_python_result(result, py_res, errbuf, errbufsize);
}
} while ( false );
return ok;
@@ -1196,7 +1306,7 @@ const extlang_t extlang_python =
};
//-------------------------------------------------------------------------
void enable_extlang_python(bool enable)
idaman void ida_export enable_extlang_python(bool enable)
{
if ( enable )
select_extlang(&extlang_python);
@@ -1247,9 +1357,10 @@ bool idaapi IDAPython_cli_execute_line(const char *line)
line = s.c_str();
} while (false);
begin_execution();
PythonEvalOrExec(line);
end_execution();
{
new_execution_t exec;
PythonEvalOrExec(line);
}
return true;
}
@@ -1294,7 +1405,7 @@ static const cli_t cli_python =
//-------------------------------------------------------------------------
// Control the Python CLI status
void enable_python_cli(bool enable)
idaman void ida_export enable_python_cli(bool enable)
{
if ( enable )
install_command_interpreter(&cli_python);
@@ -1302,14 +1413,6 @@ void enable_python_cli(bool enable)
remove_command_interpreter(&cli_python);
}
//-------------------------------------------------------------------------
// Prints the IDAPython copyright banner
void py_print_banner()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
PyRun_SimpleString("print_banner()");
}
//------------------------------------------------------------------------
// Parse plugin options
void parse_plugin_options()
@@ -1362,37 +1465,25 @@ void convert_idc_args()
PyObject_SetAttrString(py_mod.o, S_IDC_ARGS_VARNAME, py_args.o);
}
#ifdef WITH_HEXRAYS
//-------------------------------------------------------------------------
static bool is_hexrays_plugin(const plugin_info_t *pinfo)
{
bool is_hx = false;
if ( pinfo != NULL && pinfo->entry != NULL )
{
const plugin_t *p = pinfo->entry;
if ( streq(p->wanted_name, "Hex-Rays Decompiler") )
is_hx = true;
}
return is_hx;
}
#endif
//------------------------------------------------------------------------
//lint -esym(715,va) Symbol not referenced
static int idaapi on_ui_notification(void *, int code, va_list va)
static int idaapi on_ui_notification(void *, int code, va_list)
{
#ifdef WITH_HEXRAYS
qnotused(va);
#endif
switch ( code )
{
case ui_ready_to_run:
case ui_term:
{
PYW_GIL_GET; // This hook gets called from the kernel. Ensure we hold the GIL.
g_ui_ready = true;
py_print_banner();
// Let's make sure there are no non-Free()d forms.
free_compiled_form_instances();
}
break;
case ui_ready_to_run:
{
PYW_GIL_GET; // See above
g_ui_ready = true;
PyRun_SimpleString("print_banner()");
if ( g_run_when == run_on_ui_ready )
RunScript(g_run_script);
}
@@ -1400,50 +1491,13 @@ static int idaapi on_ui_notification(void *, int code, va_list va)
case ui_database_inited:
{
PYW_GIL_GET; // This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET; // See above
convert_idc_args();
if ( g_run_when == run_on_db_open )
RunScript(g_run_script);
}
break;
case ui_term:
{
PYW_GIL_GET;
// Let's make sure there are no non-Free()d forms.
free_compiled_form_instances();
}
break;
#ifdef WITH_HEXRAYS
case ui_plugin_loaded:
if ( hexdsp == NULL )
{
if ( is_hexrays_plugin(va_arg(va, plugin_info_t *)) )
{
init_hexrays_plugin(0);
if ( hexdsp != NULL )
msg("IDAPython Hex-Rays bindings initialized.\n");
}
}
break;
case ui_plugin_unloading:
{
if ( hexdsp != NULL )
{
// Hex-Rays will close. Make sure all the refcounted cfunc_t objects
// are cleared right away.
if ( is_hexrays_plugin(va_arg(va, plugin_info_t *)) )
{
hexrays_clear_python_cfuncptr_t_references();
hexdsp = NULL;
}
}
}
break;
#endif
default:
break;
}
@@ -1452,7 +1506,6 @@ static int idaapi on_ui_notification(void *, int code, va_list va)
//-------------------------------------------------------------------------
//lint -esym(526,til_clear_python_tinfo_t_instances) not defined
extern void til_clear_python_tinfo_t_instances(void);
static int idaapi on_idp_notification(void *, int code, va_list)
{
switch ( code )
@@ -1462,6 +1515,8 @@ static int idaapi on_idp_notification(void *, int code, va_list)
// through all the tinfo_t objects that are embedded in SWIG wrappers,
// (i.e., that were created from Python) and clear those.
til_clear_python_tinfo_t_instances();
// Same thing for live python timers
clear_python_timer_instances();
break;
}
return 0;
@@ -1498,8 +1553,9 @@ static int idaapi ui_debug_handler_cb(void *, int code, va_list)
#endif
//-------------------------------------------------------------------------
// remove current directory (empty entry) from the sys.path
static void sanitize_path()
// - remove current directory (empty entry) from the sys.path
// - add idadir("python")
static void prepare_sys_path()
{
char buf[QMAXPATH];
qstrncpy(buf, Py_GetPath(), sizeof(buf));
@@ -1517,6 +1573,9 @@ static void sanitize_path()
newpath.append(DELIMITER);
newpath.append(d0);
}
if ( !newpath.empty() )
newpath.append(DELIMITER);
newpath.append(idadir("python"));
PySys_SetPath(newpath.begin());
}
@@ -1540,6 +1599,26 @@ static bool initsite(void)
return true;
}
//-------------------------------------------------------------------------
static void init_ida_modules()
{
// char buf[QMAXPATH];
// // IDA_MODULES must be passed as a define
// qstrncpy(buf, IDA_MODULES, sizeof(buf));
// char *ctx;
// for ( char *module = qstrtok(buf, ",", &ctx);
// module != NULL;
// module = qstrtok(NULL, DELIMITER, &ctx) )
// {
// deb(IDA_DEBUG_PLUGIN, "Initializing \"ida_%s\"\n", module);
// }
// Load the 'ida_idaapi' module, that contains some important bits of code
// ref_t ida_idaapi(PyW_TryImportModule(S_PY_IDA_IDAAPI_MODNAME));
// ref_t sys(PyW_TryImportModule("sys"));
}
//-------------------------------------------------------------------------
// Initialize the Python environment
bool IDAPython_Init(void)
@@ -1629,7 +1708,7 @@ bool IDAPython_Init(void)
}
// remove current directory
sanitize_path();
prepare_sys_path();
// import "site"
if ( !g_use_local_python && !initsite() )
@@ -1642,8 +1721,7 @@ bool IDAPython_Init(void)
if ( !PyEval_ThreadsInitialized() )
PyEval_InitThreads();
// Init the SWIG wrapper
init_idaapi();
init_ida_modules();
#ifdef Py_DEBUG
msg("HexraysPython: Python compiled with DEBUG enabled.\n");
@@ -1654,13 +1732,23 @@ bool IDAPython_Init(void)
tmp,
sizeof(tmp),
"IDAPYTHON_VERSION=(%d, %d, %d, '%s', %d)\n"
"IDAPYTHON_REMOVE_CWD_SYS_PATH = %s\n",
"IDAPYTHON_REMOVE_CWD_SYS_PATH = %s\n"
"IDAPYTHON_DYNLOAD_BASE = r\"%s\"\n"
"IDAPYTHON_DYNLOAD_RELPATH = \"ida_%d\"\n"
"IDAPYTHON_COMPAT_AUTOIMPORT_MODULES = %s\n",
VER_MAJOR,
VER_MINOR,
VER_PATCH,
VER_STATUS,
VER_SERIAL,
g_remove_cwd_sys_path ? "True" : "False");
g_remove_cwd_sys_path ? "True" : "False",
idadir(NULL),
#ifdef __EA64__
64,
#else
32,
#endif
g_autoimport_compat_idaapi ? "True" : "False");
PyRun_SimpleString(tmp);
// Install extlang. Needs to be done before running init.py
+42
View File
@@ -0,0 +1,42 @@
import sys
${IMPORTS}
class idaapi_Cvar(object):
def __init__(self):
# prevent endless recursion
object.__setattr__(self, "modules", "${MODULES}".split(","))
object.__setattr__(self, "cvars_entries", dict())
def _get_module_cvar(self, modname):
mod = sys.modules["ida_%s" % modname]
cv, entries = None, None
if hasattr(mod, "cvar"):
cv = getattr(mod, "cvar")
entries = []
if cv:
if modname in self.cvars_entries.keys():
entries = self.cvars_entries[modname]
else:
# Parse 'str' version of cvar. Although this is braindeader than
# braindead, I'm not sure there's another way to do it.
entries_s = str(cv)
entries = entries_s[1:len(entries_s)-1].split(", ")
self.cvars_entries[modname] = entries
return cv, entries
def __getattr__(self, attr):
for mod in self.modules:
cv, entries = self._get_module_cvar(mod)
if cv and attr in entries:
return getattr(cv, attr)
def __setattr__(self, attr, value):
for mod in self.modules:
cv, entries = self._get_module_cvar(mod)
if cv and attr in entries:
setattr(cv, attr, value)
cvar = idaapi_Cvar()
Regular → Executable
+106 -91
View File
@@ -11,7 +11,22 @@
"""
idautils.py - High level utility functions for IDA
"""
import idaapi
import ida_bytes
import ida_dbg
import ida_entry
import ida_funcs
import ida_ida
import ida_idaapi
import ida_idd
import ida_idp
import ida_kernwin
import ida_loader
import ida_nalt
import ida_name
import ida_segment
import ida_strlist
import ida_ua
import ida_xref
import idc
import types
import os
@@ -22,7 +37,7 @@ def refs(ea, funcfirst, funcnext):
Generic reference collector - INTERNAL USE ONLY.
"""
ref = funcfirst(ea)
while ref != idaapi.BADADDR:
while ref != ida_idaapi.BADADDR:
yield ref
ref = funcnext(ea, ref)
@@ -43,9 +58,9 @@ def CodeRefsTo(ea, flow):
print ref
"""
if flow == 1:
return refs(ea, idaapi.get_first_cref_to, idaapi.get_next_cref_to)
return refs(ea, ida_xref.get_first_cref_to, ida_xref.get_next_cref_to)
else:
return refs(ea, idaapi.get_first_fcref_to, idaapi.get_next_fcref_to)
return refs(ea, ida_xref.get_first_fcref_to, ida_xref.get_next_fcref_to)
def CodeRefsFrom(ea, flow):
@@ -64,9 +79,9 @@ def CodeRefsFrom(ea, flow):
print ref
"""
if flow == 1:
return refs(ea, idaapi.get_first_cref_from, idaapi.get_next_cref_from)
return refs(ea, ida_xref.get_first_cref_from, ida_xref.get_next_cref_from)
else:
return refs(ea, idaapi.get_first_fcref_from, idaapi.get_next_fcref_from)
return refs(ea, ida_xref.get_first_fcref_from, ida_xref.get_next_fcref_from)
def DataRefsTo(ea):
@@ -82,7 +97,7 @@ def DataRefsTo(ea):
for ref in DataRefsTo(ScreenEA()):
print ref
"""
return refs(ea, idaapi.get_first_dref_to, idaapi.get_next_dref_to)
return refs(ea, ida_xref.get_first_dref_to, ida_xref.get_next_dref_to)
def DataRefsFrom(ea):
@@ -98,7 +113,7 @@ def DataRefsFrom(ea):
for ref in DataRefsFrom(ScreenEA()):
print ref
"""
return refs(ea, idaapi.get_first_dref_from, idaapi.get_next_dref_from)
return refs(ea, ida_xref.get_first_dref_from, ida_xref.get_next_dref_from)
def XrefTypeName(typecode):
@@ -141,14 +156,14 @@ def XrefsFrom(ea, flags=0):
Return all references from address 'ea'
@param ea: Reference address
@param flags: any of idaapi.XREF_* flags
@param flags: any of ida_xref.XREF_* flags
Example::
for xref in XrefsFrom(here(), 0):
print xref.type, XrefTypeName(xref.type), \
'from', hex(xref.frm), 'to', hex(xref.to)
"""
xref = idaapi.xrefblk_t()
xref = ida_xref.xrefblk_t()
if xref.first_from(ea, flags):
yield _copy_xref(xref)
while xref.next_from():
@@ -160,14 +175,14 @@ def XrefsTo(ea, flags=0):
Return all references to address 'ea'
@param ea: Reference address
@param flags: any of idaapi.XREF_* flags
@param flags: any of ida_xref.XREF_* flags
Example::
for xref in XrefsTo(here(), 0):
print xref.type, XrefTypeName(xref.type), \
'from', hex(xref.frm), 'to', hex(xref.to)
"""
xref = idaapi.xrefblk_t()
xref = ida_xref.xrefblk_t()
if xref.first_to(ea, flags):
yield _copy_xref(xref)
while xref.next_to():
@@ -189,15 +204,15 @@ def Heads(start=None, end=None):
@return: list of heads between start and end
"""
if not start: start = idaapi.cvar.inf.minEA
if not end: end = idaapi.cvar.inf.maxEA
if not start: start = ida_ida.cvar.inf.minEA
if not end: end = ida_ida.cvar.inf.maxEA
ea = start
if not idc.isHead(idc.GetFlags(ea)):
ea = idaapi.next_head(ea, end)
while ea != idaapi.BADADDR:
ea = ida_bytes.next_head(ea, end)
while ea != ida_idaapi.BADADDR:
yield ea
ea = idaapi.next_head(ea, end)
ea = ida_bytes.next_head(ea, end)
def Functions(start=None, end=None):
@@ -214,21 +229,21 @@ def Functions(start=None, end=None):
in multiple segments will be reported multiple times, once in each segment
as they are listed.
"""
if not start: start = idaapi.cvar.inf.minEA
if not end: end = idaapi.cvar.inf.maxEA
if not start: start = ida_ida.cvar.inf.minEA
if not end: end = ida_ida.cvar.inf.maxEA
# find first function head chunk in the range
chunk = idaapi.get_fchunk(start)
chunk = ida_funcs.get_fchunk(start)
if not chunk:
chunk = idaapi.get_next_fchunk(start)
while chunk and chunk.startEA < end and (chunk.flags & idaapi.FUNC_TAIL) != 0:
chunk = idaapi.get_next_fchunk(chunk.startEA)
chunk = ida_funcs.get_next_fchunk(start)
while chunk and chunk.startEA < end and (chunk.flags & ida_funcs.FUNC_TAIL) != 0:
chunk = ida_funcs.get_next_fchunk(chunk.startEA)
func = chunk
while func and func.startEA < end:
startea = func.startEA
yield startea
func = idaapi.get_next_func(startea)
func = ida_funcs.get_next_func(startea)
def Chunks(start):
@@ -240,7 +255,7 @@ def Chunks(start):
@return: list of funcion chunks (tuples of the form (start_ea, end_ea))
belonging to the function
"""
func_iter = idaapi.func_tail_iterator_t( idaapi.get_func( start ) )
func_iter = ida_funcs.func_tail_iterator_t( ida_funcs.get_func( start ) )
status = func_iter.main()
while status:
chunk = func_iter.chunk()
@@ -252,11 +267,11 @@ def Modules():
"""
Returns a list of module objects with name,size,base and the rebase_to attributes
"""
mod = idaapi.module_info_t()
result = idaapi.get_first_module(mod)
mod = ida_idd.module_info_t()
result = ida_dbg.get_first_module(mod)
while result:
yield idaapi.object_t(name=mod.name, size=mod.size, base=mod.base, rebase_to=mod.rebase_to)
result = idaapi.get_next_module(mod)
yield ida_idaapi.object_t(name=mod.name, size=mod.size, base=mod.base, rebase_to=mod.rebase_to)
result = ida_dbg.get_next_module(mod)
def Names():
@@ -265,9 +280,9 @@ def Names():
@return: List of tuples (ea, name)
"""
for i in xrange(idaapi.get_nlist_size()):
ea = idaapi.get_nlist_ea(i)
name = idaapi.get_nlist_name(i)
for i in xrange(ida_name.get_nlist_size()):
ea = ida_name.get_nlist_ea(i)
name = ida_name.get_nlist_name(i)
yield (ea, name)
@@ -277,8 +292,8 @@ def Segments():
@return: List of segment start addresses.
"""
for n in xrange(idaapi.get_segm_qty()):
seg = idaapi.getnseg(n)
for n in xrange(ida_segment.get_segm_qty()):
seg = ida_segment.getnseg(n)
if seg:
yield seg.startEA
@@ -289,11 +304,11 @@ def Entries():
@return: List of tuples (index, ordinal, ea, name)
"""
n = idaapi.get_entry_qty()
n = ida_entry.get_entry_qty()
for i in xrange(0, n):
ordinal = idaapi.get_entry_ordinal(i)
ea = idaapi.get_entry(ordinal)
name = idaapi.get_entry_name(ordinal)
ordinal = ida_entry.get_entry_ordinal(i)
ea = ida_entry.get_entry(ordinal)
name = ida_entry.get_entry_name(ordinal)
yield (i, ordinal, ea, name)
@@ -305,10 +320,10 @@ def FuncItems(start):
@return: ea of each item in the function
"""
func = idaapi.get_func(start)
func = ida_funcs.get_func(start)
if not func:
return
fii = idaapi.func_item_iterator_t()
fii = ida_funcs.func_item_iterator_t()
ok = fii.set(func)
while ok:
yield fii.current()
@@ -322,7 +337,7 @@ def Structs():
@return: List of tuples (idx, sid, name)
"""
idx = idc.GetFirstStrucIdx()
while idx != idaapi.BADADDR:
while idx != ida_idaapi.BADADDR:
sid = idc.GetStrucId(idx)
yield (idx, sid, idc.GetStrucName(sid))
idx = idc.GetNextStrucIdx(idx)
@@ -344,7 +359,7 @@ def StructMembers(sid):
m = idc.GetFirstMember(sid)
if m == -1:
raise Exception("No structure with ID: 0x%x" % sid)
while (m != idaapi.BADADDR):
while (m != ida_idaapi.BADADDR):
name = idc.GetMemberName(sid, m)
if name:
yield (m, name, idc.GetMemberSize(sid, m))
@@ -359,11 +374,11 @@ def DecodePrecedingInstruction(ea):
@return: (None or the decode instruction, farref)
farref will contain 'true' if followed an xref, false otherwise
"""
prev_addr, farref = idaapi.decode_preceding_insn(ea)
if prev_addr == idaapi.BADADDR:
prev_addr, farref = ida_ua.decode_preceding_insn(ea)
if prev_addr == ida_idaapi.BADADDR:
return (None, False)
else:
return (idaapi.cmd.copy(), farref)
return (ida_ua.cmd.copy(), farref)
@@ -374,11 +389,11 @@ def DecodePreviousInstruction(ea):
@param ea: address to decode
@return: None or a new insn_t instance
"""
prev_addr = idaapi.decode_prev_insn(ea)
if prev_addr == idaapi.BADADDR:
prev_addr = ida_ua.decode_prev_insn(ea)
if prev_addr == ida_idaapi.BADADDR:
return None
return idaapi.cmd.copy()
return ida_ua.cmd.copy()
def DecodeInstruction(ea):
@@ -388,11 +403,11 @@ def DecodeInstruction(ea):
@param ea: address to decode
@return: None or a new insn_t instance
"""
inslen = idaapi.decode_insn(ea)
inslen = ida_ua.decode_insn(ea)
if inslen == 0:
return None
return idaapi.cmd.copy()
return ida_ua.cmd.copy()
def GetDataList(ea, count, itemsize=1):
@@ -400,13 +415,13 @@ def GetDataList(ea, count, itemsize=1):
Get data list - INTERNAL USE ONLY
"""
if itemsize == 1:
getdata = idaapi.get_byte
getdata = ida_bytes.get_byte
elif itemsize == 2:
getdata = idaapi.get_word
getdata = ida_bytes.get_word
elif itemsize == 4:
getdata = idaapi.get_long
getdata = ida_bytes.get_long
elif itemsize == 8:
getdata = idaapi.get_qword
getdata = ida_bytes.get_qword
else:
raise ValueError, "Invalid data size! Must be 1, 2, 4 or 8"
@@ -424,11 +439,11 @@ def PutDataList(ea, datalist, itemsize=1):
putdata = None
if itemsize == 1:
putdata = idaapi.patch_byte
putdata = ida_bytes.patch_byte
if itemsize == 2:
putdata = idaapi.patch_word
putdata = ida_bytes.patch_word
if itemsize == 4:
putdata = idaapi.patch_long
putdata = ida_bytes.patch_long
assert putdata, "Invalid data size! Must be 1, 2 or 4"
@@ -488,22 +503,22 @@ class Strings(object):
return not self.is_2_bytes_encoding() and not self.is_4_bytes_encoding()
def is_2_bytes_encoding(self):
return (self.type & 7) in [idaapi.ASCSTR_UTF16, idaapi.ASCSTR_ULEN2, idaapi.ASCSTR_ULEN4]
return (self.type & 7) in [ida_nalt.ASCSTR_UTF16, ida_nalt.ASCSTR_ULEN2, ida_nalt.ASCSTR_ULEN4]
def is_4_bytes_encoding(self):
return (self.type & 7) == idaapi.ASCSTR_UTF32
return (self.type & 7) == ida_nalt.ASCSTR_UTF32
def _toseq(self, as_unicode):
if self.is_2_bytes_encoding():
conv = idaapi.ACFOPT_UTF16
conv = ida_bytes.ACFOPT_UTF16
pyenc = "utf-16"
elif self.is_4_bytes_encoding():
conv = idaapi.ACFOPT_UTF8
conv = ida_bytes.ACFOPT_UTF8
pyenc = "utf-8"
else:
conv = idaapi.ACFOPT_ASCII
conv = ida_bytes.ACFOPT_ASCII
pyenc = 'ascii'
strbytes = idaapi.get_ascii_contents2(self.ea, self.length, self.type, conv)
strbytes = ida_bytes.get_ascii_contents2(self.ea, self.length, self.type, conv)
return unicode(strbytes, pyenc, 'replace') if as_unicode else strbytes
def __str__(self):
@@ -544,17 +559,17 @@ class Strings(object):
else:
self.refresh()
self._si = idaapi.string_info_t()
self._si = ida_strlist.string_info_t()
def refresh(self, ea1=None, ea2=None):
"""Refreshes the strings list"""
if ea1 is None:
ea1 = idaapi.cvar.inf.minEA
ea1 = ida_ida.cvar.inf.minEA
if ea2 is None:
ea2 = idaapi.cvar.inf.maxEA
ea2 = ida_ida.cvar.inf.maxEA
idaapi.refresh_strlist(ea1, ea2)
self.size = idaapi.get_strlist_qty()
ida_strlist.refresh_strlist(ea1, ea2)
self.size = ida_strlist.get_strlist_qty()
def setup(self,
@@ -567,26 +582,26 @@ class Strings(object):
display_only_existing_strings = False):
if ea1 is None:
ea1 = idaapi.cvar.inf.minEA
ea1 = ida_ida.cvar.inf.minEA
if ea2 is None:
ea2 = idaapi.cvar.inf.maxEA
ea2 = ida_ida.cvar.inf.maxEA
t = idaapi.strwinsetup_t()
t = ida_strlist.strwinsetup_t()
t.strtypes = strtypes
t.minlen = minlen
t.only_7bit = only_7bit
t.ea1 = ea1
t.ea2 = ea2
t.display_only_existing_strings = display_only_existing_strings
idaapi.set_strlist_options(t)
ida_strlist.set_strlist_options(t)
# Automatically refreshes
self.refresh()
def _get_item(self, index):
if not idaapi.get_strlist_item(index, self._si):
if not ida_strlist.get_strlist_item(index, self._si):
return None
else:
return Strings.StringItem(self._si)
@@ -610,17 +625,17 @@ def GetIdbDir():
This function returns directory path of the current IDB database
"""
return os.path.dirname(idaapi.cvar.database_idb) + os.sep
return os.path.dirname(ida_loader.cvar.database_idb) + os.sep
# -----------------------------------------------------------------------
def GetRegisterList():
"""Returns the register list"""
return idaapi.ph_get_regnames()
return ida_idp.ph_get_regnames()
# -----------------------------------------------------------------------
def GetInstructionList():
"""Returns the instruction list of the current processor module"""
return [i[0] for i in idaapi.ph_get_instruc() if i[0]]
return [i[0] for i in ida_idp.ph_get_instruc() if i[0]]
# -----------------------------------------------------------------------
def _Assemble(ea, line):
@@ -633,11 +648,11 @@ def _Assemble(ea, line):
lines = line
ret = []
for line in lines:
seg = idaapi.getseg(ea)
seg = ida_segment.getseg(ea)
if not seg:
return (False, "No segment at ea")
ip = ea - (idaapi.ask_selector(seg.sel) << 4)
buf = idaapi.AssembleLine(ea, seg.sel, ip, seg.bitness, line)
ip = ea - (ida_segment.ask_selector(seg.sel) << 4)
buf = ida_idp.AssembleLine(ea, seg.sel, ip, seg.bitness, line)
if not buf:
return (False, "Assembler failed: " + line)
ea += len(buf)
@@ -705,10 +720,10 @@ class _reg_dtyp_t(object):
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):
ri = ida_idp.reg_info_t()
if not ida_idp.parse_reg_name(attr, ri):
raise AttributeError()
r = _reg_dtyp_t(ri.reg, ord(idaapi.get_dtyp_by_size(ri.size)))
r = _reg_dtyp_t(ri.reg, ord(ida_ua.get_dtyp_by_size(ri.size)))
self.__dict__[attr] = r
return r
@@ -754,7 +769,7 @@ class __process_ui_actions_helper(object):
return False
# Execute one action
idaapi.process_ui_action(
ida_kernwin.process_ui_action(
self.__action_list[self.__idx],
self.__flags)
@@ -775,7 +790,7 @@ def ProcessUiActions(actions, flags=0):
# Instantiate a helper
helper = __process_ui_actions_helper(actions, flags)
return False if len(helper) < 1 else idaapi.execute_ui_requests((helper,))
return False if len(helper) < 1 else ida_kernwin.execute_ui_requests((helper,))
# -----------------------------------------------------------------------
@@ -786,15 +801,15 @@ class peutils_t(object):
Constants from pe.h
"""
PE_NODE = "$ PE header" # netnode name for PE header
PE_ALT_DBG_FPOS = idaapi.BADADDR & -1 # altval() -> translated fpos of debuginfo
PE_ALT_IMAGEBASE = idaapi.BADADDR & -2 # altval() -> loading address (usually pe.imagebase)
PE_ALT_PEHDR_OFF = idaapi.BADADDR & -3 # altval() -> offset of PE header
PE_ALT_NEFLAGS = idaapi.BADADDR & -4 # altval() -> neflags
PE_ALT_TDS_LOADED = idaapi.BADADDR & -5 # altval() -> tds already loaded(1) or invalid(-1)
PE_ALT_PSXDLL = idaapi.BADADDR & -6 # altval() -> if POSIX(x86) imports from PSXDLL netnode
PE_ALT_DBG_FPOS = ida_idaapi.BADADDR & -1 # altval() -> translated fpos of debuginfo
PE_ALT_IMAGEBASE = ida_idaapi.BADADDR & -2 # altval() -> loading address (usually pe.imagebase)
PE_ALT_PEHDR_OFF = ida_idaapi.BADADDR & -3 # altval() -> offset of PE header
PE_ALT_NEFLAGS = ida_idaapi.BADADDR & -4 # altval() -> neflags
PE_ALT_TDS_LOADED = ida_idaapi.BADADDR & -5 # altval() -> tds already loaded(1) or invalid(-1)
PE_ALT_PSXDLL = ida_idaapi.BADADDR & -6 # altval() -> if POSIX(x86) imports from PSXDLL netnode
def __init__(self):
self.__penode = idaapi.netnode()
self.__penode = ida_netnode.netnode()
self.__penode.create(peutils_t.PE_NODE)
imagebase = property(
Regular → Executable
+952 -970
View File
File diff suppressed because it is too large Load Diff
Regular → Executable
+26 -14
View File
@@ -15,10 +15,21 @@ import os
import sys
import time
import warnings
import _idaapi
# Prepare sys.path so loading of the shared objects works
sys.path.append(os.path.join(sys.executable, IDAPYTHON_DYNLOAD_BASE, "python", "lib", "python2.7", "lib-dynload", IDAPYTHON_DYNLOAD_RELPATH))
try:
import ida_idaapi
import ida_kernwin
import ida_diskio
except ImportError as e:
print "Import failed: %s. Current sys.path:" % str(e)
for p in sys.path:
print "\t%s" % p
raise
# __EA64__ is set if IDA is running in 64-bit mode
__EA64__ = _idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
__EA64__ = ida_idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
# -----------------------------------------------------------------------
# Take over the standard text outputs
@@ -30,7 +41,7 @@ class IDAPythonStdOut:
def write(self, text):
# NB: in case 'text' is Unicode, msg() will decode it
# and call umsg() to print it
_idaapi.msg(text)
ida_kernwin.msg(text)
def flush(self):
pass
@@ -49,8 +60,8 @@ def runscript(script):
@return: Error string or None on success
"""
import idaapi
return idaapi.IDAPython_ExecScript(script, globals())
import ida_idaapi
return ida_idaapi.IDAPython_ExecScript(script, globals())
# -----------------------------------------------------------------------
def print_banner():
@@ -77,14 +88,14 @@ sys.stdout = sys.stderr = IDAPythonStdOut()
import pydoc
class IDAPythonHelpPrompter:
def readline(self):
return idaapi.askstr(0, '', 'Help topic?')
return ida_kernwin.askstr(0, '', 'Help topic?')
help = pydoc.Helper(input = IDAPythonHelpPrompter(), output = sys.stdout)
# Assign a default sys.argv
sys.argv = [""]
# Have to make sure Python finds our modules
sys.path.append(_idaapi.idadir("python"))
sys.path.append(ida_diskio.idadir("python"))
# Remove current directory from the top of the patch search
if '' in sys.path: # On non Windows, the empty path is added
@@ -97,15 +108,16 @@ if os.getcwd() in sys.path:
if not IDAPYTHON_REMOVE_CWD_SYS_PATH:
sys.path.append(os.getcwd())
# Import all the required modules
from idaapi import Choose, get_user_idadir, cvar, Choose2, Appcall, Form
from idc import *
from idautils import *
import idaapi
if IDAPYTHON_COMPAT_AUTOIMPORT_MODULES:
# Import all the required modules
from idaapi import Choose, get_user_idadir, cvar, Choose2, Appcall, Form
from idc import *
from idautils import *
import idaapi
# Load the users personal init file
userrc = os.path.join(get_user_idadir(), "idapythonrc.py")
userrc = os.path.join(ida_diskio.get_user_idadir(), "idapythonrc.py")
if os.path.exists(userrc):
idaapi.IDAPython_ExecScript(userrc, globals())
ida_idaapi.IDAPython_ExecScript(userrc, globals())
# All done, ready to rock.
+2515
View File
File diff suppressed because it is too large Load Diff
+497 -65
View File
@@ -1,6 +1,8 @@
#ifndef __PYWRAPS_HPP__
#define __PYWRAPS_HPP__
#include <Python.h>
//------------------------------------------------------------------------
// Types
#ifndef PYUL_DEFINED
@@ -14,6 +16,10 @@
#endif
#endif
// a few forward decls
class insn_t;
class op_t;
struct switch_info_ex_t;
// "A pointer can be explicitly converted to any integral type large
// enough to hold it. The mapping function is implementation-defined."
@@ -37,6 +43,11 @@
#define PTR2U64(Binding) (uint64(uint32(Binding)))
#endif
#if defined(__LINUX__) || defined(__MAC__)
#define exported __attribute__((visibility("default")))
#else
#define exported
#endif
#ifdef __EA64__
#define PY_FMT64 "K"
@@ -47,7 +58,10 @@
#endif
//------------------------------------------------------------------------
#define S_IDAAPI_MODNAME "idaapi"
#define S_IDA_IDAAPI_MODNAME "ida_idaapi"
#define S_IDA_NALT_MODNAME "ida_nalt"
#define S_IDA_UA_MODNAME "ida_ua"
#define S_IDA_KERNWIN_MODNAME "ida_kernwin"
#define S_IDC_MODNAME "idc"
#define S_IDAAPI_EXECSCRIPT "IDAPython_ExecScript"
#define S_IDAAPI_COMPLETION "IDAPython_Completion"
@@ -55,6 +69,83 @@
#define S_IDAAPI_LOADPROCMOD "IDAPython_LoadProcMod"
#define S_IDAAPI_UNLOADPROCMOD "IDAPython_UnLoadProcMod"
//------------------------------------------------------------------------
// String constants used
static const char S_PYINVOKE0[] = "_py_invoke0";
static const char S_PY_SWIEX_CLSNAME[] = "switch_info_ex_t";
static const char S_PY_OP_T_CLSNAME[] = "op_t";
static const char S_PROPS[] = "props";
static const char S_NAME[] = "name";
static const char S_TITLE[] = "title";
static const char S_ASM_KEYWORD[] = "asm_keyword";
static const char S_MENU_NAME[] = "menu_name";
static const char S_HOTKEY[] = "hotkey";
static const char S_EMBEDDED[] = "embedded";
static const char S_POPUP_NAMES[] = "popup_names";
static const char S_FLAGS[] = "flags";
static const char S_VALUE_SIZE[] = "value_size";
static const char S_MAY_CREATE_AT[] = "may_create_at";
static const char S_CALC_ITEM_SIZE[] = "calc_item_size";
static const char S_ID[] = "id";
static const char S_PRINTF[] = "printf";
static const char S_TEXT_WIDTH[] = "text_width";
static const char S_SCAN[] = "scan";
static const char S_ANALYZE[] = "analyze";
static const char S_CBSIZE[] = "cbsize";
static const char S_ON_CLICK[] = "OnClick";
static const char S_ON_CLOSE[] = "OnClose";
static const char S_ON_DBL_CLICK[] = "OnDblClick";
static const char S_ON_CURSOR_POS_CHANGED[] = "OnCursorPosChanged";
static const char S_ON_KEYDOWN[] = "OnKeydown";
static const char S_ON_COMPLETE_LINE[] = "OnCompleteLine";
static const char S_ON_CREATE[] = "OnCreate";
static const char S_ON_POPUP[] = "OnPopup";
static const char S_ON_HINT[] = "OnHint";
static const char S_ON_POPUP_MENU[] = "OnPopupMenu";
static const char S_ON_EDIT_LINE[] = "OnEditLine";
static const char S_ON_INSERT_LINE[] = "OnInsertLine";
static const char S_ON_GET_LINE[] = "OnGetLine";
static const char S_ON_DELETE_LINE[] = "OnDeleteLine";
static const char S_ON_REFRESH[] = "OnRefresh";
static const char S_ON_REFRESHED[] = "OnRefreshed";
static const char S_ON_EXECUTE_LINE[] = "OnExecuteLine";
static const char S_ON_SELECT_LINE[] = "OnSelectLine";
static const char S_ON_SELECTION_CHANGE[] = "OnSelectionChange";
static const char S_ON_COMMAND[] = "OnCommand";
static const char S_ON_GET_ICON[] = "OnGetIcon";
static const char S_ON_GET_LINE_ATTR[] = "OnGetLineAttr";
static const char S_ON_GET_SIZE[] = "OnGetSize";
static const char S_ON_GETTEXT[] = "OnGetText";
static const char S_ON_ACTIVATE[] = "OnActivate";
static const char S_ON_DEACTIVATE[] = "OnDeactivate";
static const char S_ON_SELECT[] = "OnSelect";
static const char S_ON_CREATING_GROUP[] = "OnCreatingGroup";
static const char S_ON_DELETING_GROUP[] = "OnDeletingGroup";
static const char S_ON_GROUP_VISIBILITY[] = "OnGroupVisibility";
static const char S_M_EDGES[] = "_edges";
static const char S_M_NODES[] = "_nodes";
static const char S_M_THIS[] = "_this";
static const char S_M_TITLE[] = "_title";
static const char S_CLINK_NAME[] = "__clink__";
static const char S_ON_VIEW_ACTIVATED[] = "OnViewActivated";
static const char S_ON_VIEW_DEACTIVATED[] = "OnViewDeactivated";
static const char S_ON_VIEW_KEYDOWN[] = "OnViewKeydown";
static const char S_ON_VIEW_CLICK[] = "OnViewClick";
static const char S_ON_VIEW_DBLCLICK[] = "OnViewDblclick";
static const char S_ON_VIEW_CURPOS[] = "OnViewCurpos";
static const char S_ON_VIEW_SWITCHED[] = "OnViewSwitched";
static const char S_ON_VIEW_MOUSE_OVER[] = "OnViewMouseOver";
static const char S_ON_VIEW_MOUSE_MOVED[] = "OnViewMouseMoved";
static const char S_MAIN[] = "__main__";
#ifdef __PYWRAPS__
static const char S_PY_IDA_IDAAPI_MODNAME[] = "__main__";
#else
static const char S_PY_IDA_IDAAPI_MODNAME[] = S_IDA_IDAAPI_MODNAME;
#endif
//------------------------------------------------------------------------
// PyIdc conversion object IDs
#define PY_ICID_INT64 0
@@ -100,6 +191,13 @@ public:
// Declare a variable to acquire/release the GIL
#define PYW_GIL_GET gil_lock_t lock;
// Let's declare just the relevant bits, in order to not have to force
// including 'kernwin.hpp' in all files
#ifndef __KERNWIN_HPP
idaman uint32 ida_export_data debug;
#define IDA_DEBUG_PLUGIN 0x00000020
THREAD_SAFE AS_PRINTF(1, 2) inline int msg(const char *format, ...);
#endif // __KERNWIN_HPP
#define GIL_CHKCONDFAIL (((debug & IDA_DEBUG_PLUGIN) == IDA_DEBUG_PLUGIN) \
&& PyGILState_GetThisThreadState() != _PyThreadState_Current)
@@ -128,10 +226,14 @@ struct exc_report_t
#define PYW_GIL_GET_AND_REPORT_ERROR PYW_GIL_GET; exc_report_t exc;
// Returns the linked object (void *) from a PyObject
idaman void * ida_export pyobj_get_clink(PyObject *pyobj);
//------------------------------------------------------------------------
// All the exported functions from PyWraps are forward declared here
insn_t *insn_t_get_clink(PyObject *self);
op_t *op_t_get_clink(PyObject *self);
inline insn_t *insn_t_get_clink(PyObject *self) { return (insn_t *)pyobj_get_clink(self); }
inline op_t *op_t_get_clink(PyObject *self) { return (op_t *)pyobj_get_clink(self); }
inline switch_info_ex_t *switch_info_ex_t_get_clink(PyObject *self) { return (switch_info_ex_t *)pyobj_get_clink(self); }
//-------------------------------------------------------------------------
// The base for a reference. Will automatically increase the reference
@@ -265,65 +367,52 @@ struct ref_vec_t : public qvector<ref_t>
}
};
// Returns a new reference to a class
// Return value: New reference.
ref_t get_idaapi_attr(const char *attr);
// Returns a new reference to a class by its ID
// Return value: New reference.
ref_t get_idaapi_attr_by_id(const int class_id);
// Tries to import a module and swallows the exception if it fails and returns NULL
// Return value: New reference.
ref_t PyW_TryImportModule(const char *name);
exported ref_t ida_export PyW_TryImportModule(const char *name);
// Tries to get an attribute and swallows the exception if it fails and returns NULL
ref_t PyW_TryGetAttrString(PyObject *py_var, const char *attr);
// Returns the linked object (void *) from a PyObject
void *pyobj_get_clink(PyObject *pyobj);
exported ref_t ida_export PyW_TryGetAttrString(PyObject *py_var, const char *attr);
// Converts a Python number (LONGLONG or normal integer) to an IDC variable (VT_LONG or VT_INT64)
bool PyW_GetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var);
exported bool ida_export PyW_GetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var);
// Returns a qstring from a Python attribute string
bool PyW_GetStringAttr(
exported bool ida_export PyW_GetStringAttr(
PyObject *py_obj,
const char *attr_name,
qstring *str);
// Converts a Python number to an uint64 and indicates whether the number was a long number
bool PyW_GetNumber(PyObject *py_var, uint64 *num, bool *is_64 = NULL);
exported bool ida_export PyW_GetNumber(PyObject *py_var, uint64 *num, bool *is_64 = NULL);
// Checks if an Python object can be treated like a sequence
bool PyW_IsSequenceType(PyObject *obj);
exported bool ida_export PyW_IsSequenceType(PyObject *obj);
// Returns an error string from the last exception (and clears it)
bool PyW_GetError(qstring *out = NULL, bool clear_err = true);
bool PyW_GetError(char *buf, size_t bufsz, bool clear_err = true);
exported bool ida_export PyW_GetError(qstring *out = NULL, bool clear_err = true);
// If an error occured (it calls PyGetError) it displays it and return TRUE
// This function is used when calling callbacks
bool PyW_ShowCbErr(const char *cb_name);
exported bool ida_export PyW_ShowCbErr(const char *cb_name);
// Utility function to create linked class instances
ref_t create_idaapi_linked_class_instance(const char *clsname, void *lnk);
exported ref_t ida_export create_linked_class_instance(const char *modname, const char *clsname, void *lnk);
// Returns the string representation of a PyObject
bool PyW_ObjectToString(PyObject *obj, qstring *out);
exported bool ida_export PyW_ObjectToString(PyObject *obj, qstring *out);
// Utility function to convert a python object to an IDC object
// and sets a python exception on failure.
bool pyvar_to_idcvar_or_error(const ref_t &py_obj, idc_value_t *idc_obj);
exported bool ida_export pyvar_to_idcvar_or_error(const ref_t &py_obj, idc_value_t *idc_obj);
// Creates and initializes an IDC exception
error_t PyW_CreateIdcException(idc_value_t *res, const char *msg);
exported error_t ida_export PyW_CreateIdcException(idc_value_t *res, const char *msg);
//
// Conversion functions
//
bool pyw_convert_idc_args(
exported bool ida_export pyw_convert_idc_args(
const idc_value_t args[],
int nargs,
ref_vec_t &pargs,
@@ -333,69 +422,81 @@ bool pyw_convert_idc_args(
// Converts Python variable to IDC variable
// gvar_sn is used in case the Python object was a created from a call to idcvar_to_pyvar and the IDC object was a VT_REF
int pyvar_to_idcvar(
exported int ida_export pyvar_to_idcvar(
const ref_t &py_var,
idc_value_t *idc_var,
int *gvar_sn = NULL);
// Converts from IDC to Python
// We support converting VT_REF IDC variable types
int idcvar_to_pyvar(
const idc_value_t &idc_var,
ref_t *py_var);
exported int ida_export idcvar_to_pyvar(
const idc_value_t &idc_var,
ref_t *py_var);
// Walks a Python list or Sequence and calls the callback
Py_ssize_t pyvar_walk_list(
const ref_t &py_list,
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud) = NULL,
void *ud = NULL);
Py_ssize_t pyvar_walk_list(
exported Py_ssize_t ida_export pyvar_walk_list(
PyObject *py_list,
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud) = NULL,
void *ud = NULL);
// Converts an intvec_t to a Python list object
ref_t PyW_IntVecToPyList(const intvec_t &intvec);
exported ref_t ida_export PyW_IntVecToPyList(const intvec_t &intvec);
// Converts an Python list to an intvec
bool PyW_PyListToIntVec(PyObject *py_list, intvec_t &intvec);
exported bool ida_export PyW_PyListToIntVec(PyObject *py_list, intvec_t &intvec);
// Converts an Python list to an eavec
exported bool ida_export PyW_PyListToEaVec(PyObject *py_list, eavec_t &eavec);
// Converts a Python list to a qstrvec
bool PyW_PyListToStrVec(PyObject *py_list, qstrvec_t &strvec);
exported bool ida_export PyW_PyListToStrVec(PyObject *py_list, qstrvec_t &strvec);
//-------------------------------------------------------------------------
PyObject *qstrvec2pylist(qstrvec_t &vec);
exported bool ida_export PyWStringOrNone_Check(PyObject *tp);
//-------------------------------------------------------------------------
inline bool PyWStringOrNone_Check(PyObject *tp)
{
return tp == Py_None || PyString_Check(tp);
}
#include <idd.hpp>
exported PyObject *ida_export meminfo_vec_t_to_py(meminfo_vec_t &areas);
//-------------------------------------------------------------------------
inline const p_list * PyW_Fields(PyObject *tp)
{
return tp == Py_None ? NULL : (const p_list *) PyString_AsString(tp);
}
exported void ida_export PyW_register_compiled_form(PyObject *py_form);
//-------------------------------------------------------------------------
exported void ida_export PyW_unregister_compiled_form(PyObject *py_form);
//---------------------------------------------------------------------------
//
// notify_when()
//
bool pywraps_nw_term();
bool pywraps_nw_notify(int slot, ...);
bool pywraps_nw_init();
class pywraps_notify_when_t
{
ref_vec_t table[NW_EVENTSCNT];
qstring err;
bool in_notify;
struct notify_when_args_t
{
int when;
PyObject *py_callable;
};
typedef qvector<notify_when_args_t> notify_when_args_vec_t;
notify_when_args_vec_t delayed_notify_when_list;
//---------------------------------------------------------------------------
bool pywraps_check_autoscripts(char *buf, size_t bufsize);
static int idaapi idp_callback(void *ud, int event_id, va_list va);
bool unnotify_when(int when, PyObject *py_callable);
void register_callback(int slot, PyObject *py_callable);
void unregister_callback(int slot, PyObject *py_callable);
// [De]Initializes PyWraps
bool init_pywraps();
void deinit_pywraps();
public:
bool init();
bool deinit();
bool notify_when(int when, PyObject *py_callable);
bool notify(int slot, ...);
bool notify_va(int slot, va_list va);
pywraps_notify_when_t() : in_notify(false) {}
};
exported bool ida_export add_notify_when(int when, PyObject *py_callable);
void hexrays_clear_python_cfuncptr_t_references(void);
// void hexrays_clear_python_cfuncptr_t_references(void);
void free_compiled_form_instances(void);
// void free_compiled_form_instances(void);
//#define PYGDBG_ENABLED
#ifdef PYGDBG_ENABLED
@@ -407,8 +508,17 @@ void free_compiled_form_instances(void);
//-------------------------------------------------------------------------
struct pycall_res_t
{
pycall_res_t(PyObject *pyo);
~pycall_res_t();
pycall_res_t(PyObject *pyo)
: result(pyo)
{
PYGLOG("return code: %p\n", result.o);
}
~pycall_res_t()
{
if ( PyErr_Occurred() )
PyErr_Print();
}
inline bool success() const { return result.o != NULL; }
@@ -418,4 +528,326 @@ private:
pycall_res_t(); // No.
};
#endif
//-------------------------------------------------------------------------
// CustomIDAMemo wrappers
//-------------------------------------------------------------------------i
class lookup_info_t;
class py_customidamemo_t;
struct lookup_entry_t
{
lookup_entry_t() : form(NULL), view(NULL), py_view(NULL) {}
TForm *form;
TCustomControl *view;
py_customidamemo_t *py_view;
};
DECLARE_TYPE_AS_MOVABLE(lookup_entry_t);
typedef qvector<lookup_entry_t> lookup_entries_t;
#include <graph.hpp>
#define PY_LINFO_HLPPRM_new_entry (lookup_info_t *_this, py_customidamemo_t *py_view)
#define PY_LINFO_PARAMS_new_entry (py_customidamemo_t *py_view)
#define PY_LINFO_TRANSM_new_entry (this, py_view)
#define PY_LINFO_HLPPRM_commit (lookup_info_t *_this, lookup_entry_t &e, TForm *form, TCustomControl *view)
#define PY_LINFO_PARAMS_commit (lookup_entry_t &e, TForm *form, TCustomControl *view)
#define PY_LINFO_TRANSM_commit (this, e, form, view)
#define PY_LINFO_HLPPRM_find_by_form (const lookup_info_t *_this, TCustomControl **out_view, py_customidamemo_t **out_py_view, const TForm *form)
#define PY_LINFO_PARAMS_find_by_form (TCustomControl **out_view, py_customidamemo_t **out_py_view, const TForm *form) const
#define PY_LINFO_TRANSM_find_by_form (this, out_view, out_py_view, form)
#define PY_LINFO_HLPPRM_find_by_py_view (const lookup_info_t *_this, TForm **out_form, TCustomControl **out_view, const py_customidamemo_t *py_view)
#define PY_LINFO_PARAMS_find_by_py_view (TForm **out_form, TCustomControl **out_view, const py_customidamemo_t *py_view) const
#define PY_LINFO_TRANSM_find_by_py_view (this, out_form, out_view, py_view)
#define PY_LINFO_HLPPRM_del_by_py_view (lookup_info_t *_this, const py_customidamemo_t *py_view)
#define PY_LINFO_PARAMS_del_by_py_view (const py_customidamemo_t *py_view)
#define PY_LINFO_TRANSM_del_by_py_view (this, py_view)
#define DECL_LINFO_HELPER(decl, RType, MName, MParams) \
decl RType ida_export lookup_info_t_##MName MParams
#define DECL_LINFO_HELPERS(decl) \
DECL_LINFO_HELPER(decl, lookup_entry_t&, new_entry, PY_LINFO_HLPPRM_new_entry); \
DECL_LINFO_HELPER(decl, void, commit, PY_LINFO_HLPPRM_commit); \
DECL_LINFO_HELPER(decl, bool, find_by_form, PY_LINFO_HLPPRM_find_by_form); \
DECL_LINFO_HELPER(decl, bool, find_by_py_view, PY_LINFO_HLPPRM_find_by_py_view);\
DECL_LINFO_HELPER(decl, bool, del_by_py_view, PY_LINFO_HLPPRM_del_by_py_view);
DECL_LINFO_HELPERS(idaman);
class py_customidamemo_t;
class lookup_info_t
{
DECL_LINFO_HELPERS(friend);
public:
#define PY_LINFO_TRAMPOLINE(RType, MName, MParams, PNames) \
RType MName MParams { return lookup_info_t_##MName PNames; }
PY_LINFO_TRAMPOLINE(lookup_entry_t&, new_entry, PY_LINFO_PARAMS_new_entry, PY_LINFO_TRANSM_new_entry);
PY_LINFO_TRAMPOLINE(void, commit, PY_LINFO_PARAMS_commit, PY_LINFO_TRANSM_commit);
PY_LINFO_TRAMPOLINE(bool, find_by_form, PY_LINFO_PARAMS_find_by_form, PY_LINFO_TRANSM_find_by_form);
PY_LINFO_TRAMPOLINE(bool, find_by_py_view, PY_LINFO_PARAMS_find_by_py_view, PY_LINFO_TRANSM_find_by_py_view);
PY_LINFO_TRAMPOLINE(bool, del_by_py_view, PY_LINFO_PARAMS_del_by_py_view, PY_LINFO_TRANSM_del_by_py_view);
#undef PY_LINFO_TRAMPOLINE
bool find_by_view(TForm **out_form, py_customidamemo_t **out_py_view, const TCustomControl *view) const;
private:
lookup_entries_t entries;
};
extern exported lookup_info_t ida_export_data pycim_lookup_info;
//-------------------------------------------------------------------------
struct pycim_callback_id_t
{
qstring name;
int have;
};
struct pycim_callbacks_ids_t : public qvector<pycim_callback_id_t>
{
void add(const char *_n, int _h)
{
pycim_callback_id_t &o = push_back();
o.name = _n;
o.have = _h;
}
};
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
#define PY_CIM_HLPPRM_set_node_info (py_customidamemo_t *_this, PyObject *py_node_idx, PyObject *py_node_info, PyObject *py_flags)
#define PY_CIM_PARAMS_set_node_info (PyObject *py_node_idx, PyObject *py_node_info, PyObject *py_flags)
#define PY_CIM_TRANSM_set_node_info (this, py_node_idx, py_node_info, py_flags)
#define PY_CIM_HLPPRM_set_nodes_infos (py_customidamemo_t *_this, PyObject *dict)
#define PY_CIM_PARAMS_set_nodes_infos (PyObject *dict)
#define PY_CIM_TRANSM_set_nodes_infos (this, dict)
#define PY_CIM_HLPPRM_get_node_info (py_customidamemo_t *_this, PyObject *py_node_idx)
#define PY_CIM_PARAMS_get_node_info (PyObject *py_node_idx)
#define PY_CIM_TRANSM_get_node_info (this, py_node_idx)
#define PY_CIM_HLPPRM_del_nodes_infos (py_customidamemo_t *_this, PyObject *py_nodes)
#define PY_CIM_PARAMS_del_nodes_infos (PyObject *py_nodes)
#define PY_CIM_TRANSM_del_nodes_infos (this, py_nodes)
#define PY_CIM_HLPPRM_get_current_renderer_type (py_customidamemo_t *_this)
#define PY_CIM_PARAMS_get_current_renderer_type ()
#define PY_CIM_TRANSM_get_current_renderer_type (this)
#define PY_CIM_HLPPRM_set_current_renderer_type (py_customidamemo_t *_this, PyObject *py_rto)
#define PY_CIM_PARAMS_set_current_renderer_type (PyObject *py_rto)
#define PY_CIM_TRANSM_set_current_renderer_type (this, py_rto)
#define PY_CIM_HLPPRM_create_groups (py_customidamemo_t *_this, PyObject *groups_infos)
#define PY_CIM_PARAMS_create_groups (PyObject *groups_infos)
#define PY_CIM_TRANSM_create_groups (this, groups_infos)
#define PY_CIM_HLPPRM_delete_groups (py_customidamemo_t *_this, PyObject *groups, PyObject *new_current)
#define PY_CIM_PARAMS_delete_groups (PyObject *groups, PyObject *new_current)
#define PY_CIM_TRANSM_delete_groups (this, groups, new_current)
#define PY_CIM_HLPPRM_set_groups_visibility (py_customidamemo_t *_this, PyObject *groups, PyObject *expand, PyObject *new_current)
#define PY_CIM_PARAMS_set_groups_visibility (PyObject *groups, PyObject *expand, PyObject *new_current)
#define PY_CIM_TRANSM_set_groups_visibility (this, groups, expand, new_current)
#define PY_CIM_HLPPRM_collect_pyobject_callbacks (py_customidamemo_t *_this, PyObject *self)
#define PY_CIM_PARAMS_collect_pyobject_callbacks (PyObject *in_self)
#define PY_CIM_TRANSM_collect_pyobject_callbacks (this, in_self)
#define PY_CIM_HLPPRM_collect_class_callbacks_ids (py_customidamemo_t *_this, pycim_callbacks_ids_t *out)
#define PY_CIM_PARAMS_collect_class_callbacks_ids (pycim_callbacks_ids_t *out)
#define PY_CIM_TRANSM_collect_class_callbacks_ids (this, out)
#define PY_CIM_HLPPRM_install_custom_viewer_handlers (py_customidamemo_t *_this)
#define PY_CIM_PARAMS_install_custom_viewer_handlers ()
#define PY_CIM_TRANSM_install_custom_viewer_handlers (this)
#define PY_CIM_HLPPRM_bind (py_customidamemo_t *_this, PyObject *self, TCustomControl *view)
#define PY_CIM_PARAMS_bind (PyObject *in_self, TCustomControl *in_view)
#define PY_CIM_TRANSM_bind (this, in_self, in_view)
#define PY_CIM_HLPPRM_unbind (py_customidamemo_t *_this, bool clear_view)
#define PY_CIM_PARAMS_unbind (bool clear_view)
#define PY_CIM_TRANSM_unbind (this, clear_view)
#define PY_CIM_HLPPRM_ensure_view_callbacks_installed ()
#define DECL_CIM_HELPER(decl, RType, MName, MParams) \
decl RType ida_export py_customidamemo_t_##MName MParams
#define DECL_CIM_HELPERS(decl) \
DECL_CIM_HELPER(decl, void, set_node_info, PY_CIM_HLPPRM_set_node_info); \
DECL_CIM_HELPER(decl, void, set_nodes_infos, PY_CIM_HLPPRM_set_nodes_infos); \
DECL_CIM_HELPER(decl, PyObject*, get_node_info, PY_CIM_HLPPRM_get_node_info); \
DECL_CIM_HELPER(decl, void, del_nodes_infos, PY_CIM_HLPPRM_del_nodes_infos); \
DECL_CIM_HELPER(decl, PyObject*, get_current_renderer_type, PY_CIM_HLPPRM_get_current_renderer_type); \
DECL_CIM_HELPER(decl, void, set_current_renderer_type, PY_CIM_HLPPRM_set_current_renderer_type); \
DECL_CIM_HELPER(decl, PyObject*, create_groups, PY_CIM_HLPPRM_create_groups); \
DECL_CIM_HELPER(decl, PyObject*, delete_groups, PY_CIM_HLPPRM_delete_groups); \
DECL_CIM_HELPER(decl, PyObject*, set_groups_visibility, PY_CIM_HLPPRM_set_groups_visibility);\
\
DECL_CIM_HELPER(decl, bool, collect_pyobject_callbacks, PY_CIM_HLPPRM_collect_pyobject_callbacks); \
DECL_CIM_HELPER(decl, void, collect_class_callbacks_ids, PY_CIM_HLPPRM_collect_class_callbacks_ids); \
DECL_CIM_HELPER(decl, void, install_custom_viewer_handlers, PY_CIM_HLPPRM_install_custom_viewer_handlers); \
DECL_CIM_HELPER(decl, bool, bind, PY_CIM_HLPPRM_bind); \
DECL_CIM_HELPER(decl, void, unbind, PY_CIM_HLPPRM_unbind); \
DECL_CIM_HELPER(decl, void, ensure_view_callbacks_installed, PY_CIM_HLPPRM_ensure_view_callbacks_installed)
DECL_CIM_HELPERS(idaman);
//-------------------------------------------------------------------------
#define PY_CIM_TRAMPOLINE(RType, MName, MParams, PNames) \
RType MName MParams { return py_customidamemo_t_##MName PNames; }
class py_customidamemo_t
{
void convert_node_info(
node_info_t *out,
uint32 *out_flags,
ref_t py_nodeinfo);
enum
{
GRBASE_HAVE_VIEW_ACTIVATED = 0x001,
GRBASE_HAVE_VIEW_DEACTIVATED = 0x002,
GRBASE_HAVE_KEYDOWN = 0x004,
GRBASE_HAVE_POPUP = 0x008,
GRBASE_HAVE_VIEW_CLICK = 0x010,
GRBASE_HAVE_VIEW_DBLCLICK = 0x020,
GRBASE_HAVE_VIEW_CURPOS = 0x040,
GRBASE_HAVE_CLOSE = 0x080,
GRBASE_HAVE_VIEW_SWITCHED = 0x100,
GRBASE_HAVE_VIEW_MOUSE_OVER = 0x200,
GRBASE_HAVE_VIEW_MOUSE_MOVED = 0x400,
};
int cb_flags;
// number of arguments for:
int ovc_num_args; // OnViewClick implementation
int ovdc_num_args; // OnViewDblclick implementation
int ovmo_num_args; // OnViewMouseOver implementation
int ovmm_num_args; // OnViewMouseMoved implementation
// View events
void on_view_activated();
void on_view_deactivated();
void on_view_keydown(int key, int state);
void on_view_popup();
void on_view_click(const view_mouse_event_t *event);
void on_view_dblclick(const view_mouse_event_t *event);
void on_view_curpos();
void on_view_close();
void on_view_switched(tcc_renderer_type_t rt);
void on_view_mouse_over(const view_mouse_event_t *event);
void on_view_mouse_moved(const view_mouse_event_t *event);
int get_py_method_arg_count(char *method_name);
// View events that are bound with 'set_custom_viewer_handler()'.
static void idaapi s_on_view_mouse_moved(
TCustomControl *cv,
int shift,
view_mouse_event_t *e,
void *ud);
DECL_CIM_HELPERS(friend);
protected:
ref_t self;
TCustomControl *view;
pycim_callbacks_ids_t cbids;
PY_CIM_TRAMPOLINE(bool, collect_pyobject_callbacks, PY_CIM_PARAMS_collect_pyobject_callbacks, PY_CIM_TRANSM_collect_pyobject_callbacks);
PY_CIM_TRAMPOLINE(virtual void, collect_class_callbacks_ids, PY_CIM_PARAMS_collect_class_callbacks_ids, PY_CIM_TRANSM_collect_class_callbacks_ids);
PY_CIM_TRAMPOLINE(void, install_custom_viewer_handlers, PY_CIM_PARAMS_install_custom_viewer_handlers, PY_CIM_TRANSM_install_custom_viewer_handlers);
PY_CIM_TRAMPOLINE(bool, bind, PY_CIM_PARAMS_bind, PY_CIM_TRANSM_bind);
PY_CIM_TRAMPOLINE(void, unbind, PY_CIM_PARAMS_unbind, PY_CIM_TRANSM_unbind);
friend TForm *pycim_get_tform(PyObject *self);
friend TCustomControl *pycim_get_tcustom_control(PyObject *self);
public:
py_customidamemo_t()
: self(newref_t(NULL)),
view(NULL)
{
PYGLOG("%p: py_customidamemo_t()\n", this);
py_customidamemo_t_ensure_view_callbacks_installed();
ovc_num_args = -1;
ovdc_num_args = -1;
ovmo_num_args = -1;
ovmm_num_args = -1;
}
virtual ~py_customidamemo_t()
{
PYGLOG("%p: ~py_customidamemo_t()\n", this);
unbind(true);
pycim_lookup_info.del_by_py_view(this);
}
virtual void refresh()
{
refresh_viewer(view);
}
inline bool has_callback(int flag) { return (cb_flags & flag) != 0; }
PY_CIM_TRAMPOLINE(void, set_node_info, PY_CIM_PARAMS_set_node_info, PY_CIM_TRANSM_set_node_info);
PY_CIM_TRAMPOLINE(void, set_nodes_infos, PY_CIM_PARAMS_set_nodes_infos, PY_CIM_TRANSM_set_nodes_infos);
PY_CIM_TRAMPOLINE(PyObject*, get_node_info, PY_CIM_PARAMS_get_node_info, PY_CIM_TRANSM_get_node_info);
PY_CIM_TRAMPOLINE(void, del_nodes_infos, PY_CIM_PARAMS_del_nodes_infos, PY_CIM_TRANSM_del_nodes_infos);
PY_CIM_TRAMPOLINE(PyObject*, get_current_renderer_type, PY_CIM_PARAMS_get_current_renderer_type, PY_CIM_TRANSM_get_current_renderer_type);
PY_CIM_TRAMPOLINE(void, set_current_renderer_type, PY_CIM_PARAMS_set_current_renderer_type, PY_CIM_TRANSM_set_current_renderer_type);
PY_CIM_TRAMPOLINE(PyObject*, create_groups, PY_CIM_PARAMS_create_groups, PY_CIM_TRANSM_create_groups);
PY_CIM_TRAMPOLINE(PyObject*, delete_groups, PY_CIM_PARAMS_delete_groups, PY_CIM_TRANSM_delete_groups);
PY_CIM_TRAMPOLINE(PyObject*, set_groups_visibility, PY_CIM_PARAMS_set_groups_visibility, PY_CIM_TRANSM_set_groups_visibility);
};
#undef PY_CIM_TRAMPOLINE
#undef DECL_CIM_HELPERS
#undef DECL_CIM_HELPER
//-------------------------------------------------------------------------
template <typename T>
T *view_extract_this(PyObject *self)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
ref_t py_this(PyW_TryGetAttrString(self, S_M_THIS));
if ( py_this == NULL || !PyCObject_Check(py_this.o) )
return NULL;
return (T*) PyCObject_AsVoidPtr(py_this.o);
}
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
#include <typeinf.hpp>
#define DECL_REG_UNREG_REFCOUNTED(Type) \
exported void ida_export til_register_python_##Type##_instance(Type *inst); \
exported void ida_export til_deregister_python_##Type##_instance(Type *inst);
DECL_REG_UNREG_REFCOUNTED(tinfo_t);
DECL_REG_UNREG_REFCOUNTED(ptr_type_data_t);
DECL_REG_UNREG_REFCOUNTED(array_type_data_t);
DECL_REG_UNREG_REFCOUNTED(func_type_data_t);
DECL_REG_UNREG_REFCOUNTED(udt_type_data_t);
#undef DECL_REG_UNREG_REFCOUNTED
//-------------------------------------------------------------------------
// Context structure used by register/unregister timer
struct py_timer_ctx_t
{
py_timer_ctx_t() : timer_id(NULL), pycallback(NULL) {}
qtimer_t timer_id;
PyObject *pycallback;
};
exported py_timer_ctx_t *ida_export python_timer_new(PyObject *py_callback);
exported void ida_export python_timer_del(py_timer_ctx_t *t);
#endif // __PYWRAPS_HPP__
-212
View File
@@ -1,212 +0,0 @@
# Please use the same tag for the same .i file
# That means if many insertions are going to happen in one
# given .i file then don't use more than code marking tag
print "\n-------- DEPLOY started --------------------------------------------------\n"
deploys = {
"idaapi (common functions, notifywhen)" : {
"tag" : "py_idaapi",
"src" : ["py_cvt.hpp", "py_idaapi.hpp", "py_idaapi.py", "py_notifywhen.hpp", "py_notifywhen.py"],
"tgt" : "../swig/idaapi.i"
},
"View (common)" : {
"tag" : "py_view_base",
"src" : ["py_view_base.hpp", "py_view_base.py"],
"tgt" : "../swig/view.i"
},
"IDAView" : {
"tag" : "py_idaview",
"src" : ["py_idaview.hpp", "py_idaview.py"],
"tgt" : "../swig/view.i"
},
"Graph" : {
"tag" : "py_graph",
"src" : ["py_graph.hpp", "py_graph.py"],
"tgt" : "../swig/graph.i"
},
"custview" : {
"tag" : "py_custviewer",
"src" : ["py_custview.py","py_custview.hpp"],
"tgt" : "../swig/kernwin.i.in"
},
"plgform" : {
"tag" : "py_plgform",
"src" : ["py_plgform.hpp","py_plgform.py"],
"tgt" : "../swig/kernwin.i.in"
},
"expr" : {
"tag" : "py_expr",
"src" : ["py_expr.hpp","py_expr.py"],
"tgt" : "../swig/expr.i"
},
"cli" : {
"tag" : "py_cli",
"src" : ["py_cli.py","py_cli.hpp"],
"tgt" : "../swig/kernwin.i.in"
},
"Loader" : {
"tag" : "py_loader",
"src" : ["py_loader.hpp"],
"tgt" : "../swig/loader.i"
},
"kernwin, choose2, askusingform" : {
"tag" : "py_kernwin",
"src" : ["py_kernwin.hpp","py_kernwin.py","py_choose.hpp","py_choose2.hpp","py_choose2.py","py_askusingform.hpp","py_askusingform.py"],
"tgt" : "../swig/kernwin.i.in"
},
"idd" : {
"tag" : "py_idd",
"src" : ["py_dbg.hpp","py_appcall.py"],
"tgt" : "../swig/idd.i"
},
"idd (python)" : {
"tag" : "py_idd_2",
"src" : ["py_dbg.py"],
"tgt" : "../swig/idd.i"
},
"nalt" : {
"tag" : "py_nalt",
"src" : ["py_nalt.hpp","py_nalt.py"],
"tgt" : "../swig/nalt.i"
},
"dbg" : {
"tag" : "py_dbg",
"src" : ["py_dbg.hpp"],
"tgt" : "../swig/dbg.i.in"
},
"linput/diskio" : {
"tag" : "py_diskio",
"src" : ["py_linput.hpp","py_diskio.hpp","py_diskio.py"],
"tgt" : "../swig/diskio.i"
},
"name" : {
"tag" : "py_name",
"src" : ["py_name.hpp","py_name.py"],
"tgt" : "../swig/name.i"
},
"qfile" : {
"tag" : "py_qfile",
"src" : ["py_qfile.hpp"],
"tgt" : "../swig/fpro.i"
},
"bytes" : {
"tag" : "py_bytes",
"src" : ["py_bytes.hpp","py_custdata.py","py_custdata.hpp"],
"tgt" : "../swig/bytes.i"
},
"typeinf" : {
"tag" : "py_typeinf",
"src" : ["py_typeinf.hpp","py_typeinf.py"],
"tgt" : "../swig/typeinf.i"
},
"gdl" : {
"tag" : "py_gdl",
"src" : ["py_gdl.py"],
"tgt" : "../swig/gdl.i"
},
"ua" : {
"tag" : "py_ua",
"src" : ["py_ua.hpp","py_ua.py"],
"tgt" : "../swig/ua.i"
},
"idp" : {
"tag" : "py_idp",
"src" : ["py_idp.hpp"],
"tgt" : "../swig/idp.i.in"
},
"lines" : {
"tag" : "py_lines",
"src" : ["py_lines.hpp","py_lines.py"],
"tgt" : "../swig/lines.i"
},
"registry" : {
"tag" : "py_registry",
"src" : ["py_registry.hpp"],
"tgt" : "../swig/registry.i"
},
"struct" : {
"tag" : "py_struct",
"src" : ["py_struct.hpp"],
"tgt" : "../swig/struct.i"
},
"pc_win32_appcall" : {
"tag" : "appcalltest",
"src" : ["py_appcall.py"],
"tgt" : "../../../tests/input/pc_win32_appcall.pe.hints"
},
"ex_custdata example" : {
"tag" : "ex_custdata",
"src" : ["../examples/ex_custdata.py"],
"tgt" : "../../../tests/input/pc_win32_custdata1.pe.hints"
},
"ex_choose2" : {
"tag" : "py_choose2ex1",
"src" : ["py_choose2.py"],
"tgt" : "../examples/ex_choose2.py"
},
"ex_formchooser" : {
"tag" : "ex_formchooser",
"src" : ["py_askusingform.py"],
"tgt" : "../../formchooser/formchooser.py"
},
"ex_askusingform" : {
"tag" : "ex_askusingform",
"src" : ["py_askusingform.py"],
"tgt" : "../examples/ex_askusingform.py"
},
"ex_cli example" : {
"tag" : "ex_cli_ex1",
"src" : ["py_cli.py"],
"tgt" : "../examples/ex_cli.py"
},
"ex_expr example" : {
"tag" : "ex_expr",
"src" : ["py_expr.py"],
"tgt" : "../examples/ex_expr.py"
},
"ex_custview.py example" : {
"tag" : "py_custviewerex1",
"src" : ["py_custview.py"],
"tgt" : "../examples/ex_custview.py"
}
}
import deploy
for name in deploys:
data = deploys[name]
print "Deploying %s" % name
deploy.deploy(data["tag"], data["src"], data["tgt"])
+172
View File
@@ -0,0 +1,172 @@
//--------------------------------------------------------------------------
// IDA includes
#include <windows.h>
#include <pro.h>
#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <bytes.hpp>
#include <enum.hpp>
#include <kernwin.hpp>
#include <diskio.hpp>
#include <bytes.hpp>
#include <graph.hpp>
#include <map>
#include <idd.hpp>
#include <dbg.hpp>
#include <ieee.h>
#include <err.h>
#include <expr.hpp>
#include <typeinf.hpp>
#include <struct.hpp>
#include <nalt.hpp>
#include <frame.hpp>
//--------------------------------------------------------------------------
// PyWraps
#include <Python.h>
#include "pywraps.hpp"
#include "swig_stub.h"
#include "py_cvt.hpp"
#include "py_idaapi.hpp"
#include "py_graph.hpp"
#include "py_typeinf.hpp"
#include "py_bytes.hpp"
#include "py_linput.hpp"
#include "py_qfile.hpp"
#include "py_ua.hpp"
#include "py_custdata.hpp"
#include "py_notifywhen.hpp"
#include "py_dbg.hpp"
#include "py_choose2.hpp"
#include "py_plgform.hpp"
#include "py_cli.hpp"
#include "py_custview.hpp"
#include "py_lines.hpp"
#include "py_nalt.hpp"
#include "py_loader.hpp"
#include "py_idp.hpp"
#include "py_kernwin.hpp"
#include "py_askusingform.hpp"
#include "py_expr.hpp"
//--------------------------------------------------------------------------
qvector<PyMethodDef> all_methods;
void driver_add_methods(PyMethodDef *methods)
{
for ( ; methods->ml_name != NULL; ++methods )
all_methods.push_back(*methods);
}
//--------------------------------------------------------------------------
// Define a class and declare an instance so it gets executed on startup
// It will add the desired methods to the all_methods global variable
#define DRIVER_INIT_METHODS(name) \
class init_##name##_driver_t \
{ \
public: \
init_##name##_driver_t() \
{ \
driver_add_methods(py_methods_##name##); \
} \
} init_##name##_driver;
//--------------------------------------------------------------------------
// PyWraps test drivers
//#include "driver_kernwin.cpp"
//#include "driver_chooser.cpp"
#include "driver_expr.cpp"
//#include "driver_custview.cpp"
//#include "driver_notifywhen.cpp"
//#include "driver_custdata.cpp"
//#include "driver_graph.cpp"
//#include "driver_diskio.cpp"
//#include "driver_bytes.cpp"
//#include "driver_dbg.cpp"
//#include "driver_nalt.cpp"
//#include "driver_cli.cpp"
//--------------------------------------------------------------------------
//#define DRIVER_FIX
#ifdef DRIVER_FIX
#define PLUGIN_FLAGS PLUGIN_FIX
#else
#define PLUGIN_FLAGS 0
#endif
//--------------------------------------------------------------------------
void setup_pywraps()
{
static bool installed = false;
if ( installed )
{
msg("pywraps already installed\n");
return;
}
static const PyMethodDef null_method = {0};
all_methods.push_back(null_method);
Py_InitModule("pywraps", all_methods.begin());
init_pywraps();
msg("pywraps installed!\n");
installed = true;
}
//--------------------------------------------------------------------------
void idaapi run(int /*arg*/)
{
setup_pywraps();
#ifdef DRIVER_RUN
driver_run(0);
#endif
}
//--------------------------------------------------------------------------
//
// Initialize.
//
int idaapi init(void)
{
#ifndef DRIVER_FIX
setup_pywraps();
#endif
#ifdef DRIVER_INIT
return driver_init();
#else
return PLUGIN_KEEP;
#endif
}
//--------------------------------------------------------------------------
void idaapi term(void)
{
#ifdef DRIVER_TERM
driver_term();
#endif
}
//--------------------------------------------------------------------------
//
// PLUGIN DESCRIPTION BLOCK
//
//--------------------------------------------------------------------------
plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
PLUGIN_FLAGS, // plugin flags
init, // initialize
term, // terminate. this pointer may be NULL.
run, // invoke plugin
// long comment about the plugin
"PyWraps plugin",
// it could appear in the status line
// or as a hint
"", // multiline help about the plugin
"pywraps", // the preferred short name of the plugin
"" // the preferred hotkey to run the plugin
};
+19
View File
@@ -0,0 +1,19 @@
#include "py_bytes.hpp"
//--------------------------------------------------------------------------
static PyObject *ex_nextthat(PyObject *self, PyObject *args)
{
PyObject *callback;
pyul_t addr, bound;
if ( !PyArg_ParseTuple(args, PY_FMT64 PY_FMT64 "O", &addr, &bound, &callback) )
return NULL;
return Py_BuildValue("i", py_nextthat(pyul_t(addr), pyul_t(bound), callback));
}
//--------------------------------------------------------------------------
static PyMethodDef py_methods_bytes[] =
{
{ "nextthat", ex_nextthat, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL }
};
DRIVER_INIT_METHODS(bytes);
+109
View File
@@ -0,0 +1,109 @@
#include "py_choose2.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_choose2_find(PyObject *self, PyObject *args)
{
char *title;
if ( !PyArg_ParseTuple(args, "s", &title) )
return NULL;
else
return choose2_find(title);
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_create(PyObject *self, PyObject *args)
{
PyObject *obj;
int embedded;
if ( !PyArg_ParseTuple(args, "Oi", &obj, &embedded) )
return NULL;
else
return PyInt_FromLong(choose2_create(obj, embedded == 1 ? true : false));
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_activate(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_activate(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_close(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_close(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_refresh(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_refresh(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_add_command(PyObject *self, PyObject *args)
{
PyObject *obj;
char *caption;
int flags, menu_index, icon;
if ( !PyArg_ParseTuple(args, "Osiii", &obj, &caption, &flags, &menu_index, &icon) )
return NULL;
else
return PyInt_FromLong(choose2_add_command(obj, caption, flags, menu_index, icon));
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_test_embedded(PyObject *self, PyObject *args)
{
return PyLong_FromSize_t(choose2_get_test_embedded());
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_embedded(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
else
return choose2_get_embedded(obj);
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_embedded_selection(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
else
return choose2_get_embedded_selection(obj);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_chooser[] =
{
{ "py_choose2_find", ex_choose2_find, METH_VARARGS, "" },
{ "py_choose2_create", ex_choose2_create, METH_VARARGS, "" },
{ "py_choose2_close", ex_choose2_close, METH_VARARGS, "" },
{ "py_choose2_activate", ex_choose2_activate, METH_VARARGS, "" },
{ "py_choose2_refresh", ex_choose2_refresh, METH_VARARGS, "" },
{ "py_choose2_add_command", ex_choose2_add_command, METH_VARARGS, "" },
{ "py_choose2_get_test_embedded", ex_choose2_get_test_embedded, METH_VARARGS, "" },
{ "py_choose2_get_embedded", ex_choose2_get_embedded, METH_VARARGS, "" },
{ "py_choose2_get_embedded_selection", ex_choose2_get_embedded_selection, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } // End of methods
};
DRIVER_INIT_METHODS(chooser);
+29
View File
@@ -0,0 +1,29 @@
#include "py_custview.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_install_command_interpreter(PyObject *self, PyObject *args)
{
PyObject *py_obj;
if ( !PyArg_ParseTuple(args, "O", &py_obj) )
return NULL;
return PyInt_FromLong(py_install_command_interpreter(py_obj));
}
//-------------------------------------------------------------------------
static PyObject *ex_remove_command_interpreter(PyObject *self, PyObject *args)
{
int cli_idx;
if ( !PyArg_ParseTuple(args, "i", &cli_idx) )
return NULL;
py_remove_command_interpreter(cli_idx);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_cli[] =
{
{ "install_command_interpreter", ex_install_command_interpreter, METH_VARARGS, "" },
{ "remove_command_interpreter", ex_remove_command_interpreter, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL }
};
DRIVER_INIT_METHODS(cli);
+384
View File
@@ -0,0 +1,384 @@
#include "py_custview.hpp"
//--------------------------------------------------------------------------
class my_custviewer: public customviewer_t
{
private:
cvdata_simpleline_t data;
size_t id_n;
virtual bool on_popup_menu(size_t menu_id)
{
if ( menu_id == id_n )
msg("popup menu N chosen!\n");
return true;
}
virtual bool on_click(int shift)
{
msg("onclick; shift=%d\n", shift);
return true;
}
virtual void on_close()
{
id_n = 0;
msg("closed...\n");
}
virtual bool on_keydown(int key, int shift)
{
switch ( key )
{
case 'N':
warning("The hotkey 'N' has been pressed");
return true;
case 'I':
{
int x, y;
place_t *pl = get_place(false, &x, &y);
if ( pl == NULL )
return false;
msg("x=%d y=%d\n", x, y);
simpleline_t sl = *data.get_line(pl);
sl.bgcolor = bgcolor_t(~uint32(sl.bgcolor));
data.set_line(data.to_lineno(pl), sl);
refresh_current();
return true;
}
case 'A':
{
char buf[100];
qsnprintf(buf, sizeof(buf), "This is line %d\n", data.count());
data.add_line(buf);
msg("Added one more line...\n");
return true;
}
case 'S':
{
twinpos_t p1, p2;
::readsel2(_cv, &p1, &p2);
size_t y1 = data.to_lineno(p1.at);
size_t y2 = data.to_lineno(p2.at);
int x1 = p1.x;
int x2 = p2.x;
msg("(x1=%d y1=%d) (x2=%d y2=%d)", x1, y1, x2, y2);
return true;
}
case 'X':
data.set_minmax();
return true;
case 'R':
refresh();
msg("refreshing!\n");
return true;
case IK_ESCAPE:
close();
return true;
}
return false;
}
virtual void on_curpos_changed()
{
qstring word;
if ( get_current_word(false, word) )
msg("Current word is: %s\n", word.c_str());
}
virtual bool on_hint(place_t *place, int *important_lines, qstring &hint)
{
simpleline_t *line = data.get_line(place);
if ( line == NULL )
return false;
*important_lines = 1;
hint = line->line;
return true;
}
public:
void init_sample_lines()
{
strvec_t &lines = data.get_lines();
static struct
{
const char *text;
bgcolor_t color;
} const sample_lines[] =
{
{ "This is a sample text", 0xFFFFFF },
{ "It will be displayed in the custom view", 0xFFC0C0 },
{ COLSTR("This line will be colored as erroneous", SCOLOR_ERROR), 0xC0FFC0 },
{ COLSTR("Every", SCOLOR_AUTOCMT) " "
COLSTR("word", SCOLOR_DNAME) " "
COLSTR("can", SCOLOR_IMPNAME) " "
COLSTR("be", SCOLOR_NUMBER) " "
COLSTR("colored!", SCOLOR_EXTRA), 0xC0C0FF },
{ " No limit on the number of lines.", 0xC0FFFF },
};
for ( int i=0; i < qnumber(sample_lines); i++ )
{
lines.push_back(simpleline_t("")); // add empty line
lines.push_back(simpleline_t(sample_lines[i].text));
lines.back().bgcolor = sample_lines[i].color;
}
}
my_custviewer()
{
id_n = 0;
init_sample_lines();
data.set_minmax();
}
bool init(const char *title)
{
if ( id_n != 0 )
return true;
if ( !create(title, HAVE_HINT | HAVE_CLICK | HAVE_KEYDOWN | HAVE_CURPOS, &data) )
return false;
id_n = add_popup_menu("Do this", "N");
return true;
}
};
my_custviewer *g_cv;
//-------------------------------------------------------------------------
static PyObject *ex_pyscv_init(PyObject *self, PyObject *args)
{
const char *title;
PyObject *py_link;
if ( !PyArg_ParseTuple(args, "Os", &py_link, &title) )
return NULL;
return pyscv_init(py_link, title);
}
static PyObject *ex_pyscv_add_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
if ( !PyArg_ParseTuple(args, "OO", &py_this, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_add_line(py_this, py_sl));
}
static PyObject *ex_pyscv_delete(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_delete(py_this));
}
static PyObject *ex_pyscv_show(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_show(py_this));
}
static PyObject *ex_pyscv_refresh(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_refresh(py_this));
}
static PyObject *ex_pyscv_close(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
pyscv_close(py_this);
Py_RETURN_NONE;
}
static PyObject *ex_pyscv_clear_popup_menu(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
pyscv_clear_popup_menu(py_this);
Py_RETURN_NONE;
}
static PyObject *ex_pyscv_del_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t nline;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64, &py_this, &nline) )
return NULL;
return Py_BuildValue("i", pyscv_del_line(py_this, nline));
}
static PyObject *ex_pyscv_get_pos(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return pyscv_get_pos(py_this, mouse == 0 ? false : true);
}
static PyObject *ex_pyscv_refresh_current(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return Py_BuildValue("i", pyscv_refresh_current(py_this));
}
static PyObject *ex_pyscv_get_current_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse, notags;
if ( !PyArg_ParseTuple(args, "Oii", &py_this, &mouse, &notags) )
return NULL;
return pyscv_get_current_line(py_this, mouse == 0 ? false : true, notags == 0 ? false : true);
}
static PyObject *ex_pyscv_is_focused(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_is_focused(py_this));
}
static PyObject *ex_pyscv_add_popup_menu(PyObject *self, PyObject *args)
{
PyObject *py_this;
const char *title, *hotkey;
if ( !PyArg_ParseTuple(args, "Oss", &py_this, &title, &hotkey) )
return NULL;
return Py_BuildValue("i", pyscv_add_popup_menu(py_this, title, hotkey));
}
static PyObject *ex_pyscv_get_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t nline;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64, &py_this, &nline) )
return NULL;
return pyscv_get_line(py_this, nline);
}
static PyObject *ex_pyscv_jumpto(PyObject *self, PyObject *args)
{
PyObject *py_this;
int x, y;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "ii", &py_this, &lineno, &x, &y) )
return NULL;
return Py_BuildValue("i", pyscv_jumpto(py_this, lineno, x, y));
}
static PyObject *ex_pyscv_edit_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "O", &py_this, &lineno, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_edit_line(py_this, lineno, py_sl));
}
static PyObject *ex_pyscv_insert_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "O", &py_this, &lineno, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_insert_line(py_this, lineno, py_sl));
}
static PyObject *ex_pyscv_patch_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t lineno, offs;
int value;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 PY_FMT64 "i", &py_this, &lineno, &offs, &value) )
return NULL;
return Py_BuildValue("i", pyscv_patch_line(py_this, lineno, offs, value));
}
static PyObject *ex_pyscv_count(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue(PY_FMT64, pyscv_count(py_this));
}
static PyObject *ex_pyscv_get_selection(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return pyscv_get_selection(py_this);
}
static PyObject *ex_pyscv_get_current_word(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return pyscv_get_current_word(py_this, mouse != 0);
}
static PyObject *ex_pyscv_clear_lines(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return pyscv_clear_lines(py_this);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_custview[] =
{
{ "pyscv_init", ex_pyscv_init, METH_VARARGS, "" },
{ "pyscv_close", ex_pyscv_close, METH_VARARGS, "" },
{ "pyscv_add_line", ex_pyscv_add_line, METH_VARARGS, "" },
{ "pyscv_delete", ex_pyscv_delete, METH_VARARGS, "" },
{ "pyscv_refresh", ex_pyscv_refresh, METH_VARARGS, "" },
{ "pyscv_clear_lines", ex_pyscv_clear_lines, METH_VARARGS, "" },
{ "pyscv_show", ex_pyscv_show, METH_VARARGS, "" },
{ "pyscv_clear_popup_menu", ex_pyscv_clear_popup_menu, METH_VARARGS, "" },
{ "pyscv_del_line", ex_pyscv_del_line, METH_VARARGS, "" },
{ "pyscv_get_pos", ex_pyscv_get_pos, METH_VARARGS, "" },
{ "pyscv_refresh_current", ex_pyscv_refresh_current, METH_VARARGS, "" },
{ "pyscv_get_current_line", ex_pyscv_get_current_line, METH_VARARGS, "" },
{ "pyscv_is_focused", ex_pyscv_is_focused, METH_VARARGS, "" },
{ "pyscv_add_popup_menu", ex_pyscv_add_popup_menu, METH_VARARGS, "" },
{ "pyscv_get_line", ex_pyscv_get_line, METH_VARARGS, "" },
{ "pyscv_jumpto", ex_pyscv_jumpto, METH_VARARGS, "" },
{ "pyscv_edit_line", ex_pyscv_edit_line, METH_VARARGS, "" },
{ "pyscv_insert_line", ex_pyscv_insert_line, METH_VARARGS, "" },
{ "pyscv_count", ex_pyscv_count, METH_VARARGS, "" },
{ "pyscv_patch_line", ex_pyscv_patch_line, METH_VARARGS, "" },
{ "pyscv_get_selection", ex_pyscv_get_selection, METH_VARARGS, "" },
{ "pyscv_get_current_word", ex_pyscv_get_current_word, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } /* Sentinel */
};
DRIVER_INIT_METHODS(custview);
#define DRIVER_RUN
void driver_run(int)
{
if ( !g_cv->init("My sample viewer!") )
{
msg("Failed to create cv\n!");
return;
}
g_cv->show();
}
#define DRIVER_INIT
int driver_init()
{
g_cv = new my_custviewer();
return PLUGIN_KEEP;
}
#define DRIVER_TERM
void driver_term()
{
g_cv->close();
delete g_cv;
}
+79
View File
@@ -0,0 +1,79 @@
#include "py_dbg.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_getthreadsregbase(PyObject * /*self*/, PyObject *args)
{
PyObject *py_tid, *py_sreg_value;
if ( !PyArg_ParseTuple(args, "OO", &py_tid, &py_sreg_value) )
return NULL;
return dbg_get_thread_sreg_base(py_tid, py_sreg_value);
}
//-------------------------------------------------------------------------
static PyObject *ex_readmemory(PyObject * /*self*/, PyObject *args)
{
PyObject *py_ea, *py_size;
if ( !PyArg_ParseTuple(args, "OO", &py_ea, &py_size) )
return NULL;
return dbg_read_memory(py_ea, py_size);
}
//-------------------------------------------------------------------------
static PyObject *ex_writememory(PyObject * /*self*/, PyObject *args)
{
PyObject *py_ea, *py_buf;
if ( !PyArg_ParseTuple(args, "OO", &py_ea, &py_buf) )
return NULL;
return dbg_write_memory(py_ea, py_buf);
}
//-------------------------------------------------------------------------
static PyObject *ex_getmeminfo(PyObject * /*self*/, PyObject *args)
{
return dbg_get_memory_info();
}
//-------------------------------------------------------------------------
static PyObject *ex_getregs(PyObject *self, PyObject *args)
{
return dbg_get_registers();
}
//-------------------------------------------------------------------------
static PyObject *ex_appcall(PyObject * /*self*/, PyObject *args)
{
PyObject *app_args, *type, *fields;
int func_ea, tid;
if ( !PyArg_ParseTuple(args, "iiOOO", &func_ea, &tid, &type, &fields, &app_args) )
return NULL;
return py_appcall(func_ea, tid, type, fields, app_args);
}
//-------------------------------------------------------------------------
static PyObject *ex_pytoidc(
PyObject *self,
PyObject *args)
{
if ( !PyArg_ParseTuple(args, "O", &self) )
return NULL;
idc_value_t v;
int sn = 0;
borref_t self_ref(self);
if ( pyvar_to_idcvar(self_ref, &v, &sn) < CIP_OK )
Py_RETURN_NONE;
Py_RETURN_TRUE;
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_dbg[] =
{
{ "getregs", ex_getregs, METH_VARARGS, "" },
{ "getmeminfo", ex_getmeminfo, METH_VARARGS, "" },
{ "readmemory", ex_readmemory, METH_VARARGS, "" },
{ "writememory", ex_writememory, METH_VARARGS, "" },
{ "getthreadsregbase", ex_getthreadsregbase, METH_VARARGS, "" },
{ "appcall", ex_appcall, METH_VARARGS, "" },
{ "pytoidc", ex_pytoidc, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } /* Sentinel */
};
DRIVER_INIT_METHODS(dbg);
+47
View File
@@ -0,0 +1,47 @@
#include "py_diskio.hpp"
static PyObject *ex_enumfiles(PyObject * /*self*/, PyObject *args)
{
PyObject *path, *fname, *callback;
if ( !PyArg_ParseTuple(args, "OOO", &path, &fname, &callback) )
return NULL;
return py_enumerate_files(path, fname, callback);
}
//
//static PyObject *ex_linput_close(PyObject * /*self*/, PyObject *args)
//{
// PyObject *obj;
// if ( !PyArg_ParseTuple(args, "O", &obj) )
// return NULL;
// pyl_close(obj);
// Py_RETURN_NONE;
//}
//
//static PyObject *ex_linput_open(PyObject *self, PyObject *args)
//{
// PyObject *obj, *py_filename, *py_remote;
// if ( !PyArg_ParseTuple(args, "OOO", &obj, &py_filename, &py_remote) )
// return NULL;
// return pyl_open(obj, py_filename, py_remote);
//}
//
//static PyObject *ex_linput_read(PyObject *self, PyObject *args)
//{
// PyObject *obj, *py_size;
// if ( !PyArg_ParseTuple(args, "OO", &obj, &py_size) )
// return NULL;
// return pyl_read(obj, py_size);
//}
static PyMethodDef py_methods_diskio[] =
{
{ "enumfiles", ex_enumfiles, METH_VARARGS, "" },
//{ "tell", ex_linput_tell, METH_VARARGS, "" },
//{ "open", ex_linput_open, METH_VARARGS, "" },
//{ "size", ex_linput_tell, METH_VARARGS, "" },
//{ "read", ex_linput_read, METH_VARARGS, "" },
//{ "close", ex_linput_close, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } /* Sentinel */
};
DRIVER_INIT_METHODS(diskio);
+56
View File
@@ -0,0 +1,56 @@
#include "py_expr.hpp"
#pragma warning(push)
#pragma warning(disable: 4244)
//---------------------------------------------------------------------------
static PyObject *ex_pyw_register_idc_func(PyObject *self, PyObject *args)
{
char *name, *arg;
PyObject *py_fp;
if ( !PyArg_ParseTuple(args, "ssO", &name, &arg, &py_fp) )
return NULL;
else
return PyLong_FromUnsignedLongLong(pyw_register_idc_func(name, arg, py_fp));
}
//---------------------------------------------------------------------------
static PyObject *ex_pyw_unregister_idc_func(PyObject *self, PyObject *args)
{
unsigned PY_LONG_LONG ctxptr;
if ( !PyArg_ParseTuple(args, "K", &ctxptr) )
return NULL;
return PyLong_FromLong(pyw_unregister_idc_func(ctxptr));
}
static PyObject *ex_py_set_idc_func_ex(PyObject *self, PyObject *pyargs)
{
const char *name;
unsigned PY_LONG_LONG fp_ptr;
const char *args;
int flags;
if ( !PyArg_ParseTuple(pyargs, "sKsi", &name, &fp_ptr, &args, &flags) )
return NULL;
else
return PyLong_FromLong(py_set_idc_func_ex(name, fp_ptr, args, flags));
}
//---------------------------------------------------------------------------
static PyObject *ex_py_get_call_idc_func(PyObject *self, PyObject *args)
{
return PyLong_FromUnsignedLongLong(py_get_call_idc_func());
}
//-------------------------------------------------------------------------
#pragma warning(pop)
//-------------------------------------------------------------------------
static PyMethodDef py_methods_expr[] =
{
{ "pyw_register_idc_func", ex_pyw_register_idc_func, METH_VARARGS, "" },
{ "pyw_unregister_idc_func", ex_pyw_unregister_idc_func, METH_VARARGS, "" },
{ "py_get_call_idc_func", ex_py_get_call_idc_func, METH_VARARGS, "" },
{ "py_set_idc_func_ex", ex_py_set_idc_func_ex, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } // End of methods
};
DRIVER_INIT_METHODS(expr);
+44
View File
@@ -0,0 +1,44 @@
#include "py_graph.hpp"
//--------------------------------------------------------------------------
//py_choose2_t *last_c2 = NULL;
static PyObject *ex_graph_show(PyObject * /*self*/, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
py_graph_t *ret = py_graph_t::Show(obj);
return PyBool_FromLong(ret == NULL ? 0 : 1);
}
//--------------------------------------------------------------------------
static PyObject *ex_graph_refresh(PyObject * /*self*/, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
py_graph_t::Refresh(obj);
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
static PyObject *ex_graph_addcmd(PyObject *self, PyObject *args)
{
PyObject *obj;
const char *title, *hotkey;
if ( !PyArg_ParseTuple(args, "Oss", &obj, &title, &hotkey) )
return NULL;
Py_ssize_t r = py_graph_t::AddCommand(obj, title, hotkey);
return Py_BuildValue("n", r);
}
//--------------------------------------------------------------------------
static PyMethodDef py_methods_graph[] =
{
{ "show", ex_graph_show, METH_VARARGS, "" },
{ "refresh", ex_graph_refresh, METH_VARARGS, "" },
{ "addcmd", ex_graph_addcmd, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } /* Sentinel */
};
DRIVER_INIT_METHODS(graph);
+78
View File
@@ -0,0 +1,78 @@
#include "py_kernwin.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_add_menu_item(PyObject *self, PyObject *args)
{
const char *menupath, *name, *hotkey;
PyObject *pyfunc, *pyargs;
int flags;
if ( !PyArg_ParseTuple(args, "sssiOO", &menupath, &name, &hotkey, &flags, &pyfunc, &pyargs) )
return NULL;
return py_add_menu_item(menupath, name, hotkey, flags, pyfunc, pyargs);
}
//-------------------------------------------------------------------------
static PyObject *ex_del_menu_item(PyObject *self, PyObject *args)
{
if ( !PyArg_ParseTuple(args, "O", &self) )
return NULL;
if ( py_del_menu_item(self) )
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
//-------------------------------------------------------------------------
static PyObject *ex_execute_sync(PyObject *self, PyObject *args)
{
PyObject *pycall;
int reqf;
if ( !PyArg_ParseTuple(args, "Oi", &pycall, &reqf) )
return NULL;
return PyInt_FromLong(py_execute_sync(pycall, reqf));
}
//-------------------------------------------------------------------------
static PyObject *ex_add_hotkey(PyObject *self, PyObject *args)
{
PyObject *pyfunc;
const char *hotkey;
if ( !PyArg_ParseTuple(args, "sO", &hotkey, &pyfunc) )
return NULL;
else
return py_add_hotkey(hotkey, pyfunc);
}
//-------------------------------------------------------------------------
static PyObject *ex_del_hotkey(PyObject *self, PyObject *args)
{
PyObject *pyctx;
if ( !PyArg_ParseTuple(args, "O", &pyctx) )
return NULL;
else
return PyInt_FromLong(py_del_hotkey(pyctx) ? 1 : 0);
}
//-------------------------------------------------------------------------
static PyObject *ex_execute_ui_request(PyObject *self, PyObject *args)
{
PyObject *py_list;
if ( !PyArg_ParseTuple(args, "O", &py_list) )
return NULL;
else
return PyBool_FromLong(py_execute_ui_requests(py_list) ? 1 : 0);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_kernwin[] =
{
{ "py_del_menu_item", ex_del_menu_item, METH_VARARGS, "" },
{ "py_add_menu_item", ex_add_menu_item, METH_VARARGS, "" },
{ "py_execute_sync", ex_execute_sync, METH_VARARGS, "" },
{ "py_add_hotkey", ex_add_hotkey, METH_VARARGS, "" },
{ "py_del_hotkey", ex_del_hotkey, METH_VARARGS, "" },
{ "py_execute_ui_request", ex_execute_ui_request, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } /* Sentinel */
};
DRIVER_INIT_METHODS(kernwin);
+18
View File
@@ -0,0 +1,18 @@
#include "py_nalt.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_get_switch_info_ex(PyObject *self, PyObject *args)
{
pyul_t ea;
if ( !PyArg_ParseTuple(args, PY_FMT64, &ea) )
return NULL;
return py_get_switch_info_ex(ea_t(ea));
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_nalt[] =
{
{ "get_switch_info_ex", ex_get_switch_info_ex, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL }
};
DRIVER_INIT_METHODS(nalt);
+36
View File
@@ -0,0 +1,36 @@
#include "py_notifywhen.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_notify_when(PyObject *self, PyObject *args)
{
int when;
PyObject *py_callable;
if ( !PyArg_ParseTuple(args, "IO", &when, &py_callable) )
return NULL;
return Py_BuildValue("i", notify_when(when, py_callable));
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_nw[] =
{
{ "notify_when", ex_notify_when, METH_VARARGS, "" },
{ NULL, NULL, 0, NULL } /* Sentinel */
};
DRIVER_INIT_METHODS(nw);
#define DRIVER_INIT
int driver_init()
{
bool ok = pywraps_nw_init();
if ( !ok )
return PLUGIN_SKIP;
pywraps_nw_notify(NW_INITIDA_SLOT);
return PLUGIN_KEEP;
}
#define DRIVER_TERM
void driver_term()
{
pywraps_nw_notify(NW_TERMIDA_SLOT);
pywraps_nw_term();
}
-336
View File
@@ -1,336 +0,0 @@
import types
C_TO_PY_CAST = {
'b' : 'char',
'i' : 'int',
'H' : 'uint16',
'h' : 'int16',
'B' : 'uchar',
}
# --------------------------------------------------------------------------------------------
class gen_fmt(object):
def __init__(self, fields, tp = None, bv = None, cast=None, cmt = None):
self.fields = fields
self.tp = tp
# Format to be passed to Py_BuildValue
if not bv:
self.bv = "XXX"
else:
if bv == "K":
self.bv = "PY_FMT64"
else:
self.bv = '"%s"' % bv
if not cast:
if bv == "K":
cast = "pyul_t"
elif bv in C_TO_PY_CAST:
cast = C_TO_PY_CAST[bv]
self.cast = "" if not cast else "(%s)" % cast
self.cmt = cmt
if bv == "K":
self.setcvt = "uint64 v(0); PyGetNumber(value, &v);"
elif bv == 'i':
self.setcvt = "int v = PyInt_AsLong(value);"
else:
self.setcvt = "uint64 v = %sPyInt_AsLong(value);" % self.cast
# --------------------------------------------------------------------------------------------
switch_info_ex_t_gen = [
gen_fmt('regdtyp', bv = 'b', cmt = 'size of the switch expression register as dtyp'),
gen_fmt('flags2', bv = 'i'),
gen_fmt('jcases', bv = 'i', cmt = 'number of entries in the jump table (SWI2_INDIRECT)'),
gen_fmt('regnum', bv = 'i', cmt = 'the switch expression as a register number'),
gen_fmt('flags', bv = 'H', cmt = 'the switch expression as a register number'),
gen_fmt('ncases', bv = 'H', cmt = 'number of cases (excluding default)'),
gen_fmt('defjump', bv = 'K', cmt = 'default jump address'),
gen_fmt('jumps', bv = 'K', cmt = 'jump table address'),
gen_fmt('elbase', bv = 'K', cmt = 'element base'),
gen_fmt('startea', bv = 'K', cmt = 'start of switch idiom'),
gen_fmt('custom', bv = 'K', cmt = 'information for custom tables (filled and used by modules)'),
gen_fmt('ind_lowcase', bv = 'K'),
gen_fmt(['values', 'lowcase'], bv = 'K'),
]
op_t_gen = [
gen_fmt('n', bv = 'b'),
gen_fmt('type', bv = 'B'),
gen_fmt('offb', bv = 'b'),
gen_fmt('offo', bv = 'b'),
gen_fmt('flags', bv = 'B'),
gen_fmt('dtyp', bv = 'b'),
gen_fmt(['reg', 'phrase'], bv = 'H'),
gen_fmt('value', bv = 'K'),
gen_fmt('addr', bv = 'K'),
gen_fmt('specval', bv = 'K'),
gen_fmt('specflag1', bv = 'b'),
gen_fmt('specflag2', bv = 'b'),
gen_fmt('specflag3', bv = 'b'),
gen_fmt('specflag4', bv = 'b')
]
insn_t_gen = [
gen_fmt('cs', bv = 'K'),
gen_fmt('ip', bv = 'K'),
gen_fmt('ea', bv = 'K'),
gen_fmt('itype', bv = 'H'),
gen_fmt('size', bv = 'H'),
gen_fmt('auxpref', bv = 'H'),
gen_fmt('segpref', bv = 'b'),
gen_fmt('insnpref', bv = 'b'),
gen_fmt('Op1', tp = 'op_t'),
gen_fmt('Op2', tp = 'op_t'),
gen_fmt('Op3', tp = 'op_t'),
gen_fmt('Op4', tp = 'op_t'),
gen_fmt('Op5', tp = 'op_t'),
gen_fmt('Op6', tp = 'op_t'),
gen_fmt('flags', bv = 'b')
]
regval_t_gen = [
gen_fmt('rvtype', bv = 'i'),
gen_fmt('ival', bv = 'K'),
gen_fmt('fval', bv = 'd'),
gen_fmt('bytes', bv = 's'),
]
# --------------------------------------------------------------------------------------------
S_LINK_ATTR = 'S_CLINK_NAME' # If the name is a literal, make sure you specify double quotations
S_CMOD_NAME = '_idaapi'
# --------------------------------------------------------------------------------------------
def gen_stub(gen, name, cname = None, tabs=4, gen_py_file = False, gen_c_file = False):
# Assume C type name same as python type name
if not cname:
cname = name
# Python property lines
prop_body = []
# Python get/set bodies
getset_body = []
# C get/set bodies
cgetset_body = []
# some spacing constants
spc = ' ' * tabs
spc2 = spc * 2
nspc = '\n' + spc
nspc2 = '\n' + spc2
cget_link = '%s_get_clink' % cname
#
# Process fields
#
for g in gen:
# a union will be represented by a list
if type(g.fields) != types.ListType:
fields = [g.fields]
else:
fields = g.fields
# join all field names (in case of a union)
flds_name = '_'.join(fields)
# form the method and variable names
set_method = '__set_%s__' % flds_name
get_method = '__get_%s__' % flds_name
cset_method = '%s_set_%s' % (name, flds_name)
cget_method = '%s_get_%s' % (name, flds_name)
fld_name = '__%s__' % flds_name
basic_type = not g.tp
vars = {
'get': get_method,
'set': set_method,
'l': S_LINK_ATTR,
'fld' : fld_name,
'cmod' : S_CMOD_NAME,
'cget': cget_method,
'cset': cset_method,
'csetcvt': g.setcvt,
'cname': cname,
'cgetlink': cget_link,
'cfield1': fields[0],
'bv': g.bv,
'bvcast': g.cast
}
#
# Python code
#
# basic type?
# For basic types we need to create property and get/set methods
if basic_type:
for fld in fields:
prop_body.append('%s = property(%s, %s)' % (fld, get_method, set_method))
if g.cmt:
prop_body.append('"""%s"""' % g.cmt)
#
code = '\n'.join([
# get method
'def %(get)s(self):',
spc2 + 'return %(cmod)s.%(cget)s(self)',
# set method
spc + 'def %(set)s(self, v):',
spc2 + '%(cmod)s.%(cset)s(self, v)',
]) % vars
getset_body.append(code)
#
# C code
#
if basic_type:
code = '\n'.join([
"""static PyObject *%(cget)s(PyObject *self)
{
%(cname)s *link = %(cgetlink)s(self);
if ( link == NULL )
Py_RETURN_NONE;
return Py_BuildValue(%(bv)s, %(bvcast)slink->%(cfield1)s);
}
static void %(cset)s(PyObject *self, PyObject *value)
{
%(cname)s *link = %(cgetlink)s(self);
if ( link == NULL )
return;
%(csetcvt)s
link->%(cfield1)s = %(bvcast)sv;
}
"""
]) % vars
cgetset_body.append(code)
# print 'prop_body->\n\t', '\n\t'.join(prop_body), '\n<'
# print 'getset_body->\n', '\n'.join(getset_body), '\n<'
# print 'cgetset_body->\n', '\n'.join(cgetset_body), '\n<'
vars = {
'name': name,
'cname': cname,
'getlink': cget_link,
'l': S_LINK_ATTR,
'cmod' : S_CMOD_NAME
}
#
# Form the complete Python code
#
py = '\n'.join([
'class %(name)s(py_clinked_object_t):',
# init() code
spc + 'def __init__(self, lnk = None):',
spc2 + 'py_clinked_object_t.__init__(self, lnk)',
'',
spc + 'def _create_clink(self):',
spc2 + 'return _idaapi.%(name)s_create()',
'',
spc + 'def _del_clink(self, lnk):',
spc2 + 'return _idaapi.%(name)s_destroy(lnk)',
'',
spc + 'def assign(self, other):',
spc2 + 'return _idaapi.%(name)s_assign(self, other)',
'',
'',
spc + '#',
spc + '# Autogenerated',
spc + '#',
# get/set code
spc + nspc.join(getset_body),
# props code
spc + nspc.join(prop_body),
]) % vars
#
# Form the Python to C conversion function
#
#
# Form the complete C code
#
ccode = '\n'.join([
# Form the C get link code
"""%(cname)s *%(getlink)s(PyObject *self)
{
if ( !PyObject_HasAttrString(self, %(l)s) )
return NULL;
%(cname)s *r;
PyObject *attr = PyObject_GetAttrString(self, %(l)s);
if ( PyCObject_Check(attr) )
r = (%(cname)s *) PyCObject_AsVoidPtr(attr);
else
r = NULL;
Py_DECREF(attr);
return r;
}
static PyObject *%(cname)s_create()
{
%(cname)s *inst = new %(cname)s();
return PyCObject_FromVoidPtr(inst, NULL);
}
static bool %(cname)s_destroy(PyObject *py_obj)
{
if ( !PyCObject_Check(py_obj) )
return false;
%(cname)s *inst = (%(cname)s *) PyCObject_AsVoidPtr(py_obj);
delete inst;
return true;
}
static bool %(cname)s_assign(PyObject *self, PyObject *other)
{
%(cname)s *lhs = %(cname)s_get_clink(self);
%(cname)s *rhs = %(cname)s_get_clink(other);
if (lhs == NULL || rhs == NULL)
return false;
*lhs = *rhs;
return true;
}
//-------------------------------------------------------------------------
// Auto generated - begin
//
""",
# Form C get/set functions
''.join(cgetset_body),
"""//
// Auto generated - end
//
//-------------------------------------------------------------------------"""
]) % vars
# write the Python file
if gen_py_file:
f = open(name + '.py', 'w')
f.write(py)
f.close()
# write C file
if gen_c_file:
f = open(name + '.cpp', 'w')
f.write(ccode)
f.close()
# --------------------------------------------------------------------------------------------
def main():
files = [
('switch_info_ex_t', switch_info_ex_t_gen),
]
for (n, g) in files:
gen_stub(g, n, gen_py_file = True, gen_c_file = True)
main()
+11
View File
@@ -0,0 +1,11 @@
//<inline(py_area)>
enum areacb_type_t
{
AREACB_TYPE_UNKNOWN,
AREACB_TYPE_FUNC,
AREACB_TYPE_SEGMENT,
AREACB_TYPE_HIDDEN_AREA,
AREACB_TYPE_SRAREA,
};
//</inline(py_area)>
@@ -1,7 +1,7 @@
#ifndef __PY_IDA_CUSTDATA__
#define __PY_IDA_CUSTDATA__
#ifndef __PY_IDA_BYTES_CUSTDATA__
#define __PY_IDA_BYTES_CUSTDATA__
//<code(py_custdata)>
//<code(py_bytes_custdata)>
class py_custom_data_type_t
{
data_type_t dt;
@@ -445,7 +445,7 @@ public:
}
py_custom_data_format_t *find(int dtid, int dfid, POS *loc = NULL)
{
for ( POS it=entries.begin(), it_end = entries.end(); it!=it_end; ++it )
for ( POS it=entries.begin(), it_end = entries.end(); it != it_end; ++it )
{
if ( it->dfid == dfid && it->dtid == dtid )
{
@@ -492,10 +492,10 @@ static PyObject *py_data_format_to_py_dict(const data_format_t *df)
S_MENU_NAME, df->menu_name == NULL ? "" : df->menu_name,
S_HOTKEY, df->hotkey == NULL ? "" : df->hotkey);
}
//</code(py_custdata)>
//</code(py_bytes_custdata)>
//------------------------------------------------------------------------
//<inline(py_custdata)>
//<inline(py_bytes_custdata)>
//------------------------------------------------------------------------
/*
@@ -676,6 +676,6 @@ static PyObject *py_get_custom_data_type(int dtid)
return py_data_type_to_py_dict(dt);
}
//</inline(py_custdata)>
//</inline(py_bytes_custdata)>
#endif
#endif // __PY_IDA_BYTES_CUSTDATA__
@@ -1,34 +1,6 @@
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
import struct
if pywraps_there:
_idaapi.register_custom_data_type = pywraps.register_custom_data_type
_idaapi.unregister_custom_data_type = pywraps.unregister_custom_data_type
_idaapi.register_custom_data_format = pywraps.register_custom_data_format
_idaapi.unregister_custom_data_format = pywraps.unregister_custom_data_format
_idaapi.get_custom_data_format = pywraps.get_custom_data_format
_idaapi.get_custom_data_type = pywraps.get_custom_data_type
# -----------------------------------------------------------------------
#<pycode(py_custdata)>
#<pycode(py_bytes_custdata)>
DTP_NODUP = 0x0001
class data_type_t(object):
"""
Custom data type definition. All data types should inherit from this class.
@@ -48,7 +20,7 @@ class data_type_t(object):
def register(self):
"""Registers the data type and returns the type id or < 0 on failure"""
return _idaapi.register_custom_data_type(self)
return _ida_bytes.register_custom_data_type(self)
def unregister(self):
"""Unregisters the data type and returns True on success"""
@@ -57,7 +29,7 @@ class data_type_t(object):
return True
# Try to unregister
r = _idaapi.unregister_custom_data_type(self.id)
r = _ida_bytes.unregister_custom_data_type(self.id)
# Clear the ID
if r:
@@ -111,7 +83,7 @@ class data_format_t(object):
def register(self, dtid):
"""Registers the data format with the given data type id and returns the type id or < 0 on failure"""
return _idaapi.register_custom_data_format(dtid, self)
return _ida_bytes.register_custom_data_format(dtid, self)
def unregister(self, dtid):
"""Unregisters the data format with the given data type id"""
@@ -121,7 +93,7 @@ class data_format_t(object):
return True
# Unregister
r = _idaapi.unregister_custom_data_format(dtid, self.id)
r = _ida_bytes.unregister_custom_data_format(dtid, self.id)
# Clear the ID
if r:
@@ -243,5 +215,5 @@ def unregister_data_types_and_formats(formats):
ok = __walk_types_and_formats(formats, __unreg_type, __unreg_format, False)
return 1 if ok else -1
#</pycode(py_custdata)>
#</pycode(py_bytes_custdata)>
# -----------------------------------------------------------------------
-186
View File
@@ -2,7 +2,6 @@
#define __PYDBG__
//<code(py_dbg)>
static PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas);
//</code(py_dbg)>
//<inline(py_dbg)>
@@ -90,25 +89,6 @@ public:
}
// hookgenDBG:methods
virtual void dbg_process_start(pid_t pid, thid_t tid, ea_t ea, const char * modinfo_name, ea_t modinfo_base, asize_t modinfo_size) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(modinfo_name); qnotused(modinfo_base); qnotused(modinfo_size); }
virtual void dbg_process_exit(pid_t pid, thid_t tid, ea_t ea, int exit_code) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(exit_code); }
virtual void dbg_process_attach(pid_t pid, thid_t tid, ea_t ea, const char * modinfo_name, ea_t modinfo_base, asize_t modinfo_size) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(modinfo_name); qnotused(modinfo_base); qnotused(modinfo_size); }
virtual void dbg_process_detach(pid_t pid, thid_t tid, ea_t ea) {qnotused(pid); qnotused(tid); qnotused(ea); }
virtual void dbg_thread_start(pid_t pid, thid_t tid, ea_t ea) {qnotused(pid); qnotused(tid); qnotused(ea); }
virtual void dbg_thread_exit(pid_t pid, thid_t tid, ea_t ea, int exit_code) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(exit_code); }
virtual void dbg_library_load(pid_t pid, thid_t tid, ea_t ea, const char * modinfo_name, ea_t modinfo_base, asize_t modinfo_size) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(modinfo_name); qnotused(modinfo_base); qnotused(modinfo_size); }
virtual void dbg_library_unload(pid_t pid, thid_t tid, ea_t ea, const char * info) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(info); }
virtual void dbg_information(pid_t pid, thid_t tid, ea_t ea, const char * info) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(info); }
virtual int dbg_exception(pid_t pid, thid_t tid, ea_t ea, int exc_code, bool exc_can_cont, ea_t exc_ea, const char * exc_info) {qnotused(pid); qnotused(tid); qnotused(ea); qnotused(exc_code); qnotused(exc_can_cont); qnotused(exc_ea); qnotused(exc_info); return 0;}
virtual void dbg_suspend_process() {}
virtual int dbg_bpt(thid_t tid, ea_t bptea) {qnotused(tid); qnotused(bptea); return 0;}
virtual int dbg_trace(thid_t tid, ea_t ip) {qnotused(tid); qnotused(ip); return 0;}
virtual void dbg_request_error(int failed_command, int failed_dbg_notification) {qnotused(failed_command); qnotused(failed_dbg_notification); }
virtual void dbg_step_into() {}
virtual void dbg_step_over() {}
virtual void dbg_run_to(pid_t pid, thid_t tid, ea_t ea) {qnotused(pid); qnotused(tid); qnotused(ea); }
virtual void dbg_step_until_ret() {}
virtual void dbg_bpt_changed(int bptev_code, bpt_t * bpt) {qnotused(bptev_code); qnotused(bpt); }
};
int idaapi DBG_Callback(void *ud, int notification_code, va_list va)
@@ -125,151 +105,6 @@ int idaapi DBG_Callback(void *ud, int notification_code, va_list va)
switch ( notification_code )
{
// hookgenDBG:notifications
case dbg_process_start:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_process_start(event->pid, event->tid, event->ea, event->modinfo.name, event->modinfo.base, event->modinfo.size);
}
break;
case dbg_process_exit:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_process_exit(event->pid, event->tid, event->ea, event->exit_code);
}
break;
case dbg_process_attach:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_process_attach(event->pid, event->tid, event->ea, event->modinfo.name, event->modinfo.base, event->modinfo.size);
}
break;
case dbg_process_detach:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_process_detach(event->pid, event->tid, event->ea);
}
break;
case dbg_thread_start:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_thread_start(event->pid, event->tid, event->ea);
}
break;
case dbg_thread_exit:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_thread_exit(event->pid, event->tid, event->ea, event->exit_code);
}
break;
case dbg_library_load:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_library_load(event->pid, event->tid, event->ea, event->modinfo.name, event->modinfo.base, event->modinfo.size);
}
break;
case dbg_library_unload:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_library_unload(event->pid, event->tid, event->ea, event->info);
}
break;
case dbg_information:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_information(event->pid, event->tid, event->ea, event->info);
}
break;
case dbg_exception:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
int * warn = va_arg(va, int *);
int _tmp = proxy->dbg_exception(event->pid, event->tid, event->ea, event->exc.code, event->exc.can_cont, event->exc.ea, event->exc.info);
ret = DBG_Hooks::store_int(_tmp, event, warn);
}
break;
case dbg_suspend_process:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
qnotused(event);
proxy->dbg_suspend_process();
}
break;
case dbg_bpt:
{
thid_t tid = va_arg(va, thid_t);
ea_t bptea = va_arg(va, ea_t);
int * warn = va_arg(va, int *);
int _tmp = proxy->dbg_bpt(tid, bptea);
ret = DBG_Hooks::store_int(_tmp, tid, bptea, warn);
}
break;
case dbg_trace:
{
thid_t tid = va_arg(va, thid_t);
ea_t ip = va_arg(va, ea_t);
ret = proxy->dbg_trace(tid, ip);
}
break;
case dbg_request_error:
{
ui_notification_t failed_command = ui_notification_t(va_arg(va, int));
dbg_notification_t failed_dbg_notification = dbg_notification_t(va_arg(va, int));
proxy->dbg_request_error((int) failed_command, (int) failed_dbg_notification);
}
break;
case dbg_step_into:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
qnotused(event);
proxy->dbg_step_into();
}
break;
case dbg_step_over:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
qnotused(event);
proxy->dbg_step_over();
}
break;
case dbg_run_to:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
proxy->dbg_run_to(event->pid, event->tid, event->ea);
}
break;
case dbg_step_until_ret:
{
const debug_event_t * event = va_arg(va, const debug_event_t *);
qnotused(event);
proxy->dbg_step_until_ret();
}
break;
case dbg_bpt_changed:
{
int bptev_code = va_arg(va, int);
bpt_t * bpt = va_arg(va, bpt_t *);
proxy->dbg_bpt_changed(bptev_code, bpt);
}
break;
}
}
catch (Swig::DirectorException &e)
@@ -338,26 +173,5 @@ static ea_t py_internal_get_sreg_base(thid_t tid, int sreg_value)
: answer;
}
//-------------------------------------------------------------------------
static PyObject *py_get_tev_reg_mem(int tev, int reg)
{
tev_info_t ti;
memreg_infos_t mis;
bool ok = get_tev_info(tev, &ti)
&& get_insn_tev_reg_mem(tev, &mis)
&& reg >= 0 && reg < mis.size();
if ( ok )
{
PyObject *py_str = PyString_FromStringAndSize(
(const char *) mis[reg].bytes.begin(),
mis[reg].bytes.size());
return py_str;
}
else
{
Py_RETURN_NONE;
}
}
//</inline(py_dbg)>
#endif
+8
View File
@@ -0,0 +1,8 @@
#<pycode(py_dbg)>
def get_tev_reg_mem(tev, idx):
mis = memreg_infos_t()
if get_insn_tev_reg_mem(tev, mis):
if idx < mis.size():
return mis[idx].bytes
#</pycode(py_dbg)>
+3 -2
View File
@@ -44,9 +44,10 @@ static error_t py_call_idc_func(
pargs.empty() ? NULL : pargs[0].o));
error_t err;
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
qstring qerrbuf;
if ( PyW_GetError(&qerrbuf) )
{
err = PyW_CreateIdcException(r, errbuf);
err = PyW_CreateIdcException(r, qerrbuf.c_str());
}
else
{
+5 -30
View File
@@ -1,28 +1,3 @@
# --------------------------------------------------------------------------
import os
import sys
import idaapi
import _idaapi
from sys import getrefcount
import gc
try:
import pywraps
pywraps_there = True
_idaapi.pyw_register_idc_func = pywraps.pyw_register_idc_func
_idaapi.pyw_unregister_idc_func = pywraps.pyw_unregister_idc_func
_idaapi.py_get_call_idc_func = pywraps.py_get_call_idc_func
_idaapi.py_set_idc_func_ex = pywraps.py_set_idc_func_ex
except Exception as e:
pywraps_there = False
print("exception: %s" % str(e))
print("Using PyWraps: %s" % pywraps_there)
# --------------------------------------------------------------------------
#<pycode(py_expr)>
try:
@@ -34,13 +9,13 @@ try:
# A trampoline function that is called from idcfunc_t that will
# call the Python callback with the argv and r properly serialized to python
call_idc_func__ = ctypes.CFUNCTYPE(ctypes.c_long)(_idaapi.py_get_call_idc_func())
call_idc_func__ = ctypes.CFUNCTYPE(ctypes.c_long)(_ida_expr.py_get_call_idc_func())
except:
def call_idc_func__(*args):
warning("IDC extensions need ctypes library in order to work")
return 0
try:
_IDCFUNC_CB_T = CFUNCTYPE(c_int, c_void_p, c_void_p)
_IDCFUNC_CB_T = CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p)
except:
_IDCFUNC_CB_T = None
@@ -107,7 +82,7 @@ def set_idc_func_ex(name, fp=None, args=(), flags=0):
del __IDC_FUNC_CTXS[name]
# Delete the context and unregister the function
return _idaapi.pyw_unregister_idc_func(f.ctxptr)
return _ida_expr.pyw_unregister_idc_func(f.ctxptr)
# Registering a function that is already registered?
if f is not None:
@@ -118,7 +93,7 @@ def set_idc_func_ex(name, fp=None, args=(), flags=0):
args = "".join([chr(x) for x in args])
# Create a context
ctxptr = _idaapi.pyw_register_idc_func(name, args, fp)
ctxptr = _ida_expr.pyw_register_idc_func(name, args, fp)
if ctxptr == 0:
return False
@@ -129,7 +104,7 @@ def set_idc_func_ex(name, fp=None, args=(), flags=0):
__IDC_FUNC_CTXS[name] = f
# Register IDC function with a callback
return _idaapi.py_set_idc_func_ex(
return _ida_expr.py_set_idc_func_ex(
name,
f.fp_ptr,
args,
+59
View File
@@ -0,0 +1,59 @@
//<inline(py_frame)>
//-------------------------------------------------------------------------
/*
header: frame.hpp
#<pydoc>
def add_stkvar3(op, v, flags):
"""
Automatically add stack variable if doesn't exist
Processor modules should use ua_stkvar2()
@param op: reference to instruction operand
@param v: immediate value in the operand (usually op.addr)
@param flags: combination of STKVAR_... constants
@return: Boolean
"""
pass
#</pydoc>
*/
bool py_add_stkvar3(PyObject *py_op, PyObject *py_v, int flags)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
op_t *op = op_t_get_clink(py_op);
uint64 v;
return ( op == NULL || !PyW_GetNumber(py_v, &v) || !add_stkvar3(*op, sval_t(v), flags)) ? false : true;
}
//-------------------------------------------------------------------------
/*
#<pydoc>
def get_stkvar(op, v):
"""
Get pointer to stack variable
@param op: reference to instruction operand
@param v: immediate value in the operand (usually op.addr)
@return:
- None on failure
- tuple(member_t, actval)
where actval: actual value used to fetch stack variable
"""
pass
#</pydoc>
*/
PyObject *py_get_stkvar(PyObject *py_op, PyObject *py_v)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
op_t *op = op_t_get_clink(py_op);
uint64 v;
if ( op == NULL || !PyW_GetNumber(py_v, &v) )
Py_RETURN_NONE;
sval_t actval;
member_t *member = get_stkvar(*op, sval_t(v), &actval);
if ( member == NULL )
Py_RETURN_NONE;
return Py_BuildValue("(O" PY_SFMT64 ")",
SWIG_NewPointerObj(SWIG_as_voidptr(member), SWIGTYPE_p_member_t, 0),
pyl_t(actval));
}
//</inline(py_frame)>
+4 -2
View File
@@ -1,4 +1,6 @@
#<pycode(py_gdl)>
import _ida_idaapi
import types
# -----------------------------------------------------------------------
class BasicBlock(object):
"""Basic block class. It is returned by the Flowchart class"""
@@ -52,7 +54,7 @@ class FlowChart(object):
raise Exception("Please specifiy either a function or start/end pair")
if bounds is None:
bounds = (BADADDR, BADADDR)
bounds = (_ida_idaapi.BADADDR, _ida_idaapi.BADADDR)
# Create the flowchart
self._q = qflow_chart_t("", f, bounds[0], bounds[1], flags)
@@ -61,7 +63,7 @@ class FlowChart(object):
"""Number of blocks in the flow chart"""
def refresh():
def refresh(self):
"""Refreshes the flow chart"""
self._q.refresh()
+13 -13
View File
@@ -7,7 +7,7 @@ class py_graph_t : public py_customidamemo_t
typedef py_customidamemo_t inherited;
protected:
void collect_class_callbacks_ids(callbacks_ids_t *out);
void collect_class_callbacks_ids(pycim_callbacks_ids_t *out);
private:
enum
@@ -74,7 +74,7 @@ private:
void clear(py_graph_t *pyg)
{
iterator e = end();
for ( iterator it=begin(); it!=end(); )
for ( iterator it=begin(); it != end(); )
{
if ( it->second == pyg )
{
@@ -104,7 +104,7 @@ private:
// static callback
static int idaapi s_callback(void *obj, int code, va_list va)
{
QASSERT(30453, py_customidamemo_t::lookup_info.find_by_py_view(NULL, NULL, (py_graph_t *) obj));
QASSERT(30453, pycim_lookup_info.find_by_py_view(NULL, NULL, (py_graph_t *) obj));
PYW_GIL_GET;
return ((py_graph_t *)obj)->gr_callback(code, va);
}
@@ -288,7 +288,7 @@ private:
void show()
{
TForm *form;
if ( lookup_info.find_by_py_view(&form, NULL, this) )
if ( pycim_lookup_info.find_by_py_view(&form, NULL, this) )
open_tform(form, FORM_TAB|FORM_MENU|FORM_QWIDGET);
}
@@ -330,7 +330,7 @@ private:
TForm *form = create_tform(title, &hwnd);
if ( hwnd != NULL ) // Created new tform
{
lookup_info_t::entry_t &e = lookup_info.new_entry(this);
lookup_entry_t &e = pycim_lookup_info.new_entry(this);
// get a unique graph id
netnode id;
char grnode[MAXSTR];
@@ -345,7 +345,7 @@ private:
viewer_fit_window(pview);
bind(self, pview);
install_custom_viewer_handlers();
lookup_info.commit(e, form, view);
pycim_lookup_info.commit(e, form, view);
}
else
{
@@ -387,7 +387,7 @@ public:
return;
py_graph_t *_this = view_extract_this<py_graph_t>(self);
if ( _this == NULL || !lookup_info.find_by_py_view(NULL, NULL, _this) )
if ( _this == NULL || !pycim_lookup_info.find_by_py_view(NULL, NULL, _this) )
return;
_this->jump_to_node(nid);
@@ -396,7 +396,7 @@ public:
static Py_ssize_t AddCommand(PyObject *self, const char *title, const char *hotkey)
{
py_graph_t *_this = view_extract_this<py_graph_t>(self);
if ( _this == NULL || !lookup_info.find_by_py_view(NULL, NULL, _this) )
if ( _this == NULL || !pycim_lookup_info.find_by_py_view(NULL, NULL, _this) )
return 0;
return _this->add_command(title, hotkey);
@@ -406,7 +406,7 @@ public:
{
TForm *form;
py_graph_t *_this = view_extract_this<py_graph_t>(self);
if ( _this == NULL || !lookup_info.find_by_py_view(&form, NULL, _this) )
if ( _this == NULL || !pycim_lookup_info.find_by_py_view(&form, NULL, _this) )
return;
close_tform(form, FORM_CLOSE_LATER);
}
@@ -429,7 +429,7 @@ public:
graph_viewer_t *found_view;
TForm *form = find_tform(title.c_str());
if ( form != NULL )
lookup_info.find_by_form(&found_view, (py_customidamemo_t**) &py_graph, form);
pycim_lookup_info.find_by_form(&found_view, (py_customidamemo_t**) &py_graph, form);
if ( py_graph == NULL )
{
@@ -456,7 +456,7 @@ public:
};
//-------------------------------------------------------------------------
void py_graph_t::collect_class_callbacks_ids(callbacks_ids_t *out)
void py_graph_t::collect_class_callbacks_ids(pycim_callbacks_ids_t *out)
{
inherited::collect_class_callbacks_ids(out);
out->add(S_ON_REFRESH, 0);
@@ -507,7 +507,7 @@ void py_graph_t::on_user_refresh(mutable_graph_t *g)
node_cache.clear();
// Get the edges
for ( int i=(int)PyList_Size(edges.o)-1; i>=0; i-- )
for ( int i=(int)PyList_Size(edges.o)-1; i >= 0; i-- )
{
// Each list item is a sequence (id1, id2)
borref_t item(PyList_GetItem(edges.o, i));
@@ -517,7 +517,7 @@ void py_graph_t::on_user_refresh(mutable_graph_t *g)
// Get and validate each of the two elements in the sequence
int edge_ids[2];
int j;
for ( j=0; j<qnumber(edge_ids); j++ )
for ( j=0; j < qnumber(edge_ids); j++ )
{
newref_t id(PySequence_GetItem(item.o, j));
if ( id == NULL || !PyInt_Check(id.o) )
+8 -7
View File
@@ -1,5 +1,6 @@
#<pycode(py_graph)>
class GraphViewer(CustomIDAMemo):
import ida_idaapi
class GraphViewer(ida_idaapi.CustomIDAMemo):
"""This class wraps the user graphing facility provided by the graph.hpp file"""
def __init__(self, title, close_open = False):
"""
@@ -50,7 +51,7 @@ class GraphViewer(CustomIDAMemo):
Closes the graph.
It is possible to call Show() again (which will recreate the graph)
"""
_idaapi.pyg_close(self)
_ida_graph.pyg_close(self)
def Show(self):
"""
@@ -59,14 +60,14 @@ class GraphViewer(CustomIDAMemo):
@return: Boolean
"""
if self._close_open:
frm = _idaapi.find_tform(self._title)
frm = _ida_kernwin.find_tform(self._title)
if frm:
_idaapi.close_tform(frm, 0)
return _idaapi.pyg_show(self)
_ida_kernwin.close_tform(frm, 0)
return _ida_graph.pyg_show(self)
def Select(self, node_id):
"""Selects a node on the graph"""
_idaapi.pyg_select_node(self, node_id)
_ida_graph.pyg_select_node(self, node_id)
def AddCommand(self, title, hotkey):
"""
@@ -74,7 +75,7 @@ class GraphViewer(CustomIDAMemo):
- register_action()
- attach_action_to_popup()
"""
return _idaapi.pyg_add_command(self, title, hotkey)
return _ida_graph.pyg_add_command(self, title, hotkey)
def OnRefresh(self):
"""
+439
View File
@@ -0,0 +1,439 @@
//-------------------------------------------------------------------------
//<code(py_hexrays)>
#ifdef WITH_HEXRAYS
hexdsp_t *hexdsp = NULL;
#endif // WITH_HEXRAYS
//-------------------------------------------------------------------------
qstring_printer_t *new_qstring_printer_t(const cfunc_t *f, bool tags)
{
return new qstring_printer_t(f, * (new qstring()), tags);
}
//-------------------------------------------------------------------------
void delete_qstring_printer_t(qstring_printer_t *qs)
{
delete &(qs->s);
delete qs;
}
//---------------------------------------------------------------------
static int hexrays_python_call(ref_t fct, ref_t args)
{
PYW_GIL_GET;
newref_t resultobj(PyEval_CallObject(fct.o, args.o));
if ( PyErr_Occurred() )
{
PyErr_Print();
return 0;
}
int result;
if ( SWIG_IsOK(SWIG_AsVal_int(resultobj.o, &result)) )
return result;
msg("IDAPython: Hex-rays python callback returned non-integer; value ignored.\n");
return 0;
}
//---------------------------------------------------------------------
static bool idaapi __python_custom_viewer_popup_item_callback(void *ud)
{
PYW_GIL_GET;
int ret;
borref_t fct((PyObject *)ud);
newref_t nil(NULL);
ret = hexrays_python_call(fct, nil);
return ret ? true : false;
}
//---------------------------------------------------------------------
static int idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_list va)
{
PYW_GIL_GET;
int ret;
borref_t fct((PyObject *)ud);
switch ( event )
{
case hxe_maturity:
///< Ctree maturity level is being changed.
///< cfunc_t *cfunc
///< ctree_maturity_t new_maturity
{
cfunc_t *arg0 = va_arg(va, cfunc_t *);
ctree_maturity_t arg1 = va_argi(va, ctree_maturity_t);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
newref_t args(Py_BuildValue("(iOi)", event, arg0obj.o, arg1));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_interr:
///< Internal error has occurred.
///< int errcode
{
int arg0 = va_argi(va, int);
newref_t args(Py_BuildValue("(ii)", event, arg0));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_print_func:
///< Printing ctree and generating text.
///< cfunc_t *cfunc
///< vc_printer_t *vp
///< Returns: 1 if text has been generated by the plugin
{
cfunc_t *arg0 = va_arg(va, cfunc_t *);
vc_printer_t *arg1 = va_arg(va, vc_printer_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
newref_t arg1obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg1), SWIGTYPE_p_vc_printer_t, 0 ));
newref_t args(Py_BuildValue("(iOO)", event, arg0obj.o, arg1obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_func_printed:
///< Function text has been generated. Plugins may
///< modify the text in \ref sv.
///< cfunc_t *cfunc
{
cfunc_t *arg0 = va_arg(va, cfunc_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
// User interface related events:
case hxe_open_pseudocode:
///< New pseudocode view has been opened.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_switch_pseudocode:
///< Existing pseudocode view has been reloaded
///< with a new function. Its text has not been
///< refreshed yet, only cfunc and mba pointers are ready.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_refresh_pseudocode:
///< Existing pseudocode text has been refreshed.
///< vdui_t *vu
///< See also hxe_text_ready, which happens earlier
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_close_pseudocode:
///< Pseudocode view is being closed.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_keyboard:
///< Keyboard has been hit.
///< vdui_t *vu
///< int key_code (VK_...)
///< int shift_state
///< Should return: 1 if the event has been handled
{
vdui_t *arg0 = va_arg(va, vdui_t *);
int arg1 = va_argi(va, int);
int arg2 = va_argi(va, int);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iOii)", event, arg0obj.o, arg1, arg2));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_right_click:
///< Mouse right click. We can add menu items now.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_double_click:
///< Mouse double click.
///< vdui_t *vu
///< int shift_state
///< Should return: 1 if the event has been handled
{
vdui_t *arg0 = va_arg(va, vdui_t *);
int arg1 = va_argi(va, int);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iOi)", event, arg0obj.o, arg1));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_curpos:
///< Current cursor position has been changed.
///< (for example, by left-clicking or using keyboard)
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_create_hint:
///< Create a hint for the current item.
///< vdui_t *vu
///< qstring *result_hint
///< int *implines
///< Possible return values:
///< 0: the event has not been handled
///< 1: hint has been created (should set *implines to nonzero as well)
///< 2: hint has been created but the standard hints must be
///< appended by the decompiler
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_text_ready:
///< Decompiled text is ready.
///< vdui_t *vu
///< This event can be used to modify the output text (sv).
///< The text uses regular color codes (see lines.hpp)
///< COLOR_ADDR is used to store pointers to ctree elements
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_call(fct, args);
}
break;
case hxe_populating_popup:
///< Populating popup menu. We can add menu items now.
///< TForm *form
///< TPopupMenu *popup_handle
///< vdui_t *vu
{
TForm *form = va_arg(va, TForm *);
TPopupMenu *pp = va_arg(va, TPopupMenu*);
vdui_t *vdui = va_arg(va, vdui_t *);
newref_t py_form(SWIG_NewPointerObj(SWIG_as_voidptr(form), SWIGTYPE_p_Forms__TForm, 0));
newref_t py_popup(SWIG_NewPointerObj(SWIG_as_voidptr(pp), SWIGTYPE_p_Menus__TPopupMenu, 0));
newref_t py_vdui(SWIG_NewPointerObj(SWIG_as_voidptr(vdui), SWIGTYPE_p_vdui_t, 0 ));
newref_t py_args(Py_BuildValue("(iOOO)", event, py_form.o, py_popup.o, py_vdui.o));
ret = hexrays_python_call(fct, py_args);
}
break;
default:
//~ msg("IDAPython: Unknown event `%u' occured\n", event);
ret = 0;
break;
}
return ret;
}
//-------------------------------------------------------------------------
// A set of cfuncptr_t objects that were created from IDAPython.
// This is necessary in order to delete those objects before the hexrays
// plugin is unloaded. Otherwise, IDAPython will still delete them, but
// the plugin's 'hexdsp' dispatcher function will point to dlclose()'d
// code.
static qvector<cfuncptr_t*> python_cfuncptrs;
void hexrays_clear_python_cfuncptr_t_references(void)
{
for ( size_t i = 0, n = python_cfuncptrs.size(); i < n; ++i )
python_cfuncptrs[i]->reset();
// NOTE: Don't clear() the array of pointers. All the python-exposed
// cfuncptr_t instances will be deleted through the python
// shutdown/ref-decrementing process anyway, and the entries will be
// properly pulled out of the vector when that happens.
}
//-------------------------------------------------------------------------
void hexrays_register_python_cfuncptr_t_instance(cfuncptr_t *fp)
{
QASSERT(30457, !python_cfuncptrs.has(fp));
python_cfuncptrs.push_back(fp);
}
//-------------------------------------------------------------------------
void hexrays_deregister_python_cfuncptr_t_instance(cfuncptr_t *fp)
{
qvector<cfuncptr_t*>::iterator found = python_cfuncptrs.find(fp);
if ( found != python_cfuncptrs.end() )
{
fp->reset();
python_cfuncptrs.erase(found);
}
}
//-------------------------------------------------------------------------
cfuncptr_t _decompile(func_t *pfn, hexrays_failure_t *hf)
{
try
{
cfuncptr_t cfunc = decompile(pfn, hf);
return cfunc;
}
catch(...)
{
error("Hex-Rays Python: decompiler threw an exception.\n");
}
return cfuncptr_t(0);
}
//-------------------------------------------------------------------------
static bool is_hexrays_plugin(const plugin_info_t *pinfo)
{
bool is_hx = false;
if ( pinfo != NULL && pinfo->entry != NULL )
{
const plugin_t *p = pinfo->entry;
if ( streq(p->wanted_name, "Hex-Rays Decompiler") )
is_hx = true;
}
return is_hx;
}
//-------------------------------------------------------------------------
static void try_init()
{
init_hexrays_plugin(0);
if ( hexdsp != NULL )
msg("IDAPython Hex-Rays bindings initialized.\n");
}
//-------------------------------------------------------------------------
static int idaapi on_ui_notification(void *, int code, va_list va)
{
switch ( code )
{
case ui_plugin_loaded:
if ( hexdsp == NULL && is_hexrays_plugin(va_arg(va, plugin_info_t *)) )
try_init();
break;
case ui_plugin_unloading:
{
if ( hexdsp != NULL )
{
// Hex-Rays will close. Make sure all the refcounted cfunc_t objects
// are cleared right away.
if ( is_hexrays_plugin(va_arg(va, plugin_info_t *)) )
{
hexrays_clear_python_cfuncptr_t_references();
hexdsp = NULL;
}
}
}
break;
}
return 0;
}
//</code(py_hexrays)>
//<inline(py_hexrays)>
//---------------------------------------------------------------------
extern hexdsp_t *hexdsp;
bool py_init_hexrays_plugin(int flags=0)
{
// Only initialize one time
if ( hexdsp == NULL )
return init_hexrays_plugin(flags);
else
return true;
}
//---------------------------------------------------------------------
void py_add_custom_viewer_popup_item(
TCustomControl *custom_viewer,
const char *title,
const char *hotkey,
PyObject *custom_viewer_popup_item_callback)
{
PYW_GIL_GET;
Py_INCREF(custom_viewer_popup_item_callback);
add_custom_viewer_popup_item(custom_viewer, title, hotkey, __python_custom_viewer_popup_item_callback, custom_viewer_popup_item_callback);
};
//---------------------------------------------------------------------
bool py_install_hexrays_callback(PyObject *hx_cblist_callback)
{
PYW_GIL_GET;
if ( install_hexrays_callback(__hexrays_python_callback, hx_cblist_callback) )
{
Py_INCREF(hx_cblist_callback);
return true;
}
return false;
}
//---------------------------------------------------------------------
int py_remove_hexrays_callback(PyObject *hx_cblist_callback)
{
PYW_GIL_GET;
int result, i;
result = remove_hexrays_callback(__hexrays_python_callback, hx_cblist_callback);
for ( i = 0; i < result; i++ )
Py_DECREF(hx_cblist_callback);
return result;
}
cfuncptr_t _decompile(func_t *pfn, hexrays_failure_t *hf);
//-------------------------------------------------------------------------
bool py_decompile_many(const char *outfile, PyObject *funcaddrs, int flags)
{
eavec_t leas, *eas = NULL;
if ( funcaddrs != Py_None )
{
if ( !PyW_PyListToEaVec(funcaddrs, leas) )
return false;
eas = &leas;
}
return decompile_many(outfile, eas, flags);
}
//-------------------------------------------------------------------------
// Some examples will want to use action_handler_t's whose update() method
// calls get_tform_vdui() to figure out whether the action should be enabled
// for the current form. Unfortunately, if hexrays is first unloaded before
// the widget cleanup is performed (e.g., while loading another IDB),
// the action would crash. Ideally we should wrap all toplevel calls
// with such wrappers, but it doesn't seem to be really necessary at the
// moment: only corner-cases will reveal this issue (reported by
// the idapython_hr-decompile test.)
vdui_t *py_get_tform_vdui(TForm *f)
{
return hexdsp != NULL ? get_tform_vdui(f) : NULL;
}
//</inline(py_hexrays)>
//<init(py_hexrays)>
try_init();
hook_to_notification_point(HT_UI, on_ui_notification, NULL);
//</init(py_hexrays)>
+419
View File
@@ -0,0 +1,419 @@
# -----------------------------------------------------------------------
#<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)>
+89 -1700
View File
File diff suppressed because it is too large Load Diff
+126 -78
View File
@@ -5,7 +5,7 @@ try:
except:
pywraps_there = False
import _idaapi
import _ida_idaapi
import random
import operator
import datetime
@@ -241,82 +241,6 @@ class PyIdc_cvt_int64__(pyidc_cvt_helper__):
def __rmul__(self, other): return self.__op(2, other, True)
def __rdiv__(self, other): return self.__op(3, other, True)
# -----------------------------------------------------------------------
# qstrvec_t clinked object
class _qstrvec_t(py_clinked_object_t):
"""
WARNING: It is very unlikely an IDAPython user should ever, ever
have to use this type. It should only be used for IDAPython internals.
For example, in py_askusingform.py, we ctypes-expose to the IDA
kernel & UI a qstrvec instance, in case a DropdownListControl is
constructed.
That's because that's what AskUsingForm expects, and we have no
choice but to make a DropdownListControl hold a qstrvec_t.
This is, afaict, the only situation where a Python
_qstrvec_t is required.
"""
def __init__(self, items=None):
py_clinked_object_t.__init__(self)
# Populate the list if needed
if items:
self.from_list(items)
def _create_clink(self):
return _idaapi.qstrvec_t_create()
def _del_clink(self, lnk):
return _idaapi.qstrvec_t_destroy(lnk)
def _get_clink_ptr(self):
return _idaapi.qstrvec_t_get_clink_ptr(self)
def assign(self, other):
"""Copies the contents of 'other' to 'self'"""
return _idaapi.qstrvec_t_assign(self, other)
def __setitem__(self, idx, s):
"""Sets string at the given index"""
return _idaapi.qstrvec_t_set(self, idx, s)
def __getitem__(self, idx):
"""Gets the string at the given index"""
return _idaapi.qstrvec_t_get(self, idx)
def __get_size(self):
return _idaapi.qstrvec_t_size(self)
size = property(__get_size)
"""Returns the count of elements"""
def addressof(self, idx):
"""Returns the address (as number) of the qstring at the given index"""
return _idaapi.qstrvec_t_addressof(self, idx)
def add(self, s):
"""Add a string to the vector"""
return _idaapi.qstrvec_t_add(self, s)
def from_list(self, lst):
"""Populates the vector from a Python string list"""
return _idaapi.qstrvec_t_from_list(self, lst)
def clear(self, qclear=False):
"""
Clears all strings from the vector.
@param qclear: Just reset the size but do not actually free the memory
"""
return _idaapi.qstrvec_t_clear(self, qclear)
def insert(self, idx, s):
"""Insert a string into the vector"""
return _idaapi.qstrvec_t_insert(self, idx, s)
def remove(self, idx):
"""Removes a string from the vector"""
return _idaapi.qstrvec_t_remove(self, idx)
# -----------------------------------------------------------------------
class PyIdc_cvt_refclass__(pyidc_cvt_helper__):
"""Helper class for representing references to immutable objects"""
@@ -344,7 +268,8 @@ def as_cstr(val):
def as_unicode(s):
"""Convenience function to convert a string into appropriate unicode format"""
# use UTF16 big/little endian, depending on the environment?
return unicode(s).encode("UTF-16" + ("BE" if _idaapi.cvar.inf.mf else "LE"))
import _ida_ida
return unicode(s).encode("UTF-16" + ("BE" if _ida_ida.cvar.inf.mf else "LE"))
# -----------------------------------------------------------------------
def as_uint32(v):
@@ -619,4 +544,127 @@ NW_TERMIDA = 0x0008
NW_REMOVE = 0x0010
"""Use this flag with other flags to uninstall a notifywhen callback"""
# -----------------------------------------------------------------------
# CustomIDAMemo
# -----------------------------------------------------------------------
class CustomIDAMemo(object):
def Refresh(self):
"""
Refreshes the graph. This causes the OnRefresh() to be called
"""
ida_idaapi.pygc_refresh(self)
def GetCurrentRendererType(self):
return ida_idaapi.pygc_get_current_renderer_type(self)
def SetCurrentRendererType(self, rtype):
"""
Set the current view's renderer.
@param rtype: The renderer type. Should be one of the idaapi.TCCRT_* values.
"""
ida_idaapi.pygc_set_current_renderer_type(self, rtype)
def SetNodeInfo(self, node_index, node_info, flags):
"""
Set the properties for the given node.
Example usage (set second nodes's bg color to red):
inst = ...
p = idaapi.node_info_t()
p.bg_color = 0x00ff0000
inst.SetNodeInfo(1, p, idaapi.NIF_BG_COLOR)
@param node_index: The node index.
@param node_info: An idaapi.node_info_t instance.
@param flags: An OR'ed value of NIF_* values.
"""
ida_idaapi.pygc_set_node_info(self, node_index, node_info, flags)
def SetNodesInfos(self, values):
"""
Set the properties for the given nodes.
Example usage (set first three nodes's bg color to purple):
inst = ...
p = idaapi.node_info_t()
p.bg_color = 0x00ff00ff
inst.SetNodesInfos({0 : p, 1 : p, 2 : p})
@param values: A dictionary of 'int -> node_info_t' objects.
"""
ida_idaapi.pygc_set_nodes_infos(self, values)
def GetNodeInfo(self, node):
"""
Get the properties for the given node.
@param node: The index of the node.
@return: A tuple (bg_color, frame_color, ea, text), or None.
"""
return ida_idaapi.pygc_get_node_info(self, node)
def DelNodesInfos(self, *nodes):
"""
Delete the properties for the given node(s).
@param nodes: A list of node IDs
"""
return ida_idaapi.pygc_del_nodes_infos(self, nodes)
def CreateGroups(self, groups_infos):
"""
Send a request to modify the graph by creating a
(set of) group(s), and perform an animation.
Each object in the 'groups_infos' list must be of the format:
{
"nodes" : [<int>, <int>, <int>, ...] # The list of nodes to group
"text" : <string> # The synthetic text for that group
}
@param groups_infos: A list of objects that describe those groups.
@return: A [<int>, <int>, ...] list of group nodes, or None (failure).
"""
return ida_idaapi.pygc_create_groups(self, groups_infos)
def DeleteGroups(self, groups, new_current = -1):
"""
Send a request to delete the specified groups in the graph,
and perform an animation.
@param groups: A list of group node numbers.
@param new_current: A node to focus on after the groups have been deleted
@return: True on success, False otherwise.
"""
return ida_idaapi.pygc_delete_groups(self, groups, new_current)
def SetGroupsVisibility(self, groups, expand, new_current = -1):
"""
Send a request to expand/collapse the specified groups in the graph,
and perform an animation.
@param groups: A list of group node numbers.
@param expand: True to expand the group, False otherwise.
@param new_current: A node to focus on after the groups have been expanded/collapsed.
@return: True on success, False otherwise.
"""
return ida_idaapi.pygc_set_groups_visibility(self, groups, expand, new_current)
def GetTForm(self):
"""
Return the TForm hosting this view.
@return: The TForm that hosts this view, or None.
"""
return ida_idaapi.pycim_get_tform(self)
def GetTCustomControl(self):
"""
Return the TCustomControl underlying this view.
@return: The TCustomControl underlying this view, or None.
"""
return ida_idaapi.pycim_get_tcustom_control(self)
#</pycode(py_idaapi)>
@@ -1,8 +1,8 @@
#ifndef __PY_IDA_LINPUT__
#define __PY_IDA_LINPUT__
#ifndef __PY_IDAAPI_LOADER_INPUT__
#define __PY_IDAAPI_LOADER_INPUT__
//--------------------------------------------------------------------------
//<inline(py_linput)>
//<inline(py_idaapi_loader_input)>
/*
#<pydoc>
class loader_input_t(pyidc_opaque_object_t):
@@ -412,6 +412,6 @@ public:
return Py_BuildValue("c", ch);
}
};
//</inline(py_linput)>
//</inline(py_idaapi_loader_input)>
#endif
#endif // __PY_IDAAPI_LOADER_INPUT__
-640
View File
@@ -1,640 +0,0 @@
//<inline(py_idbhooks)>
//---------------------------------------------------------------------------
// IDB hooks
//---------------------------------------------------------------------------
int idaapi IDB_Callback(void *ud, int notification_code, va_list va);
class IDB_Hooks
{
public:
virtual ~IDB_Hooks() { unhook(); }
bool hook()
{
return hook_to_notification_point(HT_IDB, IDB_Callback, this);
}
bool unhook()
{
return unhook_from_notification_point(HT_IDB, IDB_Callback, this);
}
// hookgenIDB:methods
virtual int byte_patched(ea_t ea, uint32 old_value) {qnotused(ea); qnotused(old_value); return 0;}
virtual int cmt_changed(ea_t ea, bool repeatable_cmt) {qnotused(ea); qnotused(repeatable_cmt); return 0;}
virtual int ti_changed(ea_t ea, const type_t * type, const p_list * fnames) {qnotused(ea); qnotused(type); qnotused(fnames); return 0;}
virtual int op_ti_changed(ea_t ea, int n, const type_t * type, const p_list * fnames) {qnotused(ea); qnotused(n); qnotused(type); qnotused(fnames); return 0;}
virtual int op_type_changed(ea_t ea, int n) {qnotused(ea); qnotused(n); return 0;}
virtual int enum_created(enum_t id) {qnotused(id); return 0;}
virtual int enum_deleted(enum_t id) {qnotused(id); return 0;}
virtual int enum_bf_changed(enum_t id) {qnotused(id); return 0;}
virtual int enum_renamed(tid_t id) {qnotused(id); return 0;}
virtual int enum_cmt_changed(tid_t id, bool repeatable) {qnotused(id); qnotused(repeatable); return 0;}
virtual int enum_member_created(enum_t id, const_t cid) {qnotused(id); qnotused(cid); return 0;}
virtual int enum_member_deleted(enum_t id, const_t cid) {qnotused(id); qnotused(cid); return 0;}
virtual int struc_created(tid_t struc_id) {qnotused(struc_id); return 0;}
virtual int struc_deleted(tid_t struc_id) {qnotused(struc_id); return 0;}
virtual int struc_renamed(struc_t * sptr) {qnotused(sptr); return 0;}
virtual int struc_expanded(struc_t * sptr) {qnotused(sptr); return 0;}
virtual int struc_cmt_changed(tid_t struc_id, bool repeatable_cmt) {qnotused(struc_id); qnotused(repeatable_cmt); return 0;}
virtual int struc_member_created(struc_t * sptr, member_t * mptr) {qnotused(sptr); qnotused(mptr); return 0;}
virtual int struc_member_deleted(struc_t * sptr, tid_t member_id, ea_t offset) {qnotused(sptr); qnotused(member_id); qnotused(offset); return 0;}
virtual int struc_member_renamed(struc_t * sptr, member_t * mptr) {qnotused(sptr); qnotused(mptr); return 0;}
virtual int struc_member_changed(struc_t * sptr, member_t * mptr) {qnotused(sptr); qnotused(mptr); return 0;}
virtual int thunk_func_created(func_t * pfn) {qnotused(pfn); return 0;}
virtual int func_tail_appended(func_t * pfn, func_t * tail) {qnotused(pfn); qnotused(tail); return 0;}
virtual int func_tail_removed(func_t * pfn, ea_t tail_ea) {qnotused(pfn); qnotused(tail_ea); return 0;}
virtual int tail_owner_changed(func_t * tail, ea_t owner_func, ea_t old_owner) {qnotused(tail); qnotused(owner_func); qnotused(old_owner); return 0;}
virtual int func_noret_changed(func_t * pfn) {qnotused(pfn); return 0;}
virtual int segm_added(segment_t * s) {qnotused(s); return 0;}
virtual int segm_deleted(ea_t startEA, ea_t endEA) {qnotused(startEA); qnotused(endEA); return 0;}
virtual int segm_start_changed(segment_t * s, ea_t oldstart) {qnotused(s); qnotused(oldstart); return 0;}
virtual int segm_end_changed(segment_t * s, ea_t oldend) {qnotused(s); qnotused(oldend); return 0;}
virtual int segm_moved(ea_t from, ea_t to, asize_t size) {qnotused(from); qnotused(to); qnotused(size); return 0;}
virtual int area_cmt_changed(areacb_t * cb, const area_t * a, const char * cmt, bool repeatable) {qnotused(cb); qnotused(a); qnotused(cmt); qnotused(repeatable); return 0;}
virtual int changing_cmt(ea_t ea, bool repeatable_cmt, const char * newcmt) {qnotused(ea); qnotused(repeatable_cmt); qnotused(newcmt); return 0;}
virtual int changing_ti(ea_t ea, const type_t * new_type, const p_list * new_fnames) {qnotused(ea); qnotused(new_type); qnotused(new_fnames); return 0;}
virtual int changing_op_ti(ea_t ea, int n, const type_t * new_type, const p_list * new_fnames) {qnotused(ea); qnotused(n); qnotused(new_type); qnotused(new_fnames); return 0;}
virtual int changing_op_type(ea_t ea, int n) {qnotused(ea); qnotused(n); return 0;}
virtual int deleting_enum(enum_t id) {qnotused(id); return 0;}
virtual int changing_enum_bf(enum_t id, bool new_bf) {qnotused(id); qnotused(new_bf); return 0;}
virtual int renaming_enum(tid_t id, bool is_enum, const char * newname) {qnotused(id); qnotused(is_enum); qnotused(newname); return 0;}
virtual int changing_enum_cmt(tid_t id, bool repeatable, const char * newcmt) {qnotused(id); qnotused(repeatable); qnotused(newcmt); return 0;}
virtual int deleting_enum_const() {return 0;}
virtual int deleting_struc(struc_t * sptr) {qnotused(sptr); return 0;}
virtual int renaming_struc(tid_t id, const char * oldname, const char * newname) {qnotused(id); qnotused(oldname); qnotused(newname); return 0;}
virtual int expanding_struc(struc_t * sptr, ea_t offset, adiff_t delta) {qnotused(sptr); qnotused(offset); qnotused(delta); return 0;}
virtual int changing_struc_cmt(tid_t struc_id, bool repeatable, const char * newcmt) {qnotused(struc_id); qnotused(repeatable); qnotused(newcmt); return 0;}
virtual int deleting_struc_member(struc_t * sptr, member_t * mptr) {qnotused(sptr); qnotused(mptr); return 0;}
virtual int renaming_struc_member(struc_t * sptr, member_t * mptr, const char * newname) {qnotused(sptr); qnotused(mptr); qnotused(newname); return 0;}
virtual int changing_struc_member(struc_t * sptr, member_t * mptr, flags_t flag, const opinfo_t * ti, asize_t nbytes) {qnotused(sptr); qnotused(mptr); qnotused(flag); qnotused(ti); qnotused(nbytes); return 0;}
virtual int removing_func_tail(func_t * pfn, const area_t * tail) {qnotused(pfn); qnotused(tail); return 0;}
virtual int deleting_segm(ea_t startEA) {qnotused(startEA); return 0;}
virtual int changing_segm_start(segment_t * s, ea_t new_start, int segmod_flags) {qnotused(s); qnotused(new_start); qnotused(segmod_flags); return 0;}
virtual int changing_segm_end(segment_t * s, ea_t new_end, int segmod_flags) {qnotused(s); qnotused(new_end); qnotused(segmod_flags); return 0;}
virtual int changing_area_cmt(areacb_t * cb, const area_t * a, const char * cmt, bool repeatable) {qnotused(cb); qnotused(a); qnotused(cmt); qnotused(repeatable); return 0;}
virtual int changing_segm_name(segment_t * s, const char * oldname) {qnotused(s); qnotused(oldname); return 0;}
virtual int changing_segm_class(segment_t * s) {qnotused(s); return 0;}
virtual int segm_name_changed(segment_t * s, const char * name) {qnotused(s); qnotused(name); return 0;}
virtual int segm_class_changed(segment_t * s, const char * sclass) {qnotused(s); qnotused(sclass); return 0;}
virtual int destroyed_items(ea_t ea1, ea_t ea2, bool will_disable_range) {qnotused(ea1); qnotused(ea2); qnotused(will_disable_range); return 0;}
virtual int changed_stkpnts(func_t * pfn) {qnotused(pfn); return 0;}
virtual int extra_cmt_changed(ea_t ea, int line_idx, const char * cmt) {qnotused(ea); qnotused(line_idx); qnotused(cmt); return 0;}
virtual int changing_struc(struc_t * sptr) {qnotused(sptr); return 0;}
virtual int changed_struc(struc_t * sptr) {qnotused(sptr); return 0;}
virtual int local_types_changed() {return 0;}
virtual int segm_attrs_changed(segment_t * s) {qnotused(s); return 0;}
virtual int allsegs_moved(segm_move_infos_t * info) {qnotused(info); return 0;}
};
//</inline(py_idbhooks)>
//<code(py_idbhooks)>
//---------------------------------------------------------------------------
int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
{
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
class IDB_Hooks *proxy = (class IDB_Hooks *)ud;
int ret = 0;
try
{
switch ( notification_code )
{
// hookgenIDB:notifications
case idb_event::byte_patched:
{
ea_t ea = va_arg(va, ea_t);
uint32 old_value = va_arg(va, uint32);
ret = proxy->byte_patched(ea, old_value);
}
break;
case idb_event::cmt_changed:
{
ea_t ea = va_arg(va, ea_t);
bool repeatable_cmt = bool(va_arg(va, int));
ret = proxy->cmt_changed(ea, repeatable_cmt);
}
break;
case idb_event::ti_changed:
{
ea_t ea = va_arg(va, ea_t);
const type_t * type = va_arg(va, const type_t *);
const p_list * fnames = va_arg(va, const p_list *);
ret = proxy->ti_changed(ea, type, fnames);
}
break;
case idb_event::op_ti_changed:
{
ea_t ea = va_arg(va, ea_t);
int n = va_arg(va, int);
const type_t * type = va_arg(va, const type_t *);
const p_list * fnames = va_arg(va, const p_list *);
ret = proxy->op_ti_changed(ea, n, type, fnames);
}
break;
case idb_event::op_type_changed:
{
ea_t ea = va_arg(va, ea_t);
int n = va_arg(va, int);
ret = proxy->op_type_changed(ea, n);
}
break;
case idb_event::enum_created:
{
enum_t id = va_arg(va, enum_t);
ret = proxy->enum_created(id);
}
break;
case idb_event::enum_deleted:
{
enum_t id = va_arg(va, enum_t);
ret = proxy->enum_deleted(id);
}
break;
case idb_event::enum_bf_changed:
{
enum_t id = va_arg(va, enum_t);
ret = proxy->enum_bf_changed(id);
}
break;
case idb_event::enum_renamed:
{
tid_t id = va_arg(va, tid_t);
ret = proxy->enum_renamed(id);
}
break;
case idb_event::enum_cmt_changed:
{
tid_t id = va_arg(va, tid_t);
bool repeatable = bool(va_arg(va, int));
ret = proxy->enum_cmt_changed(id, repeatable);
}
break;
case idb_event::enum_const_created:
{
enum_t id = va_arg(va, enum_t);
const_t cid = va_arg(va, const_t);
ret = proxy->enum_member_created(id, cid);
}
break;
case idb_event::enum_const_deleted:
{
enum_t id = va_arg(va, enum_t);
const_t cid = va_arg(va, const_t);
ret = proxy->enum_member_deleted(id, cid);
}
break;
case idb_event::struc_created:
{
tid_t struc_id = va_arg(va, tid_t);
ret = proxy->struc_created(struc_id);
}
break;
case idb_event::struc_deleted:
{
tid_t struc_id = va_arg(va, tid_t);
ret = proxy->struc_deleted(struc_id);
}
break;
case idb_event::struc_renamed:
{
struc_t * sptr = va_arg(va, struc_t *);
ret = proxy->struc_renamed(sptr);
}
break;
case idb_event::struc_expanded:
{
struc_t * sptr = va_arg(va, struc_t *);
ret = proxy->struc_expanded(sptr);
}
break;
case idb_event::struc_cmt_changed:
{
tid_t struc_id = va_arg(va, tid_t);
bool repeatable_cmt = bool(va_arg(va, int));
ret = proxy->struc_cmt_changed(struc_id, repeatable_cmt);
}
break;
case idb_event::struc_member_created:
{
struc_t * sptr = va_arg(va, struc_t *);
member_t * mptr = va_arg(va, member_t *);
ret = proxy->struc_member_created(sptr, mptr);
}
break;
case idb_event::struc_member_deleted:
{
struc_t * sptr = va_arg(va, struc_t *);
tid_t member_id = va_arg(va, tid_t);
ea_t offset = va_arg(va, ea_t);
ret = proxy->struc_member_deleted(sptr, member_id, offset);
}
break;
case idb_event::struc_member_renamed:
{
struc_t * sptr = va_arg(va, struc_t *);
member_t * mptr = va_arg(va, member_t *);
ret = proxy->struc_member_renamed(sptr, mptr);
}
break;
case idb_event::struc_member_changed:
{
struc_t * sptr = va_arg(va, struc_t *);
member_t * mptr = va_arg(va, member_t *);
ret = proxy->struc_member_changed(sptr, mptr);
}
break;
case idb_event::thunk_func_created:
{
func_t * pfn = va_arg(va, func_t *);
ret = proxy->thunk_func_created(pfn);
}
break;
case idb_event::func_tail_appended:
{
func_t * pfn = va_arg(va, func_t *);
func_t * tail = va_arg(va, func_t *);
ret = proxy->func_tail_appended(pfn, tail);
}
break;
case idb_event::func_tail_removed:
{
func_t * pfn = va_arg(va, func_t *);
ea_t tail_ea = va_arg(va, ea_t);
ret = proxy->func_tail_removed(pfn, tail_ea);
}
break;
case idb_event::tail_owner_changed:
{
func_t * tail = va_arg(va, func_t *);
ea_t owner_func = va_arg(va, ea_t);
ea_t old_owner = va_arg(va, ea_t);
ret = proxy->tail_owner_changed(tail, owner_func, old_owner);
}
break;
case idb_event::func_noret_changed:
{
func_t * pfn = va_arg(va, func_t *);
ret = proxy->func_noret_changed(pfn);
}
break;
case idb_event::segm_added:
{
segment_t * s = va_arg(va, segment_t *);
ret = proxy->segm_added(s);
}
break;
case idb_event::segm_deleted:
{
ea_t startEA = va_arg(va, ea_t);
ea_t endEA = va_arg(va, ea_t);
ret = proxy->segm_deleted(startEA, endEA);
}
break;
case idb_event::segm_start_changed:
{
segment_t * s = va_arg(va, segment_t *);
ea_t oldstart = va_arg(va, ea_t);
ret = proxy->segm_start_changed(s, oldstart);
}
break;
case idb_event::segm_end_changed:
{
segment_t * s = va_arg(va, segment_t *);
ea_t oldend = va_arg(va, ea_t);
ret = proxy->segm_end_changed(s, oldend);
}
break;
case idb_event::segm_moved:
{
ea_t from = va_arg(va, ea_t);
ea_t to = va_arg(va, ea_t);
asize_t size = va_arg(va, asize_t);
ret = proxy->segm_moved(from, to, size);
}
break;
case idb_event::area_cmt_changed:
{
areacb_t * cb = va_arg(va, areacb_t *);
const area_t * a = va_arg(va, const area_t *);
const char * cmt = va_arg(va, const char *);
bool repeatable = bool(va_arg(va, int));
ret = proxy->area_cmt_changed(cb, a, cmt, repeatable);
}
break;
case idb_event::changing_cmt:
{
ea_t ea = va_arg(va, ea_t);
bool repeatable_cmt = bool(va_arg(va, int));
const char * newcmt = va_arg(va, const char *);
ret = proxy->changing_cmt(ea, repeatable_cmt, newcmt);
}
break;
case idb_event::changing_ti:
{
ea_t ea = va_arg(va, ea_t);
const type_t * new_type = va_arg(va, const type_t *);
const p_list * new_fnames = va_arg(va, const p_list *);
ret = proxy->changing_ti(ea, new_type, new_fnames);
}
break;
case idb_event::changing_op_ti:
{
ea_t ea = va_arg(va, ea_t);
int n = va_arg(va, int);
const type_t * new_type = va_arg(va, const type_t *);
const p_list * new_fnames = va_arg(va, const p_list *);
ret = proxy->changing_op_ti(ea, n, new_type, new_fnames);
}
break;
case idb_event::changing_op_type:
{
ea_t ea = va_arg(va, ea_t);
int n = va_arg(va, int);
ret = proxy->changing_op_type(ea, n);
}
break;
case idb_event::deleting_enum:
{
enum_t id = va_arg(va, enum_t);
ret = proxy->deleting_enum(id);
}
break;
case idb_event::changing_enum_bf:
{
enum_t id = va_arg(va, enum_t);
bool new_bf = bool(va_arg(va, int));
ret = proxy->changing_enum_bf(id, new_bf);
}
break;
case idb_event::renaming_enum:
{
tid_t id = va_arg(va, tid_t);
bool is_enum = bool(va_arg(va, int));
const char * newname = va_arg(va, const char *);
ret = proxy->renaming_enum(id, is_enum, newname);
}
break;
case idb_event::changing_enum_cmt:
{
tid_t id = va_arg(va, tid_t);
bool repeatable = bool(va_arg(va, int));
const char * newcmt = va_arg(va, const char *);
ret = proxy->changing_enum_cmt(id, repeatable, newcmt);
}
break;
case idb_event::deleting_enum_const:
{
ret = proxy->deleting_enum_const();
}
break;
case idb_event::deleting_struc:
{
struc_t * sptr = va_arg(va, struc_t *);
ret = proxy->deleting_struc(sptr);
}
break;
case idb_event::renaming_struc:
{
tid_t id = va_arg(va, tid_t);
const char * oldname = va_arg(va, const char *);
const char * newname = va_arg(va, const char *);
ret = proxy->renaming_struc(id, oldname, newname);
}
break;
case idb_event::expanding_struc:
{
struc_t * sptr = va_arg(va, struc_t *);
ea_t offset = va_arg(va, ea_t);
adiff_t delta = va_arg(va, adiff_t);
ret = proxy->expanding_struc(sptr, offset, delta);
}
break;
case idb_event::changing_struc_cmt:
{
tid_t struc_id = va_arg(va, tid_t);
bool repeatable = bool(va_arg(va, int));
const char * newcmt = va_arg(va, const char *);
ret = proxy->changing_struc_cmt(struc_id, repeatable, newcmt);
}
break;
case idb_event::deleting_struc_member:
{
struc_t * sptr = va_arg(va, struc_t *);
member_t * mptr = va_arg(va, member_t *);
ret = proxy->deleting_struc_member(sptr, mptr);
}
break;
case idb_event::renaming_struc_member:
{
struc_t * sptr = va_arg(va, struc_t *);
member_t * mptr = va_arg(va, member_t *);
const char * newname = va_arg(va, const char *);
ret = proxy->renaming_struc_member(sptr, mptr, newname);
}
break;
case idb_event::changing_struc_member:
{
struc_t * sptr = va_arg(va, struc_t *);
member_t * mptr = va_arg(va, member_t *);
flags_t flag = va_arg(va, flags_t);
const opinfo_t * ti = va_arg(va, const opinfo_t *);
asize_t nbytes = va_arg(va, asize_t);
ret = proxy->changing_struc_member(sptr, mptr, flag, ti, nbytes);
}
break;
case idb_event::removing_func_tail:
{
func_t * pfn = va_arg(va, func_t *);
const area_t * tail = va_arg(va, const area_t *);
ret = proxy->removing_func_tail(pfn, tail);
}
break;
case idb_event::deleting_segm:
{
ea_t startEA = va_arg(va, ea_t);
ret = proxy->deleting_segm(startEA);
}
break;
case idb_event::changing_segm_start:
{
segment_t * s = va_arg(va, segment_t *);
ea_t new_start = va_arg(va, ea_t);
int segmod_flags = va_arg(va, int);
ret = proxy->changing_segm_start(s, new_start, segmod_flags);
}
break;
case idb_event::changing_segm_end:
{
segment_t * s = va_arg(va, segment_t *);
ea_t new_end = va_arg(va, ea_t);
int segmod_flags = va_arg(va, int);
ret = proxy->changing_segm_end(s, new_end, segmod_flags);
}
break;
case idb_event::changing_area_cmt:
{
areacb_t * cb = va_arg(va, areacb_t *);
const area_t * a = va_arg(va, const area_t *);
const char * cmt = va_arg(va, const char *);
bool repeatable = bool(va_arg(va, int));
ret = proxy->changing_area_cmt(cb, a, cmt, repeatable);
}
break;
case idb_event::changing_segm_name:
{
segment_t * s = va_arg(va, segment_t *);
const char * oldname = va_arg(va, const char *);
ret = proxy->changing_segm_name(s, oldname);
}
break;
case idb_event::changing_segm_class:
{
segment_t * s = va_arg(va, segment_t *);
ret = proxy->changing_segm_class(s);
}
break;
case idb_event::segm_name_changed:
{
segment_t * s = va_arg(va, segment_t *);
const char * name = va_arg(va, const char *);
ret = proxy->segm_name_changed(s, name);
}
break;
case idb_event::segm_class_changed:
{
segment_t * s = va_arg(va, segment_t *);
const char * sclass = va_arg(va, const char *);
ret = proxy->segm_class_changed(s, sclass);
}
break;
case idb_event::destroyed_items:
{
ea_t ea1 = va_arg(va, ea_t);
ea_t ea2 = va_arg(va, ea_t);
bool will_disable_range = bool(va_arg(va, int));
ret = proxy->destroyed_items(ea1, ea2, will_disable_range);
}
break;
case idb_event::changed_stkpnts:
{
func_t * pfn = va_arg(va, func_t *);
ret = proxy->changed_stkpnts(pfn);
}
break;
case idb_event::extra_cmt_changed:
{
ea_t ea = va_arg(va, ea_t);
int line_idx = va_arg(va, int);
const char * cmt = va_arg(va, const char *);
ret = proxy->extra_cmt_changed(ea, line_idx, cmt);
}
break;
case idb_event::changing_struc:
{
struc_t * sptr = va_arg(va, struc_t *);
ret = proxy->changing_struc(sptr);
}
break;
case idb_event::changed_struc:
{
struc_t * sptr = va_arg(va, struc_t *);
ret = proxy->changed_struc(sptr);
}
break;
case idb_event::local_types_changed:
{
ret = proxy->local_types_changed();
}
break;
case idb_event::segm_attrs_changed:
{
segment_t * s = va_arg(va, segment_t *);
ret = proxy->segm_attrs_changed(s);
}
break;
case idb_event::allsegs_moved:
{
segm_move_infos_t * info = va_arg(va, segm_move_infos_t *);
ret = proxy->allsegs_moved(info);
}
break;
}
}
catch (Swig::DirectorException &e)
{
msg("Exception in IDB Hook function: %s\n", e.getMessage());
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( PyErr_Occurred() )
PyErr_Print();
}
return 0;
}
//</code(py_idbhooks)>
+6 -32
View File
@@ -9,31 +9,6 @@ static bool dbg_can_query()
return dbg != NULL && (dbg->may_disturb() || get_process_state() < DSTATE_NOTASK);
}
//-------------------------------------------------------------------------
static PyObject *meminfo_vec_t_to_py(meminfo_vec_t &areas)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
PyObject *py_list = PyList_New(areas.size());
meminfo_vec_t::const_iterator it, it_end(areas.end());
Py_ssize_t i = 0;
for ( it=areas.begin(); it!=it_end; ++it, ++i )
{
const memory_info_t &mi = *it;
// startEA endEA name sclass sbase bitness perm
PyList_SetItem(py_list, i,
Py_BuildValue("(" PY_FMT64 PY_FMT64 "ss" PY_FMT64 "II)",
pyul_t(mi.startEA),
pyul_t(mi.endEA),
mi.name.c_str(),
mi.sclass.c_str(),
pyul_t(mi.sbase),
(unsigned int)(mi.bitness),
(unsigned int)mi.perm));
}
return py_list;
}
//-------------------------------------------------------------------------
PyObject *py_appcall(
ea_t func_ea,
@@ -56,7 +31,7 @@ PyObject *py_appcall(
Py_ssize_t nargs = PyList_Size(arg_list);
idc_args.resize(nargs);
bool ok = true;
for ( Py_ssize_t i=0; i<nargs; i++ )
for ( Py_ssize_t i=0; i < nargs; i++ )
{
// Get argument
borref_t py_item(PyList_GetItem(arg_list, i));
@@ -93,7 +68,7 @@ PyObject *py_appcall(
"----------------\n");
qstring s;
for ( Py_ssize_t i=0; i<nargs; i++ )
for ( Py_ssize_t i=0; i < nargs; i++ )
{
VarPrint(&s, &idc_args[i]);
msg("%d]\n%s\n-----------\n", int(i), s.c_str());
@@ -139,7 +114,7 @@ PyObject *py_appcall(
msg("return variables:\n"
"-----------------\n");
qstring s;
for ( Py_ssize_t i=0; i<nargs; i++ )
for ( Py_ssize_t i=0; i < nargs; i++ )
{
VarPrint(&s, &idc_args[i]);
msg("%d]\n%s\n-----------\n", int(i), s.c_str());
@@ -148,7 +123,7 @@ PyObject *py_appcall(
}
// Convert IDC values back to Python values
for ( Py_ssize_t i=0; i<nargs; i++ )
for ( Py_ssize_t i=0; i < nargs; i++ )
{
// Get argument
borref_t py_item(PyList_GetItem(arg_list, i));
@@ -167,7 +142,6 @@ PyObject *py_appcall(
PyErr_SetString(PyExc_ValueError, "PyAppCall: Failed while converting IDC return value to Python return value");
return NULL;
}
QASSERT(30413, py_result.o->ob_refcnt == 1);
if ( (debug & IDA_DEBUG_APPCALL) != 0 )
{
msg("return var:\n"
@@ -207,7 +181,7 @@ static PyObject *dbg_get_registers()
PyObject *py_list = PyList_New(dbg->registers_size);
for ( int i=0; i<dbg->registers_size; i++ )
for ( int i=0; i < dbg->registers_size; i++ )
{
register_info_t &ri = dbg->registers(i);
PyObject *py_bits;
@@ -218,7 +192,7 @@ static PyObject *dbg_get_registers()
{
int nbits = (int)b2a_width((int)get_dtyp_size(ri.dtyp), 0) * 4;
py_bits = PyList_New(nbits);
for ( int i=0; i<nbits; i++ )
for ( int i=0; i < nbits; i++ )
{
const char *s = ri.bit_strings[i];
PyList_SetItem(py_bits, i, PyString_FromString(s == NULL ? "" : s));
+31 -24
View File
@@ -4,6 +4,13 @@ NO_PROCESS = 0xFFFFFFFF
NO_THREAD = 0
import types
import _ida_idaapi
import _ida_dbg
import _ida_typeinf
import _ida_name
import _ida_bytes
import _ida_ida
import ida_idaapi
# -----------------------------------------------------------------------
class Appcall_array__(object):
@@ -39,7 +46,7 @@ class Appcall_array__(object):
def unpack(self, buf, as_list=True):
"""Unpacks an array back into a list or an object"""
# take the value from the special ref object
if isinstance(buf, PyIdc_cvt_refclass__):
if isinstance(buf, ida_idaapi.PyIdc_cvt_refclass__):
buf = buf.value
# we can only unpack from strings
@@ -118,9 +125,9 @@ class Appcall_callable__(object):
# Do the Appcall (use the wrapped version)
e_obj = None
try:
r = _idaapi.appcall(
r = _ida_idd.appcall(
self.ea,
_idaapi.get_current_thread(),
_ida_dbg.get_current_thread(),
self.type,
self.fields,
arg_list)
@@ -148,7 +155,7 @@ class Appcall_callable__(object):
def __get_size(self):
if self.__type == None:
return -1
r = _idaapi.calc_type_size(_idaapi.cvar.idati, self.__type)
r = _ida_typeinf.calc_type_size(_ida_typeinf.cvar.idati, self.__type)
if not r:
return -1
return r
@@ -181,9 +188,9 @@ class Appcall_callable__(object):
src = self.ea
if type(src) == types.StringType:
return _idaapi.unpack_object_from_bv(_idaapi.cvar.idati, self.type, self.fields, src, flags)
return _ida_typeinf.unpack_object_from_bv(_ida_typeinf.cvar.idati, self.type, self.fields, src, flags)
else:
return _idaapi.unpack_object_from_idb(_idaapi.cvar.idati, self.type, self.fields, src, flags)
return _ida_typeinf.unpack_object_from_idb(_ida_typeinf.cvar.idati, self.type, self.fields, src, flags)
def store(self, obj, dest_ea=None, base_ea=0, flags=0):
"""
@@ -199,15 +206,15 @@ class Appcall_callable__(object):
# no ea passed? thus pack to a string
if dest_ea is None:
return _idaapi.pack_object_to_bv(obj,
_idaapi.cvar.idati,
return _ida_typeinf.pack_object_to_bv(obj,
_ida_typeinf.cvar.idati,
self.type,
self.fields,
base_ea,
flags)
else:
return _idaapi.pack_object_to_idb(obj,
_idaapi.cvar.idati,
return _ida_typeinf.pack_object_to_idb(obj,
_ida_typeinf.cvar.idati,
self.type,
self.fields,
dest_ea,
@@ -266,11 +273,11 @@ class Appcall__(object):
# a string? try to resolve it
if type(name_or_ea) == types.StringType:
ea = _idaapi.get_name_ea(_idaapi.BADADDR, name_or_ea)
ea = _ida_name.get_name_ea(_ida_idaapi.BADADDR, name_or_ea)
else:
ea = name_or_ea
# could not resolve name or invalid address?
if ea == _idaapi.BADADDR or not _idaapi.isEnabled(ea):
if ea == _ida_idaapi.BADADDR or not _ida_bytes.isEnabled(ea):
raise ValueError, "Undefined function " + name_or_ea
return ea
@@ -292,7 +299,7 @@ class Appcall__(object):
if flags is None:
flags = 1 | 2 | 4 # PT_SIL | PT_NDC | PT_TYP
result = _idaapi.idc_parse_decl(_idaapi.cvar.idati, prototype, flags)
result = _ida_typeinf.idc_parse_decl(_ida_typeinf.cvar.idati, prototype, flags)
if result is None:
raise ValueError, "Could not parse type: " + prototype
@@ -303,7 +310,7 @@ class Appcall__(object):
"""Allows you to call functions as if they were member functions (by returning a callable object)"""
# resolve and raise exception on error
ea = self.__name_or_ea(name_or_ea)
if ea == _idaapi.BADADDR:
if ea == _ida_idaapi.BADADDR:
raise ValueError, "Undefined function " + name
# Return the callable method
return Appcall_callable__(ea)
@@ -321,7 +328,7 @@ class Appcall__(object):
Returns the numeric value of a given name string.
If the name could not be resolved then the default value will be returned
"""
t, v = _idaapi.get_name_value(_idaapi.BADADDR, name)
t, v = _ida_name.get_name_value(_ida_idaapi.BADADDR, name)
if t == 0: # NT_NONE
v = default
return v
@@ -329,7 +336,7 @@ class Appcall__(object):
@staticmethod
def int64(v):
"""Whenever a 64bit number is needed use this method to construct an object"""
return PyIdc_cvt_int64__(v)
return ida_idaapi.PyIdc_cvt_int64__(v)
@staticmethod
def byref(val):
@@ -338,7 +345,7 @@ class Appcall__(object):
Currently we support references to int/strings
Objects need not be passed by reference (this will be done automatically)
"""
return PyIdc_cvt_refclass__(val)
return ida_idaapi.PyIdc_cvt_refclass__(val)
@staticmethod
def buffer(str = None, size = 0, fill="\x00"):
@@ -358,15 +365,15 @@ class Appcall__(object):
@staticmethod
def obj(**kwds):
"""Returns an empty object or objects with attributes as passed via its keywords arguments"""
return object_t(**kwds)
return ida_idaapi.object_t(**kwds)
@staticmethod
def cstr(val):
return as_cstr(val)
return ida_idaapi.as_cstr(val)
@staticmethod
def unicode(s):
return as_unicode(s)
return ida_idaapi.as_unicode(s)
@staticmethod
def array(type_name):
@@ -382,7 +389,7 @@ class Appcall__(object):
@return: Appcall object or raises ValueError exception
"""
# parse the type
result = _idaapi.idc_parse_decl(_idaapi.cvar.idati, typestr, 1 | 2 | 4) # PT_SIL | PT_NDC | PT_TYP
result = _ida_typeinf.idc_parse_decl(_ida_typeinf.cvar.idati, typestr, 1 | 2 | 4) # PT_SIL | PT_NDC | PT_TYP
if result is None:
raise ValueError, "Could not parse type: " + typestr
# Return the callable method with type info
@@ -392,18 +399,18 @@ class Appcall__(object):
def set_appcall_options(opt):
"""Method to change the Appcall options globally (not per Appcall)"""
old_opt = Appcall__.get_appcall_options()
_idaapi.cvar.inf.appcall_options = opt
_ida_ida.cvar.inf.appcall_options = opt
return old_opt
@staticmethod
def get_appcall_options():
"""Return the global Appcall options"""
return _idaapi.cvar.inf.appcall_options
return _ida_ida.cvar.inf.appcall_options
@staticmethod
def cleanup_appcall(tid = 0):
"""Equivalent to IDC's CleanupAppcall()"""
return _idaapi.cleanup_appcall(tid)
return _ida_idd.cleanup_appcall(tid)
Appcall = Appcall__()
#</pycode(py_idd)>
+1 -1066
View File
File diff suppressed because it is too large Load Diff
+232
View File
@@ -0,0 +1,232 @@
#<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_CMD_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_386 = 0 # Intel 80x86
PLFM_Z80 = 1 # 8085, Z80
PLFM_I860 = 2 # Intel 860
PLFM_8051 = 3 # 8051
PLFM_TMS = 4 # Texas Instruments TMS320C5x
PLFM_6502 = 5 # 6502
PLFM_PDP = 6 # PDP11
PLFM_68K = 7 # Motoroal 680x0
PLFM_JAVA = 8 # Java
PLFM_6800 = 9 # Motorola 68xx
PLFM_ST7 = 10 # SGS-Thomson ST7
PLFM_MC6812 = 11 # Motorola 68HC12
PLFM_MIPS = 12 # MIPS
PLFM_ARM = 13 # Advanced RISC Machines
PLFM_TMSC6 = 14 # Texas Instruments TMS320C6x
PLFM_PPC = 15 # PowerPC
PLFM_80196 = 16 # Intel 80196
PLFM_Z8 = 17 # Z8
PLFM_SH = 18 # Renesas (formerly Hitachi) SuperH
PLFM_NET = 19 # Microsoft Visual Studio.Net
PLFM_AVR = 20 # Atmel 8-bit RISC processor(s)
PLFM_H8 = 21 # Hitachi H8/300, H8/2000
PLFM_PIC = 22 # Microchip's PIC
PLFM_SPARC = 23 # SPARC
PLFM_ALPHA = 24 # DEC Alpha
PLFM_HPPA = 25 # Hewlett-Packard PA-RISC
PLFM_H8500 = 26 # Hitachi H8/500
PLFM_TRICORE = 27 # Tasking Tricore
PLFM_DSP56K = 28 # Motorola DSP5600x
PLFM_C166 = 29 # Siemens C166 family
PLFM_ST20 = 30 # SGS-Thomson ST20
PLFM_IA64 = 31 # Intel Itanium IA64
PLFM_I960 = 32 # Intel 960
PLFM_F2MC = 33 # Fujistu F2MC-16
PLFM_TMS320C54 = 34 # Texas Instruments TMS320C54xx
PLFM_TMS320C55 = 35 # Texas Instruments TMS320C55xx
PLFM_TRIMEDIA = 36 # Trimedia
PLFM_M32R = 37 # Mitsubishi 32bit RISC
PLFM_NEC_78K0 = 38 # NEC 78K0
PLFM_NEC_78K0S = 39 # NEC 78K0S
PLFM_M740 = 40 # Mitsubishi 8bit
PLFM_M7700 = 41 # Mitsubishi 16bit
PLFM_ST9 = 42 # ST9+
PLFM_FR = 43 # Fujitsu FR Family
PLFM_MC6816 = 44 # Motorola 68HC16
PLFM_M7900 = 45 # Mitsubishi 7900
PLFM_TMS320C3 = 46 # Texas Instruments TMS320C3
PLFM_KR1878 = 47 # Angstrem KR1878
PLFM_AD218X = 48 # Analog Devices ADSP 218X
PLFM_OAKDSP = 49 # Atmel OAK DSP
PLFM_TLCS900 = 50 # Toshiba TLCS-900
PLFM_C39 = 51 # Rockwell C39
PLFM_CR16 = 52 # NSC CR16
PLFM_MN102L00 = 53 # Panasonic MN10200
PLFM_TMS320C1X = 54 # Texas Instruments TMS320C1x
PLFM_NEC_V850X = 55 # NEC V850 and V850ES/E1/E2
PLFM_SCR_ADPT = 56 # Processor module adapter for processor modules written in scripting languages
PLFM_EBC = 57 # EFI Bytecode
PLFM_MSP430 = 58 # Texas Instruments MSP430
PLFM_SPU = 59 # Cell Broadband Engine Synergistic Processor Unit
#
# 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!
# (the ones >= decorate_name)
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 codeSeg() 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_FULL_HIFXP = 0x100000 # REF_VHIGH operand value contains full operand
# not only the high bits. Meaningful if ph.high_fixup_bits
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_ua
class processor_t(ida_idaapi.pyidc_opaque_object_t):
"""Base class for all processor module scripts"""
def __init__(self):
# Take a reference to 'cmd'
self.cmd = ida_ua.cmd
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):
"""This function returns cmd.auxpref value"""
return self.cmd.auxpref
# ----------------------------------------------------------------------
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())
high_fixup_bits = property(lambda self: ph_get_high_fixup_bits())
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())
regCodeSreg = property(lambda self: ph_get_regCodeSreg())
regDataSreg = property(lambda self: ph_get_regDataSreg())
regFirstSreg = property(lambda self: ph_get_regFirstSreg())
regLastSreg = property(lambda self: ph_get_regLastSreg())
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()
#</pycode(py_idp)>
+51
View File
@@ -0,0 +1,51 @@
//<inline(py_idp_idbhooks)>
//---------------------------------------------------------------------------
// IDB hooks
//---------------------------------------------------------------------------
int idaapi IDB_Callback(void *ud, int notification_code, va_list va);
class IDB_Hooks
{
public:
virtual ~IDB_Hooks() { unhook(); }
bool hook()
{
return hook_to_notification_point(HT_IDB, IDB_Callback, this);
}
bool unhook()
{
return unhook_from_notification_point(HT_IDB, IDB_Callback, this);
}
// hookgenIDB:methods
};
//</inline(py_idp_idbhooks)>
//<code(py_idp_idbhooks)>
//---------------------------------------------------------------------------
int idaapi IDB_Callback(void *ud, int notification_code, va_list va)
{
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
class IDB_Hooks *proxy = (class IDB_Hooks *)ud;
int ret = 0;
try
{
switch ( notification_code )
{
// hookgenIDB:notifications
}
}
catch (Swig::DirectorException &e)
{
msg("Exception in IDB Hook function: %s\n", e.getMessage());
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( PyErr_Occurred() )
PyErr_Print();
}
return 0;
}
//</code(py_idp_idbhooks)>
+52 -232
View File
@@ -1,6 +1,32 @@
#ifndef __PY_KERNWIN__
#define __PY_KERNWIN__
//------------------------------------------------------------------------
//<decls(py_kernwin)>
//------------------------------------------------------------------------
//---------------------------------------------------------------------------
// Context structure used by add|del_menu_item()
struct py_add_del_menu_item_ctx
{
qstring menupath;
PyObject *cb_data;
};
//---------------------------------------------------------------------------
// Context structure used by add|del_idc_hotkey()
struct py_idchotkey_ctx_t
{
qstring hotkey;
PyObject *pyfunc;
};
//------------------------------------------------------------------------
//</decls(py_kernwin)>
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//<inline(py_kernwin)>
//------------------------------------------------------------------------
@@ -41,27 +67,20 @@ static PyObject *py_register_timer(int interval, PyObject *py_callback)
// Timer has been unregistered?
if ( ret == -1 )
{
// Free the context
Py_DECREF(ctx->pycallback);
delete ctx;
}
python_timer_del(ctx);
return ret;
};
};
py_timer_ctx_t *ctx = new py_timer_ctx_t();
ctx->pycallback = py_callback;
Py_INCREF(py_callback);
py_timer_ctx_t *ctx = python_timer_new(py_callback);
ctx->timer_id = register_timer(
interval,
tmr_t::callback,
ctx);
interval,
tmr_t::callback,
ctx);
if ( ctx->timer_id == NULL )
{
Py_DECREF(py_callback);
delete ctx;
python_timer_del(ctx);
Py_RETURN_NONE;
}
return PyCObject_FromVoidPtr(ctx, NULL);
@@ -89,12 +108,11 @@ static PyObject *py_unregister_timer(PyObject *py_timerctx)
Py_RETURN_FALSE;
py_timer_ctx_t *ctx = (py_timer_ctx_t *) PyCObject_AsVoidPtr(py_timerctx);
if ( !unregister_timer(ctx->timer_id) )
if ( ctx == NULL || !unregister_timer(ctx->timer_id) )
Py_RETURN_FALSE;
Py_DECREF(ctx->pycallback);
delete ctx;
python_timer_del(ctx);
PyCObject_SetVoidPtr(py_timerctx, NULL);
Py_RETURN_TRUE;
}
@@ -693,8 +711,6 @@ def execute_sync(callable, reqf):
If the current thread not the main thread, then the call is queued and
executed afterwards.
@note: The Python version of execute_sync() cannot be called from a different thread
for the time being.
@param callable: A python callable object
@param reqf: one of MFF_ flags
@return: -1 or the return value of the callable
@@ -823,9 +839,9 @@ static bool py_execute_ui_requests(PyObject *py_list)
bool init(PyObject *py_list)
{
Py_ssize_t count = pyvar_walk_list(
py_list,
s_py_list_walk_cb,
this);
py_list,
s_py_list_walk_cb,
this);
return count > 0;
}
@@ -1065,31 +1081,6 @@ public:
}
// hookgenUI:methods
virtual void range() {}
virtual void idcstart() {}
virtual void idcstop() {}
virtual void suspend() {}
virtual void resume() {}
virtual void saving() {}
virtual void saved() {}
virtual void term() {}
virtual int debugger_menu_change(bool enable) {qnotused(enable); return 1;}
virtual void tform_visible(TForm * form, void * HWND) {qnotused(form); qnotused(HWND); }
virtual void tform_invisible(TForm * form, void * HWND) {qnotused(form); qnotused(HWND); }
virtual PyObject * get_ea_hint(ea_t ea) {qnotused(ea); Py_RETURN_NONE;}
virtual PyObject * get_item_hint(ea_t ea, int max_lines) {qnotused(ea); qnotused(max_lines); Py_RETURN_NONE;}
virtual PyObject * get_custom_viewer_hint(TCustomControl* viewer, place_t * place) {qnotused(viewer); qnotused(place); Py_RETURN_NONE;}
virtual void database_inited(int is_new_database, const char * idc_script) {qnotused(is_new_database); qnotused(idc_script); }
virtual void ready_to_run() {}
virtual void preprocess(const char * name) {qnotused(name); }
virtual void postprocess() {}
virtual void updating_actions(action_update_ctx_t * ctx) {qnotused(ctx); }
virtual void updated_actions() {}
virtual void populating_tform_popup(TForm * form, TPopupMenu * popup_handle) {qnotused(form); qnotused(popup_handle); }
virtual void finish_populating_tform_popup(TForm * form, TPopupMenu * popup_handle) {qnotused(form); qnotused(popup_handle); }
virtual void plugin_loaded(const plugin_info_t * plugin_info) {qnotused(plugin_info); }
virtual void plugin_unloading(const plugin_info_t * plugin_info) {qnotused(plugin_info); }
virtual void current_tform_changed(TForm * form, TForm * prev_form) {qnotused(form); qnotused(prev_form); }
};
//-------------------------------------------------------------------------
@@ -1123,6 +1114,15 @@ bool py_unregister_action(const char *name)
return ok;
}
//-------------------------------------------------------------------------
PyObject *py_get_registered_actions()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
qstrvec_t actions;
get_registered_actions(&actions);
return qstrvec2pylist(actions);
}
//-------------------------------------------------------------------------
bool py_attach_dynamic_action_to_popup(
TForm *form,
@@ -1277,11 +1277,12 @@ nav_colorizer_t *py_set_nav_colorizer(PyObject *new_py_colorizer)
}
};
bool need_install = py_colorizer == NULL;
// Always perform the call to set_nav_colorizer(): that has side-effects
// (e.g., updating the legend.)
bool first_install = py_colorizer == NULL;
py_colorizer = borref_t(new_py_colorizer);
return need_install
? set_nav_colorizer(lambda_t::call_py_colorizer)
: NULL;
nav_colorizer_t *prev = set_nav_colorizer(lambda_t::call_py_colorizer);
return first_install ? prev : NULL;
}
//-------------------------------------------------------------------------
@@ -1321,187 +1322,6 @@ int idaapi UI_Callback(void *ud, int notification_code, va_list va)
switch ( notification_code )
{
// hookgenUI:notifications
case ui_range:
{
proxy->range();
}
break;
case ui_idcstart:
{
proxy->idcstart();
}
break;
case ui_idcstop:
{
proxy->idcstop();
}
break;
case ui_suspend:
{
proxy->suspend();
}
break;
case ui_resume:
{
proxy->resume();
}
break;
case ui_saving:
{
proxy->saving();
}
break;
case ui_saved:
{
proxy->saved();
}
break;
case ui_term:
{
proxy->term();
}
break;
case ui_debugger_menu_change:
{
bool enable = bool(va_arg(va, int));
ret = proxy->debugger_menu_change(enable);
}
break;
case ui_tform_visible:
{
TForm * form = va_arg(va, TForm *);
void * HWND = va_arg(va, void *);
proxy->tform_visible(form, HWND);
}
break;
case ui_tform_invisible:
{
TForm * form = va_arg(va, TForm *);
void * HWND = va_arg(va, void *);
proxy->tform_invisible(form, HWND);
}
break;
case ui_get_ea_hint:
{
ea_t ea = va_arg(va, ea_t);
char * buf = va_arg(va, char *);
size_t bufsize = va_arg(va, size_t);
PyObject * _tmp = proxy->get_ea_hint(ea);
ret = UI_Hooks::handle_get_ea_hint_output(_tmp, ea, buf, bufsize);
}
break;
case ui_get_item_hint:
{
ea_t ea = va_arg(va, ea_t);
int max_lines = va_arg(va, int);
int * important_lines = va_arg(va, int *);
qstring * hint = va_arg(va, qstring *);
PyObject * _tmp = proxy->get_item_hint(ea, max_lines);
ret = UI_Hooks::handle_hint_output(_tmp, ea, max_lines, important_lines, hint);
}
break;
case ui_get_custom_viewer_hint:
{
TCustomControl* viewer = va_arg(va, TCustomControl*);
place_t * place = va_arg(va, place_t *);
int * important_lines = va_arg(va, int *);
qstring * hint = va_arg(va, qstring *);
PyObject * _tmp = proxy->get_custom_viewer_hint(viewer, place);
ret = UI_Hooks::handle_hint_output(_tmp, viewer, place, important_lines, hint);
}
break;
case ui_database_inited:
{
int is_new_database = va_arg(va, int);
const char * idc_script = va_arg(va, const char *);
proxy->database_inited(is_new_database, idc_script);
}
break;
case ui_ready_to_run:
{
proxy->ready_to_run();
}
break;
case ui_preprocess:
{
const char * name = va_arg(va, const char *);
proxy->preprocess(name);
}
break;
case ui_postprocess:
{
proxy->postprocess();
}
break;
case ui_updating_actions:
{
action_update_ctx_t * ctx = va_arg(va, action_update_ctx_t *);
proxy->updating_actions(ctx);
}
break;
case ui_updated_actions:
{
proxy->updated_actions();
}
break;
case ui_populating_tform_popup:
{
TForm * form = va_arg(va, TForm *);
TPopupMenu * popup_handle = va_arg(va, TPopupMenu *);
proxy->populating_tform_popup(form, popup_handle);
}
break;
case ui_finish_populating_tform_popup:
{
TForm * form = va_arg(va, TForm *);
TPopupMenu * popup_handle = va_arg(va, TPopupMenu *);
proxy->finish_populating_tform_popup(form, popup_handle);
}
break;
case ui_plugin_loaded:
{
const plugin_info_t * plugin_info = va_arg(va, const plugin_info_t *);
proxy->plugin_loaded(plugin_info);
}
break;
case ui_plugin_unloading:
{
const plugin_info_t * plugin_info = va_arg(va, const plugin_info_t *);
proxy->plugin_unloading(plugin_info);
}
break;
case ui_current_tform_changed:
{
TForm * form = va_arg(va, TForm *);
TForm * prev_form = va_arg(va, TForm *);
proxy->current_tform_changed(form, prev_form);
}
break;
}
}
catch (Swig::DirectorException &e)
+6 -52
View File
@@ -1,25 +1,3 @@
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
if pywraps_there:
_idaapi.execute_sync = pywraps.py_execute_sync
_idaapi.add_hotkey = pywraps.py_add_hotkey
_idaapi.del_hotkey = pywraps.py_del_hotkey
# -----------------------------------------------------------------------
#<pycode(py_kernwin)>
DP_LEFT = 0x0001
@@ -50,15 +28,15 @@ def load_custom_icon(file_name=None, data=None, format=None):
Use free_custom_icon() to free it
"""
if file_name is not None:
return _idaapi.py_load_custom_icon_fn(file_name)
return _ida_kernwin.py_load_custom_icon_fn(file_name)
elif not (data is None and format is None):
return _idaapi.py_load_custom_icon_data(data, format)
return _ida_kernwin.py_load_custom_icon_data(data, format)
else:
return 0
# ----------------------------------------------------------------------
def asklong(defval, format):
res, val = _idaapi._asklong(defval, format)
res, val = _ida_kernwin._asklong(defval, format)
if res == 1:
return val
@@ -67,7 +45,7 @@ def asklong(defval, format):
# ----------------------------------------------------------------------
def askaddr(defval, format):
res, ea = _idaapi._askaddr(defval, format)
res, ea = _ida_kernwin._askaddr(defval, format)
if res == 1:
return ea
@@ -76,7 +54,7 @@ def askaddr(defval, format):
# ----------------------------------------------------------------------
def askseg(defval, format):
res, sel = _idaapi._askseg(defval, format)
res, sel = _ida_kernwin._askseg(defval, format)
if res == 1:
return sel
@@ -84,7 +62,7 @@ def askseg(defval, format):
return None
# ----------------------------------------------------------------------
class action_handler_t:
class action_handler_t(object):
def __init__(self):
pass
@@ -95,27 +73,3 @@ class action_handler_t:
pass
#</pycode(py_kernwin)>
# ----------------------------------------------------------------------
from threading import Thread
import time
# ----------------------------------------------------------------------
def myfunction(cnt):
i = 1
while i <= cnt:
print "i=", i
i += 1
time.sleep(1)
print "done!"
def test_thread():
t = Thread(target=myfunction, args=(2,))
t.start()
t.join()
# ----------------------------------------------------------------------
def hotkey_func1():
print "Hello from hotkey handler in Python!"
@@ -1,25 +1,11 @@
#ifndef __PY_ASKUSINGFORM__
#define __PY_ASKUSINGFORM__
#ifndef __PY_KERNWIN_ASKUSINGFORM__
#define __PY_KERNWIN_ASKUSINGFORM__
//<code(py_askusingform)>
static qvector<ref_t> py_compiled_form_vec;
void free_compiled_form_instances(void)
{
while ( !py_compiled_form_vec.empty() )
{
const ref_t &ref = py_compiled_form_vec[0];
qstring title;
if ( !PyW_GetStringAttr(ref.o, "title", &title) )
title = "<unknown title>";
msg("WARNING: Form \"%s\" was not Free()d. Force-freeing.\n", title.c_str());
// Will call 'py_unregister_compiled_form()', and thus trim the vector down.
newref_t unused(PyObject_CallMethod(ref.o, (char *)"Free", "()"));
}
}
//</code(py_askusingform)>
//<code(py_kernwin_askusingform)>
//</code(py_kernwin_askusingform)>
//---------------------------------------------------------------------------
//<inline(py_askusingform)>
//<inline(py_kernwin_askusingform)>
#define DECLARE_FORM_ACTIONS form_actions_t *fa = (form_actions_t *)p_fa;
//---------------------------------------------------------------------------
@@ -384,18 +370,15 @@ static size_t py_get_OpenForm()
static void py_register_compiled_form(PyObject *py_form)
{
ref_t ref = borref_t(py_form);
if ( !py_compiled_form_vec.has(ref) )
py_compiled_form_vec.push_back(ref);
PyW_register_compiled_form(py_form);
}
static void py_unregister_compiled_form(PyObject *py_form)
{
ref_t ref = borref_t(py_form);
if ( py_compiled_form_vec.has(ref) )
py_compiled_form_vec.del(ref);
PyW_unregister_compiled_form(py_form);
}
//</inline(py_kernwin_askusingform)>
//</inline(py_askusingform)>
#endif // __PY_ASKUSINGFORM__
#endif // __PY_KERNWIN_ASKUSINGFORM__
@@ -1,74 +1,8 @@
# --------------------------------------------------------------------------
import os
import gc
import sys
#<pycode(py_kernwin_askusingform)>
import ida_idaapi, _ida_idaapi
import ida_pro
try:
import _idaapi
from _idaapi import set_script_timeout
import idaapi
from idaapi import py_clinked_object_t
from idaapi import _qstrvec_t
stdalone = False
except:
stdalone = True
print("Standalone: %s" % stdalone)
pywraps_there = False
try:
if stdalone:
class object_t(object): pass
class py_clinked_object_t(object): pass
_idaapi = object_t()
_idaapi.choose2_get_embedded = lambda obj: (id(obj), 0)
_idaapi.choose2_get_embedded_selection = lambda obj: None
_idaapi.textctrl_info_t_set_text = lambda self, v: None
_idaapi.CHOOSER_POPUP_MENU = 1
pywraps = object_t()
pywraps.py_get_AskUsingForm = lambda: 0
pywraps.py_get_OpenForm = lambda: 0
class Choose2(object):
CH_MULTI = 1
def __init__(self, title, cols, flags=0, popup_names=None,
icon=-1, x1=-1, y1=-1, x2=-1, y2=-1, deflt=-1,
embedded=False, width=None, height=None):
pass
def Close(self):
print("Chooser closing...")
Embedded = lambda self: 1
set_script_timeout = lambda x: x
else:
import pywraps
pywraps_there = True
from py_choose2 import *
py_clinked_object_t = idaapi.py_clinked_object_t
textctrl_info_t = idaapi.textctrl_info_t
_qstrvec_t = idaapi._qstrvec_t
_idaapi.BADADDR = 0xFFFFFFFF
_idaapi.MAXSTR = 1024
set_script_timeout = _idaapi.set_script_timeout
if not hasattr(_idaapi, 'formchgcbfa_enable_field'):
_idaapi.formchgcbfa_enable_field = pywraps.py_formchgcbfa_enable_field
except Exception as e:
pass
# print("exception: %s" % str(e))
print("Using PyWraps: %s" % pywraps_there)
# --------------------------------------------------------------------------
#<pycode(py_askusingform)>
#ICON WARNING|QUESTION|INFO|NONE
#AUTOHIDE NONE|DATABASE|REGISTRY|SESSION
#HIDECANCEL
@@ -98,7 +32,7 @@ except:
# -----------------------------------------------------------------------
# textctrl_info_t clinked object
class textctrl_info_t(py_clinked_object_t):
class textctrl_info_t(ida_idaapi.py_clinked_object_t):
"""Class representing textctrl_info_t"""
# Some constants
@@ -116,7 +50,7 @@ class textctrl_info_t(py_clinked_object_t):
"""The control uses IDA's fixed font"""
def __init__(self, text="", flags=0, tabsize=0):
py_clinked_object_t.__init__(self)
ida_idaapi.py_clinked_object_t.__init__(self)
if text:
self.text = text
if flags:
@@ -125,41 +59,41 @@ class textctrl_info_t(py_clinked_object_t):
self.tabsize = tabsize
def _create_clink(self):
return _idaapi.textctrl_info_t_create()
return _ida_kernwin.textctrl_info_t_create()
def _del_clink(self, lnk):
return _idaapi.textctrl_info_t_destroy(lnk)
return _ida_kernwin.textctrl_info_t_destroy(lnk)
def _get_clink_ptr(self):
return _idaapi.textctrl_info_t_get_clink_ptr(self)
return _ida_kernwin.textctrl_info_t_get_clink_ptr(self)
def assign(self, other):
"""Copies the contents of 'other' to 'self'"""
return _idaapi.textctrl_info_t_assign(self, other)
return _ida_kernwin.textctrl_info_t_assign(self, other)
def __set_text(self, s):
"""Sets the text value"""
return _idaapi.textctrl_info_t_set_text(self, s)
return _ida_kernwin.textctrl_info_t_set_text(self, s)
def __get_text(self):
"""Sets the text value"""
return _idaapi.textctrl_info_t_get_text(self)
return _ida_kernwin.textctrl_info_t_get_text(self)
def __set_flags__(self, flags):
"""Sets the flags value"""
return _idaapi.textctrl_info_t_set_flags(self, flags)
return _ida_kernwin.textctrl_info_t_set_flags(self, flags)
def __get_flags__(self):
"""Returns the flags value"""
return _idaapi.textctrl_info_t_get_flags(self)
return _ida_kernwin.textctrl_info_t_get_flags(self)
def __set_tabsize__(self, tabsize):
"""Sets the tabsize value"""
return _idaapi.textctrl_info_t_set_tabsize(self, tabsize)
return _ida_kernwin.textctrl_info_t_set_tabsize(self, tabsize)
def __get_tabsize__(self):
"""Returns the tabsize value"""
return _idaapi.textctrl_info_t_get_tabsize(self)
return _ida_kernwin.textctrl_info_t_get_tabsize(self)
value = property(__get_text, __set_text)
"""Alias for the text property"""
@@ -218,6 +152,8 @@ class Form(object):
"""Multi text control - textctrl_info_t"""
FT_DROPDOWN_LIST = 'b'
"""Dropdown list control - Form.DropdownControl"""
FT_HTML_LABEL = 'h'
"""HTML label to display (only for GUI version, and for dynamic labels; no input)"""
FT_CHKGRP = 'C'
FT_CHKGRP2= 'c'
@@ -726,7 +662,7 @@ class Form(object):
# Get a pointer to the chooser_info_t and the selection vector
# (These two parameters are the needed arguments for the AskUsingForm())
emb, sel = _idaapi.choose2_get_embedded(chooser)
emb, sel = _ida_kernwin.choose2_get_embedded(chooser)
# Get a pointer to a c_void_p constructed from an address
p_embedded = pointer(c_void_p.from_address(emb))
@@ -751,7 +687,7 @@ class Form(object):
def AddCommand(self,
caption,
flags = _idaapi.CHOOSER_POPUP_MENU,
flags = _ida_kernwin.CHOOSER_POPUP_MENU,
menu_index = -1,
icon = -1):
"""
@@ -777,7 +713,7 @@ class Form(object):
Form.Control.free(self)
class DropdownListControl(InputControl, _qstrvec_t):
class DropdownListControl(InputControl, ida_pro._qstrvec_t):
"""
Dropdown control
This control allows manipulating a dropdown control
@@ -804,7 +740,7 @@ class Form(object):
hlp)
# Init the associated qstrvec
_qstrvec_t.__init__(self, items)
ida_pro._qstrvec_t.__init__(self, items)
# Remember if readonly or not
self.readonly = readonly
@@ -815,7 +751,7 @@ class Form(object):
val_addr = addressof(self.__selval)
else:
# Create an strvec with one qstring
self.__selval = _qstrvec_t([selval])
self.__selval = ida_pro._qstrvec_t([selval])
# Get address of the first element
val_addr = self.__selval.addressof(0)
@@ -934,7 +870,7 @@ class Form(object):
self._reset()
# Unregister, so we don't try and free it again at closing-time.
_idaapi.py_unregister_compiled_form(self)
_ida_kernwin.py_unregister_compiled_form(self)
def _reset(self):
@@ -1180,7 +1116,7 @@ class Form(object):
self.__args = self.CompileEx(self.form)
# Register this form, to make sure it will be freed at closing-time.
_idaapi.py_register_compiled_form(self)
_ida_kernwin.py_register_compiled_form(self)
return (self, self.__args)
@@ -1227,7 +1163,7 @@ class Form(object):
Enable or disable an input field
@return: False - no such control
"""
return _idaapi.formchgcbfa_enable_field(self.p_fa, ctrl.id, enable)
return _ida_kernwin.formchgcbfa_enable_field(self.p_fa, ctrl.id, enable)
def ShowField(self, ctrl, show):
@@ -1235,7 +1171,7 @@ class Form(object):
Show or hide an input field
@return: False - no such control
"""
return _idaapi.formchgcbfa_show_field(self.p_fa, ctrl.id, show)
return _ida_kernwin.formchgcbfa_show_field(self.p_fa, ctrl.id, show)
def MoveField(self, ctrl, x, y, w, h):
@@ -1244,7 +1180,7 @@ class Form(object):
@return: False - no such fiel
"""
return _idaapi.formchgcbfa_move_field(self.p_fa, ctrl.id, x, y, w, h)
return _ida_kernwin.formchgcbfa_move_field(self.p_fa, ctrl.id, x, y, w, h)
def GetFocusedField(self):
@@ -1252,7 +1188,7 @@ class Form(object):
Get currently focused input field.
@return: None if no field is selected otherwise the control ID
"""
id = _idaapi.formchgcbfa_get_focused_field(self.p_fa)
id = _ida_kernwin.formchgcbfa_get_focused_field(self.p_fa)
return self.FindControlById(id)
@@ -1261,7 +1197,7 @@ class Form(object):
Set currently focused input field
@return: False - no such control
"""
return _idaapi.formchgcbfa_set_focused_field(self.p_fa, ctrl.id)
return _ida_kernwin.formchgcbfa_set_focused_field(self.p_fa, ctrl.id)
def RefreshField(self, ctrl):
@@ -1269,7 +1205,7 @@ class Form(object):
Refresh a field
@return: False - no such control
"""
return _idaapi.formchgcbfa_refresh_field(self.p_fa, ctrl.id)
return _ida_kernwin.formchgcbfa_refresh_field(self.p_fa, ctrl.id)
def Close(self, close_normally):
@@ -1280,7 +1216,7 @@ class Form(object):
0: form is closed abnormally as if the user pressed Esc
@return: None
"""
return _idaapi.formchgcbfa_close(self.p_fa, close_normally)
return _ida_kernwin.formchgcbfa_close(self.p_fa, close_normally)
def GetControlValue(self, ctrl):
@@ -1296,7 +1232,7 @@ class Form(object):
- None: on failure
"""
tid, sz = self.ControlToFieldTypeIdAndSize(ctrl)
r = _idaapi.formchgcbfa_get_field_value(
r = _ida_kernwin.formchgcbfa_get_field_value(
self.p_fa,
ctrl.id,
tid,
@@ -1320,7 +1256,7 @@ class Form(object):
@return: Boolean true on success
"""
tid, _ = self.ControlToFieldTypeIdAndSize(ctrl)
return _idaapi.formchgcbfa_set_field_value(
return _ida_kernwin.formchgcbfa_set_field_value(
self.p_fa,
ctrl.id,
tid,
@@ -1346,7 +1282,7 @@ class Form(object):
elif isinstance(ctrl, (Form.GroupItemControl, Form.GroupControl)):
return (2, 0)
elif isinstance(ctrl, Form.StringLabel):
return (3, min(_idaapi.MAXSTR, ctrl.size))
return (3, min(_ida_kernwin.MAXSTR, ctrl.size))
elif isinstance(ctrl, Form.ColorInput):
return (4, 0)
elif isinstance(ctrl, Form.NumericInput):
@@ -1362,9 +1298,9 @@ class Form(object):
try:
import ctypes
# Setup the numeric argument size
Form.NumericArgument.DefI64 = _idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
AskUsingForm__ = ctypes.CFUNCTYPE(ctypes.c_long)(_idaapi.py_get_AskUsingForm())
OpenForm__ = ctypes.CFUNCTYPE(ctypes.c_long)(_idaapi.py_get_OpenForm())
Form.NumericArgument.DefI64 = _ida_idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
AskUsingForm__ = ctypes.CFUNCTYPE(ctypes.c_long)(_ida_kernwin.py_get_AskUsingForm())
OpenForm__ = ctypes.CFUNCTYPE(ctypes.c_long)(_ida_kernwin.py_get_OpenForm())
except:
def AskUsingForm__(*args):
warning("AskUsingForm() needs ctypes library in order to work")
@@ -1379,9 +1315,9 @@ def AskUsingForm(*args):
@param: Compiled Arguments obtain through the Form.Compile() function
@return: 1 = ok, 0 = cancel
"""
old = set_script_timeout(0)
old = _ida_idaapi.set_script_timeout(0)
r = AskUsingForm__(*args)
set_script_timeout(old)
_ida_idaapi.set_script_timeout(old)
return r
def OpenForm(*args):
@@ -1389,9 +1325,7 @@ def OpenForm(*args):
Calls OpenForm()
@param: Compiled Arguments obtain through the Form.Compile() function
"""
old = set_script_timeout(0)
old = _ida_idaapi.set_script_timeout(0)
r = OpenForm__(*args)
set_script_timeout(old)
#</pycode(py_askusingform)>
_ida_idaapi.set_script_timeout(old)
#</pycode(py_kernwin_askusingform)>
@@ -1,8 +1,8 @@
#ifndef __PY_CHOOSE__
#define __PY_CHOOSE__
#ifndef __PY_KERNWIN_CHOOSE__
#define __PY_KERNWIN_CHOOSE__
//---------------------------------------------------------------------------
//<inline(py_choose)>
//<inline(py_kernwin_choose)>
//---------------------------------------------------------------------------
uint32 idaapi choose_sizer(void *self)
{
@@ -73,6 +73,6 @@ uint32 choose_choose(
return r;
}
//</inline(py_choose)>
//</inline(py_kernwin_choose)>
#endif // __PY_CHOOSE__
#endif // __PY_KERNWIN_CHOOSE__

Some files were not shown because too many files have changed in this diff Show More