mirror of
https://github.com/cemu-project/idapython.git
synced 2024-11-28 03:54:18 +01:00
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:
parent
e056f5670f
commit
06e8cad773
@ -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
|
||||||
|
|
||||||
|
56
python.cpp
56
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 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:
|
||||||
|
@ -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)
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user