Applied patches from Hex-Rays:

- added MakeYword
- wrap obsolete IDA API functions too, so that old scripts continue to work
- added debugger trace related functions in idc.py
BUGFIX: IDAPython would fail with a cryptic error message if there was no free space on the current disk
BUGFIX: site-packages directory was missing from sys.path
BUGFIX: functions for working with additional lines (LineA/LineB etc) were broken
BUGFIX: GetFixup* functions from idc.py were broken
BUGFIX: IDA could not start if another python27.dll was present in PATH and importing site.py for that Python installation failed
BUGFIX: SaveBase() was broken
BUGFIX: IDAPython would fail with a cryptic error message if there was no free space on the current disk
BUGFIX: IDAPython: site-packages directory was missing from sys.path
BUGFIX: IDAPython: functions for working with additional lines (LineA/LineB etc) were broken
BUGFIX: IDAPython: GetFixup* functions from idc.py were broken
BUGFIX: IDAPython: IDA could not start if another python27.dll was present in PATH and importing site.py for that Python installation failed
BUGFIX: IDAPython: SaveBase() was broken
BUGFIX: Dbg/Idp hooks automatically unhook when hook object is not referenced anymore

note: these patches are already applied in IDAPython that comes with IDA Pro 6.4
This commit is contained in:
elias.bachaalany@gmail.com 2013-03-06 07:44:10 +00:00
parent 69d5c83d28
commit 223e4a5268
26 changed files with 501 additions and 123 deletions

View File

@ -18,8 +18,6 @@
#define _SSIZE_T_DEFINED 1
#endif
#include <stdio.h>
#include <string.h>
#ifdef __LINUX__
#include <dlfcn.h>
#endif
@ -28,13 +26,10 @@
#endif
#include <ida.hpp>
#include <idp.hpp>
#include <ieee.h>
#include <bytes.hpp>
#include <diskio.hpp>
#include <expr.hpp>
#include <diskio.hpp>
#include <loader.hpp>
#include <kernwin.hpp>
#include <netnode.hpp>
#include "pywraps.hpp"
//-------------------------------------------------------------------------
@ -83,6 +78,7 @@ static char g_idapython_dir[QMAXPATH];
// Prototypes and forward declarations
// Alias to SWIG_Init
//lint -esym(526,init_idaapi) not defined
extern "C" void init_idaapi(void);
// Plugin run() callback
@ -127,8 +123,8 @@ 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();
static void end_execution(void);
static void begin_execution(void);
//------------------------------------------------------------------------
// This callback is called on various interpreter events
@ -154,6 +150,10 @@ static int break_check(PyObject *obj, _frame *frame, int what, PyObject *arg)
#ifdef ENABLE_PYTHON_PROFILING
return tracefunc(obj, frame, what, arg);
#else
qnotused(obj);
qnotused(frame);
qnotused(what);
qnotused(arg);
return 0;
#endif
}
@ -200,6 +200,7 @@ static void end_execution()
}
//-------------------------------------------------------------------------
//lint -esym(714,disable_script_timeout) Symbol not referenced
void disable_script_timeout()
{
// Clear timeout
@ -210,6 +211,7 @@ void disable_script_timeout()
}
//-------------------------------------------------------------------------
//lint -esym(714,set_script_timeout) Symbol not referenced
int set_script_timeout(int timeout)
{
// Update the timeout
@ -411,6 +413,20 @@ bool CheckScriptFiles()
// Caller of this function should call handle_python_error() to clear the exception and print the error
static int PyRunFile(const char *FileName)
{
#ifdef __NT__
// if the current disk has no space (sic, the current directory, not the one
// with the input file), PyRun_File() will die with a cryptic message that
// C runtime library could not be loaded. So we check the disk space before
// calling it.
char curdir[QMAXPATH];
if ( _getcwd(curdir, sizeof(curdir)) == NULL
|| getdspace(curdir) == 0 )
{
warning("No free disk space on %s, python will not be available", curdir);
return 0;
}
#endif
PyObject *PyFileObject = PyFile_FromString((char*)FileName, "r");
PyObject *globals = GetMainGlobals();
if ( globals == NULL || PyFileObject == NULL )
@ -536,14 +552,6 @@ static bool RunScript(const char *script)
return ok;
}
//-------------------------------------------------------------------------
bool idaapi IDAPython_Menu_Callback(void *ud)
{
// note: on 64-bit systems the pointer will be truncated to 32-bits!
run((ssize_t)ud);
return true;
}
//-------------------------------------------------------------------------
// This function parses a name into two different components (if it applies).
// Example:
@ -766,7 +774,6 @@ bool idaapi IDAPython_extlang_create_object(
ok = pyw_convert_idc_args(args, nargs, pargs, NULL, errbuf, errbufsize);
if ( !ok )
break;
ok = false;
// Call the constructor
PYW_GIL_ENSURE;
@ -861,7 +868,7 @@ bool idaapi IDAPython_extlang_get_attr(
break;
result->set_string(clsname);
cvt = CIP_OK;
cvt = CIP_OK; //lint !e838
break;
}
@ -908,6 +915,7 @@ bool idaapi IDAPython_extlang_get_attr(
//-------------------------------------------------------------------------
// Returns the attribute value of a given object from the global scope
//lint -e{818}
bool idaapi IDAPython_extlang_set_attr(
idc_value_t *obj, // in: object name (may be NULL)
const char *attr, // in: attribute name
@ -969,6 +977,7 @@ bool idaapi IDAPython_extlang_set_attr(
//-------------------------------------------------------------------------
// Calculator callback for Python external language evaluator
//lint -e{818}
bool idaapi IDAPython_extlang_calcexpr(
ea_t /*current_ea*/,
const char *expr,
@ -1055,7 +1064,7 @@ bool idaapi IDAPython_extlang_call_method(
}
//-------------------------------------------------------------------------
extlang_t extlang_python =
const extlang_t extlang_python =
{
sizeof(extlang_t),
0,
@ -1142,7 +1151,7 @@ bool idaapi IDAPYthon_cli_complete_line(
return false;
PYW_GIL_ENSURE;
PyObject *py_ret = PyObject_CallFunction(py_complete, "sisi", prefix, n, line, x);
PyObject *py_ret = PyObject_CallFunction(py_complete, "sisi", prefix, n, line, x); //lint !e1776
PYW_GIL_RELEASE;
Py_DECREF(py_complete);

View File

@ -464,20 +464,19 @@ def SaveBase(idbname, flags=0):
@param idbname: name of the idb file. if empty, the current idb
file will be used.
@param flags: DBFL_BAK or 0
@param flags: combination of idaapi.DBFL_... bits or 0
"""
if len(idbname) == 0:
idbname = GetIdbPath()
saveflags = idaapi.cvar.database_flags
if flags & DBFL_BAK:
idaapi.cvar.database_flags |= DBFL_BAK
else:
idaapi.cvar.database_flags &= ~DBFL_BAK
mask = idaapi.DBFL_KILL | idaapi.DBFL_COMP | idaapi.DBFL_BAK
idaapi.cvar.database_flags &= ~mask
idaapi.cvar.database_flags |= flags & mask
res = idaapi.save_database(idbname, 0)
idaapi.cvar.database_flags = saveflags
return res
DBFL_BAK = 0x04 # create backup file
DBFL_BAK = idaapi.DBFL_BAK # for compatiblity with older versions, eventually delete this
def Exit(code):
@ -671,6 +670,12 @@ def MakeArray(ea, nitems):
"""
flags = idaapi.getFlags(ea)
if idaapi.isCode(flags) or idaapi.isTail(flags) or idaapi.isAlign(flags):
return False
if idaapi.isCode(flags) or idaapi.isTail(flags) or idaapi.isAlign(flags):
return False
if idaapi.isUnknown(flags):
flags = idaapi.FF_BYTE
@ -765,7 +770,7 @@ def MakeQword(ea):
def MakeOword(ea):
"""
Convert the current item to a octa word (16 bytes)
Convert the current item to an octa word (16 bytes/128 bits)
@param ea: linear address
@ -774,6 +779,28 @@ def MakeOword(ea):
return idaapi.doOwrd(ea, 16)
def MakeYword(ea):
"""
Convert the current item to a ymm word (32 bytes/256 bits)
@param ea: linear address
@return: 1-ok, 0-failure
"""
return idaapi.doYwrd(ea, 32)
def MakeYword(ea):
"""
Convert the current item to a ymm word (32 bytes/256 bits)
@param ea: linear address
@return: 1-ok, 0-failure
"""
return idaapi.doYwrd(ea, 32)
def MakeFloat(ea):
"""
Convert the current item to a floating point (4 bytes)
@ -1323,7 +1350,7 @@ def ExtLinA(ea, n, line):
Specify an additional line to display before the generated ones.
@param ea: linear address
@param n: number of anterior additioal line (0..MAX_ITEM_LINES)
@param n: number of anterior additional line (0..MAX_ITEM_LINES)
@param line: the line to display
@return: None
@ -1333,7 +1360,8 @@ def ExtLinA(ea, n, line):
additional line #149, your line will not be displayed. MAX_ITEM_LINES is
defined in IDA.CFG
"""
idaapi.ExtraUpdate(ea, line, idaapi.E_PREV + n)
idaapi.update_extra_cmt(ea, idaapi.E_PREV + n, line)
idaapi.doExtra(ea)
def ExtLinB(ea, n, line):
@ -1341,7 +1369,7 @@ def ExtLinB(ea, n, line):
Specify an additional line to display after the generated ones.
@param ea: linear address
@param n: number of posterior additioal line (0..MAX_ITEM_LINES)
@param n: number of posterior additional line (0..MAX_ITEM_LINES)
@param line: the line to display
@return: None
@ -1351,7 +1379,8 @@ def ExtLinB(ea, n, line):
and there is no additional line #149, your line will not be displayed.
MAX_ITEM_LINES is defined in IDA.CFG
"""
idaapi.ExtraUpdate(ea, line, idaapi.E_NEXT + n)
idaapi.update_extra_cmt(ea, idaapi.E_NEXT + n, line)
idaapi.doExtra(ea)
def DelExtLnA(ea, n):
@ -1359,11 +1388,11 @@ def DelExtLnA(ea, n):
Delete an additional anterior line
@param ea: linear address
@param n: number of anterior additioal line (0..500)
@param n: number of anterior additional line (0..500)
@return: None
"""
idaapi.ExtraDel(ea, idaapi.E_PREV + n)
idaapi.del_extra_cmt(ea, idaapi.E_PREV + n)
def DelExtLnB(ea, n):
@ -1371,11 +1400,11 @@ def DelExtLnB(ea, n):
Delete an additional posterior line
@param ea: linear address
@param n: number of posterior additioal line (0..500)
@param n: number of posterior additional line (0..500)
@return: None
"""
idaapi.ExtraDel(ea, idaapi.E_NEXT + n)
idaapi.del_extra_cmt(ea, idaapi.E_NEXT + n)
def SetManualInsn(ea, insn):
@ -2308,7 +2337,7 @@ def LineA(ea, num):
@return: anterior line string
"""
return idaapi.ExtraGet(ea, idaapi.E_PREV + num)
return idaapi.get_extra_cmt(ea, idaapi.E_PREV + num)
def LineB(ea, num):
@ -2320,7 +2349,7 @@ def LineB(ea, num):
@return: posterior line string
"""
return idaapi.ExtraGet(ea, idaapi.E_NEXT + num)
return idaapi.get_extra_cmt(ea, idaapi.E_NEXT + num)
def GetCommentEx(ea, repeatable):
@ -6954,6 +6983,159 @@ def DelHiddenArea(ea):
return idaapi.del_hidden_area(ea)
def GetStepTraceOptions():
"""
Get step current tracing options
@return: a combination of ST_... constants
"""
return idaapi.get_step_trace_options()
def SetStepTraceOptions(options):
"""
Set step current tracing options.
@param options: combination of ST_... constants
"""
return idaapi.set_step_trace_options(options)
ST_OVER_DEBUG_SEG = 0x01 # step tracing will be disabled when IP is in a debugger segment
ST_OVER_LIB_FUNC = 0x02 # step tracing will be disabled when IP is in a library function
ST_ALREADY_LOGGED = 0x04 # step tracing will be disabled when IP is already logged
ST_SKIP_LOOPS = 0x08 # step tracing will try to skip loops already recorded
def LoadTraceFile(filename):
"""
Load a previously recorded binary trace file
@param filename: trace file
"""
return idaapi.load_trace_file(filename, None)
def SaveTraceFile(filename, description):
"""
Save current trace to a binary trace file
@param filename: trace file
"""
return idaapi.save_trace_file(filename, description)
def CheckTraceFile(filename):
"""
Check the given binary trace file
@param filename: trace file
"""
return idaapi.is_valid_trace_file(filename)
def ClearTraceFile(filename):
"""
Clear the current trace buffer
"""
return idaapi.clear_trace()
def GetTraceDesc(filename):
"""
Get the trace description of the given binary trace file
@param filename: trace file
"""
return idaapi.get_trace_file_desc(filename)
def SetTraceDesc(filename, description):
"""
Update the trace description of the given binary trace file
@param filename: trace file
@description: trace description
"""
return idaapi.set_trace_file_desc(filename, description)
def GetMaxTev():
"""
Return the total number of recorded events
"""
return idaapi.get_tev_qty()
def GetTevEa(tev):
"""
Return the address of the specified event
@param tev: event number
"""
return idaapi.get_tev_ea(tev)
TEV_NONE = 0 # no event
TEV_INSN = 1 # an instruction trace
TEV_CALL = 2 # a function call trace
TEV_RET = 3 # a function return trace
TEV_BPT = 4 # write, read/write, execution trace
TEV_MEM = 5 # memory layout changed
TEV_EVENT = 6 # debug event
def GetTevType(tev):
"""
Return the type of the specified event (TEV_... constants)
@param tev: event number
"""
return idaapi.get_tev_type(tev)
def GetTevTid(tev):
"""
Return the thread id of the specified event
@param tev: event number
"""
return idaapi.get_tev_tid(tev)
def GetTevRegVal(tev, reg):
"""
Return the register value for the specified event
@param tev: event number
@param reg: register name (like EAX, RBX, ...)
"""
return idaapi.get_tev_reg_val(tev, reg)
def GetTevRegMemQty(tev):
"""
Return the number of memory addresses recorded for the specified event
@param tev: event number
"""
return idaapi.get_tev_reg_mem_qty(tev)
def GetTevRegMem(tev, idx):
"""
Return the memory pointed by 'index' for the specified event
@param tev: event number
@param idx: memory address index
"""
return idaapi.get_tev_reg_mem(tev, idx)
def GetTevRegMemEa(tev, idx):
"""
Return the address pointed by 'index' for the specified event
@param tev: event number
@param idx: memory address index
"""
return idaapi.get_tev_reg_mem_ea(tev, idx)
def GetTevCallee(tev):
"""
Return the address of the callee for the specified event
@param tev: event number
"""
return idaapi.get_call_tev_callee(tev)
def GetTevReturn(tev):
"""
Return the return address for the specified event
@param tev: event number
"""
return idaapi.get_ret_tev_return(tev)
def GetBptTevEa(tev):
"""
Return the address of the specified TEV_BPT event
@param tev: event number
"""
return idaapi.get_bpt_tev_ea(tev)
#--------------------------------------------------------------------------
# D E B U G G E R I N T E R F A C E
#--------------------------------------------------------------------------
@ -7784,13 +7966,17 @@ BPT_WRITE = 1 # Hardware: Write access
BPT_RDWR = 3 # Hardware: Read/write access
BPT_SOFT = 4 # Software breakpoint
BPTATTR_COUNT = 4
BPTATTR_FLAGS = 5
BPT_BRK = 0x01 # the debugger stops on this breakpoint
BPT_TRACE = 0x02 # the debugger adds trace information when this breakpoint is reached
BPT_UPDMEM = 0x04 # refresh the memory layout and contents before evaluating bpt condition
BPT_ENABLED = 0x08 # enabled?
BPT_LOWCND = 0x10 # condition is calculated at low level (on the server side)
BPTATTR_COUNT = 4
BPTATTR_FLAGS = 5
BPT_BRK = 0x001 # the debugger stops on this breakpoint
BPT_TRACE = 0x002 # the debugger adds trace information when this breakpoint is reached
BPT_UPDMEM = 0x004 # refresh the memory layout and contents before evaluating bpt condition
BPT_ENABLED = 0x008 # enabled?
BPT_LOWCND = 0x010 # condition is calculated at low level (on the server side)
BPT_TRACEON = 0x020 # enable tracing when the breakpoint is reached
BPT_TRACE_INSN = 0x040 # instruction tracing
BPT_TRACE_FUNC = 0x080 # function tracing
BPT_TRACE_BBLK = 0x100 # basic block tracing
BPTATTR_COND = 6 # Breakpoint condition. NOTE: the return value is a string in this case
@ -7960,6 +8146,159 @@ TRACE_STEP = 0x0 # lowest level trace. trace buffers are not maintained
TRACE_INSN = 0x1 # instruction level trace
TRACE_FUNC = 0x2 # function level trace (calls & rets)
def GetStepTraceOptions():
"""
Get step current tracing options
@return: a combination of ST_... constants
"""
return idaapi.get_step_trace_options()
def SetStepTraceOptions(options):
"""
Set step current tracing options.
@param options: combination of ST_... constants
"""
return idaapi.set_step_trace_options(options)
ST_OVER_DEBUG_SEG = 0x01 # step tracing will be disabled when IP is in a debugger segment
ST_OVER_LIB_FUNC = 0x02 # step tracing will be disabled when IP is in a library function
ST_ALREADY_LOGGED = 0x04 # step tracing will be disabled when IP is already logged
ST_SKIP_LOOPS = 0x08 # step tracing will try to skip loops already recorded
def LoadTraceFile(filename):
"""
Load a previously recorded binary trace file
@param filename: trace file
"""
return idaapi.load_trace_file(filename, None)
def SaveTraceFile(filename, description):
"""
Save current trace to a binary trace file
@param filename: trace file
"""
return idaapi.save_trace_file(filename, description)
def CheckTraceFile(filename):
"""
Check the given binary trace file
@param filename: trace file
"""
return idaapi.is_valid_trace_file(filename)
def ClearTraceFile(filename):
"""
Clear the current trace buffer
"""
return idaapi.clear_trace()
def GetTraceDesc(filename):
"""
Get the trace description of the given binary trace file
@param filename: trace file
"""
return idaapi.get_trace_file_desc(filename)
def SetTraceDesc(filename, description):
"""
Update the trace description of the given binary trace file
@param filename: trace file
@description: trace description
"""
return idaapi.set_trace_file_desc(filename, description)
def GetMaxTev():
"""
Return the total number of recorded events
"""
return idaapi.get_tev_qty()
def GetTevEa(tev):
"""
Return the address of the specified event
@param tev: event number
"""
return idaapi.get_tev_ea(tev)
TEV_NONE = 0 # no event
TEV_INSN = 1 # an instruction trace
TEV_CALL = 2 # a function call trace
TEV_RET = 3 # a function return trace
TEV_BPT = 4 # write, read/write, execution trace
TEV_MEM = 5 # memory layout changed
TEV_EVENT = 6 # debug event
def GetTevType(tev):
"""
Return the type of the specified event (TEV_... constants)
@param tev: event number
"""
return idaapi.get_tev_type(tev)
def GetTevTid(tev):
"""
Return the thread id of the specified event
@param tev: event number
"""
return idaapi.get_tev_tid(tev)
def GetTevRegVal(tev, reg):
"""
Return the register value for the specified event
@param tev: event number
@param reg: register name (like EAX, RBX, ...)
"""
return idaapi.get_tev_reg_val(tev, reg)
def GetTevRegMemQty(tev):
"""
Return the number of memory addresses recorded for the specified event
@param tev: event number
"""
return idaapi.get_tev_reg_mem_qty(tev)
def GetTevRegMem(tev, idx):
"""
Return the memory pointed by 'index' for the specified event
@param tev: event number
@param idx: memory address index
"""
return idaapi.get_tev_reg_mem(tev, idx)
def GetTevRegMemEa(tev, idx):
"""
Return the address pointed by 'index' for the specified event
@param tev: event number
@param idx: memory address index
"""
return idaapi.get_tev_reg_mem_ea(tev, idx)
def GetTevCallee(tev):
"""
Return the address of the callee for the specified event
@param tev: event number
"""
return idaapi.get_call_tev_callee(tev)
def GetTevReturn(tev):
"""
Return the return address for the specified event
@param tev: event number
"""
return idaapi.get_ret_tev_return(tev)
def GetBptTevEa(tev):
"""
Return the address of the specified TEV_BPT event
@param tev: event number
"""
return idaapi.get_bpt_tev_ea(tev)
#--------------------------------------------------------------------------
# C O L O R S
#--------------------------------------------------------------------------

View File

@ -141,8 +141,8 @@ bool PyW_GetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var);
// Returns a qstring from a Python attribute string
bool PyW_GetStringAttr(
PyObject *py_obj,
const char *attr_name,
PyObject *py_obj,
const char *attr_name,
qstring *str);
// Converts a Python number to an uint64 and indicates whether the number was a long number
@ -205,7 +205,7 @@ int idcvar_to_pyvar(
// Walks a Python list or Sequence and calls the callback
Py_ssize_t pyvar_walk_list(
PyObject *py_list,
PyObject *py_list,
int (idaapi *cb)(PyObject *py_item, Py_ssize_t index, void *ud) = NULL,
void *ud = NULL);

View File

@ -91,11 +91,11 @@ echo Deploying lines
rem --------------------------------------------------------------------------
echo Deploying pc_win32_appcall
%PY% deploy.py appcalltest py_appcall.py ..\..\..\ida\tests\input\pc_win32_appcall.pe.hints
%PY% deploy.py appcalltest py_appcall.py ..\..\..\tests\input\pc_win32_appcall.pe.hints
rem --------------------------------------------------------------------------
echo Deploying ex_custdata example
%PY% deploy.py ex_custdata ..\examples\ex_custdata.py ..\..\..\ida\tests\input\pc_win32_custdata1.pe.hints
%PY% deploy.py ex_custdata ..\examples\ex_custdata.py ..\..\..\tests\input\pc_win32_custdata1.pe.hints
rem --------------------------------------------------------------------------
echo Deploying ex_formchooser

View File

@ -167,7 +167,7 @@ class data_format_t(object):
# pass
#</pydoc>
# -----------------------------------------------------------------------
def __walk_types_and_formats(formats, type_action, format_action):
def __walk_types_and_formats(formats, type_action, format_action, installing):
broken = False
for f in formats:
if len(f) == 1:
@ -177,13 +177,19 @@ def __walk_types_and_formats(formats, type_action, format_action):
else:
dt = f[0]
dfs = f[1:]
if not type_action(dt):
# install data type before installing formats
if installing and not type_action(dt):
broken = True
break
# process formats using the correct dt.id
for df in dfs:
if not format_action(df, dt.id):
broken = True
break
# uninstall data type after uninstalling formats
if not installing and not type_action(dt):
broken = True
break
return not broken
# -----------------------------------------------------------------------
@ -208,16 +214,16 @@ def register_data_types_and_formats(formats):
def __reg_format(df, dtid):
df.register(dtid)
if dtid == 0:
print "Registering format '%s' with built-in types, ID=%d" % (df.name, df.id)
print "Registered format '%s' with built-in types, ID=%d" % (df.name, df.id)
else:
print " Registering format '%s', ID=%d (dtid=%d)" % (df.name, df.id, dtid)
print " Registered format '%s', ID=%d (dtid=%d)" % (df.name, df.id, dtid)
return df.id != -1
def __reg_type(dt):
dt.register()
print "Registering type '%s', ID=%d" % (dt.name, dt.id)
print "Registered type '%s', ID=%d" % (dt.name, dt.id)
return dt.id != -1
ok = __walk_types_and_formats(formats, __reg_type, __reg_format)
ok = __walk_types_and_formats(formats, __reg_type, __reg_format, True)
return 1 if ok else -1
# -----------------------------------------------------------------------
@ -226,15 +232,15 @@ def unregister_data_types_and_formats(formats):
unregisters multiple data types and formats at once.
"""
def __unreg_format(df, dtid):
df.unregister(dtid)
print "%snregistering format '%s'" % ("U" if dtid == 0 else " u", df.name)
df.unregister(dtid)
return True
def __unreg_type(dt):
print "Unregistering type '%s', ID=%d" % (dt.name, dt.id)
dt.unregister()
return True
ok = __walk_types_and_formats(formats, __unreg_type, __unreg_format)
ok = __walk_types_and_formats(formats, __unreg_type, __unreg_format, False)
return 1 if ok else -1
#</pycode(py_bytes)>

View File

@ -522,7 +522,7 @@ public:
if ( _form == NULL )
return false;
open_tform(_form, FORM_TAB|FORM_MENU|FORM_RESTORE);
open_tform(_form, FORM_TAB|FORM_MENU|FORM_RESTORE|FORM_QWIDGET);
return true;
}
};
@ -807,7 +807,8 @@ public:
//--------------------------------------------------------------------------
bool jumpto(size_t ln, int x, int y)
{
return customviewer_t::jumpto(&simpleline_place_t(ln), x, y);
simpleline_place_t l(ln);
return customviewer_t::jumpto(&l, x, y);
}
//--------------------------------------------------------------------------

View File

@ -466,7 +466,7 @@ int idaapi DBG_Callback(void *ud, int notification_code, va_list va);
class DBG_Hooks
{
public:
virtual ~DBG_Hooks() {};
virtual ~DBG_Hooks() { unhook(); };
bool hook() { return hook_to_notification_point(HT_DBG, DBG_Callback, this); };
bool unhook() { return unhook_from_notification_point(HT_DBG, DBG_Callback, this); };

View File

@ -562,7 +562,7 @@ private:
void show()
{
open_tform(form, FORM_TAB|FORM_MENU);
open_tform(form, FORM_TAB|FORM_MENU|FORM_QWIDGET);
}
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_TAB | FORM_MENU);
open_tform(form, FORM_TAB | FORM_MENU | FORM_QWIDGET);
if ( gv != NULL )
viewer_fit_window(gv);
}

View File

@ -674,6 +674,7 @@ class IDP_Hooks
public:
virtual ~IDP_Hooks()
{
unhook();
}
bool hook()
@ -795,7 +796,7 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va);
class IDB_Hooks
{
public:
virtual ~IDB_Hooks() {};
virtual ~IDB_Hooks() { unhook(); };
bool hook()
{

View File

@ -13,7 +13,7 @@ static void idaapi s_py_get_user_defined_prefix(
size_t bufsize)
{
PyObject *py_ret = PyObject_CallFunction(
py_get_user_defined_prefix,
py_get_user_defined_prefix,
PY_FMT64 "iis" PY_FMT64,
ea, lnnum, indent, line, bufsize);
@ -53,11 +53,11 @@ def set_user_defined_prefix(width, callback):
lnnum - line number
indent - indent of the line contents (-1 means the default instruction)
indent and is used for instruction itself. see explanations for printf_line()
line - the line to be generated. the line usually contains color tags this argument
line - the line to be generated. the line usually contains color tags this argument
can be examined to decide whether to generated the prefix
bufsize- the maximum allowed size of the output buffer
It returns a buffer of size < bufsize
In order to remove the callback before unloading the plugin, specify the width = 0 or the callback = None
"""
pass
@ -69,7 +69,7 @@ static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb)
{
// Release old callback reference
Py_XDECREF(py_get_user_defined_prefix);
// ...and clear it
py_get_user_defined_prefix = NULL;
@ -101,7 +101,7 @@ def tag_remove(colstr):
"""
Remove color escape sequences from a string
@param colstr: the colored string with embedded tags
@return:
@return:
None on failure
or a new string w/o the tags
"""
@ -114,7 +114,7 @@ PyObject *py_tag_remove(const char *instr)
char *buf = new char[sz + 5];
if ( buf == NULL )
Py_RETURN_NONE;
ssize_t r = tag_remove(instr, buf, sz);
PyObject *res;
if ( r < 0 )
@ -162,22 +162,22 @@ int py_tag_advance(const char *line, int cnt)
def generate_disassembly(ea, max_lines, as_stack, notags):
"""
Generate disassembly lines (many lines) and put them into a buffer
@param ea: address to generate disassembly for
@param max_lines: how many lines max to generate
@param as_stack: Display undefined items as 2/4/8 bytes
@return:
@return:
- None on failure
- tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
- tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
the most important line number and a tuple of generated lines
"""
pass
#</pydoc>
*/
PyObject *py_generate_disassembly(
ea_t ea,
int max_lines,
bool as_stack,
ea_t ea,
int max_lines,
bool as_stack,
bool notags)
{
if ( max_lines <= 0 )

View File

@ -440,6 +440,8 @@ dt_string = 13 # pointer to asciiz string
dt_unicode = 14 # pointer to unicode string
dt_3byte = 15 # 3-byte data
dt_ldbl = 16 # long double (which may be different from tbyte)
dt_byte32 = 17 # 256 bit
dt_byte64 = 18 # 512 bit
#
# op_t.flags

View File

@ -70,6 +70,8 @@ dt_string = 13 # pointer to asciiz string
dt_unicode = 14 # pointer to unicode string
dt_3byte = 15 # 3-byte data
dt_ldbl = 16 # long double (which may be different from tbyte)
dt_byte32 = 17 # 256 bit
dt_byte64 = 18 # 512 bit
#
# op_t.flags

View File

@ -33,8 +33,6 @@
%ignore noFlow;
%ignore doRef;
%ignore noRef;
%ignore doExtra;
%ignore noExtra;
%ignore coagulate;
%ignore coagulate_dref;
%ignore init_hidden_areas;
@ -1160,7 +1158,7 @@ class data_format_t(object):
# pass
#</pydoc>
# -----------------------------------------------------------------------
def __walk_types_and_formats(formats, type_action, format_action):
def __walk_types_and_formats(formats, type_action, format_action, installing):
broken = False
for f in formats:
if len(f) == 1:
@ -1170,13 +1168,19 @@ def __walk_types_and_formats(formats, type_action, format_action):
else:
dt = f[0]
dfs = f[1:]
if not type_action(dt):
# install data type before installing formats
if installing and not type_action(dt):
broken = True
break
# process formats using the correct dt.id
for df in dfs:
if not format_action(df, dt.id):
broken = True
break
# uninstall data type after uninstalling formats
if not installing and not type_action(dt):
broken = True
break
return not broken
# -----------------------------------------------------------------------
@ -1201,16 +1205,16 @@ def register_data_types_and_formats(formats):
def __reg_format(df, dtid):
df.register(dtid)
if dtid == 0:
print "Registering format '%s' with built-in types, ID=%d" % (df.name, df.id)
print "Registered format '%s' with built-in types, ID=%d" % (df.name, df.id)
else:
print " Registering format '%s', ID=%d (dtid=%d)" % (df.name, df.id, dtid)
print " Registered format '%s', ID=%d (dtid=%d)" % (df.name, df.id, dtid)
return df.id != -1
def __reg_type(dt):
dt.register()
print "Registering type '%s', ID=%d" % (dt.name, dt.id)
print "Registered type '%s', ID=%d" % (dt.name, dt.id)
return dt.id != -1
ok = __walk_types_and_formats(formats, __reg_type, __reg_format)
ok = __walk_types_and_formats(formats, __reg_type, __reg_format, True)
return 1 if ok else -1
# -----------------------------------------------------------------------
@ -1219,15 +1223,15 @@ def unregister_data_types_and_formats(formats):
unregisters multiple data types and formats at once.
"""
def __unreg_format(df, dtid):
df.unregister(dtid)
print "%snregistering format '%s'" % ("U" if dtid == 0 else " u", df.name)
df.unregister(dtid)
return True
def __unreg_type(dt):
print "Unregistering type '%s', ID=%d" % (dt.name, dt.id)
dt.unregister()
return True
ok = __walk_types_and_formats(formats, __unreg_type, __unreg_format)
ok = __walk_types_and_formats(formats, __unreg_type, __unreg_format, False)
return 1 if ok else -1
#</pycode(py_bytes)>

View File

@ -119,7 +119,7 @@ int idaapi DBG_Callback(void *ud, int notification_code, va_list va);
class DBG_Hooks
{
public:
virtual ~DBG_Hooks() {};
virtual ~DBG_Hooks() { unhook(); };
bool hook() { return hook_to_notification_point(HT_DBG, DBG_Callback, this); };
bool unhook() { return unhook_from_notification_point(HT_DBG, DBG_Callback, this); };

View File

@ -1,6 +1,11 @@
%ignore apply_fixup;
%ignore convert_fixups;
%ignore move_fixups;
%ignore custom_fixup_handler_t;
%ignore custom_fixup_handlers_t;
%ignore register_custom_fixup;
%ignore unregister_custom_fixup;
%ignore set_custom_fixup;
%include "fixup.hpp"

View File

@ -35,6 +35,12 @@
%include "funcs.hpp"
%inline %{
#ifndef FUNC_STATICDEF
#define FUNC_STATICDEF 0x00000008
#endif
%}
%clear(char *buf);
%clear(char *optlibs);

View File

@ -564,7 +564,7 @@ private:
void show()
{
open_tform(form, FORM_TAB|FORM_MENU);
open_tform(form, FORM_TAB|FORM_MENU|FORM_QWIDGET);
}
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_TAB | FORM_MENU);
open_tform(form, FORM_TAB | FORM_MENU | FORM_QWIDGET);
if ( gv != NULL )
viewer_fit_window(gv);
}

View File

@ -54,10 +54,6 @@ static PyObject *type##_get_clink_ptr(PyObject *self)
#define USE_DANGEROUS_FUNCTIONS 1
#endif
#ifndef NO_OBSOLETE_FUNCS
#define NO_OBSOLETE_FUNCS 1
#endif
#ifdef HAVE_SSIZE_T
#define _SSIZE_T_DEFINED 1
#endif

View File

@ -1,5 +1,5 @@
// Ignore the following symbols
%ignore WorkReg;
%ignore WorkReg;
%ignore AbstractRegister;
%ignore rginfo;
%ignore insn_t::get_canon_mnem;
@ -715,6 +715,7 @@ class IDP_Hooks
public:
virtual ~IDP_Hooks()
{
unhook();
}
bool hook()
@ -836,7 +837,7 @@ int idaapi IDB_Callback(void *ud, int notification_code, va_list va);
class IDB_Hooks
{
public:
virtual ~IDB_Hooks() {};
virtual ~IDB_Hooks() { unhook(); };
bool hook()
{

View File

@ -3352,7 +3352,7 @@ public:
if ( _form == NULL )
return false;
open_tform(_form, FORM_TAB|FORM_MENU|FORM_RESTORE);
open_tform(_form, FORM_TAB|FORM_MENU|FORM_RESTORE|FORM_QWIDGET);
return true;
}
};
@ -3637,7 +3637,8 @@ public:
//--------------------------------------------------------------------------
bool jumpto(size_t ln, int x, int y)
{
return customviewer_t::jumpto(&simpleline_place_t(ln), x, y);
simpleline_place_t l(ln);
return customviewer_t::jumpto(&l, x, y);
}
//--------------------------------------------------------------------------
@ -5703,12 +5704,12 @@ class Choose:
"""
old = set_script_timeout(0)
n = _idaapi.choose_choose(
self,
self.flags,
self.x0,
self.y0,
self.x1,
self.y1,
self,
self.flags,
self.x0,
self.y0,
self.x1,
self.y1,
self.width,
self.deflt,
self.icon)

View File

@ -35,10 +35,9 @@
%ignore set_makeline_producer;
%ignore closing_comment;
%ignore close_comment;
%ignore copy_extra_lines;
%ignore ExtraLines;
%ignore ExtraKill;
%ignore ExtraFree;
%ignore copy_extra_cmts;
%ignore gen_extra_cmts;
%ignore get_first_free_extra_cmtidx;
%ignore Dumper;
%ignore init_lines;
%ignore save_lines;
@ -87,7 +86,7 @@ static void idaapi s_py_get_user_defined_prefix(
size_t bufsize)
{
PyObject *py_ret = PyObject_CallFunction(
py_get_user_defined_prefix,
py_get_user_defined_prefix,
PY_FMT64 "iis" PY_FMT64,
ea, lnnum, indent, line, bufsize);
@ -127,11 +126,11 @@ def set_user_defined_prefix(width, callback):
lnnum - line number
indent - indent of the line contents (-1 means the default instruction)
indent and is used for instruction itself. see explanations for printf_line()
line - the line to be generated. the line usually contains color tags this argument
line - the line to be generated. the line usually contains color tags this argument
can be examined to decide whether to generated the prefix
bufsize- the maximum allowed size of the output buffer
It returns a buffer of size < bufsize
In order to remove the callback before unloading the plugin, specify the width = 0 or the callback = None
"""
pass
@ -143,7 +142,7 @@ static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb)
{
// Release old callback reference
Py_XDECREF(py_get_user_defined_prefix);
// ...and clear it
py_get_user_defined_prefix = NULL;
@ -175,7 +174,7 @@ def tag_remove(colstr):
"""
Remove color escape sequences from a string
@param colstr: the colored string with embedded tags
@return:
@return:
None on failure
or a new string w/o the tags
"""
@ -188,7 +187,7 @@ PyObject *py_tag_remove(const char *instr)
char *buf = new char[sz + 5];
if ( buf == NULL )
Py_RETURN_NONE;
ssize_t r = tag_remove(instr, buf, sz);
PyObject *res;
if ( r < 0 )
@ -236,22 +235,22 @@ int py_tag_advance(const char *line, int cnt)
def generate_disassembly(ea, max_lines, as_stack, notags):
"""
Generate disassembly lines (many lines) and put them into a buffer
@param ea: address to generate disassembly for
@param max_lines: how many lines max to generate
@param as_stack: Display undefined items as 2/4/8 bytes
@return:
@return:
- None on failure
- tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
- tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
the most important line number and a tuple of generated lines
"""
pass
#</pydoc>
*/
PyObject *py_generate_disassembly(
ea_t ea,
int max_lines,
bool as_stack,
ea_t ea,
int max_lines,
bool as_stack,
bool notags)
{
if ( max_lines <= 0 )

View File

@ -85,10 +85,6 @@
%ignore is_database_ext;
%ignore ida_database_memory;
%ignore ida_workdir;
%ignore DBFL_KILL;
%ignore DBFL_COMP;
%ignore DBFL_BAK;
%ignore DBFL_TEMP;
%ignore is_temp_database;
%ignore pe_create_idata;
%ignore pe_load_resources;
@ -118,7 +114,6 @@
%ignore update_snapshot_attributes;
%ignore build_snapshot_tree;
%ignore visit_snapshot_tree;
%ignore save_database_ex;
%ignore snapshot_t;
%ignore snapshots_t;
%ignore load_plugin;

View File

@ -6,6 +6,11 @@
%ignore NALT_EA;
%ignore enum_import_names;
%rename (enum_import_names) py_enum_import_names;
%ignore custom_refinfo_handler_t;
%ignore custom_refinfo_handlers_t;
%ignore register_custom_refinfo;
%ignore unregister_custom_refinfo;
%ignore get_custom_refinfos;
%include "nalt.hpp"

View File

@ -74,6 +74,7 @@
%ignore netnode::inited;
%ignore netnode::init;
%ignore netnode::flush;
%ignore netnode::get_linput;
%ignore netnode::term;
%ignore netnode::killbase;
%ignore netnode::getdrive;

View File

@ -88,6 +88,7 @@
%ignore gen_decorate_name;
%ignore calc_bare_name;
%ignore calc_cpp_name;
%ignore calc_c_cpp_name;
%ignore predicate_t;
%ignore choose_named_type;
%ignore get_default_align;
@ -129,6 +130,7 @@
%ignore has_delay_slot_t;
%ignore gen_use_arg_types;
%ignore enable_numbered_types;
%ignore compact_numbered_types;
%ignore type_pair_vec_t::add_names;
@ -163,6 +165,7 @@
%ignore for_all_types_ex;
%ignore fix_idb_type;
%ignore pdb2ti;
%ignore process_sdacl_padding;
%include "typeinf.hpp"

View File

@ -1276,6 +1276,8 @@ dt_string = 13 # pointer to asciiz string
dt_unicode = 14 # pointer to unicode string
dt_3byte = 15 # 3-byte data
dt_ldbl = 16 # long double (which may be different from tbyte)
dt_byte32 = 17 # 256 bit
dt_byte64 = 18 # 512 bit
#
# op_t.flags