mirror of
https://github.com/cemu-project/idapython.git
synced 2024-12-26 17:51:54 +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
|
||||
#
|
||||
# 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
|
||||
|
||||
|
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 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:
|
||||
|
@ -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)
|
||||
|
@ -39,7 +39,6 @@
|
||||
%ignore areacb_t::find_next_gap;
|
||||
|
||||
%ignore areacb_t::move_areas;
|
||||
|
||||
%ignore areacb_t::for_all_areas;
|
||||
|
||||
%include "area.hpp"
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user