mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
IDAPython for IDA 6.95: Initial commit
This commit is contained in:
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
+165
-7
@@ -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',
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#ifndef _BASETSD_H
|
||||
#define _BASETSD_H
|
||||
/* Microsoft free compilers seem to lack this file and Python needs it */
|
||||
#endif
|
||||
@@ -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__":
|
||||
|
||||
@@ -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
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
@@ -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
@@ -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
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
+5
-4
@@ -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)
|
||||
|
||||
|
||||
@@ -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
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
@@ -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.'
|
||||
@@ -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
@@ -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">
|
||||
|
||||
@@ -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.
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
Regular → Executable
+26
-14
@@ -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
File diff suppressed because it is too large
Load Diff
+497
-65
@@ -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__
|
||||
|
||||
@@ -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"])
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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, ¬ags) )
|
||||
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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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()
|
||||
@@ -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)>
|
||||
# -----------------------------------------------------------------------
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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):
|
||||
"""
|
||||
|
||||
@@ -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)>
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+126
-78
@@ -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__
|
||||
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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)>
|
||||
@@ -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
@@ -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
@@ -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
Reference in New Issue
Block a user