diff --git a/examples/idapythonrc.py b/examples/idapythonrc.py index 0a037b8..0d544ad 100644 --- a/examples/idapythonrc.py +++ b/examples/idapythonrc.py @@ -2,7 +2,7 @@ # Example user initialisation script: idapythonrc.py # # Place this script to ~/.idapro/ or to -# C:\Documents and Settings\%USER%\Application Data\Hex-Rays\IDA Pro +# %APPDATA%\Hex-Rays\IDA Pro #--------------------------------------------------------------------- import idaapi diff --git a/python.cpp b/python.cpp index 44e9f6a..58cd66c 100644 --- a/python.cpp +++ b/python.cpp @@ -59,9 +59,11 @@ static bool menu_installed = false; int idcvar_to_pyvar(const idc_value_t &idc_var, PyObject **py_var); int pyvar_to_idcvar(PyObject *py_var, idc_value_t *idc_var, int *gvar_sn = NULL); PyObject *PyObject_TryGetAttrString(PyObject *py_var, const char *attr); +PyObject *PyImport_TryImportModule(const char *name); bool PyGetError(qstring *out = NULL); bool init_pywraps(); void deinit_pywraps(); +static const char S_MAIN[] = "__main__"; //-------------------------------------------------------------------------- /* This is a simple tracing code for debugging purposes. */ @@ -176,7 +178,7 @@ static void handle_python_error(char *errbuf, size_t errbufsize) /* helper function to get globals for the __main__ module */ PyObject *GetMainGlobals() { - PyObject *module = PyImport_AddModule("__main__"); + PyObject *module = PyImport_AddModule(S_MAIN); if (module == NULL) return NULL; @@ -361,41 +363,28 @@ bool idaapi IDAPython_Menu_Callback(void *ud) //-------------------------------------------------------------------------- // This function parses a name into two different components (if it applies). -// The first mode of operation: -// split_mod_attr_name("modname.attrname", mod_buf, attr_buf) +// Example: +// parse_py_modname("modname.attrname", mod_buf, attr_buf) // It splits the full name into two parts. -// -// The second mode of operation: -// split_mod_attr_name("c:\libs\x.py", file_name_buf, NULL) -// static bool parse_py_modname( const char *full_name, char *modname, - char *attrname, size_t sz) + char *attrname, + size_t sz, + const char *defmod = "idaapi") { - if (attrname == NULL) + const char *p = strchr(full_name, '.'); + if (p == NULL) { - // take the filename.ext part - qstrncpy(modname, qbasename(full_name), sz); - // take the filename part only - qsplitfile(modname, NULL, NULL); - return true; + qstrncpy(modname, defmod, sz); + qstrncpy(attrname, full_name, sz); } else { - const char *p = strchr(full_name, '.'); - if (p == NULL) - { - qstrncpy(modname, "idaapi", sz); - qstrncpy(attrname, full_name, sz); - } - else - { - qstrncpy(modname, full_name, p - full_name + 1); - qstrncpy(attrname, p + 1, sz); - } - return p != NULL; + qstrncpy(modname, full_name, p - full_name + 1); + qstrncpy(attrname, p + 1, sz); } + return p != NULL; } /* Convert return value from Python to IDC or report about an error. */ @@ -503,7 +492,7 @@ bool idaapi IDAPython_extlang_run(const char *name, } else { - module = PyImport_AddModule("__main__"); QASSERT(module != NULL); + module = PyImport_AddModule(S_MAIN); QASSERT(module != NULL); } PyObject *globals = PyModule_GetDict(module); QASSERT(globals != NULL); PyObject *func = PyDict_GetItemString(globals, funcname); @@ -548,7 +537,11 @@ bool idaapi IDAPython_extlang_compile_file(const char *script_path, } char modname[MAXSTR] = {0}; - parse_py_modname(script_path, modname, NULL, sizeof(modname)); + // take the filename.ext part + qstrncpy(modname, qbasename(script_path), sizeof(modname)); + // take the filename part only + qsplitfile(modname, NULL, NULL); + // import the module using its absolute path qstring s; s.sprnt( @@ -578,14 +571,14 @@ bool idaapi IDAPython_extlang_create_object( parse_py_modname(name, modname, clsname, MAXSTR); // Get a reference to the module - py_mod = PyImport_ImportModule(modname); + py_mod = PyImport_TryImportModule(modname); if (py_mod == NULL) { qsnprintf(errbuf, errbufsize, "Could not import module %s!", modname); break; } // Get the class reference - py_cls = PyObject_GetAttrString(py_mod, clsname); + py_cls = PyObject_TryGetAttrString(py_mod, clsname); if (py_cls == NULL) { qsnprintf(errbuf, errbufsize, "Could not find class %s!", clsname); @@ -845,9 +838,6 @@ void parse_options() add_menu_item is called too early */ static int idaapi menu_installer_cb(void *, int code, va_list) { - const char *script; - int when; - switch ( code ) { case ui_ready_to_run: diff --git a/python/idautils.py b/python/idautils.py index ed840dc..00e2087 100644 --- a/python/idautils.py +++ b/python/idautils.py @@ -30,13 +30,13 @@ def CodeRefsTo(ea, flow): Get a list of code references to 'ea' @param ea: Target address - @param flow: Follow normal code flow or not + @param flow: Follow normal code flow or not @type flow: Boolean (0/1, False/True) @return: list of references (may be empty list) Example:: - + for ref in CodeRefsTo(ScreenEA(), 1): print ref """ @@ -51,13 +51,13 @@ def CodeRefsFrom(ea, flow): Get a list of code references from 'ea' @param ea: Target address - @param flow: Follow normal code flow or not + @param flow: Follow normal code flow or not @type flow: Boolean (0/1, False/True) @return: list of references (may be empty list) Example:: - + for ref in CodeRefsFrom(ScreenEA(), 1): print ref """ @@ -76,7 +76,7 @@ def DataRefsTo(ea): @return: list of references (may be empty list) Example:: - + for ref in DataRefsTo(ScreenEA(), 1): print ref """ @@ -92,7 +92,7 @@ def DataRefsFrom(ea): @return: list of references (may be empty list) Example:: - + for ref in DataRefsFrom(ScreenEA(), 1): print ref """ @@ -135,9 +135,9 @@ def _copy_xref(xref): def XrefsFrom(ea, flags=0): - """ + """ Return all references from address 'ea' - + @param ea: Reference address @param flags: any of idaapi.XREF_* flags @@ -156,7 +156,7 @@ def XrefsFrom(ea, flags=0): def XrefsTo(ea, flags=0): """ Return all references to address 'ea' - + @param ea: Reference address @param flags: any of idaapi.XREF_* flags @@ -229,7 +229,7 @@ def Chunks(start): Get a list of function chunks @param start: address of the function - + @return: list of funcion chunks (tuples of the form (start_ea, end_ea)) belonging to the function """ @@ -274,7 +274,7 @@ def FuncItems(start): def DecodeInstruction(ea): """ Decodes an instruction and returns an insn_t like class - + @param ea: address to decode @return: None or an insn_t like structure @@ -380,7 +380,7 @@ def GetInputFileMD5(): class Strings(object): """ Returns the string list. - + Example: s = Strings() @@ -414,7 +414,7 @@ class Strings(object): def clear_cache(self): """Clears the strings list cache""" self.refresh(0, 0) # when ea1=ea2 the kernel will clear the cache - + def __init__(self, default_setup=True): if default_setup: self.setup() @@ -471,7 +471,7 @@ def _Assemble(ea, line): return (False, "Assembler failed: " + line) ea += len(buf) ret.append(buf) - + if len(ret) == 1: ret = ret[0] return (True, ret) diff --git a/swig/area.i b/swig/area.i index b7e76ef..38f9ee2 100644 --- a/swig/area.i +++ b/swig/area.i @@ -39,7 +39,6 @@ %ignore areacb_t::find_next_gap; %ignore areacb_t::move_areas; - %ignore areacb_t::for_all_areas; %include "area.hpp" diff --git a/swig/idaapi.i b/swig/idaapi.i index 4c1c4ac..f04f734 100644 --- a/swig/idaapi.i +++ b/swig/idaapi.i @@ -189,6 +189,18 @@ PyObject *PyObject_TryGetAttrString(PyObject *py_var, const char *attr) return PyObject_GetAttrString(py_var, attr); } +//------------------------------------------------------------------------ +// Tries to import a module and clears the exception on failure +PyObject *PyImport_TryImportModule(const char *name) +{ + PyObject *result = PyImport_ImportModule(name); + if (result != NULL) + return result; + if (PyErr_Occurred()) + PyErr_Clear(); + return NULL; +} + //------------------------------------------------------------------------- // Converts a Python number into an IDC value (32 or 64bits) // The function will first try to convert the number into a 32bit value