mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
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:
@@ -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()
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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)>
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
"""
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user