- IDA Pro 6.3 support

- The Functions() generator function now accepts function tail start parameter
- Added into idc.py: DbgRead/DbgWrite/SetTargetAssembler and stack pointer related functions
- Wrapped more type info related functions
This commit is contained in:
elias.bachaalany 2012-06-24 20:49:11 +00:00
parent 4d21b10dc4
commit 69d5c83d28
31 changed files with 908 additions and 586 deletions

View File

@ -1,5 +1,11 @@
Please see http://code.google.com/p/idapython/source/list for a detailed list of changes.
Changes from version 1.5.4 to 1.5.5
------------------------------------
- IDA Pro 6.3 support
- The Functions() generator function now accepts function tail start parameter
- Added into idc.py: DbgRead/DbgWrite/SetTargetAssembler and stack pointer related functions
- Wrapped more type info related functions
Changes from version 1.5.3 to 1.5.4
------------------------------------

View File

@ -24,7 +24,7 @@ from distutils import sysconfig
VERBOSE = True
IDA_MAJOR_VERSION = 6
IDA_MINOR_VERSION = 2
IDA_MINOR_VERSION = 3
if 'IDA' in os.environ:
IDA_SDK = os.environ['IDA']
@ -36,7 +36,7 @@ else:
# IDAPython version
VERSION_MAJOR = 1
VERSION_MINOR = 5
VERSION_PATCH = 4
VERSION_PATCH = 5
# Determine Python version
PYTHON_MAJOR_VERSION = int(platform.python_version()[0])
@ -319,10 +319,11 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
builder = GCCBuilder()
platform_macros = [ "__LINUX__" ]
python_libpath = os.path.join(sysconfig.EXEC_PREFIX, "lib")
python_library = "-lpython%d.%d" % (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION)
python_library = "-Bdynamic -lpython%d.%d" % (PYTHON_MAJOR_VERSION, PYTHON_MINOR_VERSION)
ida_libpath = os.path.join(idasdkdir, "lib", ea64 and "x86_linux_gcc_64" or "x86_linux_gcc_32")
ida_lib = ""
extra_link_parameters = ""
extra_link_parameters = " -s"
builder.compiler_parameters += " -O2"
# Platform-specific settings for the Windows build
elif platform == "win32":
builder = MSVCBuilder()
@ -333,6 +334,7 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
ida_lib = "ida.lib"
SWIG_OPTIONS += " -D__NT__ "
extra_link_parameters = ""
builder.compiler_parameters += " -Ox"
# Platform-specific settings for the Mac OS X build
elif platform == "macosx":
builder = GCCBuilder()
@ -342,7 +344,8 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
python_library = "-framework Python"
ida_libpath = os.path.join(idasdkdir, "lib", ea64 and "x86_mac_gcc_64" or "x86_mac_gcc_32")
ida_lib = ea64 and "-lida64" or "-lida"
extra_link_parameters = ""
extra_link_parameters = " -s"
builder.compiler_parameters += " -O3"
assert builder, "Unknown platform! No idea how to build here..."
@ -350,6 +353,8 @@ def build_plugin(platform, idasdkdir, plugin_name, ea64):
if ea64:
platform_macros.append("__EA64__")
platform_macros.append("NDEBUG")
if not '--no-early-load' in sys.argv:
platform_macros.append("PLUGINFIX")

View File

@ -1,16 +1,16 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to extend IDC from Python
# (c) Hex-Rays
#
from idaapi import set_idc_func_ex
#<pycode(ex_expr)>
def py_power(n, e):
return n ** e
ok = set_idc_func_ex("pow", py_power, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if ok:
print("Now the pow() will be present IDC!")
else:
print("Failed to register pow() IDC function")
#</pycode(ex_expr)>
# -----------------------------------------------------------------------
# This is an example illustrating how to extend IDC from Python
# (c) Hex-Rays
#
from idaapi import set_idc_func_ex
#<pycode(ex_expr)>
def py_power(n, e):
return n ** e
ok = set_idc_func_ex("pow", py_power, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if ok:
print("Now the pow() will be present IDC!")
else:
print("Failed to register pow() IDC function")
#</pycode(ex_expr)>

View File

@ -8,3 +8,7 @@ REMOVE_CWD_SYS_PATH = 0
// Script timeout (in seconds)
// (A value of 0 disables the timeout)
SCRIPT_TIMEOUT = 3
// Use a local Python library
// If enabled, the "lib" directory tree with modules must be present in IDADIR/python
USE_LOCAL_PYTHON = 0

View File

@ -125,6 +125,7 @@ static int script_timeout = 2;
static bool g_ui_ready = false;
static bool g_alert_auto_scripts = true;
static bool g_remove_cwd_sys_path = false;
static bool g_use_local_python = false;
static void end_execution();
static void begin_execution();
@ -369,6 +370,11 @@ const char *idaapi set_python_options(
g_remove_cwd_sys_path = *(uval_t *)value != 0;
break;
}
else if ( qstrcmp(keyword, "USE_LOCAL_PYTHON") == 0 )
{
g_use_local_python = *(uval_t *)value != 0;
break;
}
}
return IDPOPT_BADKEY;
} while (false);
@ -466,7 +472,10 @@ static bool IDAPython_ExecFile(const char *FileName, char *errbuf, size_t errbuf
{
PyObject *py_execscript = get_idaapi_attr(S_IDAAPI_EXECSCRIPT);
if ( py_execscript == NULL )
{
qstrncpy(errbuf, "Could not find idaapi." S_IDAAPI_EXECSCRIPT " ?!", errbufsz);
return false;
}
char script[MAXSTR];
qstrncpy(script, FileName, sizeof(script));
@ -1288,6 +1297,25 @@ static void sanitize_path()
PySys_SetPath(newpath.begin());
}
//-------------------------------------------------------------------------
// we have to do it ourselves because Python 2.7 calls exit() if importing site fails
static bool initsite(void)
{
PyObject *m;
m = PyImport_ImportModule("site");
if (m == NULL)
{
PyErr_Print();
Py_Finalize();
return false;
}
else {
Py_DECREF(m);
}
return true;
}
//-------------------------------------------------------------------------
// Initialize the Python environment
bool IDAPython_Init(void)
@ -1306,12 +1334,11 @@ bool IDAPython_Init(void)
char tmp[QMAXPATH];
#ifdef __LINUX__
// Export symbols from libpython to resolve imported module deps
qsnprintf(tmp, sizeof(tmp), "libpython%d.%d.so.1",
PY_MAJOR_VERSION,
PY_MINOR_VERSION);
if ( !dlopen(tmp, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
// use the standard soname: libpython2.7.so.1.0
#define PYLIB "libpython" QSTRINGIZE(PY_MAJOR_VERSION) "." QSTRINGIZE(PY_MINOR_VERSION) ".so.1.0"
if ( !dlopen(PYLIB, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
{
warning("IDAPython: %s", dlerror());
warning("IDAPython dlopen(" PYLIB ") error: %s", dlerror());
return false;
}
#endif
@ -1350,16 +1377,31 @@ bool IDAPython_Init(void)
}
}
if ( g_use_local_python )
Py_SetPythonHome(g_idapython_dir);
// don't import "site" right now
Py_NoSiteFlag = 1;
// Start the interpreter
Py_Initialize();
if ( !Py_IsInitialized() )
{
warning("IDAPython: Py_Initialize() failed");
return false;
}
// remove current directory
sanitize_path();
// import "site"
if ( !g_use_local_python && !initsite() )
{
warning("IDAPython: importing \"site\" failed");
return false;
}
// Enable multi-threading support
if ( !PyEval_ThreadsInitialized() )
PyEval_InitThreads();
@ -1416,7 +1458,7 @@ bool IDAPython_Init(void)
parse_plugin_options();
// Register a RunPythonStatement() function for IDC
set_idc_func(S_IDC_RUNPYTHON_STATEMENT, idc_runpythonstatement, idc_runpythonstatement_args);
set_idc_func_ex(S_IDC_RUNPYTHON_STATEMENT, idc_runpythonstatement, idc_runpythonstatement_args, 0);
// A script specified on the command line is run
if ( g_run_when == run_on_init )
@ -1463,7 +1505,7 @@ void IDAPython_Term(void)
deinit_pywraps();
// Uninstall IDC function
set_idc_func(S_IDC_RUNPYTHON_STATEMENT, NULL, NULL);
set_idc_func_ex(S_IDC_RUNPYTHON_STATEMENT, NULL, NULL, 0);
// Shut the interpreter down
Py_Finalize();

View File

@ -217,9 +217,14 @@ def Functions(start=None, end=None):
if not start: start = idaapi.cvar.inf.minEA
if not end: end = idaapi.cvar.inf.maxEA
func = idaapi.get_func(start)
if not func:
func = idaapi.get_next_func(start)
# find first function head chunk in the range
chunk = idaapi.get_fchunk(start)
if not chunk:
chunk = idaapi.get_next_fchunk(start)
while chunk and chunk.startEA < end and (chunk.flags & idaapi.FUNC_TAIL) != 0:
chunk = idaapi.get_next_fchunk(chunk.startEA)
func = chunk
while func and func.startEA < end:
startea = func.startEA
yield startea

View File

@ -1772,6 +1772,35 @@ def DbgQword(ea):
return __DbgValue(ea, 8)
def DbgRead(ea, size):
"""
Read from debugger memory.
@param ea: linear address
@param size: size of data to read
@return: data as a string. If failed, If failed, throws an exception
Thread-safe function (may be called only from the main thread and debthread)
"""
return idaapi.dbg_read_memory(ea, size)
def DbgWrite(ea, data):
"""
Write to debugger memory.
@param ea: linear address
@param data: string to write
@return: number of written bytes (-1 - network/debugger error)
Thread-safe function (may be called only from the main thread and debthread)
"""
if not idaapi.dbg_can_query():
return -1
elif len(data) > 0:
return idaapi.dbg_write_memory(ea, data)
def GetOriginalByte(ea):
"""
Get original value of program byte
@ -2867,6 +2896,16 @@ def SetProcessorType (processor, level):
"""
return idaapi.set_processor_type(processor, level)
def SetTargetAssembler(asmidx):
"""
Set target assembler
@param asmidx: index of the target assembler in the array of
assemblers for the current processor.
@return: 1-ok, 0-failed
"""
return idaapi.set_target_assembler(asmidx)
SETPROC_COMPAT = idaapi.SETPROC_COMPAT
SETPROC_ALL = idaapi.SETPROC_ALL
SETPROC_USER = idaapi.SETPROC_USER
@ -4340,6 +4379,75 @@ def SetSpDiff(ea, delta):
return idaapi.add_user_stkpnt(ea, delta)
# ----------------------------------------------------------------------------
# S T A C K
# ----------------------------------------------------------------------------
def AddAutoStkPnt2(func_ea, ea, delta):
"""
Add automatical SP register change point
@param func_ea: function start
@param ea: linear address where SP changes
usually this is the end of the instruction which
modifies the stack pointer (cmd.ea+cmd.size)
@param delta: difference between old and new values of SP
@return: 1-ok, 0-failed
"""
pfn = idaapi.get_func(func_ea)
if not pfn:
return 0
return idaapi.add_auto_stkpnt2(pfn, ea, delta)
def AddUserStkPnt(ea, delta):
"""
Add user-defined SP register change point.
@param ea: linear address where SP changes
@param delta: difference between old and new values of SP
@return: 1-ok, 0-failed
"""
return idaapi.add_user_stkpnt(ea, delta);
def DelStkPnt(func_ea, ea):
"""
Delete SP register change point
@param func_ea: function start
@param ea: linear address
@return: 1-ok, 0-failed
"""
pfn = idaapi.get_func(func_ea)
if not pfn:
return 0
return idaapi.del_stkpnt(pfn, ea)
def GetMinSpd(func_ea):
"""
Return the address with the minimal spd (stack pointer delta)
If there are no SP change points, then return BADADDR.
@param func_ea: function start
@return: BADDADDR - no such function
"""
pfn = idaapi.get_func(func_ea)
if not pfn:
return BADADDR
return idaapi.get_min_spd_ea(pfn)
def RecalcSpd(cur_ea):
"""
Recalculate SP delta for an instruction that stops execution.
@param cur_ea: linear address of the current instruction
@return: 1 - new stkpnt is added, 0 - nothing is changed
"""
return idaapi.recalc_spd(cur_ea)
# ----------------------------------------------------------------------------
# E N T R Y P O I N T S
# ----------------------------------------------------------------------------
@ -4458,9 +4566,9 @@ def GetFixupTgtType(ea):
@return: -1 - no fixup at the specified address
otherwise returns fixup target type:
"""
fd = idaapi.get_fixup(ea)
fd = idaapi.fixup_data_t()
if not fd:
if not idaapi.get_fixup(ea, fd):
return -1
return fd.type
@ -4504,8 +4612,12 @@ def GetFixupTgtSel(ea):
@return: -1 - no fixup at the specified address
otherwise returns fixup target selector
"""
fd = idaapi.get_fixup(ea)
return -1 if not fd else fd.sel
fd = idaapi.fixup_data_t()
if not idaapi.get_fixup(ea, fd):
return -1
return fd.sel
def GetFixupTgtOff(ea):
@ -4517,8 +4629,12 @@ def GetFixupTgtOff(ea):
@return: -1 - no fixup at the specified address
otherwise returns fixup target offset
"""
fd = idaapi.get_fixup(ea)
return -1 if not fd else fd.off
fd = idaapi.fixup_data_t()
if not idaapi.get_fixup(ea, fd):
return -1
return fd.off
def GetFixupTgtDispl(ea):
@ -4530,8 +4646,12 @@ def GetFixupTgtDispl(ea):
@return: -1 - no fixup at the specified address
otherwise returns fixup target displacement
"""
fd = idaapi.get_fixup(ea)
return -1 if not fd else fd.displacement
fd = idaapi.fixup_data_t()
if not idaapi.get_fixup(ea, fd):
return -1
return fd.displacement
def SetFixup(ea, fixuptype, targetsel, targetoff, displ):
@ -4791,6 +4911,30 @@ def GetMemberQty(sid):
return -1 if not s else s.memqty
def GetMemberId(sid, member_offset):
"""
@param sid: structure type ID
@param member_offset:. The offset can be
any offset in the member. For example,
is a member is 4 bytes long and starts
at offset 2, then 2,3,4,5 denote
the same structure member.
@return: -1 if bad structure type ID is passed or there is
no member at the specified offset.
otherwise returns the member id.
"""
s = idaapi.get_struc(sid)
if not s:
return -1
m = idaapi.get_member(s, member_offset)
if not m:
return -1
return m.id
def GetStrucPrevOff(sid, offset):
"""
Get previous offset in a structure
@ -6633,6 +6777,15 @@ def SizeOf(typestr):
"""
return idaapi.get_type_size0(idaapi.cvar.idati, typestr)
def GetTinfo(ea):
"""
Get type information of function/variable as 'typeinfo' object
@param ea: the address of the object
@return: None on failure, or (type, fields) tuple.
"""
return idaapi.idc_get_type_raw(ea)
def GuessType(ea):
"""
Guess type of function/variable
@ -6652,11 +6805,16 @@ def SetType(ea, newtype):
@param newtype: the type string in C declaration form.
Must contain the closing ';'
if specified as an empty string, then the
assciated with 'ea' will be deleted
item associated with 'ea' will be deleted.
@return: 1-ok, 0-failed.
"""
return idaapi.apply_cdecl2(idaapi.cvar.idati, ea, newtype)
if newtype is not '':
return idaapi.apply_cdecl2(idaapi.cvar.idati, ea, newtype)
if idaapi.has_ti(ea):
idaapi.del_tinfo(ea)
return True
return False
def ParseType(inputtype, flags):
"""
@ -7680,6 +7838,29 @@ def SetBptAttr(address, bptattr, value):
idaapi.update_bpt(bpt)
return True
def SetBptCndEx(ea, cnd, is_lowcnd):
"""
Set breakpoint condition
@param ea: any address in the breakpoint range
@param cnd: breakpoint condition
@param is_lowcnd: 0 - regular condition, 1 - low level condition
@return: success
"""
bpt = idaapi.bpt_t()
if not idaapi.get_bpt(ea, bpt):
return False
bpt.condition = cnd
if not is_lowcnd:
bpt.flags |= BPT_LOWCND
else:
bpt.flags &= ~BPT_LOWCND
return idaapi.update_bpt(bpt)
def SetBptCnd(ea, cnd):
"""
@ -7690,14 +7871,7 @@ def SetBptCnd(ea, cnd):
@return: success
"""
bpt = idaapi.bpt_t()
if not idaapi.get_bpt(ea, bpt):
return False
bpt.condition = cnd
return idaapi.update_bpt(bpt)
return SetBptCndEx(ea, cnd, 0)
def AddBptEx(ea, size, bpttype):

View File

@ -68,6 +68,8 @@ def print_banner():
# -----------------------------------------------------------------------
# Redirect stderr and stdout to the IDA message window
_orig_stdout = sys.stdout;
_orig_stderr = sys.stderr;
sys.stdout = sys.stderr = IDAPythonStdOut()
# Assign a default sys.argv

View File

@ -3,7 +3,7 @@
rem Please use the same tag for the same .i file
rem That means if many insertions are going to happen in one given .i file then don't use more than code marking tag
set PY=c:\python26\python.exe
set PY=c:\python27\python.exe
echo.
echo -------- DEPLOY started --------------------------------------------------

View File

@ -168,5 +168,5 @@ plugin_t PLUGIN =
"", // multiline help about the plugin
"pywraps", // the preferred short name of the plugin
"Alt-0" // the preferred hotkey to run the plugin
"" // the preferred hotkey to run the plugin
};

View File

@ -571,6 +571,14 @@ def test_gpa():
return 1
# -----------------------------------------------------------------------
def test_loaddll():
h = loadlib("twain_32.dll")
if h == 0:
print "failed to load twain32 library!"
return -1
return 1
# -----------------------------------------------------------------------
# Packs a simple structure (into the database) and unpacks it back using the idaapi methods
def test_pck_idb_raw():
@ -884,7 +892,7 @@ def test_exec_throw():
# all the tests that take zero parameters
tests0 = (test_gpa, test_pck_idb_raw, test_pck_bv_raw,
test_unpack_raw, test_pck_idb, test_pck_bv,
test_enum_files, test2, test_exec_throw)
test_enum_files, test2, test_exec_throw, test_loaddll)
test_log = None # test log file
# -----------------------------------------------------------------------

View File

@ -152,6 +152,16 @@ static PyObject *py_get_many_bytes(ea_t ea, unsigned int size)
//---------------------------------------------------------------------------
/*
#<pydoc>
# Conversion options for get_ascii_contents2():
ACFOPT_ASCII = 0x00000000 # convert Unicode strings to ASCII
ACFOPT_UTF16 = 0x00000001 # return UTF-16 (aka wide-char) array for Unicode strings
# ignored for non-Unicode strings
ACFOPT_UTF8 = 0x00000002 # convert Unicode strings to UTF-8
# ignored for non-Unicode strings
ACFOPT_CONVMASK = 0x0000000F
ACFOPT_ESCAPE = 0x00000010 # for ACFOPT_ASCII, convert non-printable
# characters to C escapes (\n, \xNN, \uNNNN)
def get_ascii_contents2(ea, len, type, flags = ACFOPT_ASCII):
"""
Get contents of ascii string

View File

@ -562,7 +562,7 @@ private:
void show()
{
open_tform(form, FORM_MDI|FORM_TAB|FORM_MENU);
open_tform(form, FORM_TAB|FORM_MENU);
}
static py_graph_t *extract_this(PyObject *self)
@ -666,7 +666,7 @@ private:
qsnprintf(grnode, sizeof(grnode), "$ pygraph %s", title);
id.create(grnode);
gv = create_graph_viewer(form, id, s_callback, this, 0);
open_tform(form, FORM_MDI | FORM_TAB | FORM_MENU);
open_tform(form, FORM_TAB | FORM_MENU);
if ( gv != NULL )
viewer_fit_window(gv);
}

View File

@ -619,7 +619,7 @@ def parse_command_line(cmdline):
static PyObject *py_parse_command_line(const char *cmdline)
{
qstrvec_t args;
if ( parse_command_line(cmdline, &args) == 0 )
if ( parse_command_line2(cmdline, &args, NULL) == 0 )
Py_RETURN_NONE;
PyObject *py_list = PyList_New(args.size());
@ -729,8 +729,8 @@ static PyObject *qstrvec_t_addressof(PyObject *self, size_t idx)
static bool qstrvec_t_set(
PyObject *self,
size_t idx,
PyObject *self,
size_t idx,
const char *s)
{
qstrvec_t *sv = qstrvec_t_get_clink(self);
@ -741,7 +741,7 @@ static bool qstrvec_t_set(
}
static bool qstrvec_t_from_list(
PyObject *self,
PyObject *self,
PyObject *py_list)
{
qstrvec_t *sv = qstrvec_t_get_clink(self);
@ -781,13 +781,13 @@ static bool qstrvec_t_clear(PyObject *self, bool qclear)
sv->qclear();
else
sv->clear();
return true;
}
static bool qstrvec_t_insert(
PyObject *self,
size_t idx,
PyObject *self,
size_t idx,
const char *s)
{
qstrvec_t *sv = qstrvec_t_get_clink(self);
@ -802,7 +802,7 @@ static bool qstrvec_t_remove(PyObject *self, size_t idx)
qstrvec_t *sv = qstrvec_t_get_clink(self);
if ( sv == NULL || idx >= sv->size() )
return false;
sv->erase(sv->begin()+idx);
return true;
}

View File

@ -434,7 +434,7 @@ class IDP_Hooks(object):
- cmd.itype must be set >= idaapi.CUSTOM_CMD_ITYPE
- cmd.size must be set to the instruction length
@return: Boolean
@return: Boolean
- False if the instruction is not recognized
- True if the instruction was decoded. idaapi.cmd should be filled in that case.
"""

View File

@ -494,7 +494,7 @@ in this case.
This flag can be used to delay the code execution
until the next UI loop run even from the main thread"""
def execute_sync(callable, reqf)
def execute_sync(callable, reqf):
"""
Executes a function in the context of the main thread.
If the current thread not the main thread, then the call is queued and
@ -567,7 +567,7 @@ static int py_execute_sync(PyObject *py_callable, int reqf)
/*
#<pydoc>
def execute_ui_requests(callable_list)
def execute_ui_requests(callable_list):
"""
Inserts a list of callables into the UI message processing queue.
When the UI is ready it will call one callable.
@ -760,7 +760,11 @@ class UI_Hooks(object):
IDA is terminated and the database is already closed.
The UI may close its windows in this callback.
"""
pass
# if the user forgot to call unhook, do it for him
self.unhook()
def __term__(self):
self.term()
#</pydoc>
*/
@ -769,6 +773,7 @@ class UI_Hooks
public:
virtual ~UI_Hooks()
{
unhook();
}
bool hook()

View File

@ -24,10 +24,10 @@ private:
PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallMethod(
_this->py_obj,
(char *)S_ON_CREATE, "O",
(char *)S_ON_CREATE, "O",
PyCObject_FromVoidPtr(form, NULL));
PYW_GIL_RELEASE;
PyW_ShowCbErr(S_ON_CREATE);
Py_XDECREF(py_result);
}
@ -40,10 +40,10 @@ private:
PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallMethod(
_this->py_obj,
(char *)S_ON_CLOSE, "O",
(char *)S_ON_CLOSE, "O",
PyCObject_FromVoidPtr(form, NULL));
PYW_GIL_RELEASE;
PyW_ShowCbErr(S_ON_CLOSE);
Py_XDECREF(py_result);
@ -57,7 +57,7 @@ private:
{
unhook_from_notification_point(HT_UI, s_callback, this);
form = NULL;
// Call DECREF at last, since it may trigger __del__
Py_XDECREF(py_obj);
}
@ -69,7 +69,7 @@ public:
bool show(
PyObject *obj,
const char *caption,
const char *caption,
int options)
{
// Already displayed?
@ -91,7 +91,7 @@ public:
form = create_tform(caption, NULL);
if ( form == NULL )
return false;
if ( !hook_to_notification_point(HT_UI, s_callback, this) )
{
form = NULL;
@ -119,7 +119,7 @@ public:
{
return PyCObject_FromVoidPtr(new plgform_t(), destroy);
}
static void destroy(void *obj)
{
delete (plgform_t *)obj;
@ -137,9 +137,9 @@ static PyObject *plgform_new()
static bool plgform_show(
PyObject *py_link,
PyObject *py_obj,
const char *caption,
int options = FORM_MDI|FORM_TAB|FORM_MENU|FORM_RESTORE)
PyObject *py_obj,
const char *caption,
int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
{
DECL_PLGFORM;
return plgform->show(py_obj, caption, options);

View File

@ -9,7 +9,7 @@ class PluginForm(object):
"""
FORM_MDI = 0x01
"""start by default as MDI"""
"""start by default as MDI (obsolete)"""
FORM_TAB = 0x02
"""attached by default to a tab"""
FORM_RESTORE = 0x04
@ -38,7 +38,7 @@ class PluginForm(object):
@param caption: The form caption
@param options: One of PluginForm.FORM_ constants
"""
options |= PluginForm.FORM_MDI|PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
options |= PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
return _idaapi.plgform_show(self.__clink__, self, caption, options)

View File

@ -101,12 +101,12 @@ PyObject *py_unpack_object_from_idb(
p_list *fields = (p_list *) PyString_AsString(py_fields);
idc_value_t idc_obj;
error_t err = unpack_object_from_idb(
&idc_obj,
ti,
type,
fields,
ea,
NULL,
&idc_obj,
ti,
type,
fields,
ea,
NULL,
pio_flags);
// Unpacking failed?
@ -116,7 +116,7 @@ PyObject *py_unpack_object_from_idb(
// Convert
PyObject *py_ret(NULL);
err = idcvar_to_pyvar(idc_obj, &py_ret);
// Conversion failed?
if ( err != CIP_OK )
return Py_BuildValue("(ii)", 0, err);
@ -169,11 +169,11 @@ PyObject *py_unpack_object_from_bv(
idc_value_t idc_obj;
error_t err = unpack_object_from_bv(
&idc_obj,
ti,
type,
fields,
bytes,
&idc_obj,
ti,
type,
fields,
bytes,
pio_flags);
// Unpacking failed?

View File

@ -11,6 +11,7 @@
%ignore auto_save;
%ignore auto_term;
%ignore ea_without_xrefs;
%ignore postpone_lastinsn_analysis;
%include "auto.hpp"

View File

@ -764,6 +764,16 @@ static PyObject *py_get_many_bytes(ea_t ea, unsigned int size)
//---------------------------------------------------------------------------
/*
#<pydoc>
# Conversion options for get_ascii_contents2():
ACFOPT_ASCII = 0x00000000 # convert Unicode strings to ASCII
ACFOPT_UTF16 = 0x00000001 # return UTF-16 (aka wide-char) array for Unicode strings
# ignored for non-Unicode strings
ACFOPT_UTF8 = 0x00000002 # convert Unicode strings to UTF-8
# ignored for non-Unicode strings
ACFOPT_CONVMASK = 0x0000000F
ACFOPT_ESCAPE = 0x00000010 # for ACFOPT_ASCII, convert non-printable
# characters to C escapes (\n, \xNN, \uNNNN)
def get_ascii_contents2(ea, len, type, flags = ACFOPT_ASCII):
"""
Get contents of ascii string

View File

@ -1,341 +1,341 @@
%ignore extfun_t;
%ignore funcset_t;
%ignore extlang_t;
%ignore extlang;
%ignore extlangs_t;
%ignore extlangs;
%ignore register_extlang;
%ignore IDCFuncs;
%ignore set_idc_func;
%ignore set_idc_dtor;
%ignore set_idc_method;
%ignore set_idc_getattr;
%ignore set_idc_setattr;
%ignore set_idc_func_ex;
%ignore run_statements_idc;
%ignore VarLong;
%ignore VarNum;
%ignore extlang_get_attr_exists;
%ignore extlang_create_object_exists;
%ignore create_script_object;
%ignore set_script_attr;
%ignore set_attr_exists;
%ignore get_script_attr;
%ignore extlang_get_attr_exists;
%ignore extlang_compile_file;
%ignore get_extlangs;
%ignore create_idc_object;
%ignore run_script_func;
%ignore VarString;
%ignore VarFloat;
%ignore VarFree;
%ignore calcexpr_long;
%ignore Run;
%ignore ExecuteLine;
%ignore ExecuteFile;
%ignore set_idc_func_body;
%ignore get_idc_func_body;
%ignore idc_stacksize;
%ignore idc_calldepth;
%ignore expr_printf;
%ignore expr_sprintf;
%ignore expr_printfer;
%ignore init_idc;
%ignore term_idc;
%ignore create_default_idc_classes;
%ignore insn_to_idc;
%ignore find_builtin_idc_func;
%ignore idc_mutex;
%ignore idc_lx;
%ignore idc_vars;
%ignore idc_resolve_label;
%ignore idc_resolver_ea;
%ignore setup_lowcnd_regfuncs;
%cstring_output_maxstr_none(char *errbuf, size_t errbufsize);
%ignore CompileEx;
%rename (CompileEx) CompileEx_wrap;
%ignore Compile;
%rename (Compile) Compile_wrap;
%ignore calcexpr;
%rename (calcexpr) calcexpr_wrap;
%ignore calc_idc_expr;
%rename (calc_idc_expr) calc_idc_expr_wrap;
%ignore CompileLine(const char *line, char *errbuf, size_t errbufsize, uval_t (idaapi*_getname)(const char *name)=NULL);
%ignore CompileLineEx;
%ignore CompileLine;
%rename (CompileLine) CompileLine_wrap;
%{
//<code(py_expr)>
struct py_idcfunc_ctx_t
{
PyObject *py_func;
qstring name;
int nargs;
py_idcfunc_ctx_t(PyObject *py_func, const char *name, int nargs): py_func(py_func), name(name), nargs(nargs)
{
Py_INCREF(py_func);
}
~py_idcfunc_ctx_t()
{
Py_DECREF(py_func);
}
};
//---------------------------------------------------------------------------
static error_t py_call_idc_func(
void *_ctx,
idc_value_t *argv,
idc_value_t *r)
{
// Convert IDC arguments to Python list
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)_ctx;
int cvt;
ppyobject_vec_t pargs;
char errbuf[MAXSTR];
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, NULL, errbuf, sizeof(errbuf)) )
{
// Error during conversion? Create an IDC exception
return PyW_CreateIdcException(r, errbuf);
}
// Call the Python function
PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallObject(
ctx->py_func,
pargs.empty() ? NULL : pargs[0]);
error_t err;
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
{
err = PyW_CreateIdcException(r, errbuf);
Py_XDECREF(py_result);
}
else
{
// Convert the result to IDC
r->clear();
cvt = pyvar_to_idcvar(py_result, r);
if ( cvt < CIP_OK )
err = PyW_CreateIdcException(r, "ERROR: bad return value");
else
err = eOk;
if ( cvt != CIP_OK_NODECREF )
Py_XDECREF(py_result);
}
PYW_GIL_RELEASE;
// Free the converted args
pyw_free_idc_args(pargs);
return err;
}
//</code(py_expr)>
%}
%inline %{
//<inline(py_expr)>
//---------------------------------------------------------------------------
static size_t py_get_call_idc_func()
{
return (size_t)py_call_idc_func;
}
//---------------------------------------------------------------------------
// Internal function:
// - capture the python callable
// - return a C context as a numeric value
static size_t pyw_register_idc_func(
const char *name,
const char *args,
PyObject *py_fp)
{
return (size_t)new py_idcfunc_ctx_t(py_fp, name, strlen(args));
}
//---------------------------------------------------------------------------
// Internal function:
// - free the C context
static bool pyw_unregister_idc_func(size_t ctxptr)
{
// Unregister the function
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)ctxptr;
bool ok = set_idc_func_ex(ctx->name.c_str(), NULL, NULL, 0);
// Delete the context
delete ctx;
return ok;
}
//---------------------------------------------------------------------------
static bool py_set_idc_func_ex(
const char *name,
size_t fp_ptr,
const char *args,
int flags)
{
return set_idc_func_ex(name, (idc_func_t *)fp_ptr, args, flags);
}
//---------------------------------------------------------------------------
// Compile* functions return false when error so the return
// value must be negated for the error string to be returned
bool CompileEx_wrap(
const char *file,
bool del_macros,
char *errbuf, size_t errbufsize)
{
return !CompileEx(file, del_macros, errbuf, errbufsize);
}
bool Compile_wrap(const char *file, char *errbuf, size_t errbufsize)
{
return !Compile(file, errbuf, errbufsize);
}
bool calcexpr_wrap(
ea_t where,
const char *line,
idc_value_t *rv,
char *errbuf, size_t errbufsize)
{
return !calcexpr(where, line, rv, errbuf, errbufsize);
}
bool calc_idc_expr_wrap(
ea_t where,
const char *line,
idc_value_t *rv,
char *errbuf, size_t errbufsize)
{
return !calc_idc_expr(where, line, rv, errbuf, errbufsize);
}
bool CompileLine_wrap(const char *line, char *errbuf, size_t errbufsize)
{
return !CompileLineEx(line, errbuf, errbufsize);
}
//</inline(py_expr)>
%}
%include "expr.hpp"
%pythoncode %{
#<pycode(py_expr)>
try:
import types
import ctypes
# Callback for IDC func callback (On Windows, we use stdcall)
# typedef error_t idaapi idc_func_t(idc_value_t *argv,idc_value_t *r);
_IDCFUNC_CB_T = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p)
# A trampoline function that is called from idcfunc_t that will
# call the Python callback with the argv and r properly serialized to python
call_idc_func__ = ctypes.CFUNCTYPE(ctypes.c_long)(_idaapi.py_get_call_idc_func())
except:
def call_idc_func__(*args):
warning("IDC extensions need ctypes library in order to work")
return 0
try:
_IDCFUNC_CB_T = CFUNCTYPE(c_int, c_void_p, c_void_p)
except:
_IDCFUNC_CB_T = None
# --------------------------------------------------------------------------
EXTFUN_BASE = 0x0001
"""requires open database"""
EXTFUN_NORET = 0x0002
"""does not return. the interpreter may clean up its state before calling it."""
EXTFUN_SAFE = 0x0004
"""thread safe function. may be called"""
# --------------------------------------------------------------------------
class _IdcFunction(object):
"""
Internal class that calls pyw_call_idc_func() with a context
"""
def __init__(self, ctxptr):
self.ctxptr = ctxptr
# Take a reference to the ctypes callback
# (note: this will create a circular reference)
self.cb = _IDCFUNC_CB_T(self)
fp_ptr = property(lambda self: ctypes.cast(self.cb, ctypes.c_void_p).value)
def __call__(self, args, res):
return call_idc_func__(self.ctxptr, args, res)
# --------------------------------------------------------------------------
# Dictionary to remember IDC function names along with the context pointer
# retrieved by using the internal pyw_register_idc_func()
__IDC_FUNC_CTXS = {}
# --------------------------------------------------------------------------
def set_idc_func_ex(name, fp=None, args=(), flags=0):
"""
Extends the IDC language by exposing a new IDC function that is backed up by a Python function
This function also unregisters the IDC function if 'fp' was passed as None
@param name: IDC function name to expose
@param fp: Python callable that will receive the arguments and return a tuple.
If this argument is None then the IDC function is unregistered
@param args: Arguments. A tuple of idaapi.VT_XXX constants
@param flags: IDC function flags. A combination of EXTFUN_XXX constants
@return: Boolean.
"""
global __IDC_FUNC_CTXS
# Get the context
f = __IDC_FUNC_CTXS.get(name, None)
# Unregistering?
if fp is None:
# Not registered?
if f is None:
return False
# Break circular reference
del f.cb
# Delete the name from the dictionary
del __IDC_FUNC_CTXS[name]
# Delete the context and unregister the function
return _idaapi.pyw_unregister_idc_func(f.ctxptr)
# Registering a function that is already registered?
if f is not None:
# Unregister it first
set_idc_func_ex(name, None)
# Convert the tupple argument info to a string
args = "".join([chr(x) for x in args])
# Create a context
ctxptr = _idaapi.pyw_register_idc_func(name, args, fp)
if ctxptr == 0:
return False
# Bind the context with the IdcFunc object
f = _IdcFunction(ctxptr)
# Remember the Python context
__IDC_FUNC_CTXS[name] = f
# Register IDC function with a callback
return _idaapi.py_set_idc_func_ex(
name,
f.fp_ptr,
args,
flags)
#</pycode(py_expr)>
%ignore extfun_t;
%ignore funcset_t;
%ignore extlang_t;
%ignore extlang;
%ignore extlangs_t;
%ignore extlangs;
%ignore register_extlang;
%ignore IDCFuncs;
%ignore set_idc_func;
%ignore set_idc_dtor;
%ignore set_idc_method;
%ignore set_idc_getattr;
%ignore set_idc_setattr;
%ignore set_idc_func_ex;
%ignore run_statements_idc;
%ignore VarLong;
%ignore VarNum;
%ignore extlang_get_attr_exists;
%ignore extlang_create_object_exists;
%ignore create_script_object;
%ignore set_script_attr;
%ignore set_attr_exists;
%ignore get_script_attr;
%ignore extlang_get_attr_exists;
%ignore extlang_compile_file;
%ignore get_extlangs;
%ignore create_idc_object;
%ignore run_script_func;
%ignore VarString;
%ignore VarFloat;
%ignore VarFree;
%ignore calcexpr_long;
%ignore Run;
%ignore ExecuteLine;
%ignore ExecuteFile;
%ignore set_idc_func_body;
%ignore get_idc_func_body;
%ignore idc_stacksize;
%ignore idc_calldepth;
%ignore expr_printf;
%ignore expr_sprintf;
%ignore expr_printfer;
%ignore init_idc;
%ignore term_idc;
%ignore create_default_idc_classes;
%ignore insn_to_idc;
%ignore find_builtin_idc_func;
%ignore idc_mutex;
%ignore idc_lx;
%ignore idc_vars;
%ignore idc_resolve_label;
%ignore idc_resolver_ea;
%ignore setup_lowcnd_regfuncs;
%cstring_output_maxstr_none(char *errbuf, size_t errbufsize);
%ignore CompileEx;
%rename (CompileEx) CompileEx_wrap;
%ignore Compile;
%rename (Compile) Compile_wrap;
%ignore calcexpr;
%rename (calcexpr) calcexpr_wrap;
%ignore calc_idc_expr;
%rename (calc_idc_expr) calc_idc_expr_wrap;
%ignore CompileLine(const char *line, char *errbuf, size_t errbufsize, uval_t (idaapi*_getname)(const char *name)=NULL);
%ignore CompileLineEx;
%ignore CompileLine;
%rename (CompileLine) CompileLine_wrap;
%{
//<code(py_expr)>
struct py_idcfunc_ctx_t
{
PyObject *py_func;
qstring name;
int nargs;
py_idcfunc_ctx_t(PyObject *py_func, const char *name, int nargs): py_func(py_func), name(name), nargs(nargs)
{
Py_INCREF(py_func);
}
~py_idcfunc_ctx_t()
{
Py_DECREF(py_func);
}
};
//---------------------------------------------------------------------------
static error_t py_call_idc_func(
void *_ctx,
idc_value_t *argv,
idc_value_t *r)
{
// Convert IDC arguments to Python list
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)_ctx;
int cvt;
ppyobject_vec_t pargs;
char errbuf[MAXSTR];
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, NULL, errbuf, sizeof(errbuf)) )
{
// Error during conversion? Create an IDC exception
return PyW_CreateIdcException(r, errbuf);
}
// Call the Python function
PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallObject(
ctx->py_func,
pargs.empty() ? NULL : pargs[0]);
error_t err;
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
{
err = PyW_CreateIdcException(r, errbuf);
Py_XDECREF(py_result);
}
else
{
// Convert the result to IDC
r->clear();
cvt = pyvar_to_idcvar(py_result, r);
if ( cvt < CIP_OK )
err = PyW_CreateIdcException(r, "ERROR: bad return value");
else
err = eOk;
if ( cvt != CIP_OK_NODECREF )
Py_XDECREF(py_result);
}
PYW_GIL_RELEASE;
// Free the converted args
pyw_free_idc_args(pargs);
return err;
}
//</code(py_expr)>
%}
%inline %{
//<inline(py_expr)>
//---------------------------------------------------------------------------
static size_t py_get_call_idc_func()
{
return (size_t)py_call_idc_func;
}
//---------------------------------------------------------------------------
// Internal function:
// - capture the python callable
// - return a C context as a numeric value
static size_t pyw_register_idc_func(
const char *name,
const char *args,
PyObject *py_fp)
{
return (size_t)new py_idcfunc_ctx_t(py_fp, name, strlen(args));
}
//---------------------------------------------------------------------------
// Internal function:
// - free the C context
static bool pyw_unregister_idc_func(size_t ctxptr)
{
// Unregister the function
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)ctxptr;
bool ok = set_idc_func_ex(ctx->name.c_str(), NULL, NULL, 0);
// Delete the context
delete ctx;
return ok;
}
//---------------------------------------------------------------------------
static bool py_set_idc_func_ex(
const char *name,
size_t fp_ptr,
const char *args,
int flags)
{
return set_idc_func_ex(name, (idc_func_t *)fp_ptr, args, flags);
}
//---------------------------------------------------------------------------
// Compile* functions return false when error so the return
// value must be negated for the error string to be returned
bool CompileEx_wrap(
const char *file,
bool del_macros,
char *errbuf, size_t errbufsize)
{
return !CompileEx(file, del_macros, errbuf, errbufsize);
}
bool Compile_wrap(const char *file, char *errbuf, size_t errbufsize)
{
return !Compile(file, errbuf, errbufsize);
}
bool calcexpr_wrap(
ea_t where,
const char *line,
idc_value_t *rv,
char *errbuf, size_t errbufsize)
{
return !calcexpr(where, line, rv, errbuf, errbufsize);
}
bool calc_idc_expr_wrap(
ea_t where,
const char *line,
idc_value_t *rv,
char *errbuf, size_t errbufsize)
{
return !calc_idc_expr(where, line, rv, errbuf, errbufsize);
}
bool CompileLine_wrap(const char *line, char *errbuf, size_t errbufsize)
{
return !CompileLineEx(line, errbuf, errbufsize);
}
//</inline(py_expr)>
%}
%include "expr.hpp"
%pythoncode %{
#<pycode(py_expr)>
try:
import types
import ctypes
# Callback for IDC func callback (On Windows, we use stdcall)
# typedef error_t idaapi idc_func_t(idc_value_t *argv,idc_value_t *r);
_IDCFUNC_CB_T = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p)
# A trampoline function that is called from idcfunc_t that will
# call the Python callback with the argv and r properly serialized to python
call_idc_func__ = ctypes.CFUNCTYPE(ctypes.c_long)(_idaapi.py_get_call_idc_func())
except:
def call_idc_func__(*args):
warning("IDC extensions need ctypes library in order to work")
return 0
try:
_IDCFUNC_CB_T = CFUNCTYPE(c_int, c_void_p, c_void_p)
except:
_IDCFUNC_CB_T = None
# --------------------------------------------------------------------------
EXTFUN_BASE = 0x0001
"""requires open database"""
EXTFUN_NORET = 0x0002
"""does not return. the interpreter may clean up its state before calling it."""
EXTFUN_SAFE = 0x0004
"""thread safe function. may be called"""
# --------------------------------------------------------------------------
class _IdcFunction(object):
"""
Internal class that calls pyw_call_idc_func() with a context
"""
def __init__(self, ctxptr):
self.ctxptr = ctxptr
# Take a reference to the ctypes callback
# (note: this will create a circular reference)
self.cb = _IDCFUNC_CB_T(self)
fp_ptr = property(lambda self: ctypes.cast(self.cb, ctypes.c_void_p).value)
def __call__(self, args, res):
return call_idc_func__(self.ctxptr, args, res)
# --------------------------------------------------------------------------
# Dictionary to remember IDC function names along with the context pointer
# retrieved by using the internal pyw_register_idc_func()
__IDC_FUNC_CTXS = {}
# --------------------------------------------------------------------------
def set_idc_func_ex(name, fp=None, args=(), flags=0):
"""
Extends the IDC language by exposing a new IDC function that is backed up by a Python function
This function also unregisters the IDC function if 'fp' was passed as None
@param name: IDC function name to expose
@param fp: Python callable that will receive the arguments and return a tuple.
If this argument is None then the IDC function is unregistered
@param args: Arguments. A tuple of idaapi.VT_XXX constants
@param flags: IDC function flags. A combination of EXTFUN_XXX constants
@return: Boolean.
"""
global __IDC_FUNC_CTXS
# Get the context
f = __IDC_FUNC_CTXS.get(name, None)
# Unregistering?
if fp is None:
# Not registered?
if f is None:
return False
# Break circular reference
del f.cb
# Delete the name from the dictionary
del __IDC_FUNC_CTXS[name]
# Delete the context and unregister the function
return _idaapi.pyw_unregister_idc_func(f.ctxptr)
# Registering a function that is already registered?
if f is not None:
# Unregister it first
set_idc_func_ex(name, None)
# Convert the tupple argument info to a string
args = "".join([chr(x) for x in args])
# Create a context
ctxptr = _idaapi.pyw_register_idc_func(name, args, fp)
if ctxptr == 0:
return False
# Bind the context with the IdcFunc object
f = _IdcFunction(ctxptr)
# Remember the Python context
__IDC_FUNC_CTXS[name] = f
# Register IDC function with a callback
return _idaapi.py_set_idc_func_ex(
name,
f.fp_ptr,
args,
flags)
#</pycode(py_expr)>
%}

View File

@ -62,9 +62,8 @@ static ea_t get_fchunk_referer(ea_t ea, size_t idx)
def get_idasgn_desc(n):
"""
Get information about a signature in the list.
It returns both:
signame - the name of the signature
optlibs - the names of the optional libraries
It returns both: the name of the signature, and names of the
optional libraries
@param n: number of signature in the list (0..get_idasgn_qty()-1)
@return: None on failure or tuple(signame, optlibs)

View File

@ -564,7 +564,7 @@ private:
void show()
{
open_tform(form, FORM_MDI|FORM_TAB|FORM_MENU);
open_tform(form, FORM_TAB|FORM_MENU);
}
static py_graph_t *extract_this(PyObject *self)
@ -668,7 +668,7 @@ private:
qsnprintf(grnode, sizeof(grnode), "$ pygraph %s", title);
id.create(grnode);
gv = create_graph_viewer(form, id, s_callback, this, 0);
open_tform(form, FORM_MDI | FORM_TAB | FORM_MENU);
open_tform(form, FORM_TAB | FORM_MENU);
if ( gv != NULL )
viewer_fit_window(gv);
}

View File

@ -15,7 +15,7 @@
%constant size_t SIZE_MAX = size_t(-1);
// Enable automatic docstring generation
%feature(autodoc);
%feature(autodoc,0);
%define SWIG_DECLARE_PY_CLINKED_OBJECT(type)
%inline %{
@ -2056,11 +2056,11 @@ bool pywraps_nw_term()
{
if ( g_nw == NULL )
return true;
// If could not deinitialize then return w/o stopping nw
if ( !g_nw->deinit() )
return false;
// Cleanup
delete g_nw;
g_nw = NULL;
@ -2694,7 +2694,7 @@ def parse_command_line(cmdline):
static PyObject *py_parse_command_line(const char *cmdline)
{
qstrvec_t args;
if ( parse_command_line(cmdline, &args) == 0 )
if ( parse_command_line2(cmdline, &args, NULL) == 0 )
Py_RETURN_NONE;
PyObject *py_list = PyList_New(args.size());

View File

@ -475,7 +475,7 @@ class IDP_Hooks(object):
- cmd.itype must be set >= idaapi.CUSTOM_CMD_ITYPE
- cmd.size must be set to the instruction length
@return: Boolean
@return: Boolean
- False if the instruction is not recognized
- True if the instruction was decoded. idaapi.cmd should be filled in that case.
"""

View File

@ -619,7 +619,7 @@ in this case.
This flag can be used to delay the code execution
until the next UI loop run even from the main thread"""
def execute_sync(callable, reqf)
def execute_sync(callable, reqf):
"""
Executes a function in the context of the main thread.
If the current thread not the main thread, then the call is queued and
@ -692,7 +692,7 @@ static int py_execute_sync(PyObject *py_callable, int reqf)
/*
#<pydoc>
def execute_ui_requests(callable_list)
def execute_ui_requests(callable_list):
"""
Inserts a list of callables into the UI message processing queue.
When the UI is ready it will call one callable.
@ -885,7 +885,11 @@ class UI_Hooks(object):
IDA is terminated and the database is already closed.
The UI may close its windows in this callback.
"""
pass
# if the user forgot to call unhook, do it for him
self.unhook()
def __term__(self):
self.term()
#</pydoc>
*/
@ -894,6 +898,7 @@ class UI_Hooks
public:
virtual ~UI_Hooks()
{
unhook();
}
bool hook()
@ -2690,10 +2695,10 @@ private:
PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallMethod(
_this->py_obj,
(char *)S_ON_CREATE, "O",
(char *)S_ON_CREATE, "O",
PyCObject_FromVoidPtr(form, NULL));
PYW_GIL_RELEASE;
PyW_ShowCbErr(S_ON_CREATE);
Py_XDECREF(py_result);
}
@ -2706,10 +2711,10 @@ private:
PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallMethod(
_this->py_obj,
(char *)S_ON_CLOSE, "O",
(char *)S_ON_CLOSE, "O",
PyCObject_FromVoidPtr(form, NULL));
PYW_GIL_RELEASE;
PyW_ShowCbErr(S_ON_CLOSE);
Py_XDECREF(py_result);
@ -2723,7 +2728,7 @@ private:
{
unhook_from_notification_point(HT_UI, s_callback, this);
form = NULL;
// Call DECREF at last, since it may trigger __del__
Py_XDECREF(py_obj);
}
@ -2735,7 +2740,7 @@ public:
bool show(
PyObject *obj,
const char *caption,
const char *caption,
int options)
{
// Already displayed?
@ -2757,7 +2762,7 @@ public:
form = create_tform(caption, NULL);
if ( form == NULL )
return false;
if ( !hook_to_notification_point(HT_UI, s_callback, this) )
{
form = NULL;
@ -2785,7 +2790,7 @@ public:
{
return PyCObject_FromVoidPtr(new plgform_t(), destroy);
}
static void destroy(void *obj)
{
delete (plgform_t *)obj;
@ -2805,9 +2810,9 @@ static PyObject *plgform_new()
static bool plgform_show(
PyObject *py_link,
PyObject *py_obj,
const char *caption,
int options = FORM_MDI|FORM_TAB|FORM_MENU|FORM_RESTORE)
PyObject *py_obj,
const char *caption,
int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
{
DECL_PLGFORM;
return plgform->show(py_obj, caption, options);
@ -5531,7 +5536,7 @@ class PluginForm(object):
"""
FORM_MDI = 0x01
"""start by default as MDI"""
"""start by default as MDI (obsolete)"""
FORM_TAB = 0x02
"""attached by default to a tab"""
FORM_RESTORE = 0x04
@ -5560,7 +5565,7 @@ class PluginForm(object):
@param caption: The form caption
@param options: One of PluginForm.FORM_ constants
"""
options |= PluginForm.FORM_MDI|PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
options |= PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
return _idaapi.plgform_show(self.__clink__, self, caption, options)

View File

@ -1,111 +1,111 @@
%cstring_output_maxstr_none(char *buf, int bufsize);
%cstring_bounded_output(char *dstname, MAXSTR);
%cstring_bounded_output(char *buf, MAXSTR);
// This is for get_name_value's output value
%apply unsigned long *OUTPUT { uval_t *value };
// FIXME: These should be fixed
%ignore append_struct_fields;
%ignore get_struct_operand;
%ignore set_debug_names;
%ignore get_debug_name;
%ignore nameVa;
// Unexported & kernel-only
%ignore get_short_name;
%ignore get_long_name;
%ignore get_colored_short_name;
%ignore get_colored_long_name;
%ignore addDummyName;
%ignore convert_debug_names_to_normal;
%ignore convert_name_formats;
%ignore showhide_name;
%ignore clear_lname_bit;
%ignore fix_new_name;
%ignore rename;
%ignore move_names;
%ignore is_noret_name;
%ignore is_exit_name;
%ignore dummy_name_ea;
%ignore get_debug_names;
%rename (get_debug_names) py_get_debug_names;
%inline %{
//<inline(py_name)>
//------------------------------------------------------------------------
PyObject *py_get_debug_names(ea_t ea1, ea_t ea2)
{
// Get debug names
ea_name_vec_t names;
get_debug_names(ea1, ea2, names);
PyObject *dict = Py_BuildValue("{}");
if (dict == NULL)
return NULL;
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
{
PyDict_SetItem(dict,
Py_BuildValue(PY_FMT64, it->ea),
PyString_FromString(it->name.c_str()));
}
return dict;
}
//------------------------------------------------------------------------
//</inline(py_name)>
%}
%pythoncode %{
#<pycode(py_name)>
class NearestName:
"""
Utility class to help find the nearest name in a given ea/name dictionary
"""
def __init__(self, ea_names):
self.update(ea_names)
def update(self, ea_names):
"""Updates the ea/names map"""
self._names = ea_names
self._addrs = ea_names.keys()
self._addrs.sort()
def find(self, ea):
"""
Returns a tupple (ea, name, pos) that is the nearest to the passed ea
If no name is matched then None is returned
"""
pos = bisect.bisect_left(self._addrs, ea)
# no match
if pos >= len(self._addrs):
return None
# exact match?
if self._addrs[pos] != ea:
pos -= 1 # go to previous element
if pos < 0:
return None
return self[pos]
def _get_item(self, index):
ea = self._addrs[index]
return (ea, self._names[ea], index)
def __iter__(self):
return (self._get_item(index) for index in xrange(0, len(self._addrs)))
def __getitem__(self, index):
"""Returns the tupple (ea, name, index)"""
if index > len(self._addrs):
raise StopIteration
return self._get_item(index)
#</pycode(py_name)>
%}
%include "name.hpp"
%cstring_output_maxstr_none(char *buf, int bufsize);
%cstring_bounded_output(char *dstname, MAXSTR);
%cstring_bounded_output(char *buf, MAXSTR);
// This is for get_name_value's output value
%apply unsigned long *OUTPUT { uval_t *value };
// FIXME: These should be fixed
%ignore append_struct_fields;
%ignore get_struct_operand;
%ignore set_debug_names;
%ignore get_debug_name;
%ignore nameVa;
// Unexported & kernel-only
%ignore get_short_name;
%ignore get_long_name;
%ignore get_colored_short_name;
%ignore get_colored_long_name;
%ignore addDummyName;
%ignore convert_debug_names_to_normal;
%ignore convert_name_formats;
%ignore showhide_name;
%ignore clear_lname_bit;
%ignore fix_new_name;
%ignore rename;
%ignore move_names;
%ignore is_noret_name;
%ignore is_exit_name;
%ignore dummy_name_ea;
%ignore get_debug_names;
%rename (get_debug_names) py_get_debug_names;
%inline %{
//<inline(py_name)>
//------------------------------------------------------------------------
PyObject *py_get_debug_names(ea_t ea1, ea_t ea2)
{
// Get debug names
ea_name_vec_t names;
get_debug_names(ea1, ea2, names);
PyObject *dict = Py_BuildValue("{}");
if (dict == NULL)
return NULL;
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
{
PyDict_SetItem(dict,
Py_BuildValue(PY_FMT64, it->ea),
PyString_FromString(it->name.c_str()));
}
return dict;
}
//------------------------------------------------------------------------
//</inline(py_name)>
%}
%pythoncode %{
#<pycode(py_name)>
class NearestName:
"""
Utility class to help find the nearest name in a given ea/name dictionary
"""
def __init__(self, ea_names):
self.update(ea_names)
def update(self, ea_names):
"""Updates the ea/names map"""
self._names = ea_names
self._addrs = ea_names.keys()
self._addrs.sort()
def find(self, ea):
"""
Returns a tupple (ea, name, pos) that is the nearest to the passed ea
If no name is matched then None is returned
"""
pos = bisect.bisect_left(self._addrs, ea)
# no match
if pos >= len(self._addrs):
return None
# exact match?
if self._addrs[pos] != ea:
pos -= 1 # go to previous element
if pos < 0:
return None
return self[pos]
def _get_item(self, index):
ea = self._addrs[index]
return (ea, self._names[ea], index)
def __iter__(self):
return (self._get_item(index) for index in xrange(0, len(self._addrs)))
def __getitem__(self, index):
"""Returns the tupple (ea, name, index)"""
if index > len(self._addrs):
raise StopIteration
return self._get_item(index)
#</pycode(py_name)>
%}
%include "name.hpp"

View File

@ -83,7 +83,17 @@
%ignore get_process_exit_code;
%ignore BELOW_NORMAL_PRIORITY_CLASS;
%ignore parse_command_line;
%rename (parse_command_line) py_parse_command_line;
%ignore parse_command_line2;
%rename (parse_command_line2) py_parse_command_line;
%ignore qgetenv;
%ignore qsetenv;
%ignore qctime;
%ignore qlocaltime;
%ignore qstrftime;
%ignore qstrftime64;
%ignore qstrtok;
%ignore qstrlwr;
%ignore qstrupr;
%include "pro.h"
SWIG_DECLARE_PY_CLINKED_OBJECT(qstrvec_t)

View File

@ -87,6 +87,7 @@
%ignore decorate_name;
%ignore gen_decorate_name;
%ignore calc_bare_name;
%ignore calc_cpp_name;
%ignore predicate_t;
%ignore choose_named_type;
%ignore get_default_align;
@ -131,6 +132,14 @@
%ignore type_pair_vec_t::add_names;
%ignore format_data_info_t;
%ignore valinfo_t;
%ignore print_c_data;
%ignore format_c_data;
%ignore format_c_number;
%ignore get_enum_member_expr;
%ignore extend_sign;
// Kernel-only symbols
%ignore init_til;
%ignore save_til;
@ -161,6 +170,7 @@
%rename (load_til) load_til_wrap;
%rename (get_type_size0) py_get_type_size0;
%rename (idc_get_type_raw) py_idc_get_type_raw;
%rename (unpack_object_from_idb) py_unpack_object_from_idb;
%rename (unpack_object_from_bv) py_unpack_object_from_bv;
%rename (pack_object_to_idb) py_pack_object_to_idb;
@ -266,12 +276,12 @@ PyObject *py_unpack_object_from_idb(
p_list *fields = (p_list *) PyString_AsString(py_fields);
idc_value_t idc_obj;
error_t err = unpack_object_from_idb(
&idc_obj,
ti,
type,
fields,
ea,
NULL,
&idc_obj,
ti,
type,
fields,
ea,
NULL,
pio_flags);
// Unpacking failed?
@ -281,7 +291,7 @@ PyObject *py_unpack_object_from_idb(
// Convert
PyObject *py_ret(NULL);
err = idcvar_to_pyvar(idc_obj, &py_ret);
// Conversion failed?
if ( err != CIP_OK )
return Py_BuildValue("(ii)", 0, err);
@ -334,11 +344,11 @@ PyObject *py_unpack_object_from_bv(
idc_value_t idc_obj;
error_t err = unpack_object_from_bv(
&idc_obj,
ti,
type,
fields,
bytes,
&idc_obj,
ti,
type,
fields,
bytes,
pio_flags);
// Unpacking failed?
@ -519,6 +529,19 @@ int idc_parse_types(const char *input, int flags)
return parse_decls(idati, input, (flags & 2) == 0 ? msg : NULL, hti);
}
PyObject *py_idc_get_type_raw(ea_t ea)
{
qtype type, fields;
if (get_tinfo(ea, &type, &fields))
{
return Py_BuildValue("(ss)", (char *)type.c_str(), (char *)fields.c_str());
}
else
{
Py_RETURN_NONE;
}
}
char *idc_get_type(ea_t ea, char *buf, size_t bufsize)
{
qtype type, fnames;

View File

@ -5,6 +5,7 @@
#
import glob
import sys
import os
# ---------------------------------------------------------------------------
def extract_docs(lines, out):
@ -67,17 +68,29 @@ def extract_docs(lines, out):
elif line == S_INLINE:
in_inline = True
# ---------------------------------------------------------------------------
def gen_docs_from(file, out):
f = open(file, 'r')
lines = f.readlines()
f.close()
extract_docs(lines, out)
# ---------------------------------------------------------------------------
def gen_docs(path = '../swig/', outfn = 'idaapi.py', mask = '*.i'):
out = []
# idaapi contains definitions used by other modules
# handle it first
idaapi_i = os.path.join(path, 'idaapi.i')
gen_docs_from(idaapi_i, out)
for fn in glob.glob(path + mask):
f = open(fn, 'r')
lines = f.readlines()
f.close()
extract_docs(lines, out)
fn = fn.replace('\\', '/')
if fn != idaapi_i:
gen_docs_from(fn, out)
f = open(outfn, 'w')
f.write('"""This is a placeholder module used to document all the IDA SDK functions that are wrapped manually. You still need to import \'idaapi\' and not this module to use the functions"""\n')
# f.write('"""This is a placeholder module used to document all the IDA SDK functions that are wrapped manually. You still need to import \'idaapi\' (not this module) to use the functions"""\n')
f.write('\n'.join(out))
f.close()