Brought in all fixes since Jan 8th, 2016.

Specifically:
 BUGFIX: IDAPython's choose.choose() was broken.
 BUGFIX: calling idaapi.del_hotkey() twice with the same argument could crash IDA.
 BUGFIX: IDAPython's IDC emulation of idc.GetTevRegMem() was not working.
 BUGFIX: IDAPython: execute_ui_requests() could crash IDA.
 BUGFIX: IDAPython: IDP_Hooks instances could prevent the decompiler from working properly
This commit is contained in:
Arnaud Diederen
2016-03-09 10:33:06 +01:00
parent 696cd2d551
commit c04b70e0e5
22 changed files with 278 additions and 150 deletions
+11 -11
View File
@@ -3,14 +3,14 @@
# - enumerate imports
# - enumerate entrypoints
# - Use PluginForm class
# - Use PySide with PluginForm to create a Python UI
# - Use PyQt with PluginForm to create a Python UI
#
# (c) Hex-Rays
#
import idaapi
import idautils
from idaapi import PluginForm
from PySide import QtGui, QtCore
from PyQt5 import QtCore, QtWidgets
# --------------------------------------------------------------------------
class ImpExpForm_t(PluginForm):
@@ -51,24 +51,24 @@ class ImpExpForm_t(PluginForm):
self.tree.clear()
# Build imports
root = QtGui.QTreeWidgetItem(self.tree)
root = QtWidgets.QTreeWidgetItem(self.tree)
root.setText(0, "Imports")
for dll_name, imp_entries in self.BuildImports().items():
imp_dll = QtGui.QTreeWidgetItem(root)
imp_dll = QtWidgets.QTreeWidgetItem(root)
imp_dll.setText(0, dll_name)
for imp_ea, imp_name, imp_ord in imp_entries:
item = QtGui.QTreeWidgetItem(imp_dll)
item = QtWidgets.QTreeWidgetItem(imp_dll)
item.setText(0, "%s [0x%08x]" %(imp_name, imp_ea))
# Build exports
root = QtGui.QTreeWidgetItem(self.tree)
root = QtWidgets.QTreeWidgetItem(self.tree)
root.setText(0, "Exports")
for exp_i, exp_ord, exp_ea, exp_name in self.BuildExports():
item = QtGui.QTreeWidgetItem(root)
item = QtWidgets.QTreeWidgetItem(root)
item.setText(0, "%s [#%d] [0x%08x]" % (exp_name, exp_ord, exp_ea))
@@ -78,15 +78,15 @@ class ImpExpForm_t(PluginForm):
"""
# Get parent widget
self.parent = self.FormToPySideWidget(form)
self.parent = self.FormToPyQtWidget(form)
# Create tree control
self.tree = QtGui.QTreeWidget()
self.tree = QtWidgets.QTreeWidget()
self.tree.setHeaderLabels(("Names",))
self.tree.setColumnWidth(0, 100)
# Create layout
layout = QtGui.QVBoxLayout()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(self.tree)
self.PopulateTree()
@@ -121,4 +121,4 @@ def main():
ImpExpForm.Show()
# --------------------------------------------------------------------------
main()
main()
+43
View File
@@ -2051,6 +2051,7 @@
'delete_enumplace_t',
'delete_eval_ctx_t',
'delete_exception_info_t',
'delete_excvec_t',
'delete_extra_cmts',
'delete_fixup_data_t',
'delete_fnumber_t',
@@ -2461,6 +2462,44 @@
'exception_info_t_handle',
'exception_info_t_name_get',
'exception_info_t_name_set',
'excvec_t___getitem__',
'excvec_t___len__',
'excvec_t___setitem__',
'excvec_t_at',
'excvec_t_back',
'excvec_t_back__SWIG_0',
'excvec_t_back__SWIG_1',
'excvec_t_begin',
'excvec_t_begin__SWIG_0',
'excvec_t_begin__SWIG_1',
'excvec_t_capacity',
'excvec_t_clear',
'excvec_t_empty',
'excvec_t_end',
'excvec_t_end__SWIG_0',
'excvec_t_end__SWIG_1',
'excvec_t_erase',
'excvec_t_erase__SWIG_0',
'excvec_t_erase__SWIG_1',
'excvec_t_extract',
'excvec_t_front',
'excvec_t_front__SWIG_0',
'excvec_t_front__SWIG_1',
'excvec_t_grow',
'excvec_t_inject',
'excvec_t_insert',
'excvec_t_pop_back',
'excvec_t_push_back',
'excvec_t_push_back__SWIG_0',
'excvec_t_push_back__SWIG_1',
'excvec_t_qclear',
'excvec_t_reserve',
'excvec_t_resize',
'excvec_t_resize__SWIG_0',
'excvec_t_resize__SWIG_1',
'excvec_t_size',
'excvec_t_swap',
'excvec_t_truncate',
'execute',
'execute_sync',
'execute_ui_requests',
@@ -3279,6 +3318,7 @@
'get_tev_info',
'get_tev_memory_info',
'get_tev_qty',
'get_tev_reg_mem',
'get_tev_reg_mem_ea',
'get_tev_reg_mem_qty',
'get_tev_reg_val',
@@ -4711,6 +4751,9 @@
'new_exception_info_t',
'new_exception_info_t__SWIG_0',
'new_exception_info_t__SWIG_1',
'new_excvec_t',
'new_excvec_t__SWIG_0',
'new_excvec_t__SWIG_1',
'new_fixup_data_t',
'new_fnumber_t',
'new_func_item_iterator_t',
-3
View File
@@ -4,7 +4,6 @@
#
from idaapi import Form
#<pycode(ex_askusingform)>
# --------------------------------------------------------------------------
class TestEmbeddedChooserClass(Choose2):
"""
@@ -372,8 +371,6 @@ def test_dropdown_nomodal():
tdn_form, _ = tdn_form.Compile()
tdn_form.Open()
#</pycode(ex_askusingform)>
# --------------------------------------------------------------------------
ida_main()
-5
View File
@@ -1,9 +1,6 @@
import idaapi
from idaapi import Choose2
#<pycode(py_choose2ex1)>
class chooser_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
@@ -129,5 +126,3 @@ if __name__ == '__main__':
#test_choose2_embedded()
test_choose2(False)
#</pycode(py_choose2ex1)>
-2
View File
@@ -4,7 +4,6 @@
#
from idaapi import NW_OPENIDB, NW_CLOSEIDB, NW_TERMIDA, NW_REMOVE, COLSTR, cli_t
#<pycode(ex_cli_ex1)>
class mycli_t(cli_t):
flags = 0
sname = "pycli"
@@ -59,7 +58,6 @@ class mycli_t(cli_t):
"""
print "OnCompleteLine: prefix=%s n=%d line=%s prefix_start=%d" % (prefix, n, line, prefix_start)
return None
#</pycode(ex_cli_ex1)>
# -----------------------------------------------------------------------
+1 -3
View File
@@ -5,8 +5,8 @@
import idaapi
import idc
from idaapi import simplecustviewer_t
#<pycode(py_custviewerex1)>
# -----------------------------------------------------------------------
class say_something_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
@@ -179,5 +179,3 @@ def make_many(n):
v.Show()
L.append(v)
return L
#</pycode(py_custviewerex1)>
-2
View File
@@ -4,7 +4,6 @@
#
from idaapi import set_idc_func_ex
#<pycode(ex_expr)>
def py_power(n, e):
return n ** e
@@ -13,4 +12,3 @@ if ok:
print("Now the pow() will be present IDC!")
else:
print("Failed to register pow() IDC function")
#</pycode(ex_expr)>
+25 -4
View File
@@ -17,30 +17,51 @@ class GraphCloser(action_handler_t):
return AST_ENABLE_ALWAYS
class ColorChanger(action_handler_t):
def __init__(self, graph):
action_handler_t.__init__(self)
self.graph = graph
def activate(self, ctx):
self.graph.color = self.graph.color ^ 0xffffff
self.graph.Refresh()
return 1
def update(self, ctx):
return AST_ENABLE_ALWAYS
class MyGraph(GraphViewer):
def __init__(self, funcname, result):
self.title = "call graph of " + funcname
GraphViewer.__init__(self, self.title)
self.funcname = funcname
self.result = result
self.color = 0xff00ff
def OnRefresh(self):
self.Clear()
id = self.AddNode(self.funcname)
id = self.AddNode((self.funcname, self.color))
for x in self.result.keys():
callee = self.AddNode(x)
callee = self.AddNode((x, self.color))
self.AddEdge(id, callee)
return True
def OnGetText(self, node_id):
return str(self[node_id])
return self[node_id]
def Show(self):
if not GraphViewer.Show(self):
return False
# graph closer
actname = "graph_closer:%s" % self.title
register_action(action_desc_t(actname, "Close %s" % self.title, GraphCloser(self)))
register_action(action_desc_t(actname, "Close: %s" % self.title, GraphCloser(self)))
attach_action_to_popup(self.GetTCustomControl(), None, actname)
# color changer
actname = "color_changer:%s" % self.title
register_action(action_desc_t(actname, "Change colors: %s" % self.title, ColorChanger(self)))
attach_action_to_popup(self.GetTCustomControl(), None, actname)
return True
+12 -41
View File
@@ -68,51 +68,22 @@ def run():
idaapi.user_numforms_free(numforms)
# Display user-defined local variable information
# First defined the visitor class
class dump_lvar_info_t(idaapi.user_lvar_visitor_t):
lvinf = idaapi.lvar_uservec_t()
if idaapi.restore_user_lvar_settings(lvinf, entry_ea):
print "------- User defined local variable information\n"
for lv in lvinf.lvvec:
print "Lvar defined at %x" % (lv.ll.defea, )
def __init__(self):
idaapi.user_lvar_visitor_t.__init__(self)
self.displayed_header = False
return
if len(str(lv.name)):
print " Name: %s" % (str(lv.name), )
def get_info_qty_for_saving(self):
return 0
if len(str(lv.type)):
#~ print_type_to_one_line(buf, sizeof(buf), idati, .c_str());
print " Type: %s" % (str(lv.type), )
def get_info_for_saving(self, lv):
return False
if len(str(lv.cmt)):
print " Comment: %s" % (str(lv.cmt), )
def handle_retrieved_info(self, lv):
try:
if not self.displayed_header:
self.displayed_header = True;
print "------- User defined local variable information"
print "Lvar defined at %x" % (lv.ll.defea, )
if len(str(lv.name)):
print " Name: %s" % (str(lv.name), )
if len(str(lv.type)):
#~ print_type_to_one_line(buf, sizeof(buf), idati, .c_str());
print " Type: %s" % (str(lv.type), )
if len(str(lv.cmt)):
print " Comment: %s" % (str(lv.cmt), )
except:
traceback.print_exc()
return 0
def handle_retrieved_mapping(self, lm):
return 0
def get_info_mapping_for_saving(self):
return None
# Now iterate over all user definitions
dli = dump_lvar_info_t();
idaapi.restore_user_lvar_settings(entry_ea, dli)
return
+13 -26
View File
@@ -15,17 +15,7 @@ import idc
import traceback
try:
from PyQt4 import QtCore, QtGui
print 'Using PyQt'
except:
print 'PyQt not available'
try:
from PySide import QtGui, QtCore
print 'Using PySide'
except:
print 'PySide not available'
from PyQt5 import QtCore, QtWidgets
XREF_EA = 0
XREF_STRUC_MEMBER = 1
@@ -78,10 +68,7 @@ class XrefsForm(idaapi.PluginForm):
def OnCreate(self, form):
# Get parent widget
try:
self.parent = self.FormToPySideWidget(form)
except:
self.parent = self.FormToPyQtWidget(form)
self.parent = self.FormToPyQtWidget(form)
self.populate_form()
@@ -93,16 +80,16 @@ class XrefsForm(idaapi.PluginForm):
def populate_form(self):
# Create layout
layout = QtGui.QVBoxLayout()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(QtGui.QLabel(self.__name))
self.table = QtGui.QTableWidget()
layout.addWidget(QtWidgets.QLabel(self.__name))
self.table = QtWidgets.QTableWidget()
layout.addWidget(self.table)
self.table.setColumnCount(3)
self.table.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("Address"))
self.table.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("Function"))
self.table.setHorizontalHeaderItem(2, QtGui.QTableWidgetItem("Line"))
self.table.setHorizontalHeaderItem(0, QtWidgets.QTableWidgetItem("Address"))
self.table.setHorizontalHeaderItem(1, QtWidgets.QTableWidgetItem("Function"))
self.table.setHorizontalHeaderItem(2, QtWidgets.QTableWidgetItem("Line"))
self.table.setColumnWidth(0, 80)
self.table.setColumnWidth(1, 150)
@@ -110,8 +97,8 @@ class XrefsForm(idaapi.PluginForm):
self.table.cellDoubleClicked.connect(self.double_clicked)
#~ self.table.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
self.table.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows )
#~ self.table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows )
self.parent.setLayout(layout)
self.populate_table()
@@ -244,13 +231,13 @@ class XrefsForm(idaapi.PluginForm):
i = 0
for item in self.items:
address, func, line = item
item = QtGui.QTableWidgetItem('0x%x' % (address, ))
item = QtWidgets.QTableWidgetItem('0x%x' % (address, ))
item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
self.table.setItem(i, 0, item)
item = QtGui.QTableWidgetItem(func)
item = QtWidgets.QTableWidgetItem(func)
item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
self.table.setItem(i, 1, item)
item = QtGui.QTableWidgetItem(line)
item = QtWidgets.QTableWidgetItem(line)
item.setFlags(item.flags() ^ QtCore.Qt.ItemIsEditable)
self.table.setItem(i, 2, item)
+1
View File
@@ -94,6 +94,7 @@ ifeq ($(OUT_OF_TREE_BUILD),)
DEPLOY_INIT_PY=$(SCRIPTDIR)/init.py
DEPLOY_IDC_PY=$(SCRIPTDIR)/idc.py
DEPLOY_IDAUTILS_PY=$(SCRIPTDIR)/idautils.py
DEPLOY_PYTHON_CFG=$(C)python.cfg
TEST_IDC=test_idc
else
SCRIPTDIR=python
+54 -12
View File
@@ -1715,11 +1715,7 @@ def GetInputMD5():
@return: MD5 string or None on error
"""
ua = idaapi.uchar_array(16)
if idaapi.retrieve_input_file_md5(ua.cast()):
return "".join(["%02X" % ua[i] for i in xrange(16)])
else:
return None
return idaapi.retrieve_input_file_md5()
def GetFlags(ea):
@@ -2032,7 +2028,7 @@ def GetReg(ea, reg):
@return: the value of the segment register or -1 on error
@note: The segment registers in 32bit program usually contain selectors,
so to get paragraph pointed by the segment register you need to
so to get paragraph pointed to by the segment register you need to
call AskSelector() function.
"""
reg = idaapi.str2reg(reg);
@@ -2598,6 +2594,8 @@ LFLG_64BIT = 0x04 # 64-bit program?
LFLG_DBG_NOPATH = 0x08 # do not store input full path
LFLG_SNAPSHOT = 0x10 # is memory snapshot?
# in debugger process options
LFLG_8ALIGN4 = 0x40 # 4 byte alignment for 8byte scalars
# (__int64/double) inside structures
INF_DEMNAMES = 14 # char; display demangled names as:
DEMNAM_CMNT = 0 # comments
DEMNAM_NAME = 1 # regular names
@@ -2822,6 +2820,9 @@ INF_SIZEOF_LONG = 190
INF_SIZEOF_LLONG = 191
INF_CHANGE_COUNTER = 192 # database change counter; keeps track of byte and segment modifications
INF_SIZEOF_LDBL = 196 # uchar; sizeof(long double)
INF_REFCMTS = 221 # uchar; number of comment lines to generate for refs
# to ASCII string or demangled name
# 0 - such comments won't be generated at all
# Redefine these offsets for 64-bit version
if __EA64__:
@@ -2895,7 +2896,8 @@ if __EA64__:
INF_SIZEOF_LONG = 274
INF_SIZEOF_LLONG = 275
INF_CHANGE_COUNTER = 276
INF_SIZEOF_LBDL = 280
INF_SIZEOF_LDBL = 280
INF_REFCMTS = 305
_INFMAP = {
INF_VERSION : (False, 'version'), # short; Version of database
@@ -7050,6 +7052,38 @@ PT_HIGH = 0x0080 # assume high level prototypes
PT_LOWER = 0x0100 # lower the function prototypes
def PrintLocalTypes(ordinals, flags):
"""
Print types in a format suitable for use in a header file
@param ordinals: comma-separated list of type ordinals
@param flags: combination of PDF_... constants or 0
@return: string containing the type definitions
"""
class def_sink(idaapi.text_sink_t):
def __init__(self):
idaapi.text_sink_t.__init__(self)
self.text = ""
def _print(self, defstr):
self.text += defstr
return 0
sink = def_sink()
py_ordinals = map(lambda l : int(l), ordinals.split(","))
idaapi.print_decls(sink, idaapi.cvar.idati, py_ordinals, flags)
return sink.text
PDF_INCL_DEPS = 0x1 # include dependencies
PDF_DEF_FWD = 0x2 # allow forward declarations
PDF_DEF_BASE = 0x4 # include base types: __int8, __int16, etc..
PDF_HEADER_CMT = 0x8 # prepend output with a descriptive comment
def GetMaxLocalType():
"""
Get number of local types + 1
@@ -8038,8 +8072,7 @@ def SetBptAttr(address, bptattr, value):
if bptattr == BPTATTR_FLAGS:
bpt.flags = value
idaapi.update_bpt(bpt)
return True
return idaapi.update_bpt(bpt)
def SetBptCndEx(ea, cnd, is_lowcnd):
"""
@@ -8281,14 +8314,20 @@ def GetTevRegVal(tev, reg):
def GetTevRegMemQty(tev):
"""
Return the number of memory addresses recorded for the specified event
Return the number of blobs of memory recorded, for the specified event
Note: this requires that the tracing options have been set to record pieces of memory for instruction events
@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
Return the blob of memory pointed to by 'index', for the specified event
Note: this requires that the tracing options have been set to record pieces of memory for instruction events
@param tev: event number
@param idx: memory address index
"""
@@ -8296,7 +8335,10 @@ def GetTevRegMem(tev, idx):
def GetTevRegMemEa(tev, idx):
"""
Return the address pointed by 'index' for the specified event
Return the address of the blob of memory pointed to by 'index' for the specified event
Note: this requires that the tracing options have been set to record pieces of memory for instruction events
@param tev: event number
@param idx: memory address index
"""
+3 -3
View File
@@ -39,7 +39,7 @@ void idaapi choose_enter(void *self, uint32 n)
//---------------------------------------------------------------------------
uint32 choose_choose(
void *self,
PyObject *self,
int flags,
int x0,int y0,
int x1,int y1,
@@ -48,14 +48,14 @@ uint32 choose_choose(
int icon)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t pytitle(PyObject_GetAttrString((PyObject *)self, "title"));
newref_t pytitle(PyObject_GetAttrString(self, "title"));
const char *title = pytitle != NULL ? PyString_AsString(pytitle.o) : "Choose";
int r = choose(
flags,
x0, y0,
x1, y1,
self,
(void*) self,
width,
choose_sizer,
choose_getl,
+21
View File
@@ -338,5 +338,26 @@ static ea_t py_internal_get_sreg_base(thid_t tid, int sreg_value)
: answer;
}
//-------------------------------------------------------------------------
static PyObject *py_get_tev_reg_mem(int tev, int reg)
{
tev_info_t ti;
memreg_infos_t mis;
bool ok = get_tev_info(tev, &ti)
&& get_insn_tev_reg_mem(tev, &mis)
&& reg >= 0 && reg < mis.size();
if ( ok )
{
PyObject *py_str = PyString_FromStringAndSize(
(const char *) mis[reg].bytes.begin(),
mis[reg].bytes.size());
return py_str;
}
else
{
Py_RETURN_NONE;
}
}
//</inline(py_dbg)>
#endif
+1 -1
View File
@@ -1757,7 +1757,7 @@ static PyObject *qstrvec_t_addressof(PyObject *self, size_t idx)
if ( sv == NULL || idx >= sv->size() )
Py_RETURN_NONE;
else
return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)&sv->at(idx));
return PyLong_FromUnsignedLongLong(size_t(&sv->at(idx)));
}
+50 -28
View File
@@ -695,35 +695,29 @@ struct libfunc_t;
int idaapi IDP_Callback(void *ud, int notification_code, va_list va);
class IDP_Hooks
{
public:
virtual ~IDP_Hooks()
{
unhook();
}
bool hook()
{
return hook_to_notification_point(HT_IDP, IDP_Callback, this);
}
bool unhook()
{
return unhook_from_notification_point(HT_IDP, IDP_Callback, this);
}
friend int idaapi IDP_Callback(void *ud, int notification_code, va_list va);
static int bool_to_cmdsize(bool in) { return in ? (1 + cmd.size) : 0; }
static int bool_to_2or0(bool in) { return in ? 2 : 0; }
static int cm_t_to_int(cm_t cm) { return int(cm); }
static bool _handle_string_output(PyObject *o, char *buf, size_t bufsize)
{
bool is_str = o != NULL && PyString_Check(o);
if ( is_str && buf != NULL )
qstrncpy(buf, PyString_AS_STRING(o), bufsize);
Py_XDECREF(o);
return is_str;
}
static bool _handle_qstring_output(PyObject *o, qstring *buf)
{
bool is_str = o != NULL && PyString_Check(o);
if ( is_str && buf != NULL )
buf->append(PyString_AS_STRING(o));
Py_XDECREF(o);
return is_str;
}
static int handle_custom_mnem_output(PyObject *o, char *buf, size_t bufsize)
{
int rc = 0;
if ( o != NULL && PyString_Check(o) )
{
qstrncpy(buf, PyString_AS_STRING(o), bufsize);
rc = 2;
}
Py_XDECREF(o);
return rc;
return _handle_string_output(o, buf, bufsize) ? 2 : 0;
}
static int handle_assemble_output(PyObject *o, ea_t /*ea*/, ea_t /*cs*/, ea_t /*ip*/, bool /*use32*/, const char */*line*/, uchar *bin)
{
@@ -743,7 +737,33 @@ public:
Py_XDECREF(o);
return rc;
}
static int handle_get_reg_name_output(PyObject *o, int /*reg*/, size_t /*width*/, char *buf, size_t bufsize, int /*reghi*/)
{
int rc = 0;
if ( _handle_string_output(o, buf, bufsize) )
rc = qstrlen(buf) + 2;
return rc;
}
static int handle_decorate_name3_output(PyObject *o, qstring *outbuf, const char * /*name*/, bool /*mangle*/, int /*cc*/)
{
return _handle_qstring_output(o, outbuf) ? 2 : 0;
}
public:
virtual ~IDP_Hooks()
{
unhook();
}
bool hook()
{
return hook_to_notification_point(HT_IDP, IDP_Callback, this);
}
bool unhook()
{
return unhook_from_notification_point(HT_IDP, IDP_Callback, this);
}
// hookgenIDP:methods
virtual int init(const char * idp_modname) {qnotused(idp_modname); return 0;}
virtual int term() {return 0;}
@@ -792,7 +812,7 @@ virtual void kernel_config_loaded() {}
virtual int might_change_sp(ea_t ea) {qnotused(ea); return 0;}
virtual int is_alloca_probe(ea_t ea) {qnotused(ea); return 0;}
virtual int out_3byte(ea_t dataea, uint32 value, bool analyze_only) {qnotused(dataea); qnotused(value); qnotused(analyze_only); return 0;}
virtual int get_reg_name(int reg, size_t width, char * buf, size_t bufsize, int reghi) {qnotused(reg); qnotused(width); qnotused(buf); qnotused(bufsize); qnotused(reghi); return 0;}
virtual PyObject * get_reg_name(int reg, size_t width, int reghi) {qnotused(reg); qnotused(width); qnotused(reghi); Py_RETURN_NONE;}
virtual void savebase() {}
virtual void gen_asm_or_lst(bool starting, FILE * fp, bool is_asm, int flags, gen_outline_t ** outline) {qnotused(starting); qnotused(fp); qnotused(is_asm); qnotused(flags); qnotused(outline); }
virtual int out_src_file_lnnum() {return 0;}
@@ -847,7 +867,7 @@ virtual int calc_cdecl_purged_bytes2() {return 0;}
virtual int get_stkarg_offset2() {return 0;}
virtual int til_for_file() {return 0;}
virtual int equal_reglocs(argloc_t * a1, argloc_t * a2) {qnotused(a1); qnotused(a2); return 0;}
virtual int decorate_name3(qstring * outbuf, const char * name, bool mangle, int cc) {qnotused(outbuf); qnotused(name); qnotused(mangle); qnotused(cc); return 0;}
virtual PyObject * decorate_name3(const char * name, bool mangle, int cc) {qnotused(name); qnotused(mangle); qnotused(cc); Py_RETURN_NONE;}
virtual int calc_retloc3(const tinfo_t * rettype, cm_t cc, argloc_t * retloc) {qnotused(rettype); qnotused(cc); qnotused(retloc); return 0;}
virtual int calc_varglocs3(const func_type_data_t * ftd, regobjs_t * regs, relobj_t * stkargs, int nfixed) {qnotused(ftd); qnotused(regs); qnotused(stkargs); qnotused(nfixed); return 0;}
virtual int calc_arglocs3(func_type_data_t * fti) {qnotused(fti); return 0;}
@@ -1260,7 +1280,8 @@ case processor_t::get_reg_name:
char * buf = va_arg(va, char *);
size_t bufsize = va_arg(va, size_t);
int reghi = va_arg(va, int);
ret = proxy->get_reg_name(reg, width, buf, bufsize, reghi);
PyObject * _tmp = proxy->get_reg_name(reg, width, reghi);
ret = IDP_Hooks::handle_get_reg_name_output(_tmp, reg, width, buf, bufsize, reghi);
}
break;
@@ -1707,7 +1728,8 @@ case processor_t::decorate_name3:
const char * name = va_arg(va, const char *);
bool mangle = bool(va_arg(va, int));
cm_t cc = cm_t(va_arg(va, int));
ret = proxy->decorate_name3(outbuf, name, mangle, IDP_Hooks::cm_t_to_int(cc));
PyObject * _tmp = proxy->decorate_name3(name, mangle, IDP_Hooks::cm_t_to_int(cc));
ret = IDP_Hooks::handle_decorate_name3_output(_tmp, outbuf, name, mangle, cc);
}
break;
+7 -1
View File
@@ -427,11 +427,16 @@ bool py_del_hotkey(PyObject *pyctx)
return false;
py_idchotkey_ctx_t *ctx = (py_idchotkey_ctx_t *) PyCObject_AsVoidPtr(pyctx);
if ( !del_idc_hotkey(ctx->hotkey.c_str()) )
if ( ctx == NULL || !del_idc_hotkey(ctx->hotkey.c_str()) )
return false;
Py_DECREF(ctx->pyfunc);
delete ctx;
// Here we must ensure that the python object is invalidated.
// This is to avoid the possibility of this function being called again
// with the same ctx, which would contain a pointer to a deleted object.
PyCObject_SetVoidPtr(pyctx, NULL);
return true;
}
@@ -826,6 +831,7 @@ static bool py_execute_ui_requests(PyObject *py_list)
virtual idaapi ~py_ui_request_t()
{
PYW_GIL_GET;
py_callables.clear();
}
};
+2
View File
@@ -44,6 +44,8 @@ typedef struct
%ignore internal_get_sreg_base;
%rename (internal_get_sreg_base) py_internal_get_sreg_base;
%rename (get_tev_reg_mem) py_get_tev_reg_mem;
// We want ALL wrappers around what is declared in dbg.hpp
// to release the GIL when calling into the IDA api: those
// might be very long operations, that even require some
+8
View File
@@ -10,6 +10,14 @@
%ignore gdecode_t;
%apply unsigned char { char dtyp };
%ignore qvector<exception_info_t>::operator==;
%ignore qvector<exception_info_t>::operator!=;
%ignore qvector<exception_info_t>::find;
%ignore qvector<exception_info_t>::has;
%ignore qvector<exception_info_t>::del;
%ignore qvector<exception_info_t>::add_unique;
%template(excvec_t) qvector<exception_info_t>;
%include "idd.hpp"
%clear(char dtyp);
+2
View File
@@ -90,6 +90,8 @@
%rename (get_named_type64) py_get_named_type64;
%rename ("%s") tinfo_t::get_named_type;
%ignore udt_type_data_t::is_last_baseclass;
%rename (print_decls) py_print_decls;
%ignore print_decls;
+3 -6
View File
@@ -9,13 +9,10 @@ import re
import os
major, minor, micro, _, _ = sys.version_info
if major < 2 or minor < 7:
raise Exception("Expected Python version 2.7.x, but got %s.%s.%s (from %s)" % (major, minor, micro, sys.executable))
try:
from argparse import ArgumentParser
except:
print "Failed to import module 'argparse'. Upgrade to Python 2.7, copy argparse.py to this directory or try 'apt-get install python-argparse'"
raise
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("-t", "--template", required=True)
parser.add_argument("-o", "--output", required=True)
+21 -2
View File
@@ -82,7 +82,26 @@ recipe = {
"cc" : {
"type" : "int",
"convertor" : "IDP_Hooks::cm_t_to_int",
}
},
"outbuf" : { "suppress_for_call" : True, },
},
"return" : {
"type" : "PyObject *",
"retexpr" : "Py_RETURN_NONE",
"convertor" : "IDP_Hooks::handle_decorate_name3_output",
"convertor_pass_args" : True,
}
}
},
"get_reg_name" : {
"params" : {
"buf" : { "suppress_for_call" : True, },
"bufsize" : { "suppress_for_call" : True, },
},
"return" : {
"type" : "PyObject *",
"retexpr" : "Py_RETURN_NONE",
"convertor" : "IDP_Hooks::handle_get_reg_name_output",
"convertor_pass_args" : True,
}
},
}