- 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. 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 Changes from version 1.5.3 to 1.5.4
------------------------------------ ------------------------------------

View File

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

View File

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

View File

@ -8,3 +8,7 @@ REMOVE_CWD_SYS_PATH = 0
// Script timeout (in seconds) // Script timeout (in seconds)
// (A value of 0 disables the timeout) // (A value of 0 disables the timeout)
SCRIPT_TIMEOUT = 3 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_ui_ready = false;
static bool g_alert_auto_scripts = true; static bool g_alert_auto_scripts = true;
static bool g_remove_cwd_sys_path = false; static bool g_remove_cwd_sys_path = false;
static bool g_use_local_python = false;
static void end_execution(); static void end_execution();
static void begin_execution(); static void begin_execution();
@ -369,6 +370,11 @@ const char *idaapi set_python_options(
g_remove_cwd_sys_path = *(uval_t *)value != 0; g_remove_cwd_sys_path = *(uval_t *)value != 0;
break; break;
} }
else if ( qstrcmp(keyword, "USE_LOCAL_PYTHON") == 0 )
{
g_use_local_python = *(uval_t *)value != 0;
break;
}
} }
return IDPOPT_BADKEY; return IDPOPT_BADKEY;
} while (false); } 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); PyObject *py_execscript = get_idaapi_attr(S_IDAAPI_EXECSCRIPT);
if ( py_execscript == NULL ) if ( py_execscript == NULL )
{
qstrncpy(errbuf, "Could not find idaapi." S_IDAAPI_EXECSCRIPT " ?!", errbufsz);
return false; return false;
}
char script[MAXSTR]; char script[MAXSTR];
qstrncpy(script, FileName, sizeof(script)); qstrncpy(script, FileName, sizeof(script));
@ -1288,6 +1297,25 @@ static void sanitize_path()
PySys_SetPath(newpath.begin()); 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 // Initialize the Python environment
bool IDAPython_Init(void) bool IDAPython_Init(void)
@ -1306,12 +1334,11 @@ bool IDAPython_Init(void)
char tmp[QMAXPATH]; char tmp[QMAXPATH];
#ifdef __LINUX__ #ifdef __LINUX__
// Export symbols from libpython to resolve imported module deps // Export symbols from libpython to resolve imported module deps
qsnprintf(tmp, sizeof(tmp), "libpython%d.%d.so.1", // use the standard soname: libpython2.7.so.1.0
PY_MAJOR_VERSION, #define PYLIB "libpython" QSTRINGIZE(PY_MAJOR_VERSION) "." QSTRINGIZE(PY_MINOR_VERSION) ".so.1.0"
PY_MINOR_VERSION); if ( !dlopen(PYLIB, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
if ( !dlopen(tmp, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
{ {
warning("IDAPython: %s", dlerror()); warning("IDAPython dlopen(" PYLIB ") error: %s", dlerror());
return false; return false;
} }
#endif #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 // Start the interpreter
Py_Initialize(); Py_Initialize();
if ( !Py_IsInitialized() ) if ( !Py_IsInitialized() )
{ {
warning("IDAPython: Py_Initialize() failed"); warning("IDAPython: Py_Initialize() failed");
return false; return false;
} }
// remove current directory
sanitize_path(); sanitize_path();
// import "site"
if ( !g_use_local_python && !initsite() )
{
warning("IDAPython: importing \"site\" failed");
return false;
}
// Enable multi-threading support // Enable multi-threading support
if ( !PyEval_ThreadsInitialized() ) if ( !PyEval_ThreadsInitialized() )
PyEval_InitThreads(); PyEval_InitThreads();
@ -1416,7 +1458,7 @@ bool IDAPython_Init(void)
parse_plugin_options(); parse_plugin_options();
// Register a RunPythonStatement() function for IDC // 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 // A script specified on the command line is run
if ( g_run_when == run_on_init ) if ( g_run_when == run_on_init )
@ -1463,7 +1505,7 @@ void IDAPython_Term(void)
deinit_pywraps(); deinit_pywraps();
// Uninstall IDC function // 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 // Shut the interpreter down
Py_Finalize(); Py_Finalize();

View File

@ -217,9 +217,14 @@ def Functions(start=None, end=None):
if not start: start = idaapi.cvar.inf.minEA if not start: start = idaapi.cvar.inf.minEA
if not end: end = idaapi.cvar.inf.maxEA if not end: end = idaapi.cvar.inf.maxEA
func = idaapi.get_func(start) # find first function head chunk in the range
if not func: chunk = idaapi.get_fchunk(start)
func = idaapi.get_next_func(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: while func and func.startEA < end:
startea = func.startEA startea = func.startEA
yield startea yield startea

View File

@ -1772,6 +1772,35 @@ def DbgQword(ea):
return __DbgValue(ea, 8) 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): def GetOriginalByte(ea):
""" """
Get original value of program byte Get original value of program byte
@ -2867,6 +2896,16 @@ def SetProcessorType (processor, level):
""" """
return idaapi.set_processor_type(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_COMPAT = idaapi.SETPROC_COMPAT
SETPROC_ALL = idaapi.SETPROC_ALL SETPROC_ALL = idaapi.SETPROC_ALL
SETPROC_USER = idaapi.SETPROC_USER SETPROC_USER = idaapi.SETPROC_USER
@ -4340,6 +4379,75 @@ def SetSpDiff(ea, delta):
return idaapi.add_user_stkpnt(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 # 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 @return: -1 - no fixup at the specified address
otherwise returns fixup target type: 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 -1
return fd.type return fd.type
@ -4504,8 +4612,12 @@ def GetFixupTgtSel(ea):
@return: -1 - no fixup at the specified address @return: -1 - no fixup at the specified address
otherwise returns fixup target selector otherwise returns fixup target selector
""" """
fd = idaapi.get_fixup(ea) fd = idaapi.fixup_data_t()
return -1 if not fd else fd.sel
if not idaapi.get_fixup(ea, fd):
return -1
return fd.sel
def GetFixupTgtOff(ea): def GetFixupTgtOff(ea):
@ -4517,8 +4629,12 @@ def GetFixupTgtOff(ea):
@return: -1 - no fixup at the specified address @return: -1 - no fixup at the specified address
otherwise returns fixup target offset otherwise returns fixup target offset
""" """
fd = idaapi.get_fixup(ea) fd = idaapi.fixup_data_t()
return -1 if not fd else fd.off
if not idaapi.get_fixup(ea, fd):
return -1
return fd.off
def GetFixupTgtDispl(ea): def GetFixupTgtDispl(ea):
@ -4530,8 +4646,12 @@ def GetFixupTgtDispl(ea):
@return: -1 - no fixup at the specified address @return: -1 - no fixup at the specified address
otherwise returns fixup target displacement otherwise returns fixup target displacement
""" """
fd = idaapi.get_fixup(ea) fd = idaapi.fixup_data_t()
return -1 if not fd else fd.displacement
if not idaapi.get_fixup(ea, fd):
return -1
return fd.displacement
def SetFixup(ea, fixuptype, targetsel, targetoff, displ): def SetFixup(ea, fixuptype, targetsel, targetoff, displ):
@ -4791,6 +4911,30 @@ def GetMemberQty(sid):
return -1 if not s else s.memqty 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): def GetStrucPrevOff(sid, offset):
""" """
Get previous offset in a structure Get previous offset in a structure
@ -6633,6 +6777,15 @@ def SizeOf(typestr):
""" """
return idaapi.get_type_size0(idaapi.cvar.idati, 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): def GuessType(ea):
""" """
Guess type of function/variable Guess type of function/variable
@ -6652,11 +6805,16 @@ def SetType(ea, newtype):
@param newtype: the type string in C declaration form. @param newtype: the type string in C declaration form.
Must contain the closing ';' Must contain the closing ';'
if specified as an empty string, then the 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: 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): def ParseType(inputtype, flags):
""" """
@ -7680,6 +7838,29 @@ def SetBptAttr(address, bptattr, value):
idaapi.update_bpt(bpt) idaapi.update_bpt(bpt)
return True 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): def SetBptCnd(ea, cnd):
""" """
@ -7690,14 +7871,7 @@ def SetBptCnd(ea, cnd):
@return: success @return: success
""" """
bpt = idaapi.bpt_t() return SetBptCndEx(ea, cnd, 0)
if not idaapi.get_bpt(ea, bpt):
return False
bpt.condition = cnd
return idaapi.update_bpt(bpt)
def AddBptEx(ea, size, bpttype): def AddBptEx(ea, size, bpttype):

View File

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

View File

@ -3,7 +3,7 @@
rem Please use the same tag for the same .i file 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 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.
echo -------- DEPLOY started -------------------------------------------------- echo -------- DEPLOY started --------------------------------------------------

View File

@ -168,5 +168,5 @@ plugin_t PLUGIN =
"", // multiline help about the plugin "", // multiline help about the plugin
"pywraps", // the preferred short name of 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 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 # Packs a simple structure (into the database) and unpacks it back using the idaapi methods
def test_pck_idb_raw(): def test_pck_idb_raw():
@ -884,7 +892,7 @@ def test_exec_throw():
# all the tests that take zero parameters # all the tests that take zero parameters
tests0 = (test_gpa, test_pck_idb_raw, test_pck_bv_raw, tests0 = (test_gpa, test_pck_idb_raw, test_pck_bv_raw,
test_unpack_raw, test_pck_idb, test_pck_bv, 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 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> #<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): def get_ascii_contents2(ea, len, type, flags = ACFOPT_ASCII):
""" """
Get contents of ascii string Get contents of ascii string

View File

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

View File

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

View File

@ -434,7 +434,7 @@ class IDP_Hooks(object):
- cmd.itype must be set >= idaapi.CUSTOM_CMD_ITYPE - cmd.itype must be set >= idaapi.CUSTOM_CMD_ITYPE
- cmd.size must be set to the instruction length - cmd.size must be set to the instruction length
@return: Boolean @return: Boolean
- False if the instruction is not recognized - False if the instruction is not recognized
- True if the instruction was decoded. idaapi.cmd should be filled in that case. - 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 This flag can be used to delay the code execution
until the next UI loop run even from the main thread""" 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. Executes a function in the context of the main thread.
If the current thread not the main thread, then the call is queued and 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> #<pydoc>
def execute_ui_requests(callable_list) def execute_ui_requests(callable_list):
""" """
Inserts a list of callables into the UI message processing queue. Inserts a list of callables into the UI message processing queue.
When the UI is ready it will call one callable. 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. IDA is terminated and the database is already closed.
The UI may close its windows in this callback. 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> #</pydoc>
*/ */
@ -769,6 +773,7 @@ class UI_Hooks
public: public:
virtual ~UI_Hooks() virtual ~UI_Hooks()
{ {
unhook();
} }
bool hook() bool hook()

View File

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

View File

@ -9,7 +9,7 @@ class PluginForm(object):
""" """
FORM_MDI = 0x01 FORM_MDI = 0x01
"""start by default as MDI""" """start by default as MDI (obsolete)"""
FORM_TAB = 0x02 FORM_TAB = 0x02
"""attached by default to a tab""" """attached by default to a tab"""
FORM_RESTORE = 0x04 FORM_RESTORE = 0x04
@ -38,7 +38,7 @@ class PluginForm(object):
@param caption: The form caption @param caption: The form caption
@param options: One of PluginForm.FORM_ constants @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) 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); p_list *fields = (p_list *) PyString_AsString(py_fields);
idc_value_t idc_obj; idc_value_t idc_obj;
error_t err = unpack_object_from_idb( error_t err = unpack_object_from_idb(
&idc_obj, &idc_obj,
ti, ti,
type, type,
fields, fields,
ea, ea,
NULL, NULL,
pio_flags); pio_flags);
// Unpacking failed? // Unpacking failed?
@ -116,7 +116,7 @@ PyObject *py_unpack_object_from_idb(
// Convert // Convert
PyObject *py_ret(NULL); PyObject *py_ret(NULL);
err = idcvar_to_pyvar(idc_obj, &py_ret); err = idcvar_to_pyvar(idc_obj, &py_ret);
// Conversion failed? // Conversion failed?
if ( err != CIP_OK ) if ( err != CIP_OK )
return Py_BuildValue("(ii)", 0, err); return Py_BuildValue("(ii)", 0, err);
@ -169,11 +169,11 @@ PyObject *py_unpack_object_from_bv(
idc_value_t idc_obj; idc_value_t idc_obj;
error_t err = unpack_object_from_bv( error_t err = unpack_object_from_bv(
&idc_obj, &idc_obj,
ti, ti,
type, type,
fields, fields,
bytes, bytes,
pio_flags); pio_flags);
// Unpacking failed? // Unpacking failed?

View File

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

View File

@ -764,6 +764,16 @@ static PyObject *py_get_many_bytes(ea_t ea, unsigned int size)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
/* /*
#<pydoc> #<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): def get_ascii_contents2(ea, len, type, flags = ACFOPT_ASCII):
""" """
Get contents of ascii string Get contents of ascii string

View File

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

View File

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

View File

@ -15,7 +15,7 @@
%constant size_t SIZE_MAX = size_t(-1); %constant size_t SIZE_MAX = size_t(-1);
// Enable automatic docstring generation // Enable automatic docstring generation
%feature(autodoc); %feature(autodoc,0);
%define SWIG_DECLARE_PY_CLINKED_OBJECT(type) %define SWIG_DECLARE_PY_CLINKED_OBJECT(type)
%inline %{ %inline %{
@ -2056,11 +2056,11 @@ bool pywraps_nw_term()
{ {
if ( g_nw == NULL ) if ( g_nw == NULL )
return true; return true;
// If could not deinitialize then return w/o stopping nw // If could not deinitialize then return w/o stopping nw
if ( !g_nw->deinit() ) if ( !g_nw->deinit() )
return false; return false;
// Cleanup // Cleanup
delete g_nw; delete g_nw;
g_nw = NULL; g_nw = NULL;
@ -2694,7 +2694,7 @@ def parse_command_line(cmdline):
static PyObject *py_parse_command_line(const char *cmdline) static PyObject *py_parse_command_line(const char *cmdline)
{ {
qstrvec_t args; qstrvec_t args;
if ( parse_command_line(cmdline, &args) == 0 ) if ( parse_command_line2(cmdline, &args, NULL) == 0 )
Py_RETURN_NONE; Py_RETURN_NONE;
PyObject *py_list = PyList_New(args.size()); 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.itype must be set >= idaapi.CUSTOM_CMD_ITYPE
- cmd.size must be set to the instruction length - cmd.size must be set to the instruction length
@return: Boolean @return: Boolean
- False if the instruction is not recognized - False if the instruction is not recognized
- True if the instruction was decoded. idaapi.cmd should be filled in that case. - 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 This flag can be used to delay the code execution
until the next UI loop run even from the main thread""" 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. Executes a function in the context of the main thread.
If the current thread not the main thread, then the call is queued and 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> #<pydoc>
def execute_ui_requests(callable_list) def execute_ui_requests(callable_list):
""" """
Inserts a list of callables into the UI message processing queue. Inserts a list of callables into the UI message processing queue.
When the UI is ready it will call one callable. 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. IDA is terminated and the database is already closed.
The UI may close its windows in this callback. 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> #</pydoc>
*/ */
@ -894,6 +898,7 @@ class UI_Hooks
public: public:
virtual ~UI_Hooks() virtual ~UI_Hooks()
{ {
unhook();
} }
bool hook() bool hook()
@ -2690,10 +2695,10 @@ private:
PYW_GIL_ENSURE; PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallMethod( PyObject *py_result = PyObject_CallMethod(
_this->py_obj, _this->py_obj,
(char *)S_ON_CREATE, "O", (char *)S_ON_CREATE, "O",
PyCObject_FromVoidPtr(form, NULL)); PyCObject_FromVoidPtr(form, NULL));
PYW_GIL_RELEASE; PYW_GIL_RELEASE;
PyW_ShowCbErr(S_ON_CREATE); PyW_ShowCbErr(S_ON_CREATE);
Py_XDECREF(py_result); Py_XDECREF(py_result);
} }
@ -2706,10 +2711,10 @@ private:
PYW_GIL_ENSURE; PYW_GIL_ENSURE;
PyObject *py_result = PyObject_CallMethod( PyObject *py_result = PyObject_CallMethod(
_this->py_obj, _this->py_obj,
(char *)S_ON_CLOSE, "O", (char *)S_ON_CLOSE, "O",
PyCObject_FromVoidPtr(form, NULL)); PyCObject_FromVoidPtr(form, NULL));
PYW_GIL_RELEASE; PYW_GIL_RELEASE;
PyW_ShowCbErr(S_ON_CLOSE); PyW_ShowCbErr(S_ON_CLOSE);
Py_XDECREF(py_result); Py_XDECREF(py_result);
@ -2723,7 +2728,7 @@ private:
{ {
unhook_from_notification_point(HT_UI, s_callback, this); unhook_from_notification_point(HT_UI, s_callback, this);
form = NULL; form = NULL;
// Call DECREF at last, since it may trigger __del__ // Call DECREF at last, since it may trigger __del__
Py_XDECREF(py_obj); Py_XDECREF(py_obj);
} }
@ -2735,7 +2740,7 @@ public:
bool show( bool show(
PyObject *obj, PyObject *obj,
const char *caption, const char *caption,
int options) int options)
{ {
// Already displayed? // Already displayed?
@ -2757,7 +2762,7 @@ public:
form = create_tform(caption, NULL); form = create_tform(caption, NULL);
if ( form == NULL ) if ( form == NULL )
return false; return false;
if ( !hook_to_notification_point(HT_UI, s_callback, this) ) if ( !hook_to_notification_point(HT_UI, s_callback, this) )
{ {
form = NULL; form = NULL;
@ -2785,7 +2790,7 @@ public:
{ {
return PyCObject_FromVoidPtr(new plgform_t(), destroy); return PyCObject_FromVoidPtr(new plgform_t(), destroy);
} }
static void destroy(void *obj) static void destroy(void *obj)
{ {
delete (plgform_t *)obj; delete (plgform_t *)obj;
@ -2805,9 +2810,9 @@ static PyObject *plgform_new()
static bool plgform_show( static bool plgform_show(
PyObject *py_link, PyObject *py_link,
PyObject *py_obj, PyObject *py_obj,
const char *caption, const char *caption,
int options = FORM_MDI|FORM_TAB|FORM_MENU|FORM_RESTORE) int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
{ {
DECL_PLGFORM; DECL_PLGFORM;
return plgform->show(py_obj, caption, options); return plgform->show(py_obj, caption, options);
@ -5531,7 +5536,7 @@ class PluginForm(object):
""" """
FORM_MDI = 0x01 FORM_MDI = 0x01
"""start by default as MDI""" """start by default as MDI (obsolete)"""
FORM_TAB = 0x02 FORM_TAB = 0x02
"""attached by default to a tab""" """attached by default to a tab"""
FORM_RESTORE = 0x04 FORM_RESTORE = 0x04
@ -5560,7 +5565,7 @@ class PluginForm(object):
@param caption: The form caption @param caption: The form caption
@param options: One of PluginForm.FORM_ constants @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) return _idaapi.plgform_show(self.__clink__, self, caption, options)

View File

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

View File

@ -83,7 +83,17 @@
%ignore get_process_exit_code; %ignore get_process_exit_code;
%ignore BELOW_NORMAL_PRIORITY_CLASS; %ignore BELOW_NORMAL_PRIORITY_CLASS;
%ignore parse_command_line; %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" %include "pro.h"
SWIG_DECLARE_PY_CLINKED_OBJECT(qstrvec_t) SWIG_DECLARE_PY_CLINKED_OBJECT(qstrvec_t)

View File

@ -87,6 +87,7 @@
%ignore decorate_name; %ignore decorate_name;
%ignore gen_decorate_name; %ignore gen_decorate_name;
%ignore calc_bare_name; %ignore calc_bare_name;
%ignore calc_cpp_name;
%ignore predicate_t; %ignore predicate_t;
%ignore choose_named_type; %ignore choose_named_type;
%ignore get_default_align; %ignore get_default_align;
@ -131,6 +132,14 @@
%ignore type_pair_vec_t::add_names; %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 // Kernel-only symbols
%ignore init_til; %ignore init_til;
%ignore save_til; %ignore save_til;
@ -161,6 +170,7 @@
%rename (load_til) load_til_wrap; %rename (load_til) load_til_wrap;
%rename (get_type_size0) py_get_type_size0; %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_idb) py_unpack_object_from_idb;
%rename (unpack_object_from_bv) py_unpack_object_from_bv; %rename (unpack_object_from_bv) py_unpack_object_from_bv;
%rename (pack_object_to_idb) py_pack_object_to_idb; %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); p_list *fields = (p_list *) PyString_AsString(py_fields);
idc_value_t idc_obj; idc_value_t idc_obj;
error_t err = unpack_object_from_idb( error_t err = unpack_object_from_idb(
&idc_obj, &idc_obj,
ti, ti,
type, type,
fields, fields,
ea, ea,
NULL, NULL,
pio_flags); pio_flags);
// Unpacking failed? // Unpacking failed?
@ -281,7 +291,7 @@ PyObject *py_unpack_object_from_idb(
// Convert // Convert
PyObject *py_ret(NULL); PyObject *py_ret(NULL);
err = idcvar_to_pyvar(idc_obj, &py_ret); err = idcvar_to_pyvar(idc_obj, &py_ret);
// Conversion failed? // Conversion failed?
if ( err != CIP_OK ) if ( err != CIP_OK )
return Py_BuildValue("(ii)", 0, err); return Py_BuildValue("(ii)", 0, err);
@ -334,11 +344,11 @@ PyObject *py_unpack_object_from_bv(
idc_value_t idc_obj; idc_value_t idc_obj;
error_t err = unpack_object_from_bv( error_t err = unpack_object_from_bv(
&idc_obj, &idc_obj,
ti, ti,
type, type,
fields, fields,
bytes, bytes,
pio_flags); pio_flags);
// Unpacking failed? // 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); 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) char *idc_get_type(ea_t ea, char *buf, size_t bufsize)
{ {
qtype type, fnames; qtype type, fnames;

View File

@ -5,6 +5,7 @@
# #
import glob import glob
import sys import sys
import os
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
def extract_docs(lines, out): def extract_docs(lines, out):
@ -67,17 +68,29 @@ def extract_docs(lines, out):
elif line == S_INLINE: elif line == S_INLINE:
in_inline = True 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'): def gen_docs(path = '../swig/', outfn = 'idaapi.py', mask = '*.i'):
out = [] 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): for fn in glob.glob(path + mask):
f = open(fn, 'r') fn = fn.replace('\\', '/')
lines = f.readlines() if fn != idaapi_i:
f.close() gen_docs_from(fn, out)
extract_docs(lines, out)
f = open(outfn, 'w') 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.write('\n'.join(out))
f.close() f.close()