From 1d2f1d1f074677fe17f4c4eefa9e8b886008d8f2 Mon Sep 17 00:00:00 2001 From: "elias.bachaalany" Date: Thu, 7 Oct 2010 09:47:04 +0000 Subject: [PATCH] Committed last updates to IDAPython 1.4.2 --- CHANGES.txt | 6 ++ build.py | 1 + examples/ex_custview.py | 12 ++-- examples/ex_prefix_plugin.py | 42 +++++++++++ python/idc.py | 7 +- swig/idaapi.i | 8 +-- swig/kernwin.i | 6 +- swig/lines.i | 130 +++++++++++++++++++++++++++++++---- swig/pro.i | 17 +++++ 9 files changed, 197 insertions(+), 32 deletions(-) create mode 100644 examples/ex_prefix_plugin.py diff --git a/CHANGES.txt b/CHANGES.txt index cd975e3..2b6cd0f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,11 @@ Please see http://code.google.com/p/idapython/source/list for a detailed list of changes. +Changes from version 1.4.1 to 1.4.2 +------------------------------------ +- Added command completion +- Added necessary changes so it compiles with Python 2.7 +- Wrapped set_user_defined_prefix() + Changes from version 1.4.0 to 1.4.1 ------------------------------------ - Added cli_t diff --git a/build.py b/build.py index e82a48c..fdc66e1 100644 --- a/build.py +++ b/build.py @@ -88,6 +88,7 @@ BINDIST_MANIFEST = [ "examples/ex_graph.py", "examples/ex_dbg.py", "examples/ex_custview.py", + "examples/ex_prefix_plugin.py", "examples/ex_imports.py" ] diff --git a/examples/ex_custview.py b/examples/ex_custview.py index eb8de0f..48e6a71 100644 --- a/examples/ex_custview.py +++ b/examples/ex_custview.py @@ -32,7 +32,7 @@ class mycv_t(simplecustviewer_t): """ User clicked in the view @param shift: Shift flag - @return Boolean. True if you handled the event + @return: Boolean. True if you handled the event """ print "OnClick, shift=%d" % shift return True @@ -41,7 +41,7 @@ class mycv_t(simplecustviewer_t): """ User dbl-clicked in the view @param shift: Shift flag - @return Boolean. True if you handled the event + @return: Boolean. True if you handled the event """ word = self.GetCurrentWord() if not word: word = "" @@ -51,14 +51,14 @@ class mycv_t(simplecustviewer_t): def OnCursorPosChanged(self): """ Cursor position changed. - @return Nothing + @return: Nothing """ print "OnCurposChanged" def OnClose(self): """ The view is closing. Use this event to cleanup. - @return Nothing + @return: Nothing """ print "OnClose " + self.title @@ -67,7 +67,7 @@ class mycv_t(simplecustviewer_t): User pressed a key @param vkey: Virtual key code @param shift: Shift flag - @return Boolean. True if you handled the event + @return: Boolean. True if you handled the event """ print "OnKeydown, vk=%d shift=%d" % (vkey, shift) # ESCAPE? @@ -123,7 +123,7 @@ class mycv_t(simplecustviewer_t): def OnPopup(self): """ Context menu popup is about to be shown. Create items dynamically if you wish - @return Boolean. True if you handled the event + @return: Boolean. True if you handled the event """ print "OnPopup" diff --git a/examples/ex_prefix_plugin.py b/examples/ex_prefix_plugin.py new file mode 100644 index 0000000..aae8c2b --- /dev/null +++ b/examples/ex_prefix_plugin.py @@ -0,0 +1,42 @@ +import idaapi + +PREFIX = idaapi.SCOLOR_INV + ' ' + idaapi.SCOLOR_INV + +class prefix_plugin_t(idaapi.plugin_t): + flags = 0 + comment = "This is a user defined prefix sample plugin" + help = "This is help" + wanted_name = "user defined prefix" + wanted_hotkey = "" + + + def user_prefix(self, ea, lnnum, indent, line, bufsize): + #print("ea=%x lnnum=%d indent=%d line=%s bufsize=%d" % (ea, lnnum, indent, line, bufsize)) + + if (ea % 2 == 0) and indent == -1: + return PREFIX + else: + return "" + + + def init(self): + self.prefix_installed = idaapi.set_user_defined_prefix(8, self.user_prefix) + if self.prefix_installed: + print("prefix installed") + + return idaapi.PLUGIN_KEEP + + + def run(self, arg): + pass + + + def term(self): + if self.prefix_installed: + idaapi.set_user_defined_prefix(0, None) + print("prefix uninstalled!") + + +def PLUGIN_ENTRY(): + return prefix_plugin_t() + diff --git a/python/idc.py b/python/idc.py index 6631c8f..013914d 100644 --- a/python/idc.py +++ b/python/idc.py @@ -466,8 +466,8 @@ def SaveBase(idbname, flags=0): file will be used. @param flags: DBFL_BAK or 0 """ - if len(idbname)==0: - idbname = idaapi.cvar.database_idb + if len(idbname) == 0: + idbname = GetIdbPath() saveflags = idaapi.cvar.database_flags if flags & DBFL_BAK: idaapi.cvar.database_flags |= DBFL_BAK @@ -1635,8 +1635,7 @@ def GetIdbPath(): This function returns full path of the current IDB database """ - idb_path = idaapi.cvar.database_idb + '\x00' - return idb_path[ : idb_path.find('\x00') ] + return idaapi.as_cstr(idaapi.cvar.database_idb) def GetInputMD5(): diff --git a/swig/idaapi.i b/swig/idaapi.i index 3327fdd..668add1 100644 --- a/swig/idaapi.i +++ b/swig/idaapi.i @@ -1828,11 +1828,9 @@ def as_cstr(val): """ if isinstance(val, PyIdc_cvt_refclass__): val = val.value - n = val.find('\0') - if n == -1: - return val - else: - return val[:n] + + n = val.find('\x00') + return val if n == -1 else val[:n] # ----------------------------------------------------------------------- def as_unicode(s): diff --git a/swig/kernwin.i b/swig/kernwin.i index f9e8188..3e2133d 100644 --- a/swig/kernwin.i +++ b/swig/kernwin.i @@ -2805,14 +2805,14 @@ class simplecustviewer_t(object): def InsertLine(self, lineno, line, fgcolor=None, bgcolor=None): """ Inserts a line in the given position - @return Boolean + @return: Boolean """ return _idaapi.pyscv_insert_line(self.__this, lineno, self.__make_sl_arg(line, fgcolor, bgcolor)) def EditLine(self, lineno, line, fgcolor=None, bgcolor=None): """ Edits an existing line. - @return Boolean + @return: Boolean """ return _idaapi.pyscv_edit_line(self.__this, lineno, self.__make_sl_arg(line, fgcolor, bgcolor)) @@ -2823,7 +2823,7 @@ class simplecustviewer_t(object): def DelLine(self, lineno): """ Deletes an existing line - @return Boolean + @return: Boolean """ return _idaapi.pyscv_del_line(self.__this, lineno) diff --git a/swig/lines.i b/swig/lines.i index 15885f3..7828aad 100644 --- a/swig/lines.i +++ b/swig/lines.i @@ -1,15 +1,9 @@ // FIXME: These should be fixed %ignore requires_color_esc; %ignore tag_on; -%ignore tag_remove; %ignore tag_off; %ignore tag_addchr; %ignore tag_addstr; -%ignore tag_addr; -%ignore tag_advance; -%ignore tag_skipcodes; -%ignore tag_skipcode; -%ignore set_user_defined_prefix; %ignore get_user_defined_prefix; // Ignore va_list versions %ignore printf_line_v; @@ -35,7 +29,6 @@ %ignore save_line_in_array; %ignore init_lines_array; %ignore finish_makeline; -%ignore generate_disassembly; %ignore gen_labeled_line; %ignore gen_lname_line; %ignore makeline_producer_t; @@ -58,18 +51,127 @@ %ignore remove_spaces; %ignore bgcolors; +%ignore set_user_defined_prefix; +%rename (set_user_defined_prefix) py_set_user_defined_prefix; + +%ignore generate_disassembly; +%rename (generate_disassembly) py_generate_disassembly; + +%ignore tag_remove; +%rename (tag_remove) py_tag_remove; + +%ignore tag_addr; +%rename (tag_addr) py_tag_addr; + +%ignore tag_skipcodes; +%rename (tag_skipcodes) py_tag_skipcodes; + +%ignore tag_skipcode; +%rename (tag_skipcode) py_tag_skipcode; + +%ignore tag_advance; +%rename (tag_advance) py_tag_advance; + %include "lines.hpp" -%rename (generate_disassembly) py_generate_disassembly; -%rename (tag_remove) py_tag_remove; -%rename (tag_addr) py_tag_addr; -%rename (tag_skipcodes) py_tag_skipcodes; -%rename (tag_skipcode) py_tag_skipcode; -%rename (tag_advance) py_tag_advance; -%rename (generate_disassembly) py_generate_disassembly; +%{ +// +//------------------------------------------------------------------------ +static PyObject *py_get_user_defined_prefix = NULL; +static qstring py_get_user_defined_prefix_err; +static void idaapi s_py_get_user_defined_prefix( + ea_t ea, + int lnnum, + int indent, + const char *line, + char *buf, + size_t bufsize) +{ + PyObject *py_ret = PyObject_CallFunction( + py_get_user_defined_prefix, + PY_FMT64 "iis" PY_FMT64, + ea, lnnum, indent, line, bufsize); + + if ( PyW_GetError(&py_get_user_defined_prefix_err) || py_ret == NULL ) + { + msg("py_get_user_defined_prefix() error: %s\n", py_get_user_defined_prefix_err.c_str()); + PyErr_Clear(); + } + else + { + Py_ssize_t py_len; + char *py_str; + if ( PyString_AsStringAndSize(py_ret, &py_str, &py_len) != -1 ) + { + memcpy(buf, py_str, qmin(bufsize, py_len)); + if ( py_len < bufsize ) + buf[py_len] = '\0'; + } + } + Py_XDECREF(py_ret); +} +// +%} %inline %{ // + +//------------------------------------------------------------------------ +/* +# +def set_user_defined_prefix(width, callback): + """ + User-defined line-prefixes are displayed just after the autogenerated + line prefixes. In order to use them, the plugin should call the + following function to specify its width and contents. + @param width: the width of the user-defined prefix + @param callback: a get_user_defined_prefix callback to get the contents of the prefix. + Its arguments: + ea - linear address + lnnum - line number + indent - indent of the line contents (-1 means the default instruction) + indent and is used for instruction itself. see explanations for printf_line() + line - the line to be generated. the line usually contains color tags this argument + can be examined to decide whether to generated the prefix + bufsize- the maximum allowed size of the output buffer + It returns a buffer of size < bufsize + + In order to remove the callback before unloading the plugin, specify the width = 0 or the callback = None + """ + pass +# +*/ +static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb) +{ + if ( width == 0 || pycb == Py_None ) + { + // Release old callback reference + Py_XDECREF(py_get_user_defined_prefix); + + // ...and clear it + py_get_user_defined_prefix = NULL; + + // Uninstall user defind prefix + set_user_defined_prefix(0, NULL); + } + else if ( PyCallable_Check(pycb) ) + { + // Release old callback reference + Py_XDECREF(py_get_user_defined_prefix); + + // Copy new callback and hold a reference + py_get_user_defined_prefix = pycb; + Py_INCREF(py_get_user_defined_prefix); + + set_user_defined_prefix(width, s_py_get_user_defined_prefix); + } + else + { + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; +} + //------------------------------------------------------------------------- /* # diff --git a/swig/pro.i b/swig/pro.i index bd22e02..22a6edf 100644 --- a/swig/pro.i +++ b/swig/pro.i @@ -7,6 +7,23 @@ %ignore incrementer_t; %ignore reloc_info_t; // swig under mac chokes on this +%ignore qmutex_create; +%ignore qmutex_free; +%ignore qmutex_lock; +%ignore qmutex_t; +%ignore qmutex_unlock; +%ignore qsem_create; +%ignore qsem_free; +%ignore qsem_post; +%ignore qsem_wait; +%ignore qsemaphore_t; +%ignore qthread_cb_t; +%ignore qthread_create; +%ignore qthread_free; +%ignore qthread_join; +%ignore qthread_kill; +%ignore qthread_self; +%ignore qthread_t; %ignore qstrlen; %ignore qstrcmp; %ignore qstrstr;