- 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

@ -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.
"""
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());

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

@ -139,7 +139,7 @@ static bool plgform_show(
PyObject *py_link,
PyObject *py_obj,
const char *caption,
int options = FORM_MDI|FORM_TAB|FORM_MENU|FORM_RESTORE)
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

@ -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

@ -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 %{
@ -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

@ -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()
@ -2807,7 +2812,7 @@ static bool plgform_show(
PyObject *py_link,
PyObject *py_obj,
const char *caption,
int options = FORM_MDI|FORM_TAB|FORM_MENU|FORM_RESTORE)
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

@ -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;
@ -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):
@ -68,16 +69,28 @@ def extract_docs(lines, out):
in_inline = True
# ---------------------------------------------------------------------------
def gen_docs(path = '../swig/', outfn = 'idaapi.py', mask = '*.i'):
out = []
for fn in glob.glob(path + mask):
f = open(fn, 'r')
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):
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()