bugfix: IDAPython_extlang_create_object may cause exceptions to be reported to the running Python script if called with an invalid object name

minor changes: removed trailing spaces from files
This commit is contained in:
elias.bachaalany 2010-02-12 13:16:37 +00:00
parent e056f5670f
commit 06e8cad773
5 changed files with 50 additions and 49 deletions

View File

@ -2,7 +2,7 @@
# Example user initialisation script: idapythonrc.py # Example user initialisation script: idapythonrc.py
# #
# Place this script to ~/.idapro/ or to # 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 import idaapi

View File

@ -59,9 +59,11 @@ static bool menu_installed = false;
int idcvar_to_pyvar(const idc_value_t &idc_var, PyObject **py_var); 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); 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 *PyObject_TryGetAttrString(PyObject *py_var, const char *attr);
PyObject *PyImport_TryImportModule(const char *name);
bool PyGetError(qstring *out = NULL); bool PyGetError(qstring *out = NULL);
bool init_pywraps(); bool init_pywraps();
void deinit_pywraps(); void deinit_pywraps();
static const char S_MAIN[] = "__main__";
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
/* This is a simple tracing code for debugging purposes. */ /* 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 */ /* helper function to get globals for the __main__ module */
PyObject *GetMainGlobals() PyObject *GetMainGlobals()
{ {
PyObject *module = PyImport_AddModule("__main__"); PyObject *module = PyImport_AddModule(S_MAIN);
if (module == NULL) if (module == NULL)
return 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). // This function parses a name into two different components (if it applies).
// The first mode of operation: // Example:
// split_mod_attr_name("modname.attrname", mod_buf, attr_buf) // parse_py_modname("modname.attrname", mod_buf, attr_buf)
// It splits the full name into two parts. // 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( static bool parse_py_modname(
const char *full_name, const char *full_name,
char *modname, 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, defmod, sz);
qstrncpy(modname, qbasename(full_name), sz); qstrncpy(attrname, full_name, sz);
// take the filename part only
qsplitfile(modname, NULL, NULL);
return true;
} }
else else
{ {
const char *p = strchr(full_name, '.'); qstrncpy(modname, full_name, p - full_name + 1);
if (p == NULL) qstrncpy(attrname, p + 1, sz);
{
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;
} }
return p != NULL;
} }
/* Convert return value from Python to IDC or report about an error. */ /* 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 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 *globals = PyModule_GetDict(module); QASSERT(globals != NULL);
PyObject *func = PyDict_GetItemString(globals, funcname); PyObject *func = PyDict_GetItemString(globals, funcname);
@ -548,7 +537,11 @@ bool idaapi IDAPython_extlang_compile_file(const char *script_path,
} }
char modname[MAXSTR] = {0}; 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 // import the module using its absolute path
qstring s; qstring s;
s.sprnt( s.sprnt(
@ -578,14 +571,14 @@ bool idaapi IDAPython_extlang_create_object(
parse_py_modname(name, modname, clsname, MAXSTR); parse_py_modname(name, modname, clsname, MAXSTR);
// Get a reference to the module // Get a reference to the module
py_mod = PyImport_ImportModule(modname); py_mod = PyImport_TryImportModule(modname);
if (py_mod == NULL) if (py_mod == NULL)
{ {
qsnprintf(errbuf, errbufsize, "Could not import module %s!", modname); qsnprintf(errbuf, errbufsize, "Could not import module %s!", modname);
break; break;
} }
// Get the class reference // Get the class reference
py_cls = PyObject_GetAttrString(py_mod, clsname); py_cls = PyObject_TryGetAttrString(py_mod, clsname);
if (py_cls == NULL) if (py_cls == NULL)
{ {
qsnprintf(errbuf, errbufsize, "Could not find class %s!", clsname); qsnprintf(errbuf, errbufsize, "Could not find class %s!", clsname);
@ -845,9 +838,6 @@ void parse_options()
add_menu_item is called too early */ add_menu_item is called too early */
static int idaapi menu_installer_cb(void *, int code, va_list) static int idaapi menu_installer_cb(void *, int code, va_list)
{ {
const char *script;
int when;
switch ( code ) switch ( code )
{ {
case ui_ready_to_run: case ui_ready_to_run:

View File

@ -30,13 +30,13 @@ def CodeRefsTo(ea, flow):
Get a list of code references to 'ea' Get a list of code references to 'ea'
@param ea: Target address @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) @type flow: Boolean (0/1, False/True)
@return: list of references (may be empty list) @return: list of references (may be empty list)
Example:: Example::
for ref in CodeRefsTo(ScreenEA(), 1): for ref in CodeRefsTo(ScreenEA(), 1):
print ref print ref
""" """
@ -51,13 +51,13 @@ def CodeRefsFrom(ea, flow):
Get a list of code references from 'ea' Get a list of code references from 'ea'
@param ea: Target address @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) @type flow: Boolean (0/1, False/True)
@return: list of references (may be empty list) @return: list of references (may be empty list)
Example:: Example::
for ref in CodeRefsFrom(ScreenEA(), 1): for ref in CodeRefsFrom(ScreenEA(), 1):
print ref print ref
""" """
@ -76,7 +76,7 @@ def DataRefsTo(ea):
@return: list of references (may be empty list) @return: list of references (may be empty list)
Example:: Example::
for ref in DataRefsTo(ScreenEA(), 1): for ref in DataRefsTo(ScreenEA(), 1):
print ref print ref
""" """
@ -92,7 +92,7 @@ def DataRefsFrom(ea):
@return: list of references (may be empty list) @return: list of references (may be empty list)
Example:: Example::
for ref in DataRefsFrom(ScreenEA(), 1): for ref in DataRefsFrom(ScreenEA(), 1):
print ref print ref
""" """
@ -135,9 +135,9 @@ def _copy_xref(xref):
def XrefsFrom(ea, flags=0): def XrefsFrom(ea, flags=0):
""" """
Return all references from address 'ea' Return all references from address 'ea'
@param ea: Reference address @param ea: Reference address
@param flags: any of idaapi.XREF_* flags @param flags: any of idaapi.XREF_* flags
@ -156,7 +156,7 @@ def XrefsFrom(ea, flags=0):
def XrefsTo(ea, flags=0): def XrefsTo(ea, flags=0):
""" """
Return all references to address 'ea' Return all references to address 'ea'
@param ea: Reference address @param ea: Reference address
@param flags: any of idaapi.XREF_* flags @param flags: any of idaapi.XREF_* flags
@ -229,7 +229,7 @@ def Chunks(start):
Get a list of function chunks Get a list of function chunks
@param start: address of the function @param start: address of the function
@return: list of funcion chunks (tuples of the form (start_ea, end_ea)) @return: list of funcion chunks (tuples of the form (start_ea, end_ea))
belonging to the function belonging to the function
""" """
@ -274,7 +274,7 @@ def FuncItems(start):
def DecodeInstruction(ea): def DecodeInstruction(ea):
""" """
Decodes an instruction and returns an insn_t like class Decodes an instruction and returns an insn_t like class
@param ea: address to decode @param ea: address to decode
@return: None or an insn_t like structure @return: None or an insn_t like structure
@ -380,7 +380,7 @@ def GetInputFileMD5():
class Strings(object): class Strings(object):
""" """
Returns the string list. Returns the string list.
Example: Example:
s = Strings() s = Strings()
@ -414,7 +414,7 @@ class Strings(object):
def clear_cache(self): def clear_cache(self):
"""Clears the strings list cache""" """Clears the strings list cache"""
self.refresh(0, 0) # when ea1=ea2 the kernel will clear the cache self.refresh(0, 0) # when ea1=ea2 the kernel will clear the cache
def __init__(self, default_setup=True): def __init__(self, default_setup=True):
if default_setup: if default_setup:
self.setup() self.setup()
@ -471,7 +471,7 @@ def _Assemble(ea, line):
return (False, "Assembler failed: " + line) return (False, "Assembler failed: " + line)
ea += len(buf) ea += len(buf)
ret.append(buf) ret.append(buf)
if len(ret) == 1: if len(ret) == 1:
ret = ret[0] ret = ret[0]
return (True, ret) return (True, ret)

View File

@ -39,7 +39,6 @@
%ignore areacb_t::find_next_gap; %ignore areacb_t::find_next_gap;
%ignore areacb_t::move_areas; %ignore areacb_t::move_areas;
%ignore areacb_t::for_all_areas; %ignore areacb_t::for_all_areas;
%include "area.hpp" %include "area.hpp"

View File

@ -189,6 +189,18 @@ PyObject *PyObject_TryGetAttrString(PyObject *py_var, const char *attr)
return PyObject_GetAttrString(py_var, 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) // Converts a Python number into an IDC value (32 or 64bits)
// The function will first try to convert the number into a 32bit value // The function will first try to convert the number into a 32bit value