diff --git a/BUILDING.txt b/BUILDING.txt index 9f6e5a3..b18f104 100644 --- a/BUILDING.txt +++ b/BUILDING.txt @@ -11,19 +11,18 @@ REQUIREMENTS - IDA and IDA SDK [5.1] http://www.datarescue.com/idabase/ - - Python [2.4.4, 2.5] + - Python [2.4.4, 2.5.1] http://www.python.org/ - Simplified Wrapper Interface Generator (SWIG) [1.3.31] - SWIG is not needed for regular building, only if you want to tweak the wrappers. http://www.swig.org/ - Unix utilities (GNU patch on Windows): http://www.research.att.com/sw/tools/uwin/ or - http://unxutils.sourceforge.net/ or - http://www.cygwin.com/ + http://unxutils.sourceforge.net/ or + http://www.cygwin.com/ - - GCC on Linux and Mac OS X [4.0] + - GCC on Linux and Mac OS X [4.1.3] Comes with your distribution - Microsoft Visual C on Windows [Microsoft Visual C++ 2005 Express Edition] @@ -32,32 +31,33 @@ REQUIREMENTS BUILDING -Make sure all the needed tools (compiler, make, swig, etc) are on the -PATH. +Make sure all the needed tools (compiler, swig) are on the PATH. 1, Unpack the IDAPython source and IDA Pro SDK into the following directory structure: - swigsdk-versions/5.1/ - version 5.0 of the IDA Pro SDK + swigsdk-versions/5.1/ - version 5.1 of the IDA Pro SDK idapython/ - IDAPython source code 2, Patch the SDK using GNU Patch with one of patches from patches/ directory. You will have to use the -P option depending on which directory you patch from. -2, Build the plugin +3, On Mac OS X copy libida.dylib from the IDA install directory to + swigsdk-versions/5.1/libgcc32.mac/ + +4, Build the plugin python build.py It is possible to build the plugin for different Python versions by running build.py with the corresponding Python binary. -3, Install the components as described in README.txt +5, Install the components as described in README.txt -See build.py for build details and tweak opportunities. +See build.py for build details and possible tweaks. ------------------------------------------------------------------------------- Copyright (c) 2004-2007 Gergely Erdelyi . All rights reserved. ------------------------------------------------------------------------------- - diff --git a/build.py b/build.py index 2fa18af..24bbb73 100644 --- a/build.py +++ b/build.py @@ -24,7 +24,7 @@ IDA_SDK = ".." + os.sep + "swigsdk-versions" + os.sep + "%d.%d" % (IDA_MAJOR_VER # IDAPython version VERSION_MAJOR = 0 VERSION_MINOR = 9 -VERSION_PATCH = 54 +VERSION_PATCH = 55 # Determine Python version PYTHON_MAJOR_VERSION = int(platform.python_version()[0]) @@ -34,7 +34,7 @@ PYTHON_MINOR_VERSION = int(platform.python_version()[2]) PYTHON_INCLUDE_DIRECTORY = sysconfig.get_config_var('INCLUDEPY') # Swig command-line parameters -SWIG_OPTIONS = '-modern -python -c++ -shadow -D__GNUC__' +SWIG_OPTIONS = '-modern -python -c++ -w451 -shadow -D__GNUC__' # Common macros for all compilations COMMON_MACROS = [ @@ -360,7 +360,7 @@ if __name__ == "__main__": # Detect the platform system = platform.system() - if system == "Windows": + if system == "Windows" or system == "Microsoft": platform_string = "win32" plugin_name = "python.plw" diff --git a/patches/ida51.patch b/patches/ida51.patch index eda6878..92b9450 100644 --- a/patches/ida51.patch +++ b/patches/ida51.patch @@ -19,7 +19,7 @@ diff -ur idasdk-versions/5.1/include/area.hpp swigsdk-versions/5.1/include/area. // Last request information -- for internal use diff -ur idasdk-versions/5.1/include/bytes.hpp swigsdk-versions/5.1/include/bytes.hpp --- idasdk-versions/5.1/include/bytes.hpp 2007-01-22 04:07:12.000000000 +0200 -+++ swigsdk-versions/5.1/include/bytes.hpp 2007-09-30 06:56:51.000000000 +0300 ++++ swigsdk-versions/5.1/include/bytes.hpp 2007-12-01 12:25:09.000000000 +0200 @@ -1644,9 +1644,9 @@ const uchar *mask, // comparision mask size_t len, // length of string to search @@ -200,7 +200,7 @@ diff -ur idasdk-versions/5.1/include/idd.hpp swigsdk-versions/5.1/include/idd.hp #endif // _IDD_HPP diff -ur idasdk-versions/5.1/include/idp.hpp swigsdk-versions/5.1/include/idp.hpp --- idasdk-versions/5.1/include/idp.hpp 2007-02-09 12:54:06.000000000 +0200 -+++ swigsdk-versions/5.1/include/idp.hpp 2007-09-30 06:56:51.000000000 +0300 ++++ swigsdk-versions/5.1/include/idp.hpp 2007-12-06 14:52:16.000000000 +0200 @@ -31,6 +31,7 @@ #define IDP_INTERFACE_VERSION 76 @@ -225,26 +225,42 @@ diff -ur idasdk-versions/5.1/include/idp.hpp swigsdk-versions/5.1/include/idp.hp //----------------------------------------------------------------------- // Structures related to checkarg_dispatch() -@@ -1384,6 +1387,7 @@ - int high_fixup_bits; - +@@ -189,6 +192,7 @@ + // arguments: NULL, char * const **outptr + // This callback must be implemented }; +#endif // SWIG #ifdef __BORLANDC__ - #if sizeof(processor_t) % 4 -@@ -1394,8 +1398,10 @@ - // The following two structures contain information about the current - // processor and assembler. + #pragma option pop +@@ -553,6 +557,7 @@ + // processor is changed. + // (NULL terminated) +#ifndef SWIG - idaman processor_t ida_export_data ph; // Current processor - idaman asm_t ida_export_data ash; // Current assembler + // + // Callback function. IDP module can take appropriate + // actions when some events occurs in the kernel. +@@ -1111,6 +1116,7 @@ + // defined by the loaders + }; + int (idaapi* notify)(idp_notify msgid, ...); // Various notifications for the idp +#endif // SWIG - idaman int ida_export str2regf(const char *p); // -1 - error. Returns word reg number - idaman int ida_export str2reg(const char *p); // -1 - error. Returns any reg number -@@ -1500,10 +1506,12 @@ + // Get the stack variable scaling factor + // Useful for processors who refer to the stack with implicit scaling factor. +@@ -1363,8 +1369,10 @@ + int icode_return; + + ++#ifndef SWIG + // Set IDP-specific option (see below) + set_options_t *set_idp_options; ++#endif // SWIG + + // Is the instruction created only for alignment purposes? + // returns: number of bytes in the instruction +@@ -1500,10 +1508,12 @@ idaman char *ida_export get_idp_name(char *buf, size_t bufsize); @@ -257,7 +273,7 @@ diff -ur idasdk-versions/5.1/include/idp.hpp swigsdk-versions/5.1/include/idp.hp // Set target assembler -@@ -1512,11 +1520,13 @@ +@@ -1512,11 +1522,13 @@ idaman void ida_export set_target_assembler(int asmnum); @@ -459,6 +475,7 @@ diff -ur idasdk-versions/5.1/include/lines.hpp swigsdk-versions/5.1/include/line idaman bool ida_export save_line_in_array(const char *line); // a standard line saver() idaman void ida_export init_lines_array(char *lnar[],int maxsize);// initialization function for it +Only in swigsdk-versions/5.1/include/: md5.h.new diff -ur idasdk-versions/5.1/include/moves.hpp swigsdk-versions/5.1/include/moves.hpp --- idasdk-versions/5.1/include/moves.hpp 2006-03-17 17:41:22.000000000 +0200 +++ swigsdk-versions/5.1/include/moves.hpp 2007-09-30 06:56:51.000000000 +0300 @@ -500,7 +517,7 @@ diff -ur idasdk-versions/5.1/include/moves.hpp swigsdk-versions/5.1/include/move location_t(void) {} diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt.hpp --- idasdk-versions/5.1/include/nalt.hpp 2007-01-29 22:06:46.000000000 +0200 -+++ swigsdk-versions/5.1/include/nalt.hpp 2007-09-30 06:56:51.000000000 +0300 ++++ swigsdk-versions/5.1/include/nalt.hpp 2007-12-04 21:37:14.000000000 +0200 @@ -29,6 +29,7 @@ // in them. Look at netnode.hpp for the definition of netnodes. // @@ -509,7 +526,23 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. #include //-------------------------------------------------------------------------- -@@ -324,6 +325,7 @@ +@@ -231,6 +232,7 @@ + // position of cursor in the window with cross-references to the address + // Used by the user-interface. + NALT_EA(get_xrefpos, set_xrefpos, del_xrefpos, NALT_XREFPOS) ++#endif // SWIG + + // Additional flags for the location. + // All 32-bits of the main flags (see bytes.hpp) are used up. +@@ -285,6 +287,7 @@ + #define AFL_USERTI 0x02000000L // the type information is definitive + // (comes from the user or type library) + ++#ifndef SWIG + // The following macro is used to define 3 functions to work with a bit: + // int test(ea_t ea); - test if the bit is set + // void set(ea_t ea); - set bit +@@ -324,6 +327,7 @@ IMPL__IS_AFLAG_FUNCS(AFL_FIXEDSPD, fixed_spd) IMPL__IS_AFLAG_FUNCS(AFL_ALIGNFLOW,align_flow) IMPL__IS_AFLAG_FUNCS(AFL_USERTI, userti) @@ -517,7 +550,7 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. inline void set_visible_item(ea_t ea, bool visible) { -@@ -341,11 +343,14 @@ +@@ -341,11 +345,14 @@ // source line numbers (they are sometimes present in object files) // Thes functions may be used if necessary. @@ -532,7 +565,7 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. // absolute segment base address // These functions may be used if necessary. NALT_EA(get_absbase,set_absbase, del_absbase, NALT_ABSBASE) -@@ -366,6 +371,7 @@ +@@ -366,6 +373,7 @@ // type of string // Don't use, see: get_typeinfo() NALT_ULONG(get_str_type,set_str_type,del_str_type,NALT_STRTYPE) @@ -540,7 +573,7 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. inline char idaapi get_str_type_code(uval_t strtype) { return char(strtype); } -@@ -402,16 +408,19 @@ +@@ -402,16 +410,19 @@ } @@ -560,7 +593,7 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. //---------------------------------------------------------------------- NSUP_STRING(nalt_cmt,NSUP_CMT) // regular comment (low level, don't use) NSUP_STRING(nalt_rptcmt,NSUP_REPCMT) // repeatable comment (low level, don't use) -@@ -559,6 +568,7 @@ +@@ -559,6 +570,7 @@ // Address which holds the switch info. Used at the jump targets. NALT_EA(get_switch_parent,set_switch_parent,del_switch_parent, NALT_SWITCH) @@ -568,7 +601,7 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. //-------------------------------------------------------------------------- -@@ -671,6 +681,7 @@ +@@ -671,6 +683,7 @@ idaman void ida_export write_struc_path(netnode node, int idx, const tid_t *path, int plen, adiff_t delta); idaman int ida_export read_struc_path(netnode node, int idx, tid_t *path, adiff_t *delta); // returns plen @@ -576,7 +609,7 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. #define DEFINE_PATH_FUNCS(name, code) \ inline int N_PASTE(get_,name)(ea_t ea, tid_t *path, adiff_t *delta) \ { return read_struc_path(netnode(ea), code, path, delta); } \ -@@ -738,6 +749,7 @@ +@@ -738,6 +751,7 @@ #define RIDX_ALT_CRC32 uval_t(-5) // input file crc32 #define RIDX_ALT_IMAGEBASE uval_t(-6) // image base #define RIDX_ALT_IDSNODE uval_t(-7) // ids modnode id (for import_module) @@ -584,7 +617,7 @@ diff -ur idasdk-versions/5.1/include/nalt.hpp swigsdk-versions/5.1/include/nalt. //-------------------------------------------------------------------------- // Get full path of the input file -@@ -784,11 +796,13 @@ +@@ -784,11 +798,13 @@ return get_input_file_path(buf, bufsize); } diff --git a/python/idc.py b/python/idc.py index 823382d..57889e4 100644 --- a/python/idc.py +++ b/python/idc.py @@ -3715,16 +3715,22 @@ def MakeFrame(ea, lvsize, frregs, argsize): @param frregs: size of saved registers @param argsize: size of function arguments - @return: ID of function frame or None + @return: ID of function frame or -1 If the function did not have a frame, the frame will be created. Otherwise the frame will be modified """ func = idaapi.get_func(ea) if not func: - return None + return -1 - return idaapi.add_frame(func, lvsize, frregs, argsize) + id = idaapi.add_frame(func, lvsize, frregs, argsize) + + if not id: + if not idaapi.set_frame_size(func, lvsize, frregs, argsize): + return -1 + + return func.frame def GetSpd(ea): @@ -4604,7 +4610,13 @@ def _IDC_PrepareStrucMemberTypeinfo(flag, typeid): elif idaapi.isOff0(flag): ti = idaapi.typeinfo_t() ri = idaapi.refinfo_t() + ri.target = BADADDR ri.base = typeid + ri.tdelta = 0 + if (flag & FF_WORD): + ri.flags = REF_OFF16 + else: + ri.flags = REF_OFF32 ti.ri = ri elif idaapi.isEnum0(flag): ti = idaapi.typeinfo_t() @@ -4877,10 +4889,13 @@ def FirstFuncFchunk(funcea): @return: the function entry point or BADADDR @note: This function returns the first (main) chunk of the specified function - - FIXME: unimplemented """ - raise NotImplementedError + func = idaapi.get_func(funcea) + fci = idaapi.func_tail_iterator_t(func, funcea) + if fci.main(): + return fci.chunk().startEA + else: + return BADADDR def NextFuncFchunk(funcea, tailea): @@ -4893,10 +4908,27 @@ def NextFuncFchunk(funcea, tailea): @return: the starting address of the next function chunk or BADADDR @note: This function returns the next chunk of the specified function - - FIXME: unimplemented """ - raise NotImplementedError + func = idaapi.get_func(funcea) + fci = idaapi.func_tail_iterator_t(func, funcea) + if not fci.main(): + return BADADDR + + # Iterate and try to find the current chunk + found = False + while True: + if fci.chunk().startEA <= tailea and \ + fci.chunk().endEA > tailea: + found = True + break + if not fci.next(): + break + + # Return the next chunk, if there is one + if found and fci.next(): + return fci.chunk().startEA + else: + return BADADDR # ---------------------------------------------------------------------------- @@ -5664,10 +5696,8 @@ def SetType(ea, type): assciated with 'ea' will be deleted @return: 1-ok, 0-failed. - - FIXME: unimplemented """ - raise NotImplementedError + return idaapi.apply_cdecl(ea, type) def ParseTypes(input, flags): diff --git a/swig/bytes.i b/swig/bytes.i index a5f5b58..b25fd5d 100644 --- a/swig/bytes.i +++ b/swig/bytes.i @@ -1,4 +1,4 @@ -// This makes put_many_bytes and patch_many_bytes work nicely +// Make put_many_bytes and patch_many_bytes work %apply (char *STRING, int LENGTH) { (const void *buf, size_t size) }; // Make get_any_cmt() work @@ -58,15 +58,15 @@ // TODO: These could be fixed if someone needs them. %ignore get_many_bytes; -%ignore put_many_bytes; -%ignore patch_many_bytes; %ignore set_dbgmem_source; %ignore invalidate_dbgmem_config; %ignore invalidate_dbgmem_contents; -%ignore is_debugger_on; %include "bytes.hpp" +%clear(void *buf, ssize_t size); + %clear(const void *buf, size_t size); %clear(void *buf, ssize_t size); %clear(typeinfo_t *); + diff --git a/swig/idaapi.i b/swig/idaapi.i index 76cef32..a9a6cc6 100644 --- a/swig/idaapi.i +++ b/swig/idaapi.i @@ -1,4 +1,4 @@ -%module(docstring="IDA Pro Plugin SDK API wrapper") idaapi +%module(docstring="IDA Pro Plugin SDK API wrapper",directors="1") idaapi // Suppress 'previous definition of XX' warnings #pragma SWIG nowarn=302 // Enable automatic docstring generation diff --git a/swig/idp.i b/swig/idp.i index 0ca4590..85c9b6e 100644 --- a/swig/idp.i +++ b/swig/idp.i @@ -1,3 +1,253 @@ %ignore gen_idb_event; +// Ignore the function pointers +%ignore asm_t::checkarg_dispatch; +%ignore asm_t::func_header; +%ignore asm_t::func_footer; +%ignore asm_t::get_type_name; +%ignore processor_t::notify; +%ignore processor_t::header; +%ignore processor_t::footer; +%ignore processor_t::segstart; +%ignore processor_t::segend; +%ignore processor_t::assumes; +%ignore processor_t::u_ana; +%ignore processor_t::u_emu; +%ignore processor_t::u_out; +%ignore processor_t::u_outop; +%ignore processor_t::d_out; +%ignore processor_t::cmp_opnd; +%ignore processor_t::can_have_type; +%ignore processor_t::getreg; +%ignore processor_t::is_far_jump; +%ignore processor_t::translate; +%ignore processor_t::realcvt; +%ignore processor_t::is_switch; +%ignore processor_t::gen_map_file; +%ignore processor_t::extract_address; +%ignore processor_t::is_sp_based; +%ignore processor_t::create_func_frame; +%ignore processor_t::get_frame_retsize; +%ignore processor_t::gen_stkvar_def; +%ignore processor_t::u_outspec; +%ignore processor_t::is_align_insn; + %include "idp.hpp" + +%feature("director") IDB_Hooks; + +%inline %{ + +int idaapi IDB_Callback(void *ud, int notification_code, va_list va); +class IDB_Hooks +{ +public: + virtual ~IDB_Hooks() {}; + + bool hook() { return hook_to_notification_point(HT_IDB, IDB_Callback, this); } + bool unhook() { return unhook_from_notification_point(HT_IDB, IDB_Callback, this); } + /* Hook functions to override in Python */ + virtual int byte_patched(ea_t ea) { return 0; }; + virtual int cmt_changed(ea_t, bool repeatable_cmt) { return 0; }; + virtual int ti_changed(ea_t ea, const type_t *type, const p_list *fnames) { msg("ti_changed hook not supported yet\n"); return 0; }; + virtual int op_ti_changed(ea_t ea, int n, const type_t *type, const p_list *fnames) { msg("op_ti_changed hook not supported yet\n"); return 0; }; + virtual int op_type_changed(ea_t ea, int n) { return 0; }; + virtual int enum_created(enum_t id) { return 0; }; + virtual int enum_deleted(enum_t id) { return 0; }; + virtual int enum_bf_changed(enum_t id) { return 0; }; + virtual int enum_renamed(enum_t id) { return 0; }; + virtual int enum_cmt_changed(enum_t id) { return 0; }; + virtual int enum_const_created(enum_t id, const_t cid) { return 0; }; + virtual int enum_const_deleted(enum_t id, const_t cid) { return 0; }; + virtual int struc_created(tid_t struc_id) { return 0; }; + virtual int struc_deleted(tid_t struc_id) { return 0; }; + virtual int struc_renamed(struc_t *sptr) { return 0; }; + virtual int struc_expanded(struc_t *sptr) { return 0; }; + virtual int struc_cmt_changed(tid_t struc_id) { return 0; }; + virtual int struc_member_created(struc_t *sptr, member_t *mptr) { return 0; }; + virtual int struc_member_deleted(struc_t *sptr, tid_t member_id) { return 0; }; + virtual int struc_member_renamed(struc_t *sptr, member_t *mptr) { return 0; }; + virtual int struc_member_changed(struc_t *sptr, member_t *mptr) { return 0; }; + virtual int thunk_func_created(func_t *pfn) { return 0; }; + virtual int func_tail_appended(func_t *pfn, func_t *tail) { return 0; }; + virtual int func_tail_removed(func_t *pfn, ea_t tail_ea) { return 0; }; + virtual int tail_owner_changed(func_t *tail, ea_t owner_func) { return 0; }; + virtual int func_noret_changed(func_t *pfn) { return 0; }; + virtual int segm_added(segment_t *s) { return 0; }; + virtual int segm_deleted(ea_t startEA) { return 0; }; + virtual int segm_start_changed(segment_t *s) { return 0; }; + virtual int segm_end_changed(segment_t *s) { return 0; }; + virtual int segm_moved(ea_t from, ea_t to, asize_t size) { return 0; }; +}; + +int idaapi IDB_Callback(void *ud, int notification_code, va_list va) +{ + class IDB_Hooks *proxy = (class IDB_Hooks *)ud; + ea_t ea, ea2; + bool repeatable_cmt; + type_t *type; + /* p_list *fnames; */ + int n; + enum_t id; + const_t cid; + tid_t struc_id; + struc_t *sptr; + member_t *mptr; + tid_t member_id; + func_t *pfn; + func_t *tail; + segment_t *seg; + asize_t size; + + try { + switch (notification_code) + { + case idb_event::byte_patched: + ea = va_arg(va, ea_t); + return proxy->byte_patched(ea); + + case idb_event::cmt_changed: + ea = va_arg(va, ea_t); + repeatable_cmt = va_arg(va, int); + return proxy->cmt_changed(ea, repeatable_cmt); +#if 0 + case idb_event::ti_changed: + ea = va_arg(va, ea_t); + type = va_arg(va, type_t *); + fnames = va_arg(va, fnames); + return proxy->ti_changed(ea, type, fnames); + + case idb_event::op_ti_changed: + ea = va_arg(va, ea_t); + n = va_arg(va, int); + type = va_arg(va, type_t *); + fnames = va_arg(va, fnames); + return proxy->op_ti_changed(ea, n, type, fnames); +#endif + case idb_event::op_type_changed: + ea = va_arg(va, ea_t); + n = va_arg(va, int); + return proxy->op_type_changed(ea, n); + + case idb_event::enum_created: + id = va_arg(va, enum_t); + return proxy->enum_created(id); + + case idb_event::enum_deleted: + id = va_arg(va, enum_t); + return proxy->enum_deleted(id); + + case idb_event::enum_bf_changed: + id = va_arg(va, enum_t); + return proxy->enum_bf_changed(id); + + case idb_event::enum_cmt_changed: + id = va_arg(va, enum_t); + return proxy->enum_cmt_changed(id); + + case idb_event::enum_const_created: + id = va_arg(va, enum_t); + cid = va_arg(va, const_t); + return proxy->enum_const_created(id, cid); + + case idb_event::enum_const_deleted: + id = va_arg(va, enum_t); + cid = va_arg(va, const_t); + return proxy->enum_const_deleted(id, cid); + + case idb_event::struc_created: + struc_id = va_arg(va, tid_t); + return proxy->struc_created(struc_id); + + case idb_event::struc_deleted: + struc_id = va_arg(va, tid_t); + return proxy->struc_deleted(struc_id); + + case idb_event::struc_renamed: + sptr = va_arg(va, struc_t *); + return proxy->struc_renamed(sptr); + + case idb_event::struc_expanded: + sptr = va_arg(va, struc_t *); + return proxy->struc_expanded(sptr); + + case idb_event::struc_cmt_changed: + struc_id = va_arg(va, tid_t); + return proxy->struc_cmt_changed(struc_id); + + case idb_event::struc_member_created: + sptr = va_arg(va, struc_t *); + mptr = va_arg(va, member_t *); + return proxy->struc_member_created(sptr, mptr); + + case idb_event::struc_member_deleted: + sptr = va_arg(va, struc_t *); + member_id = va_arg(va, tid_t); + return proxy->struc_member_deleted(sptr, member_id); + + case idb_event::struc_member_renamed: + sptr = va_arg(va, struc_t *); + mptr = va_arg(va, member_t *); + return proxy->struc_member_renamed(sptr, mptr); + + case idb_event::struc_member_changed: + sptr = va_arg(va, struc_t *); + mptr = va_arg(va, member_t *); + return proxy->struc_member_changed(sptr, mptr); + + case idb_event::thunk_func_created: + pfn = va_arg(va, func_t *); + return proxy->thunk_func_created(pfn); + + case idb_event::func_tail_appended: + pfn = va_arg(va, func_t *); + tail = va_arg(va, func_t *); + return proxy->func_tail_appended(pfn, tail); + + case idb_event::func_tail_removed: + pfn = va_arg(va, func_t *); + ea = va_arg(va, ea_t); + return proxy->func_tail_removed(pfn, ea); + + case idb_event::tail_owner_changed: + tail = va_arg(va, func_t *); + ea = va_arg(va, ea_t); + return proxy->tail_owner_changed(tail, ea); + + case idb_event::func_noret_changed: + pfn = va_arg(va, func_t *); + return proxy->func_noret_changed(pfn); + + case idb_event::segm_added: + seg = va_arg(va, segment_t *); + return proxy->segm_added(seg); + + case idb_event::segm_deleted: + ea = va_arg(va, ea_t); + return proxy->segm_deleted(ea); + + case idb_event::segm_start_changed: + seg = va_arg(va, segment_t *); + return proxy->segm_start_changed(seg); + + case idb_event::segm_end_changed: + seg = va_arg(va, segment_t *); + return proxy->segm_end_changed(seg); + + case idb_event::segm_moved: + ea = va_arg(va, ea_t); + ea2 = va_arg(va, ea_t); + size = va_arg(va, asize_t); + return proxy->segm_moved(ea, ea2, size); + } + } + catch (Swig::DirectorException &e) + { + msg("Exception in IDP Hook function:\n"); + if (PyErr_Occurred()) + { + PyErr_Print(); + } + } +} +%}