IDAPython for IDA 7.2

This commit is contained in:
Arnaud Diederen
2018-11-06 08:14:17 +01:00
parent a3855ab969
commit 701bb1b44e
123 changed files with 7136 additions and 4391 deletions
+91 -8
View File
@@ -1,16 +1,99 @@
IDAPython
=========
### Contributing to IDAPython
This page really is only a read-only version of the source code we
host internally at http://www.hex-rays.com, and pull requests will
not be honored.
Anyone with a valid license is welcome to contribute to IDAPython, and pull
requests will be honored provided their nature matches the criteria below.
However, we will gladly accept patches & suggestions. Please send
If you prefer using patches over git/github+pull requests, please send
those to <support@hex-rays.com>.
Found a bug?
------------
Users with an IDA license that is still under support are
encouraged to report bugs to <support@hex-rays.com>.
### What can I contribute?
We at Hex-Rays are currently maintaining the official IDAPython repository.
Because we are not an infinite-sized company and thus have limited resources
([interested?](https://www.hex-rays.com/jobs.shtml)), we have to keep the
scope of IDAPython itself to a manageable size.
Most of IDAPython consists of rather low-level, arguably non-pythonic APIs.
The reason for that is of course not that we have anything against pythonic
APIs, but we have found that:
- what is idiomatic & pythonic to certain users, will not necessarily be
to the taste of others,
- when trying to provide pythonic/somewhat higher-level APIs, we often
ended up not providing the lower-level APIs, sometimes making it
impossible to build your own utilities should the APIs IDAPython provides
out-of-the box be insufficient, buggy or just not to your taste,
- users are better at coming up with their own layers anyway.
E.g., https://github.com/tmr232/Sark
Therefore, the most important aspect of any contribution to IDAPython
should not be about making it more pythonic and/or higher-level, but
instead to make sure that its low-level API (which to a significant degree
are generated from the C/C++ IDA SDK by using SWiG) work fine, are
correctly documented, and tested.
That is the approach we took in order to make sane & well-working
higher-level APIs possible at all.
### Should I write a test?
If your changes touch the APIs from a functional perspective (e.g., fix
a bug, or make a new function available), yes.
There is no such thing as a _code_ change in IDAPython, that is not
accompanied by a test, so please go through the trouble of writing one
so we don't have to do it ourselves.
When it comes to other types of pull requests (e.g., documentation),
it should usually not be necessary to write a test.
### How to write tests?
Pull requests that actually modify IDAPython code, and that come
together with a test script, have a better chance of being accepted,
because we do not happily push code to IDAPython without making sure
we have non-regression mechanisms into place.
While we won't share our non-regression tools, it is enough to say
that many IDAPython APIs can be tested by mimicking the user entering
commands directly into IDA, and looking at the output.
E.g., here is a part of an actual, real test currently running in
our non-regression environment, testing the `refwidth` property of a
`cexpr_t` instance:
```
Python>x = cexpr_t()
Python>x.refwidth
0
Python>x.refwidth = 18
Python>x.refwidth
18
Python>x.refwidth = var_ref_t()
Traceback (most recent call last):
<snipped file>, <snipped line>, in <module>
<snipped file>, <snipped line>, in <lambda>
refwidth = property( lambda self: self._get_refwidth() if True else 0, lambda self, v: True and self._ensure_no_obj(self._get_refwidth(),"refwidth", False) and self._acquire_ownership(v, False) and self._set_refwidth(v))
<snipped file>, <snipped line>, in _set_refwidth
return _ida_hexrays.cexpr_t__set_refwidth(self, *args)
TypeError: in method 'cexpr_t__set_refwidth', argument 2 of type 'int'
```
The key points are:
- this represents a "dialog" with IDAPython: input is prepended with
"Python>", and output is inline
- this describes what should happen when those operations are performed
Sending us similar testing 'scripts' alongside a pull request, will speed
up its integration significantly, since we'll be able to add the test to
our non-regression environment very quickly.
Please also see [the best practices for developing on IDAPython](HOWTO.md)
+2 -2
View File
@@ -1,6 +1,6 @@
# HOW-TO
# Developing IDAPython: best practices
### Whatever you do
### Rule of thumb
If you are doing something non-trivial in IDAPython, or if you added something
to the C++ SDK which will then be reflected in IDAPython, an *immensely*
+16 -2
View File
@@ -17,6 +17,21 @@ try:
except:
ida_kernwin.warning('Feedparser package not installed')
def get_url(ident):
"""
Note: This code is left in a separate, toplevel function so that
tests can easily override it and provide a replacement file://
URL and work on machines without an internet connection
"""
try:
# This is a 'hook' to enable testing on machines disconnected
# from the internet (we're not testing feedparser's HTTPS URL
# download capabilities anyway)
import sys
return sys.modules["__main__"].get_url(ident)
except:
return "https://social.msdn.microsoft.com/search/en-US/feed?query=%s&format=RSS&theme=feed%%2fen-us" % ident
# -----------------------------------------------------------------------
class msdnapihelp_plugin_t(ida_idaapi.plugin_t):
flags = ida_idaapi.PLUGIN_UNL
@@ -47,8 +62,7 @@ class msdnapihelp_plugin_t(ida_idaapi.plugin_t):
ident = self.sanitize_name(ident)
print "Looking up '%s' in MSDN online" % ident
qurl = "https://social.msdn.microsoft.com/search/en-US/feed?query=%s&format=RSS&theme=feed%%2fen-us"
d = feedparser.parse(qurl % ident)
d = feedparser.parse(get_url(ident))
if len(d['entries']) > 0:
url = d['entries'][0].link
if arg > 0:
+561 -115
View File
File diff suppressed because it is too large Load Diff
+10 -25
View File
@@ -16,40 +16,27 @@ import os, sys, argparse
parser = argparse.ArgumentParser(epilog="""
A very specific version of SWiG is expected in order to produce reliable
bindings. If your platform doesn't provide that version by default and you
had to build/install it yourself, you will have to specify '--swig-bin' and
'--swig-inc' arguments.
had to build/install it yourself, you will have to specify '--swig-home'.
What follows, are example build commands
### Windows (assume SWiG is installed in C:\swigwin-2.0.12, and IDA is in C:\Program Files\IDA7)
python build.py \\
--swig-bin C:/swigwin-2.0.12/swig.exe \\
--swig-inc "C:/swigwin-2.0.12/Lib/python;C:/swigwin-2.0.12/Lib" \\
--with-hexrays \\
--swig-home C:/swigwin-2.0.12 \\
--idc "c:/Program\ Files/IDA_7.0-171130-tests/idc/idc.idc"
(note the argument quoting)
### Linux/OSX (assume SWiG is installed in /opt/my-swig/, and IDA is in /opt/my-ida-install)
### Linux/OSX (assume SWiG is installed in /opt/swiglinux-2.0.12, and IDA is in /opt/my-ida-install)
python build.py \\
--swig-bin /opt/my-swig/bin/swig \\
--swig-inc /opt/my-swig/share/swig/2.0.12/python/:/opt/my-swig/share/swig/2.0.12 \\
--with-hexrays \\
--swig-home /opt/swiglinux-2.0.12 \\
--idc /opt/my-ida-install/idc/idc.idc
Notes:
* '--swig-inc' here has 2 path components, separated by the platform's
path separator; i.e., ':' in this case (if you were building on Windows,
you would have to use ';'.)
* SWiG can be tricky to deal with when specifying input paths. The path
to the '.../2.0.12/python/' subdirectory should be placed before the
more global '.../2.0.12/' directory.
""",
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument("--swig-bin", type=str, help="Path to the SWIG binary", default=None)
parser.add_argument("--swig-inc", type=str, help="Path(s) to the SWIG includes directory(ies)", default=None)
parser.add_argument("--swig-home", type=str, help="Path to the SWIG installation", default=None)
parser.add_argument("--with-hexrays", help="Build Hex-Rays decompiler bindings (requires the 'hexrays.hpp' header to be present in the SDK's include/ directory)", default=False, action="store_true")
parser.add_argument("--debug", help="Build debug version of the plugin", default=False, action="store_true")
if "linux" in sys.platform:
@@ -80,14 +67,12 @@ def main():
env = {
"OUT_OF_TREE_BUILD" : "1"
}
if args.swig_bin:
env["SWIG"] = args.swig_bin
if args.swig_inc:
env["SWIGINCLUDES"] = " ".join(map(lambda p: "-I%s" % p, args.swig_inc.split(os.pathsep)))
if args.swig_home:
env["SWIG_HOME"] = args.swig_home
if args.with_hexrays:
env["HAS_HEXRAYS"] = "1"
if args.debug:
env["__VC__"] = "1" # to enable PDB flags
env["__NT__"] = "1" # to enable PDB flags
else:
env["NDEBUG"] = "1"
try:
+3 -4
View File
@@ -32,7 +32,6 @@ class TestEmbeddedChooserClass(Choose):
class MyForm(Form):
def __init__(self):
self.invert = False
self.EChooser = TestEmbeddedChooserClass("E1", flags=Choose.CH_MULTI)
Form.__init__(self, r"""STARTITEM {id:rNormal}
BUTTON YES* Yeah
BUTTON NO Nope
@@ -85,7 +84,7 @@ The end!
'cGroup1': Form.ChkGroupControl(("rNormal", "rError", "rWarnings")),
'cGroup2': Form.RadGroupControl(("rRed", "rGreen", "rBlue")),
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'cEChooser' : Form.EmbeddedChooserControl(self.EChooser)
'cEChooser' : Form.EmbeddedChooserControl(TestEmbeddedChooserClass("E1", flags=Choose.CH_MULTI))
})
@@ -152,6 +151,7 @@ def ida_main():
f.iColor1.value = 0x5bffff
f.iDir.value = os.getcwd()
f.iChar.value = ord("a")
f.rNormal.checked = True
f.rWarnings.checked = True
f.rGreen.selected = True
@@ -174,8 +174,7 @@ def ida_main():
print("f.addr=%x" % f.iAddr.value)
print("f.cGroup1=%x" % f.cGroup1.value)
print("f.cGroup2=%x" % f.cGroup2.value)
sel = f.EChooser.GetEmbSelection()
sel = f.cEChooser.selection
if sel is None:
print("No selection")
else:
@@ -0,0 +1,110 @@
import ida_idaapi
import ida_kernwin
title = "Auto-instantiable at IDA startup"
# -----------------------------------------------------------------------
class auto_inst_t(ida_kernwin.simplecustviewer_t):
def __init__(self):
ida_kernwin.simplecustviewer_t.__init__(self)
def Create(self):
if not ida_kernwin.simplecustviewer_t.Create(self, title):
return False
text = r"""
This is an example demonstrating how one can create widgets from a plugin,
and have them re-created automatically at IDA startup-time or at desktop load-time.
This example should be placed in the 'plugins' directory of the
IDA installation, for it to work.
There are 2 ways to use this example:
1) reloading an IDB, where the widget was opened
- open the widget ('View > Open subview > """ + title + """')
- save this IDB, and close IDA
- restart IDA with this IDB
=> the widget will be visible
2) reloading a desktop, where the widget was opened
- open the widget ('View > Open subview > """ + title + """')
- save the desktop ('Windows > Save desktop...') under, say, the name 'with_auto'
- start another IDA instance with some IDB, and load that desktop
=> the widget will be visible
"""
for l in text.split("\n"):
self.AddLine(l)
return True
# -----------------------------------------------------------------------
auto_inst = None
# -----------------------------------------------------------------------
def register_open_action():
"""
Provide the action that will create the widget
when the user asks for it.
"""
class create_widget_t(ida_kernwin.action_handler_t):
def activate(self, ctx):
if ida_kernwin.find_widget(title) is None:
global auto_inst
auto_inst = auto_inst_t()
assert(auto_inst.Create())
assert(auto_inst.Show())
def update(self, ctx):
return ida_kernwin.AST_ENABLE_ALWAYS
action_name = "autoinst:create"
ida_kernwin.register_action(
ida_kernwin.action_desc_t(
action_name,
title,
create_widget_t()))
ida_kernwin.attach_action_to_menu(
"View/Open subviews/Strings",
action_name,
ida_kernwin.SETMENU_APP)
# -----------------------------------------------------------------------
auto_inst_hooks = None
def register_autoinst_hooks():
"""
Register hooks that will create the widget when IDA
requires it because of the IDB/desktop
"""
class auto_inst_hooks_t(ida_kernwin.UI_Hooks):
def create_desktop_widget(self, ttl, cfg):
if ttl == title:
global auto_inst
auto_inst = auto_inst_t()
assert(auto_inst.Create())
return auto_inst.GetWidget()
global auto_inst_hooks
auto_inst_hooks = auto_inst_hooks_t()
auto_inst_hooks.hook()
# -----------------------------------------------------------------------
class auto_inst_plugin_t(ida_idaapi.plugin_t):
flags = 0
comment = "This plugin creates a widget that will be recreated automatically if needed, either at startup or when loading a desktop that requires it"
help = "No help, really"
wanted_name = "autoinst"
wanted_hotkey = ""
def init(self):
register_open_action()
register_autoinst_hooks()
def run(self, arg):
pass
def term(self):
pass
def PLUGIN_ENTRY():
return auto_inst_plugin_t()
+2 -1
View File
@@ -27,7 +27,8 @@ class MyChoose(Choose):
self,
title,
[ ["Address", 10], ["Name", 30] ],
flags = flags | (Choose.CH_CAN_INS
flags = flags | Choose.CH_RESTORE
| (Choose.CH_CAN_INS
| Choose.CH_CAN_DEL
| Choose.CH_CAN_EDIT
| Choose.CH_CAN_REFRESH),
+4 -4
View File
@@ -21,11 +21,11 @@ class pascal_data_type(data_type_t):
def calc_item_size(self, ea, maxsize):
# Custom data types may be used in structure definitions. If this case
# ea is a member id. Check for this situation and return 1
if _idaapi.is_member_id(ea):
if idaapi.is_member_id(ea):
return 1
# get the length byte
n = _idaapi.get_byte(ea)
n = idaapi.get_byte(ea)
# string too big?
if n > maxsize:
@@ -71,10 +71,10 @@ class simplevm_data_type(data_type_t):
asm_keyword)
def calc_item_size(self, ea, maxsize):
if _idaapi.is_member_id(ea):
if idaapi.is_member_id(ea):
return 1
# get the opcode and see if it has an imm
n = 5 if (_idaapi.get_byte(ea) & 3) == 0 else 1
n = 5 if (idaapi.get_byte(ea) & 3) == 0 else 1
# string too big?
if n > maxsize:
return 0
+15 -12
View File
@@ -21,24 +21,28 @@ class say_something_handler_t(idaapi.action_handler_t):
# -----------------------------------------------------------------------
class mycv_t(simplecustviewer_t):
def Create(self, sn=None):
def Create(self, sn=None, use_colors=True):
# Form the title
title = "Simple custom view test"
if sn:
title += " %d" % sn
self.use_colors = use_colors
# Create the customviewer
if not simplecustviewer_t.Create(self, title):
return False
for i in xrange(0, 100):
fg, bg = idaapi.COLOR_PREFIX, None
prefix, bg = idaapi.COLOR_DEFAULT, None
# make every 10th line a bit special
if i % 10 == 0:
fg = idaapi.COLOR_DEFAULT # i.e., white...
bg = 0xFFFF00 # ...on cyan
prefix = idaapi.COLOR_DNAME # i.e., dark yellow...
bg = 0xFFFF00 # ...on cyan
pfx = idaapi.COLSTR("%3d" % i, idaapi.SCOLOR_PREFIX)
self.AddLine("%s: Line %d" % (pfx, i), fgcolor=fg, bgcolor=bg)
if self.use_colors:
self.AddLine("%s: Line %d" % (pfx, i), fgcolor=prefix, bgcolor=bg)
else:
self.AddLine("%s: Line %d" % (pfx, i))
return True
@@ -51,6 +55,12 @@ class mycv_t(simplecustviewer_t):
print "OnClick, shift=%d" % shift
return True
def OnPopup(self, form, popup_handle):
for thing in ["Hello", "World"]:
actname = "custview:say_%s" % thing
desc = ida_kernwin.action_desc_t(actname, "Say %s" % thing, say_something_handler_t(thing))
ida_kernwin.attach_dynamic_action_to_popup(form, popup_handle, desc)
def OnDblClick(self, shift):
"""
User dbl-clicked in the view
@@ -161,13 +171,6 @@ def show_win():
return None
x.Show()
tcc = x.GetWidget()
# Register actions
for thing in ["Hello", "World"]:
actname = "custview:say_%s" % thing
idaapi.register_action(
idaapi.action_desc_t(actname, "Say %s" % thing, say_something_handler_t(thing)))
idaapi.attach_action_to_popup(tcc, None, actname)
return x
mycv = show_win()
+1 -1
View File
@@ -2,7 +2,7 @@ import idaapi
import idautils
"""
This is a sample plugin for extending the assemble().
This is a sample script for extending the assemble() hook.
We add support for assembling the following pseudo instructions:
- "zero eax" -> xor eax, eax
+66
View File
@@ -0,0 +1,66 @@
import random
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtWidgets
import ida_kernwin
import ida_segment
import idc
class painter_t(QtCore.QObject):
def __init__(self):
QtCore.QObject.__init__(self)
self.target = ida_kernwin.PluginForm.FormToPyQtWidget(ida_kernwin.open_navband_window(idc.here(), 1))
self.target.installEventFilter(self)
self.items = []
self.painting = False
def add_item(self, ea, radius, color):
self.items.append((ea, radius, color))
self.target.update()
def add_random_item(self):
R = random.random
s = ida_segment.getnseg(int(ida_segment.get_segm_qty() * R()))
ea = s.start_ea + long((s.end_ea - s.start_ea) * R())
radius = 4 + long(R() * 8)
color = QtGui.QColor(long(255 * R()), long(255 * R()), long(255 * R()))
self.add_item(ea, radius, color)
def eventFilter(self, receiver, event):
if not self.painting and \
self.target == receiver and \
event.type() == QtCore.QEvent.Paint:
# Send a paint event that we won't intercept
self.painting = True
try:
pev = QtGui.QPaintEvent(self.target.rect())
QtWidgets.QApplication.instance().sendEvent(self.target, pev)
finally:
self.painting = False
# now we can paint our items
for ea, radius, color in self.items:
painter = QtGui.QPainter(receiver)
painter.setRenderHints(QtGui.QPainter.Antialiasing)
pxl, is_vertical = ida_kernwin.get_navband_pixel(ea)
if pxl >= 0:
x = (self.target.width() / 2) if is_vertical else pxl
y = pxl if is_vertical else (self.target.height() / 2)
painter.setPen(color)
painter.setBrush(color)
painter.drawEllipse(QtCore.QPoint(x, y), radius, radius)
painter.end()
# ...and prevent the widget form painting itself again
return True
return QtCore.QObject.eventFilter(self, receiver, event)
painter = painter_t()
# Try the following:
# for i in xrange(100): painter.add_random_item()
+2 -2
View File
@@ -6,7 +6,7 @@ import sip
class MyPluginFormClass(PluginForm):
def OnCreate(self, form):
"""
Called when the plugin form is created
Called when the widget is created
"""
# Get parent widget
@@ -28,7 +28,7 @@ class MyPluginFormClass(PluginForm):
def OnClose(self, form):
"""
Called when the plugin form is closed
Called when the widget is closed
"""
pass
+15 -1
View File
@@ -44,7 +44,7 @@ class MyUiHook(idaapi.UI_Hooks):
IDA is terminated and the database is already closed.
The UI may close its windows in this callback.
This callback is best used with a plugin_t with flags PLUGIN_FIX
This callback is best used within the context of a plugin_t with PLUGIN_FIX flags
"""
print("IDA terminated")
@@ -57,6 +57,20 @@ class MyUiHook(idaapi.UI_Hooks):
"""
print("get_ea_hint(%x)" % ea)
def populating_widget_popup(self, widget, popup, ctx):
"""
The UI is currently populating the widget popup. Now is a good time to
attach actions.
"""
print("populating_widget_popup; title: %s" % (ctx.widget_title,))
def finish_populating_widget_popup(self, widget, popup, ctx):
"""
The UI is done populating the widget popup. Now is the last chance to
attach actions.
"""
print("finish_populating_widget_popup; title: %s" % (ctx.widget_title,))
#---------------------------------------------------------------------
# Remove an existing hook on second run
+14 -10
View File
@@ -168,19 +168,22 @@ class hexrays_callback_info(object):
return
def event_callback(self, event, *args):
if event == idaapi.hxe_populating_popup:
widget, phandle, vu = args
res = idaapi.attach_action_to_popup(vu.ct, None, inverter_actname)
elif event == idaapi.hxe_maturity:
cfunc, maturity = args
if maturity == idaapi.CMAT_FINAL:
self.restore(cfunc)
class vds3_hooks_t(idaapi.Hexrays_Hooks):
def __init__(self, i):
idaapi.Hexrays_Hooks.__init__(self)
self.i = i
def populating_popup(self, widget, phandle, vu):
idaapi.attach_action_to_popup(vu.ct, None, inverter_actname)
return 0
def maturity(self, cfunc, maturity):
if maturity == idaapi.CMAT_FINAL:
self.i.restore(cfunc)
return 0
if idaapi.init_hexrays_plugin():
i = hexrays_callback_info()
idaapi.register_action(
@@ -189,7 +192,8 @@ if idaapi.init_hexrays_plugin():
"Invert then/else",
invert_action_handler_t(i),
"I"))
idaapi.install_hexrays_callback(i.event_callback)
vds3_hooks = vds3_hooks_t(i)
vds3_hooks.hook()
else:
print 'invert-if: hexrays is not available.'
+2 -2
View File
@@ -41,8 +41,8 @@ def run():
iflags = idaapi.restore_user_iflags(entry_ea)
if iflags is not None:
print "------- %u user defined citem iflags" % (len(iflags), )
for cl, t in iflags.iteritems():
print "%a(%d): %08X%s" % (cl.ea, cl.op, f, " CIT_COLLAPSED" if f & CIT_COLLAPSED else "")
for cl, f in iflags.iteritems():
print "%x(%d): %08X%s" % (cl.ea, cl.op, f, " CIT_COLLAPSED" if f & idaapi.CIT_COLLAPSED else "")
idaapi.user_iflags_free(iflags)
# Display user defined number formats
+7 -7
View File
@@ -290,12 +290,10 @@ class display_graph_ah_t(ida_kernwin.action_handler_t):
ida_kernwin.AST_DISABLE_FOR_WIDGET
def cb(event, *args):
if event == ida_hexrays.hxe_populating_popup:
widget, phandle, vu = args
res = idaapi.attach_action_to_popup(vu.ct, None, ACTION_NAME)
return 0
class vds5_hooks_t(ida_hexrays.Hexrays_Hooks):
def populating_popup(self, widget, handle, vu):
idaapi.attach_action_to_popup(vu.ct, None, ACTION_NAME)
return 0
if ida_hexrays.init_hexrays_plugin():
ida_kernwin.register_action(
@@ -304,6 +302,8 @@ if ida_hexrays.init_hexrays_plugin():
"Hex-Rays show C graph (IDAPython)",
display_graph_ah_t(),
ACTION_SHORTCUT))
idaapi.install_hexrays_callback(cb)
vds5_hooks = vds5_hooks_t()
vds5_hooks.hook()
else:
print 'hexrays-graph: hexrays is not available.'
+7 -6
View File
@@ -80,14 +80,15 @@ def remove_spaces(sl):
sl.line = "".join(out)
def cb(event, *args):
if event == ida_hexrays.hxe_func_printed:
cf = args[0]
for sl in cf.get_pseudocode():
class vds6_hooks_t(ida_hexrays.Hexrays_Hooks):
def func_printed(self, cfunc):
for sl in cfunc.get_pseudocode():
remove_spaces(sl);
return 0
return 0
if ida_hexrays.init_hexrays_plugin():
ida_hexrays.install_hexrays_callback(cb)
vds6_hooks = vds6_hooks_t()
vds6_hooks.hook()
else:
print 'remove spaces: hexrays is not available.'
+8 -19
View File
@@ -35,28 +35,17 @@ class cblock_visitor_t(idaapi.ctree_visitor_t):
return
class hexrays_callback_info(object):
def __init__(self):
return
def event_callback(self, event, *args):
try:
if event == idaapi.hxe_maturity:
cfunc, maturity = args
if maturity == idaapi.CMAT_BUILT:
cbv = cblock_visitor_t()
cbv.apply_to(cfunc.body, None)
except:
traceback.print_exc()
class vds7_hooks_t(idaapi.Hexrays_Hooks):
def maturity(self, cfunc, maturity):
if maturity == idaapi.CMAT_BUILT:
cbv = cblock_visitor_t()
cbv.apply_to(cfunc.body, None)
return 0
if idaapi.init_hexrays_plugin():
i = hexrays_callback_info()
idaapi.install_hexrays_callback(i.event_callback)
vds7_hooks = vds7_hooks_t()
vds7_hooks.hook()
else:
print 'cblock visitor: hexrays is not available.'
+2 -2
View File
@@ -3,10 +3,10 @@
# Copyright (c) 2007-2018 by Hex-Rays, support@hex-rays.com
# ALL RIGHTS RESERVED.
#
# Sample plugin for Hex-Rays Decompiler usage of udc_filter_t
# Sample script for Hex-Rays Decompiler usage of udc_filter_t
# class: decompile svc 0x900001 and svc 0x9000F8 as function calls to
# svc_exit() and svc_exit_group() respectively.
# NOTE: You will need to have an ARM + Linux IDB for this plugin to be usable
# NOTE: You will need to have an ARM + Linux IDB for this script to be usable
#
# It is also added into the right-click menu as "vds8.py:Toggle UDC"
+7 -12
View File
@@ -1,6 +1,6 @@
"""'Hints' plugin for Hexrays Decompiler
"""'Hints' example for Hexrays Decompiler
Hijack the 'hxe_create_hint' notification, to return our own.
Handle 'hxe_create_hint' notification using hooks, to return our own.
If the object under the cursor is:
- a function call, prefix the original decompiler hint with "==> "
- a local variable declaration, replace the hint with our own in the form of "!{varname}" (where '{varname}' is replaced w/ the variable name)
@@ -9,9 +9,8 @@ If the object under the cursor is:
import ida_hexrays
def create_hint_cb(event, *args):
if event == ida_hexrays.hxe_create_hint:
vu = args[0]
class hint_hooks_t(ida_hexrays.Hexrays_Hooks):
def create_hint(self, vu):
if vu.get_current_item(ida_hexrays.USE_MOUSE):
cit = vu.item.citype
if cit == ida_hexrays.VDI_LVAR:
@@ -22,11 +21,7 @@ def create_hint_cb(event, *args):
return 2, "==> ", 1
if ce.op == ida_hexrays.cit_if:
return 1, "condition", 1
return 0
return 0
if ida_hexrays.init_hexrays_plugin():
ida_hexrays.install_hexrays_callback(create_hint_cb)
else:
print 'hexrays is not available.'
return 0
vds_hooks = hint_hooks_t()
vds_hooks.hook()
+128
View File
@@ -0,0 +1,128 @@
"""
Various hooks for Hexrays Decompiler
"""
import ida_typeinf
import ida_hexrays
class vds_hooks_t(ida_hexrays.Hexrays_Hooks):
def _shorten(self, cfunc):
raw = str(cfunc)
if len(raw) > 20:
raw = raw[0:20] + "[...snipped...]"
return raw
def _format_lvar(self, v):
parts = []
if v:
if v.name:
parts.append("name=%s" % v.name)
if v.cmt:
parts.append("cmt=%s" % v.cmt)
parts.append("width=%s" % v.width)
parts.append("defblk=%s" % v.defblk)
parts.append("divisor=%s" % v.divisor)
return "{%s}" % ", ".join(parts)
def _log(self, msg):
print("### %s" % msg)
return 0
def flowchart(self, fc):
return self._log("flowchart: fc=%s" % fc)
def stkpnts(self, mba, stkpnts):
return self._log("stkpnts: mba=%s, stkpnts=%s" % (mba, stkpnts))
def prolog(self, mba, fc, reachable_blocks):
return self._log("prolog: mba=%s, fc=%s, reachable_blocks=%s" % (mba, fc, reachable_blocks))
def microcode(self, mba):
return self._log("microcode: mba=%s" % (mba,))
def preoptimized(self, mba):
return self._log("preoptimized: mba=%s" % (mba,))
def locopt(self, mba):
return self._log("locopt: mba=%s" % (mba,))
def prealloc(self, mba):
return self._log("prealloc: mba=%s" % (mba,))
def glbopt(self, mba):
return self._log("glbopt: mba=%s" % (mba,))
def structural(self, ctrl_graph):
return self._log("structural: ctrl_graph: %s" % (ctrl_graph,))
def maturity(self, cfunc, maturity):
return self._log("maturity: cfunc=%s, maturity=%s" % (self._shorten(cfunc), maturity))
def interr(self, code):
return self._log("interr: code=%s" % (code,))
def combine(self, blk, insn):
return self._log("combine: blk=%s, insn=%s" % (blk, insn))
def print_func(self, cfunc, printer):
# Note: we can't print/str()-ify 'cfunc' here,
# because that'll call print_func() us recursively.
return self._log("print_func: cfunc=..., printer=%s" % (printer,))
def func_printed(self, cfunc):
return self._log("func_printed: cfunc=%s" % (cfunc,))
def resolve_stkaddrs(self, mba):
return self._log("resolve_stkaddrs: mba=%s" % (mba,))
def open_pseudocode(self, vu):
return self._log("open_pseudocode: vu=%s" % (vu,))
def switch_pseudocode(self, vu):
return self._log("switch_pseudocode: vu=%s" % (vu,))
def refresh_pseudocode(self, vu):
return self._log("refresh_pseudocode: vu=%s" % (vu,))
def close_pseudocode(self, vu):
return self._log("close_pseudocode: vu=%s" % (vu,))
def keyboard(self, vu, key_code, shift_state):
return self._log("keyboard: vu=%s, key_code=%s, shift_state=%s" % (vu, key_code, shift_state))
def right_click(self, vu):
return self._log("right_click: vu=%s" % (vu,))
def double_click(self, vu, shift_state):
return self._log("double_click: vu=%s, shift_state=%s" % (vu, shift_state))
def curpos(self, vu):
return self._log("curpos: vu=%s" % (vu,))
def create_hint(self, vu):
return self._log("create_hint: vu=%s: " % (vu,))
def text_ready(self, vu):
return self._log("text_ready: vu=%s" % (vu,))
def populating_popup(self, widget, popup, vu):
return self._log("populating_popup: widget=%s, popup=%s, vu=%s" % (widget, popup, vu))
def lvar_name_changed(self, vu, v, name, is_user_name):
return self._log("lvar_name_changed: vu=%s, v=%s, name=%s, is_user_name=%s" % (vu, self._format_lvar(v), name, is_user_name))
def lvar_type_changed(self, vu, v, tif):
return self._log("lvar_type_changed: vu=%s, v=%s, tinfo=%s" % (vu, self._format_lvar(v), tif._print()))
def lvar_cmt_changed(self, vu, v, cmt):
return self._log("lvar_cmt_changed: vu=%s, v=%s, cmt=%s" % (vu, self._format_lvar(v), cmt))
def lvar_mapping_changed(self, vu, _from, to):
return self._log("lvar_mapping_changed: vu=%s, from=%s, to=%s" % (vu, _from, to))
def cmt_changed(self, cfunc, loc, cmt):
return self._log("cmt_changed: cfunc=%s, loc=%s, cmt=%s" % (self._shorten(cfunc),loc, cmt))
vds_hooks = vds_hooks_t()
vds_hooks.hook()
+7 -16
View File
@@ -1,4 +1,4 @@
""" Xref plugin for Hexrays Decompiler
""" Xref script for Hexrays Decompiler
Author: EiNSTeiN_ <einstein@g3nius.org>
@@ -283,27 +283,18 @@ class show_xrefs_ah_t(idaapi.action_handler_t):
return idaapi.AST_ENABLE if self.sel else idaapi.AST_DISABLE
class hexrays_callback_info(object):
def __init__(self):
return
def event_callback(self, event, *args):
try:
if event == idaapi.hxe_populating_popup:
widget, phandle, vu = args
idaapi.attach_action_to_popup(widget, phandle, "vdsxrefs:show", None)
except:
traceback.print_exc()
class vds_xrefs_hooks_t(idaapi.Hexrays_Hooks):
def populating_popup(self, widget, phandle, vu):
idaapi.attach_action_to_popup(widget, phandle, "vdsxrefs:show", None)
return 0
if idaapi.init_hexrays_plugin():
adesc = idaapi.action_desc_t('vdsxrefs:show', 'Show xrefs', show_xrefs_ah_t(), "Ctrl+X")
if idaapi.register_action(adesc):
i = hexrays_callback_info()
idaapi.install_hexrays_callback(i.event_callback)
vds_xrefs_hooks = vds_xrefs_hooks_t()
vds_xrefs_hooks.hook()
else:
print "Couldn't register action."
else:
+75
View File
@@ -0,0 +1,75 @@
{
global:
PLUGIN;
PyWStringOrNone_Check;
PyW_CreateIdcException;
PyW_GetError;
PyW_GetNumber;
PyW_GetNumberAsIDC;
PyW_GetStringAttr;
PyW_IsSequenceType;
PyW_ObjectToString;
PyW_PyListToEaVec;
PyW_PyListToSizeVec;
PyW_PyListToStrVec;
PyW_ShowCbErr;
PyW_SizeVecToPyList;
PyW_UvalVecToPyList;
PyW_TryGetAttrString;
PyW_TryImportModule;
PyW_register_compiled_form;
PyW_unregister_compiled_form;
add_notify_when;
create_linked_class_instance;
disable_script_timeout;
enable_extlang_python;
enable_python_cli;
idapython_hook_to_notification_point;
idapython_unhook_from_notification_point;
idcvar_to_pyvar;
lookup_info_t_commit;
lookup_info_t_del_by_py_view;
lookup_info_t_find_by_py_view;
lookup_info_t_find_by_view;
lookup_info_t_new_entry;
meminfo_vec_t_to_py;
prepare_programmatic_plugin_load;
py_customidamemo_t_bind;
py_customidamemo_t_collect_class_callbacks_ids;
py_customidamemo_t_collect_pyobject_callbacks;
py_customidamemo_t_create_groups;
py_customidamemo_t_del_nodes_infos;
py_customidamemo_t_delete_groups;
py_customidamemo_t_get_current_renderer_type;
py_customidamemo_t_get_node_info;
py_customidamemo_t_set_current_renderer_type;
py_customidamemo_t_set_groups_visibility;
py_customidamemo_t_set_node_info;
py_customidamemo_t_set_nodes_infos;
py_customidamemo_t_unbind;
pycim_lookup_info;
pyobj_get_clink;
python_timer_del;
python_timer_new;
pyvar_to_idcvar;
pyvar_to_idcvar_or_error;
pyvar_walk_list;
pyw_convert_idc_args;
register_module_lifecycle_callbacks;
set_script_timeout;
set_interruptible_state;
til_deregister_python_array_type_data_t_instance;
til_deregister_python_func_type_data_t_instance;
til_deregister_python_ptr_type_data_t_instance;
til_deregister_python_tinfo_t_instance;
til_deregister_python_udt_type_data_t_instance;
til_register_python_array_type_data_t_instance;
til_register_python_func_type_data_t_instance;
til_register_python_ptr_type_data_t_instance;
til_register_python_tinfo_t_instance;
til_register_python_udt_type_data_t_instance;
try_create_swig_wrapper;
get_callable_arg_count;
local:
*;
};
-26
View File
@@ -1,26 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idapython", "idapython.vcxproj", "{F43D6BB8-B7D6-486A-82E5-BABBA9848525}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug64|Win32 = Debug64|Win32
Release|Win32 = Release|Win32
SemiDebug|Win32 = SemiDebug|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug|Win32.ActiveCfg = Debug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug|Win32.Build.0 = Debug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug64|Win32.ActiveCfg = Debug64|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug64|Win32.Build.0 = Debug64|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Release|Win32.ActiveCfg = Release|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Release|Win32.Build.0 = Release|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.SemiDebug|Win32.ActiveCfg = SemiDebug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.SemiDebug|Win32.Build.0 = SemiDebug|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
-455
View File
@@ -1,455 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug64|Win32">
<Configuration>Debug64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="SemiDebug|Win32">
<Configuration>SemiDebug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F43D6BB8-B7D6-486A-82E5-BABBA9848525}</ProjectGuid>
<RootNamespace>idapython</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">.\Debug64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">.\Debug64\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</PostBuildEventUseInBuild>
<OutDir Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</LinkIncremental>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PostBuildEventUseInBuild>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WITH_HEXRAYS;NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=3;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4804;4800;4018;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>c:\temp\ida\plugins\python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python26\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=0;PLUGINFIX;%(PreprocessorDefinitions);__EA64__</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4804;4800;4018;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\..\bin\x86_win_vc\plugins\python.p64</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>C:\Python26\libs;..\..\lib\x86_win_vc_64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>copy ..\..\bin\x86_win_vc\plugins\python.p64 ..\..\bin\x86_win_bcc\plugins\python.p64</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=3;VER_PATCH=7;PLUGINFIX;4804;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4005;4804;4018;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0419</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>C:\temp\ida\plugins\python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Release/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Release/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>copy ..\..\bin\x86_win_vc\plugins\python.plw ..\..\bin\x86_win_bcc\plugins\python.plw</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=3;VER_PATCH=7;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4804;4800;4018;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../bin/x86_win_vc/plugins/python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>C:\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="build.py" />
<None Include="BUILDING.txt" />
<None Include="CHANGES.txt" />
<None Include="obj\x86_win_vc_32\idaapi.py" />
<None Include="python.cfg" />
<None Include="python\idautils.py" />
<None Include="python\idc.py" />
<None Include="python\init.py" />
<None Include="pywraps\deploy.bat" />
<None Include="pywraps\deploy.py" />
<None Include="pywraps\py_appcall.py" />
<None Include="pywraps\py_askusingform.py" />
<None Include="pywraps\py_choose2.py" />
<None Include="pywraps\py_cli.py" />
<None Include="pywraps\py_custdata.py" />
<None Include="pywraps\py_custview.py" />
<None Include="pywraps\py_expr.py" />
<None Include="pywraps\py_gdl.py" />
<None Include="pywraps\py_graph.py" />
<None Include="pywraps\py_idaapi.py" />
<None Include="pywraps\py_kernwin.py" />
<None Include="pywraps\py_lines.py" />
<None Include="pywraps\py_nalt.py" />
<None Include="pywraps\py_name.py" />
<None Include="pywraps\py_notifywhen.py" />
<None Include="pywraps\py_plgform.py" />
<None Include="pywraps\py_ua.py" />
<None Include="README.txt" />
<None Include="STATUS.txt" />
<None Include="swig\allins.i" />
<None Include="swig\auto.i" />
<None Include="swig\bytes.i" />
<None Include="swig\dbg.i" />
<None Include="swig\diskio.i" />
<None Include="swig\entry.i" />
<None Include="swig\enum.i" />
<None Include="swig\expr.i" />
<None Include="swig\fixup.i" />
<None Include="swig\fpro.i" />
<None Include="swig\frame.i" />
<None Include="swig\funcs.i" />
<None Include="swig\gdl.i" />
<None Include="swig\graph.i" />
<None Include="swig\hexrays.i" />
<None Include="swig\ida.i" />
<None Include="swig\idaapi.i" />
<None Include="swig\idd.i" />
<None Include="swig\idp.i" />
<None Include="swig\kernwin.i" />
<None Include="swig\lines.i" />
<None Include="swig\loader.i" />
<None Include="swig\moves.i" />
<None Include="swig\nalt.i" />
<None Include="swig\name.i" />
<None Include="swig\netnode.i" />
<None Include="swig\offset.i" />
<None Include="swig\pro.i" />
<None Include="swig\queue.i" />
<None Include="swig\range.i" />
<None Include="swig\search.i" />
<None Include="swig\segment.i" />
<None Include="swig\segregs.i" />
<None Include="swig\strlist.i" />
<None Include="swig\struct.i" />
<None Include="swig\typeconv.i" />
<None Include="swig\typeinf.i" />
<None Include="swig\ua.i" />
<None Include="swig\xref.i" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="idaapi.cpp" />
<ClCompile Include="python.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="idaapi.h" />
<ClInclude Include="pywraps.hpp" />
<ClInclude Include="pywraps\pywraps.hpp" />
<ClInclude Include="pywraps\py_askusingform.hpp" />
<ClInclude Include="pywraps\py_bytes.hpp" />
<ClInclude Include="pywraps\py_choose.hpp" />
<ClInclude Include="pywraps\py_choose2.hpp" />
<ClInclude Include="pywraps\py_cli.hpp" />
<ClInclude Include="pywraps\py_custdata.hpp" />
<ClInclude Include="pywraps\py_custview.hpp" />
<ClInclude Include="pywraps\py_cvt.hpp" />
<ClInclude Include="pywraps\py_dbg.hpp" />
<ClInclude Include="pywraps\py_diskio.hpp" />
<ClInclude Include="pywraps\py_expr.hpp" />
<ClInclude Include="pywraps\py_graph.hpp" />
<ClInclude Include="pywraps\py_idaapi.hpp" />
<ClInclude Include="pywraps\py_idp.hpp" />
<ClInclude Include="pywraps\py_kernwin.hpp" />
<ClInclude Include="pywraps\py_lines.hpp" />
<ClInclude Include="pywraps\py_linput.hpp" />
<ClInclude Include="pywraps\py_loader.hpp" />
<ClInclude Include="pywraps\py_nalt.hpp" />
<ClInclude Include="pywraps\py_name.hpp" />
<ClInclude Include="pywraps\py_notifywhen.hpp" />
<ClInclude Include="pywraps\py_plgform.hpp" />
<ClInclude Include="pywraps\py_qfile.hpp" />
<ClInclude Include="pywraps\py_typeinf.hpp" />
<ClInclude Include="pywraps\py_ua.hpp" />
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="C:\Python25\libs\python25.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python25\libs\python25_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python26\libs\python26.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python26\libs\python26_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python27\libs\python27.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python27\libs\python27_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
-314
View File
@@ -1,314 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="python.cpp" />
<ClCompile Include="idaapi.cpp">
<Filter>autogen</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pywraps.hpp" />
<ClInclude Include="pywraps\py_askusingform.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_bytes.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_choose.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_choose2.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_cli.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_custdata.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_custview.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_cvt.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_dbg.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_diskio.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_expr.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_graph.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_idaapi.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_idp.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_kernwin.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_lines.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_linput.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_loader.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_nalt.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_name.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_notifywhen.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_plgform.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_qfile.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_typeinf.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_ua.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\pywraps.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="idaapi.h">
<Filter>autogen</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="python.cfg" />
<None Include="swig\allins.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\auto.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\bytes.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\diskio.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idaapi.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\entry.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\enum.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\expr.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\fixup.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\fpro.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\frame.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\funcs.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\gdl.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\graph.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\ida.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idp.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idd.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\dbg.i">
<Filter>swig_i</Filter>
</None>
<None Include="obj\x86_win_vc_32\idaapi.py">
<Filter>autogen</Filter>
</None>
<None Include="swig\loader.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\kernwin.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\lines.i">
<Filter>swig_i</Filter>
</None>
<None Include="pywraps\deploy.py">
<Filter>py</Filter>
</None>
<None Include="python\init.py">
<Filter>py</Filter>
</None>
<None Include="python\idautils.py">
<Filter>py</Filter>
</None>
<None Include="python\idc.py">
<Filter>py</Filter>
</None>
<None Include="pywraps\py_appcall.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_custdata.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_askusingform.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_choose2.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_cli.py">
<Filter>pywraps</Filter>
</None>
<None Include="swig\nalt.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\pro.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\name.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\netnode.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\offset.i">
<Filter>swig_i</Filter>
</None>
<None Include="pywraps\py_lines.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_custview.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_expr.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_gdl.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_graph.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_idaapi.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_kernwin.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_ua.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_nalt.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_name.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_notifywhen.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_plgform.py">
<Filter>pywraps</Filter>
</None>
<None Include="swig\queue.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\range.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\search.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\segment.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\segregs.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\strlist.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\struct.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\typeconv.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\typeinf.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\ua.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\xref.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\moves.i">
<Filter>swig_i</Filter>
</None>
<None Include="BUILDING.txt">
<Filter>TEXT</Filter>
</None>
<None Include="CHANGES.txt">
<Filter>TEXT</Filter>
</None>
<None Include="pywraps\deploy.bat">
<Filter>pywraps</Filter>
</None>
<None Include="STATUS.txt">
<Filter>TEXT</Filter>
</None>
<None Include="README.txt">
<Filter>TEXT</Filter>
</None>
<None Include="swig\hexrays.i">
<Filter>swig_i</Filter>
</None>
<None Include="build.py">
<Filter>py</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Filter Include="swig_i">
<UniqueIdentifier>{16b55e12-2b1e-4d6d-a1bf-df3400f06d21}</UniqueIdentifier>
</Filter>
<Filter Include="autogen">
<UniqueIdentifier>{f733d65b-1c25-4587-8566-7000875727ff}</UniqueIdentifier>
</Filter>
<Filter Include="py">
<UniqueIdentifier>{e2ec193c-4803-45b0-96c8-bfdc173c14ff}</UniqueIdentifier>
</Filter>
<Filter Include="pywraps">
<UniqueIdentifier>{01459f9f-5d55-4797-aab4-81876a9163d3}</UniqueIdentifier>
</Filter>
<Filter Include="TEXT">
<UniqueIdentifier>{b581ad45-b3f6-4591-baf0-306dab4e0590}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
@@ -1,4 +1,3 @@
LIBRARY %LIBNAME%
EXPORTS
PyWStringOrNone_Check
PyW_CreateIdcException
@@ -7,6 +6,7 @@ EXPORTS
PyW_GetNumberAsIDC
PyW_GetStringAttr
PyW_SizeVecToPyList
PyW_UvalVecToPyList
PyW_IsSequenceType
PyW_ObjectToString
PyW_PyListToEaVec
@@ -62,8 +62,9 @@ EXPORTS
til_register_python_tinfo_t_instance
til_register_python_udt_type_data_t_instance
try_create_swig_wrapper
get_callable_arg_count
idapython_hook_to_notification_point
idapython_unhook_from_notification_point
register_module_lifecycle_callbacks
prepare_programmatic_plugin_load
pycim_lookup_info DATA
%PLUGIN_DATA_EXP%
+410 -353
View File
@@ -1,5 +1,6 @@
include ../../allmake.mak
#
#----------------------------------------------------------------------
# WARNING: Many rules in this file use pattern matching, where 'make'
# first considers rules as simple strings, not paths. Consequently,
# it is necessary that we don't end up with 'some_dir//some_file'.
@@ -13,71 +14,103 @@
# non-hexrays people looking at the file, it also allows us to work in
# a more natural manner with other tools (such as the build.py wrapper, that
# uses os.path.join())
#
PROC=python
API_CONTENTS=api_contents.txt
PYDOC_INJECTIONS=pydoc_injections.txt
#----------------------------------------------------------------------
# default goals
.PHONY: configs modules pyfiles deployed_modules idapython_modules api_contents pydoc_injections public_tree test_idc docs
all: configs modules pyfiles deployed_modules idapython_modules api_contents pydoc_injections # public_tree test_idc docs
BC695=1
#----------------------------------------------------------------------
# configurable variables for this makefile
BC695 = 1
ifdef BC695
BC695_CFLAGS=-DBC695
BC695_SWIGFLAGS=-DBC695
BC695_DEPLOYFLAGS=--bc695
BC695_CC_DEF = BC695
BC695_SWIGFLAGS = -DBC695
BC695_DEPLOYFLAGS = --bc695
endif
IDA_INCLUDE=../../include
#----------------------------------------------------------------------
# Build system hacks
DIST=$(F)dist
ifdef __NT__
SYSNAME=win
MSRUNTIME=/MD
MSCLOPTS=/nologo
MSLDOPTS=/nologo
# HACK HIJACK the $(I) variable to point to our staging SDK
# (but don't let mkdep know about it)
IDA_INCLUDE = ../../include
ifeq ($(OUT_OF_TREE_BUILD),)
ST_SDK = $(F)idasdk
else
ST_SDK = $(IDA_INCLUDE)
endif
ifndef __MKDEP__
I = $(ST_SDK)/
else
# HACK for mkdep to add dependencies for $(F)python$(O)
OBJS += $(F)python$(O)
endif
ifdef __LINUX__
SYSNAME=linux
DEFS=-D__LINUX__
PYTHON32_LIBRARY_PATH?=/usr/lib
PYTHON32_LIBRARY_INCLUDE=-L$(PYTHON32_LIBRARY_PATH)
endif
ifdef __MAC__
SYSNAME=mac
DEFS=-D__MAC__
endif
DONT_ERASE_LIB=1
include ../plugin.mak
include ../pyplg.mak
# allmake.unx defines 'CP' as 'qcp.sh' which is an internal tool providing
# allmake.mak defines 'CP' as 'qcp.sh' which is an internal tool providing
# support for the '-u' flag on OSX. However, since this makefile is part
# of the public release of IDAPython, we cannot rely on it (we do not use
# that flag in IDAPython anyway)
ifdef __MAC__
CP=cp -f
CP = cp -f
endif
PLUGIN_SCRIPT=
#----------------------------------------------------------------------
# the 'configs' target is in $(IDA)module.mak
CONFIGS += python.cfg
#----------------------------------------------------------------------
# the 'modules' target is in $(IDA)module.mak
MODULE = $(call module_dll,python)
MODULES += $(MODULE)
#----------------------------------------------------------------------
# we explicitly added our module targets
NO_DEFAULT_MODULE = 1
DONT_ERASE_LIB = 1
# NOTE: all MODULES must be defined before including plugin.mak.
include ../plugin.mak
include ../pyplg.mak
# NOTE: target-specific rules and dependencies that use variable
# expansion to name the target (such as "$(MODULE): [...]") must
# come after including plugin.mak
#----------------------------------------------------------------------
PYTHON_OBJS += $(F)python$(O)
$(MODULE): MODULE_OBJS += $(PYTHON_OBJS)
$(MODULE): $(PYTHON_OBJS)
ifdef __NT__
$(MODULE): LDFLAGS += /DEF:$(IDAPYTHON_IMPLIB_DEF) /IMPLIB:$(IDAPYTHON_IMPLIB_PATH)
endif
# TODO these should apply only to $(MODULE)
DEFFILE = idapython.script
INSTALL_NAME = @executable_path/plugins/$(notdir $(MODULE))
ifdef __LINUX__
OUTDLLOPTS=-Wl,-soname,$(notdir $(BINARY))
else
ifdef __MAC__
OUTDLLOPTS=-Wl,-install_name,@executable_path/plugins/$(notdir $(BINARY))
endif
LDFLAGS += -Wl,-soname,$(notdir $(MODULE))
endif
IDA_CMD=TVHEADLESS=1 $(R)idat$(X64SUFF)$(SUFF64)
ST_SWIG=$(F)swig
ifeq ($(OUT_OF_TREE_BUILD),)
ST_SDK=$(F)idasdk
else
ST_SDK=$(IDA_INCLUDE)
#----------------------------------------------------------------------
# TODO move this below, but it might be necessary before the defines-*
ifdef DO_IDAMAKE_SIMPLIFY
QCHKAPI = @echo $(call qcolor,chkapi) && #
QDEPLOY = @echo $(call qcolor,deploy) $$< && #
QGENDOXYCFG = @echo $(call qcolor,gendoxycfg) $@ && #
QGENHOOKS = @echo $(call qcolor,genhooks) $< && #
QGENIDAAPI = @echo $(call qcolor,genidaapi) $< && #
QGENSWIGHEADER = @echo $(call qcolor,genswigheader) $< && #
QGEN_IDC_BC695 = @echo $(call qcolor,gen_idc_bc695) $< && #
QINJECT_PLFM = @echo $(call qcolor,inject_plfm) $< && #
QINJECT_PYDOC = @echo $(call qcolor,inject_pydoc) $$< && #
QPATCH_CODEGEN = @echo $(call qcolor,patch_codegen) $$< && #
QSWIG = @echo $(call qcolor,swig) $$< && #
QUPATE_SDK = @echo $(call qcolor,update_sdk) $< && #
endif
#----------------------------------------------------------------------
IDA_CMD=TVHEADLESS=1 $(R)idat$(SUFF64)
ST_SWIG=$(F)swig
ST_PYW=$(F)pywraps
ST_WRAP=$(F)wrappers
ST_PARSED_HEADERS_NOXML=$(F)parsed_notifications
@@ -85,8 +118,6 @@ ST_PARSED_HEADERS=$(ST_PARSED_HEADERS_NOXML)/xml
ifeq ($(OUT_OF_TREE_BUILD),)
ST_PARSED_HEADERS_CONFIG=$(ST_PARSED_HEADERS_NOXML)/doxy_gen_notifs.cfg
endif
ST_API_CONTENTS=$(F)api_contents.txt.new
ST_PYDOC_INJECTIONS=$(F)pydoc_injections.txt
# output directory for python scripts
DEPLOY_PYDIR=$(R)python
@@ -98,32 +129,24 @@ DEPLOY_IDAAPI_PY=$(DEPLOY_PYDIR)/idaapi.py
DEPLOY_IDADEX_PY=$(DEPLOY_PYDIR)/idadex.py
ifeq ($(OUT_OF_TREE_BUILD),)
TEST_IDC=test_idc
DBLZIP_SCRIPT:=$(abspath ../../ida/build/dblzip.py)
PKGBIN_SCRIPT:=$(abspath ../../ida/build/pkgbin.py)
IDC_BC695_IDC_SOURCE?=$(DEPLOY_PYDIR)/../idc/idc.idc
endif
#
SDK_SOURCES=$(wildcard $(IDA_INCLUDE)/*.h) $(wildcard $(IDA_INCLUDE)/*.hpp)
ifeq ($(OUT_OF_TREE_BUILD),)
ST_SDK_TARGETS=$(SDK_SOURCES:$(IDA_INCLUDE)/%=$(ST_SDK)/%)
ST_SDK_TARGETS = $(SDK_SOURCES:$(IDA_INCLUDE)/%=$(ST_SDK)/%)
else
ST_SDK_TARGETS=$(SDK_SOURCES)
ST_SDK_TARGETS = $(SDK_SOURCES)
endif
PYTHON_DYNLOAD=$(BIN_PATH)../python/lib/python2.7/lib-dynload
DEPLOY_LIBDIR=$(PYTHON_DYNLOAD)/ida_$(ADRSIZE)
$(DEPLOY_LIBDIR):
-@if [ ! -d "$(DEPLOY_LIBDIR)" ] ; then mkdir -p 2>/dev/null $(DEPLOY_LIBDIR) ; fi
$(DEPLOY_PYDIR):
-@if [ ! -d "$(DEPLOY_PYDIR)" ] ; then mkdir -p 2>/dev/null $(DEPLOY_PYDIR) ; fi
ifdef __NT__
MODULE_SFX=.pyd
MODULE_SFX = .pyd
else
MODULE_SFX=.so
MODULE_SFX = .so
endif
ifneq ($(OUT_OF_TREE_BUILD),)
@@ -132,86 +155,85 @@ else
HAS_HEXRAYS=1 # force hexrays bindings
endif
ifneq ($(HAS_HEXRAYS),)
WITH_HEXRAYS=-DWITH_HEXRAYS
WITH_HEXRAYS_DEF = WITH_HEXRAYS
WITH_HEXRAYS_CHKAPI=--with-hexrays
HEXRAYS_MODNAME=hexrays
endif
# We are building 'MODULES_NAMES' from subvars because it appears some versions
# of make do not deal too well with '\'s, and introduce spaces, which later is
# problematic when substituting ' ' for ',' & passing modules list to scripts
MNAMES_0=allins range auto bytes dbg diskio entry enum expr fixup
MNAMES_1=fpro frame funcs gdl graph $(HEXRAYS_MODNAME) ida idaapi idd idp
MNAMES_2=kernwin lines loader moves nalt name netnode offset pro problems
MNAMES_3=registry search segment segregs strlist struct typeinf tryblks ua xref
MNAMES_EXTRA=idc
MODULES_NAMES=$(MNAMES_0) $(MNAMES_1) $(MNAMES_2) $(MNAMES_3) $(MNAMES_EXTRA)
#----------------------------------------------------------------------
MODULES_NAMES += $(HEXRAYS_MODNAME)
MODULES_NAMES += allins
MODULES_NAMES += auto
MODULES_NAMES += bytes
MODULES_NAMES += dbg
MODULES_NAMES += diskio
MODULES_NAMES += entry
MODULES_NAMES += enum
MODULES_NAMES += expr
MODULES_NAMES += fixup
MODULES_NAMES += fpro
MODULES_NAMES += frame
MODULES_NAMES += funcs
MODULES_NAMES += gdl
MODULES_NAMES += graph
MODULES_NAMES += ida
MODULES_NAMES += idaapi
MODULES_NAMES += idc
MODULES_NAMES += idd
MODULES_NAMES += idp
MODULES_NAMES += kernwin
MODULES_NAMES += lines
MODULES_NAMES += loader
MODULES_NAMES += moves
MODULES_NAMES += nalt
MODULES_NAMES += name
MODULES_NAMES += netnode
MODULES_NAMES += offset
MODULES_NAMES += pro
MODULES_NAMES += problems
MODULES_NAMES += range
MODULES_NAMES += registry
MODULES_NAMES += search
MODULES_NAMES += segment
MODULES_NAMES += segregs
MODULES_NAMES += strlist
MODULES_NAMES += struct
MODULES_NAMES += tryblks
MODULES_NAMES += typeinf
MODULES_NAMES += ua
MODULES_NAMES += xref
MODULES=$(MODULES_NAMES:%=$(F)_ida_%$(MODULE_SFX))
DEPLOYED_MODULES=$(MODULES_NAMES:%=$(DEPLOY_LIBDIR)/_ida_%$(MODULE_SFX))
MODULES_OBJECTS=$(MODULES_NAMES:%=$(F)%$(O))
ALL_ST_WRAP_CPP = $(foreach mod,$(MODULES_NAMES),$(ST_WRAP)/$(mod).cpp)
ALL_ST_WRAP_PY = $(foreach mod,$(MODULES_NAMES),$(ST_WRAP)/ida_$(mod).py)
DEPLOYED_MODULES = $(foreach mod,$(MODULES_NAMES),$(DEPLOY_LIBDIR)/_ida_$(mod)$(MODULE_SFX))
IDAPYTHON_MODULES = $(foreach mod,$(MODULES_NAMES),$(DEPLOY_PYDIR)/ida_$(mod).py)
PYTHON_BINARY_MODULES = $(foreach mod,$(MODULES_NAMES),$(DEPLOY_LIBDIR)/_ida_$(mod)$(MODULE_SFX))
ALL_ST_SWIG=$(foreach mod,$(MODULES_NAMES),$(ST_SWIG)/$(mod).i)
ALL_ST_WRAP_CPP=$(foreach mod,$(MODULES_NAMES),$(ST_WRAP)/$(mod).cpp)
ALL_ST_WRAP_PY=$(foreach mod,$(MODULES_NAMES),$(ST_WRAP)/ida_$(mod).py)
PYTHON_MODULES=$(MODULES_NAMES:%=$(DEPLOY_PYDIR)/ida_%.py)
PYTHON_BINARY_MODULES=$(MODULES_NAMES:%=$(DEPLOY_LIBDIR)/_ida_%$(MODULE_SFX))
#----------------------------------------------------------------------
idapython_modules: $(IDAPYTHON_MODULES)
deployed_modules: $(DEPLOYED_MODULES)
ifdef __NT__
MODULE_LINKIDA=
CREATE_IMPLIB=$(RS)lib32.bat
IDAPYTHON_IMPLIB_DEF=$(F)idapython_implib.def
IDAPYTHON_IMPLIB_DEF_IN=tools/idapython_implib.def.in
IDAPYTHON_IMPLIB_DEF=idapython_implib.def
IDAPYTHON_IMPLIB_PATH=$(F)python.lib
BINARY_LINKOPTS=/def:$(IDAPYTHON_IMPLIB_DEF) /IMPLIB:$(IDAPYTHON_IMPLIB_PATH)
RESFILES=$(IDAPYTHON_IMPLIB_DEF)
LINKIDAPYTHON = $(IDAPYTHON_IMPLIB_PATH)
else
ifeq ($(OUT_OF_TREE_BUILD),)
LIBIDA_DIR:=$(R)
else
LIBIDA_DIR:=$(L)
endif
MODULE_LINKIDA=-L$(LIBIDA_DIR) $(LINKIDA) $(BINARY)
endif
all: objdir pyfiles config $(DEPLOYED_MODULES) $(PYTHON_MODULES) $(ST_API_CONTENTS) $(IDAPYTHON_IMPLIB) $(ST_PYDOC_INJECTIONS) #$(TEST_IDC)
# IDAPython version
IDAPYTHON_VERSION_MAJOR=6
IDAPYTHON_VERSION_MINOR=9
IDAPYTHON_VERSION_PATCH=5
PACKAGE_NAME=idapython-$(IDAPYTHON_VERSION_MAJOR).$(IDAPYTHON_VERSION_MINOR).$(IDAPYTHON_VERSION_PATCH)-python$(PYTHON_VERSION_MAJOR).$(PYTHON_VERSION_MINOR)-$(SYSNAME)
# HIJACK the $(I) variable to point to our staging SDK
I=$(ST_SDK)/
ifdef __CODE_CHECKER__
ADDITIONAL_GOALS:=$(filter-out pyfiles config $(TEST_IDC),$(ADDITIONAL_GOALS))
OBJS:=$(filter-out $(OBJ1),$(OBJS))
LINKIDAPYTHON = $(MODULE)
endif
ifdef __NT__ # os and compiler specific flags
ifneq ($(UCRT_INCLUDE),)
I_UCRT_INCLUDE=/I$(UCRT_INCLUDE)
endif
IDAPYTHON_CFLAGS=$(PYTHON_CFLAGS) -w -Z7 /bigobj /I$(MSVCDIR)Include $(I_UCRT_INCLUDE)
_SWIGFLAGS=-D__NT__ -DWIN32 -D_USRDLL -I$(PYTHON_DIR)/include
SWIGINCLUDES?= # nothing
# FIXME: Cannot enable the .cfg file ATM, because there's just too many errors if I do.
PLATFORM_CFLAGS=$(_SWIGFLAGS) -UNO_OBSOLETE_FUNCS
_SWIGFLAGS = -D__NT__ -DWIN32 -D_USRDLL -I$(PYTHON_DIR)/include
CFLAGS += /bigobj $(_SWIGFLAGS) -I$(ST_SDK) /U_DEBUG
# override runtime libs in CFLAGS
RUNTIME_LIBSW = /MD
else # unix/mac
ifdef __LINUX__
PYTHON_LDFLAGS_RPATH_MAIN=-Wl,-rpath='$$ORIGIN/..'
PYTHON_LDFLAGS_RPATH_MODULE=-Wl,-rpath='$$$$ORIGIN/../../..'
else
MACDEFINES=-DMACSDKVER=$(MACSDKVER)
PYTHON_LDFLAGS_RPATH_MODULE=-Wl,-rpath='$$ORIGIN/../../..'
_SWIGFLAGS = -D__LINUX__
else ifdef __MAC__
_SWIGFLAGS = -D__MAC__
endif
IDAPYTHON_CFLAGS=-w -g
PLATFORM_CFLAGS=$(SYS) -g $(PYTHON_CFLAGS) $(ARCH_CFLAGS) $(PIC) -UNO_OBSOLETE_FUNCS # gcc flags
_SWIGFLAGS=$(DEFS)
SWIGINCLUDES?=-I$(SWIGDIR)share/swig/$(SWIG_VERSION)/python -I$(SWIGDIR)share/swig/$(SWIG_VERSION)
endif
# Apparently that's not needed, but I don't understand why ATM, since doc says:
# ...Then, only modules compiled with SWIG_TYPE_TABLE set to myprojectname
@@ -219,184 +241,186 @@ endif
# should be compiled with -DSWIG_TYPE_TABLE=myprojectname, and then these
# three modules will share type information. But any other project's
# types will not interfere or clash with the types in your module.
DEF_TYPE_TABLE=-DSWIG_TYPE_TABLE=idaapi
SWIGFLAGS=$(_SWIGFLAGS) -Itools/typemaps-supplement $(SWIGINCLUDES) $(DEF_TYPE_TABLE) -D__IDP__ -D__PLUGIN__ $(BC695_SWIGFLAGS)
DEF_TYPE_TABLE = SWIG_TYPE_TABLE=idaapi
SWIGFLAGS=$(_SWIGFLAGS) -Itools/typemaps-supplement $(SWIG_INCLUDES) $(addprefix -D,$(DEF_TYPE_TABLE)) $(BC695_SWIGFLAGS)
ADDITIONAL_LIBS=$(PYTHON_LDFLAGS) $(PYTHON_LDFLAGS_RPATH_MAIN)
ifdef __LINUX__
ADDITIONAL_LIBS_MODULE=$(PYTHON_LDFLAGS) $(PYTHON_LDFLAGS_RPATH_MODULE)
else
ADDITIONAL_LIBS_MODULE=$(ADDITIONAL_LIBS)
endif
PUBTREE_DIR=$(F)/public_tree
.PHONY: pyfiles docs $(TEST_IDC) staging_dirs clean check_python package public_tree
config: $(C)python.cfg
clean::
rm -rf obj/
LDFLAGS += $(PYTHON_LDFLAGS) $(PYTHON_LDFLAGS_RPATH_MAIN)
pyfiles: $(DEPLOY_IDAUTILS_PY) \
$(DEPLOY_IDC_PY) \
$(DEPLOY_IDC_BC695_PY) \
$(DEPLOY_INIT_PY) \
$(DEPLOY_IDAAPI_PY) \
$(DEPLOY_IDADEX_PY)
$(DEPLOY_IDC_PY) \
$(DEPLOY_IDC_BC695_PY) \
$(DEPLOY_INIT_PY) \
$(DEPLOY_IDAAPI_PY) \
$(DEPLOY_IDADEX_PY)
GENHOOKS=tools/genhooks/
_SPACE := $(null) #
_COMMA := ,
$(DEPLOY_INIT_PY): python/init.py | $(DEPLOY_PYDIR)
$(DEPLOY_INIT_PY): python/init.py
$(CP) $? $@
$(DEPLOY_IDC_PY): python/idc.py | $(DEPLOY_PYDIR)
$(DEPLOY_IDC_PY): python/idc.py
$(CP) $? $@
$(DEPLOY_IDAUTILS_PY): python/idautils.py | $(DEPLOY_PYDIR)
$(DEPLOY_IDAUTILS_PY): python/idautils.py
$(CP) $? $@
$(DEPLOY_IDC_BC695_PY): $(IDC_BC695_IDC_SOURCE) python/idc.py tools/gen_idc_bc695.py | $(DEPLOY_PYDIR)
$(PYTHON) tools/gen_idc_bc695.py --idc $(IDC_BC695_IDC_SOURCE) --output $@
$(DEPLOY_IDC_BC695_PY): $(IDC_BC695_IDC_SOURCE) python/idc.py tools/gen_idc_bc695.py
$(QGEN_IDC_BC695)$(PYTHON) tools/gen_idc_bc695.py --idc $(IDC_BC695_IDC_SOURCE) --output $@
$(DEPLOY_PYDIR)/idaapi.py: python/idaapi.py tools/genidaapi.py $(PYTHON_MODULES) | $(DEPLOY_PYDIR)
$(PYTHON) tools/genidaapi.py -i $< -o $@ -m $(subst $(_SPACE),$(_COMMA),$(MODULES_NAMES))
$(DEPLOY_IDAAPI_PY): python/idaapi.py tools/genidaapi.py $(IDAPYTHON_MODULES)
$(QGENIDAAPI)$(PYTHON) tools/genidaapi.py -i $< -o $@ -m $(subst $(space),$(comma),$(MODULES_NAMES))
$(DEPLOY_PYDIR)/idadex.py: python/idadex.py | $(DEPLOY_PYDIR)
$(DEPLOY_IDADEX_PY): python/idadex.py
$(CP) $? $@
$(DEPLOY_PYDIR)/lib/%: precompiled/lib/%
mkdir -p $(@D)
cp $< $@
@chmod +w $@
$(Q)chmod +w $@
$(C)python.cfg: python.cfg
$(CP) $? $@
$(R)$(LIBPYTHON_NAME): $(PRECOMPILED_DIR)/$(LIBPYTHON_NAME)
$(CP) $? $@
# -------------------------------------------------------------------------
#----------------------------------------------------------------------
# Hooks generation
# http://stackoverflow.com/questions/11032280/specify-doxygen-parameters-through-command-line
$(ST_PARSED_HEADERS_CONFIG): $(GENHOOKS)doxy_gen_notifs.cfg.in $(ST_SDK_TARGETS) $(GENHOOKS)gendoxycfg.py | staging_dirs
@$(PYTHON) $(GENHOOKS)gendoxycfg.py -i $< -o $@ --includes $(subst $(_SPACE),$(_COMMA),$(ST_SDK_TARGETS))
$(ST_PARSED_HEADERS_CONFIG): $(GENHOOKS)doxy_gen_notifs.cfg.in $(ST_SDK_TARGETS) $(GENHOOKS)gendoxycfg.py
$(QGENDOXYCFG)$(PYTHON) $(GENHOOKS)gendoxycfg.py -i $< -o $@ --includes $(subst $(space),$(comma),$(ST_SDK_TARGETS))
PARSED_HEADERS_MARKER=$(ST_PARSED_HEADERS)/headers_generated.marker
$(PARSED_HEADERS_MARKER): $(ST_SDK_TARGETS) $(ST_PARSED_HEADERS_CONFIG) $(ST_SDK_TARGETS)
ifeq ($(OUT_OF_TREE_BUILD),)
@( cat $(ST_PARSED_HEADERS_CONFIG); echo "OUTPUT_DIRECTORY=$(ST_PARSED_HEADERS_NOXML)" ) | $(DOXYGEN_BIN) -
$(Q)( cat $(ST_PARSED_HEADERS_CONFIG); echo "OUTPUT_DIRECTORY=$(ST_PARSED_HEADERS_NOXML)" ) | $(DOXYGEN_BIN) - >/dev/null
else
(cd $(F) && unzip ../../out_of_tree/parsed_notifications.zip)
endif
@touch $@
$(Q)touch $@
#
staging_dirs:
-@if [ ! -d "$(ST_SDK)" ] ; then mkdir -p 2>/dev/null $(ST_SDK) ; fi
-@if [ ! -d "$(ST_SWIG)" ] ; then mkdir -p 2>/dev/null $(ST_SWIG) ; fi
-@if [ ! -d "$(ST_PYW)" ] ; then mkdir -p 2>/dev/null $(ST_PYW) ; fi
-@if [ ! -d "$(ST_WRAP)" ] ; then mkdir -p 2>/dev/null $(ST_WRAP) ; fi
-@if [ ! -d "$(ST_PARSED_HEADERS)" ] ; then mkdir -p 2>/dev/null $(ST_PARSED_HEADERS) ; fi
#----------------------------------------------------------------------
# Create directories in the first phase of makefile parsing.
DIRLIST += $(DEPLOY_LIBDIR)
DIRLIST += $(DEPLOY_PYDIR)
DIRLIST += $(DEPLOY_PYDIR)/lib
DIRLIST += $(ST_PARSED_HEADERS)
DIRLIST += $(ST_PYW)
DIRLIST += $(ST_SDK)
DIRLIST += $(ST_SWIG)
DIRLIST += $(ST_WRAP)
$(foreach d,$(sort $(DIRLIST)),$(if $(wildcard $(d)),,$(shell mkdir -p $(d))))
# -------------------------------------------------------------------------
#----------------------------------------------------------------------
# obj/.../idasdk/*.h[pp]
#
ifeq ($(OUT_OF_TREE_BUILD),)
$(ST_SDK)/%.h: $(IDA_INCLUDE)/%.h | staging_dirs $(PRECOMPILED_COPY)
$(PYTHON) ../../bin/update_sdk.py $(FILTER_SDK_FLAGS) -filter-file -input $^ -output $@
$(ST_SDK)/%.hpp: $(IDA_INCLUDE)/%.hpp | staging_dirs $(PRECOMPILED_COPY)
$(PYTHON) ../../bin/update_sdk.py $(FILTER_SDK_FLAGS) -filter-file -input $^ -output $@
$(ST_SDK)/%.h: $(IDA_INCLUDE)/%.h
$(QUPATE_SDK)$(PYTHON) ../../bin/update_sdk.py $(FILTER_SDK_FLAGS) -filter-file -input $^ -output $@
$(ST_SDK)/%.hpp: $(IDA_INCLUDE)/%.hpp
$(QUPATE_SDK)$(PYTHON) ../../bin/update_sdk.py $(FILTER_SDK_FLAGS) -filter-file -input $^ -output $@
endif
# -------------------------------------------------------------------------
#----------------------------------------------------------------------
# obj/.../pywraps/*
#
$(ST_PYW)/%.hpp: pywraps/%.hpp | staging_dirs
@$(CP) $^ $@ && chmod +rw $@
$(ST_PYW)/%.py: pywraps/%.py | staging_dirs
@$(CP) $^ $@ && chmod +rw $@
$(ST_PYW)/%.hpp: pywraps/%.hpp
$(Q)$(CP) $^ $@ && chmod +rw $@
$(ST_PYW)/%.py: pywraps/%.py
$(Q)$(CP) $^ $@ && chmod +rw $@
# These require special care, as they will have to be injected w/ hooks -- this
# only happens if we are sitting in the hexrays source tree; when published to
# the outside world, the pywraps must already contain the injected code.
$(ST_PYW)/py_idp.hpp: pywraps/py_idp.hpp \
$(I)idp.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_idphooks.py \
$(PARSED_HEADERS_MARKER) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/structprocessor__t.xml -e event_t \
-r int -n 0 -m hookgenIDP -q "processor_t::" \
-R $(GENHOOKS)recipe_idphooks.py
$(I)idp.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_idphooks.py \
$(PARSED_HEADERS_MARKER) $(MAKEFILE_DEP) | $(SDK_SOURCES)
$(QGENHOOKS)$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/structprocessor__t.xml -e event_t \
-r int -n 0 -m hookgenIDP -q "processor_t::" \
-R $(GENHOOKS)recipe_idphooks.py
$(ST_PYW)/py_idp_idbhooks.hpp: pywraps/py_idp_idbhooks.hpp \
$(I)idp.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_idbhooks.py \
$(PARSED_HEADERS_MARKER) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/namespaceidb__event.xml -e event_code_t \
-r int -n 0 -m hookgenIDB -q "idb_event::" \
-R $(GENHOOKS)recipe_idbhooks.py
$(I)idp.hpp \
$(GENHOOKS)recipe_idbhooks.py \
$(GENHOOKS)genhooks.py $(PARSED_HEADERS_MARKER) $(MAKEFILE_DEP) | $(SDK_SOURCES)
$(QGENHOOKS)$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/namespaceidb__event.xml -e event_code_t \
-r int -n 0 -m hookgenIDB -q "idb_event::" \
-R $(GENHOOKS)recipe_idbhooks.py
$(ST_PYW)/py_dbg.hpp: pywraps/py_dbg.hpp \
$(I)dbg.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_dbghooks.py \
$(PARSED_HEADERS_MARKER) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/dbg_8hpp.xml -e dbg_notification_t \
-r void -n 0 -m hookgenDBG \
-R $(GENHOOKS)recipe_dbghooks.py
$(I)dbg.hpp \
$(GENHOOKS)recipe_dbghooks.py \
$(GENHOOKS)genhooks.py $(PARSED_HEADERS_MARKER) $(MAKEFILE_DEP) | $(SDK_SOURCES)
$(QGENHOOKS)$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/dbg_8hpp.xml -e dbg_notification_t \
-r void -n 0 -m hookgenDBG \
-R $(GENHOOKS)recipe_dbghooks.py
$(ST_PYW)/py_kernwin.hpp: pywraps/py_kernwin.hpp \
$(I)kernwin.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_uihooks.py \
$(PARSED_HEADERS_MARKER) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/kernwin_8hpp.xml -e ui_notification_t \
-r void -n 0 -m hookgenUI \
-R $(GENHOOKS)recipe_uihooks.py \
-d "ui_dbg_,ui_obsolete" -D "ui:" -s "ui_"
$(I)kernwin.hpp \
$(GENHOOKS)recipe_uihooks.py \
$(GENHOOKS)genhooks.py $(PARSED_HEADERS_MARKER) $(MAKEFILE_DEP) | $(SDK_SOURCES)
$(QGENHOOKS)$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/kernwin_8hpp.xml -e ui_notification_t \
-r void -n 0 -m hookgenUI \
-R $(GENHOOKS)recipe_uihooks.py \
-d "ui_dbg_,ui_obsolete" -D "ui:" -s "ui_"
$(ST_PYW)/py_kernwin_viewhooks.hpp: pywraps/py_kernwin_viewhooks.hpp \
$(I)kernwin.hpp \
$(GENHOOKS)genhooks.py \
$(GENHOOKS)recipe_viewhooks.py \
$(PARSED_HEADERS_MARKER) | staging_dirs $(SDK_SOURCES)
@$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/kernwin_8hpp.xml -e view_notification_t \
-r void -n 0 -m hookgenVIEW \
-R $(GENHOOKS)recipe_viewhooks.py
$(I)kernwin.hpp \
$(GENHOOKS)recipe_viewhooks.py \
$(GENHOOKS)genhooks.py $(PARSED_HEADERS_MARKER) $(MAKEFILE_DEP) | $(SDK_SOURCES)
$(QGENHOOKS)$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/kernwin_8hpp.xml -e view_notification_t \
-r void -n 0 -m hookgenVIEW \
-R $(GENHOOKS)recipe_viewhooks.py
$(ST_PYW)/py_hexrays_hooks.hpp: pywraps/py_hexrays_hooks.hpp \
$(I)hexrays.hpp \
$(GENHOOKS)recipe_hexrays.py \
$(GENHOOKS)genhooks.py $(PARSED_HEADERS_MARKER) $(MAKEFILE_DEP) | $(SDK_SOURCES)
$(QGENHOOKS)$(PYTHON) $(GENHOOKS)genhooks.py -i $< -o $@ \
-x $(ST_PARSED_HEADERS)/hexrays_8hpp.xml -e hexrays_event_t \
-r int -n 0 -m hookgenHEXRAYS \
-R $(GENHOOKS)recipe_hexrays.py \
-s "hxe_,lxe_"
CFLAGS= $(CCOPT) $(PLATFORM_CFLAGS) $(MSRUNTIME) -D__EXPR_SRC -I. -I$(ST_SWIG) -I$(ST_SDK) -I$(F) \
-DVER_MAJOR="1" -DVER_MINOR="7" -DVER_PATCH="0" -D__IDP__ -D__PLUGIN__ \
-DUSE_STANDARD_FILE_FUNCTIONS $(IDAPYTHON_CFLAGS) \
$(SWITCH64) $(SWITCHX64) $(ARCH_CFLAGS) $(WITH_HEXRAYS) $(DEF_TYPE_TABLE) $(BC695_CFLAGS)
#----------------------------------------------------------------------
CFLAGS += $(PYTHON_CFLAGS)
CC_DEFS += $(BC695_CC_DEF)
CC_DEFS += $(DEF_TYPE_TABLE)
CC_DEFS += $(WITH_HEXRAYS_DEF)
CC_DEFS += USE_STANDARD_FILE_FUNCTIONS
CC_DEFS += VER_MAJOR="1"
CC_DEFS += VER_MINOR="7"
CC_DEFS += VER_PATCH="0"
CC_DEFS += __EXPR_SRC
CC_INCP += $(F)
CC_INCP += $(IDA_INCLUDE)
CC_INCP += $(ST_SWIG)
CC_INCP += .
# suppress warnings
WARNS = $(NOWARNS)
# disable -pthread in CFLAGS
PTHR_SWITCH =
# disable -DNO_OBSOLETE_FUNCS in CFLAGS
NO_OBSOLETE_FUNCS =
#----------------------------------------------------------------------
ifdef TESTABLE_BUILD
CFLAGS+=-DTESTABLE_BUILD
SWIGFLAGS+=-DTESTABLE_BUILD
FILTER_SDK_FLAGS+=-testable-build
endif
ST_SWIG_HEADER=$(ST_SWIG)/header.i
$(ST_SWIG)/header.i: tools/deploy/header.i.in tools/genswigheader.py $(ST_SDK_TARGETS) | staging_dirs
$(PYTHON) tools/genswigheader.py -i $< -o $@ -m $(subst $(_SPACE),$(_COMMA),$(MODULES_NAMES)) -s $(ST_SDK)
ST_SWIG_HEADER = $(ST_SWIG)/header.i
$(ST_SWIG)/header.i: tools/deploy/header.i.in tools/genswigheader.py $(ST_SDK_TARGETS)
$(QGENSWIGHEADER)$(PYTHON) tools/genswigheader.py -i $< -o $@ -m $(subst $(space),$(comma),$(MODULES_NAMES)) -s $(ST_SDK)
ifdef __NT__
PATCH_DIRECTORS_SCRIPT:=tools/patch_directors_cc.py
$(IDAPYTHON_IMPLIB_DEF): $(IDAPYTHON_IMPLIB_DEF_IN)
sed s/%LIBNAME%/$(notdir $(BINARY))/ < $? > $@
sed -i s/%PLUGIN_DATA_EXP%// $@
PATCH_DIRECTORS_SCRIPT = tools/patch_directors_cc.py
endif
PATCH_CODEGEN_X64_OPTS=--apply-valist-patches
find-pywraps-deps = $(wildcard pywraps/py_$(subst .i,,$(notdir $(1)))*.hpp) $(wildcard pywraps/py_$(subst .i,,$(notdir $(1)))*.py)
find-pydoc-patches-deps = $(wildcard tools/inject_pydoc/$(1).py)
find-pywraps-deps = $(wildcard pywraps/py_$(subst .i,,$(notdir $1))*.*)
find-pydoc-patches-deps = $(wildcard tools/inject_pydoc/$1.py)
ADDITIONAL_PYWRAP_DEP_idp=$(ST_PYW)/py_idp.py
$(ST_PYW)/py_idp.py: pywraps/py_idp.py.in tools/inject_plfm.py $(ST_SDK)/idp.hpp
$(QINJECT_PLFM)$(PYTHON) tools/inject_plfm.py -i $< -o $@ -d $(ST_SDK)/idp.hpp
# Some .i files depend on some other .i files in order to be parseable by SWiG
# (e.g., segregs.i imports range.i). Declare the list of such dependencies here
@@ -407,6 +431,7 @@ SWIG_IFACE_frame=range
SWIG_IFACE_funcs=range
SWIG_IFACE_gdl=range
SWIG_IFACE_hexrays=typeinf
SWIG_IFACE_idd=range
SWIG_IFACE_segment=range
SWIG_IFACE_segregs=range
SWIG_IFACE_typeinf=idp
@@ -421,116 +446,146 @@ define make-module-rules
# http://stackoverflow.com/questions/19822435/multiple-targets-from-one-recipe-and-parallel-execution
# Consequently, rules such as this:
#
# $(ST_WRAP)/ida_$1.py: $(ST_WRAP)/$1.cpp
# $(ST_WRAP)/ida_$(1).py: $(ST_WRAP)/$(1).cpp
#
# i.e., that do nothing but rely on the generation of another file,
# will not work in // execution. Thus, we will rely exclusively on
# the presence of the generated .cpp file, and not other generated
# files.
# ../../bin/x86_linux_gcc/python/ida_$1.py (note: dep. on .cpp. See note above.)
$(DEPLOY_PYDIR)/ida_$1.py: $(ST_WRAP)/$1.cpp $(PARSED_HEADERS_MARKER) $(call find-pydoc-patches-deps,$1) | $(DEPLOY_PYDIR) tools/inject_pydoc.py
$(PYTHON) tools/inject_pydoc.py \
# ../../bin/x86_linux_gcc/python/ida_$(1).py (note: dep. on .cpp. See note above.)
$(DEPLOY_PYDIR)/ida_$(1).py: $(ST_WRAP)/$(1).cpp $(PARSED_HEADERS_MARKER) $(call find-pydoc-patches-deps,$(1)) | tools/inject_pydoc.py
$(QINJECT_PYDOC)$(PYTHON) tools/inject_pydoc.py \
-x $(ST_PARSED_HEADERS) \
-m $1 \
-i $(ST_WRAP)/ida_$1.py \
-w $(ST_SWIG)/$1.i \
-o $$@ \
-e $(ST_WRAP)/ida_$1.epydoc_injection \
-v > $(ST_WRAP)/ida_$1.pydoc_injection 2>&1
-m $(1) \
-i $(ST_WRAP)/ida_$(1).py \
-w $(ST_SWIG)/$(1).i \
-o $$@ \
-e $(ST_WRAP)/ida_$(1).epydoc_injection \
-v > $(ST_WRAP)/ida_$(1).pydoc_injection 2>&1
# obj/x86_linux_gcc/swig/X.i
$(ST_SWIG)/$1.i: $(addprefix $(F),$(call find-pywraps-deps,$1)) swig/$1.i $(ST_SWIG_HEADER) $(SWIG_IFACE_$1:%=$(ST_SWIG)/%.i) $(ST_SWIG_HEADER) tools/deploy.py
$(PYTHON) tools/deploy.py \
--pywraps $(ST_PYW) \
--template $$(subst $(F),,$$@) \
--output $$@ \
--module $$(subst .i,,$$(notdir $$@)) \
$(MODULE_LIFECYCLE_$1) \
$(BC695_DEPLOYFLAGS) \
--interface-dependencies=$(subst $(_SPACE),$(_COMMA),$(SWIG_IFACE_$1))
$(ST_SWIG)/$(1).i: $(addprefix $(F),$(call find-pywraps-deps,$(1))) $(ADDITIONAL_PYWRAP_DEP_$(1)) swig/$(1).i $(ST_SWIG_HEADER) $(SWIG_IFACE_$(1):%=$(ST_SWIG)/%.i) $(ST_SWIG_HEADER) tools/deploy.py $(PARSED_HEADERS_MARKER)
$(QDEPLOY)$(PYTHON) tools/deploy.py \
--pywraps $(ST_PYW) \
--template $$(subst $(F),,$$@) \
--output $$@ \
--module $$(subst .i,,$$(notdir $$@)) \
$(MODULE_LIFECYCLE_$(1)) \
$(BC695_DEPLOYFLAGS) \
--interface-dependencies=$(subst $(space),$(comma),$(SWIG_IFACE_$(1))) \
--xml-doc-directory $(ST_PARSED_HEADERS)
# obj/x86_linux_gcc/wrappers/X.cpp
$(ST_WRAP)/$1.cpp: $(ST_SWIG)/$1.i tools/patch_codegen.py makefile $(PATCH_DIRECTORS_SCRIPT) tools/chkapi.py
$(SWIG) -modern $(WITH_HEXRAYS) -python -threads -c++ -shadow \
$(MACDEFINES) -D__GNUC__ $(SWIGFLAGS) $(SWITCH64) $(SWITCHX64) -I$(ST_SWIG) \
-outdir $(ST_WRAP) -o $$@ -I$(ST_SDK) $$<
@$(PYTHON) tools/patch_constants.py --file $(ST_WRAP)/$1.cpp
$(PYTHON) tools/patch_codegen.py $(PATCH_CODEGEN_X64_OPTS) --file $(ST_WRAP)/$1.cpp --patches tools/patch_codegen/$1.py
$(ST_WRAP)/$(1).cpp: $(ST_SWIG)/$(1).i tools/patch_codegen.py $(PATCH_DIRECTORS_SCRIPT) $(PARSED_HEADERS_MARKER) tools/chkapi.py
$(QSWIG)$(SWIG) -modern $(addprefix -D,$(WITH_HEXRAYS_DEF)) -python -threads -c++ -shadow \
-D__GNUC__ $(SWIGFLAGS) $(addprefix -D,$(DEF64)) -I$(ST_SWIG) \
-outdir $(ST_WRAP) -o $$@ -I$(ST_SDK) $$<
$(Q)$(PYTHON) tools/patch_constants.py --file $(ST_WRAP)/$(1).cpp
$(QPATCH_CODEGEN)$(PYTHON) tools/patch_codegen.py \
--apply-valist-patches \
--file $(ST_WRAP)/$(1).cpp \
--module $(1) \
--xml-doc-directory $(ST_PARSED_HEADERS) \
--patches tools/patch_codegen/$(1).py
ifdef __NT__
$(PYTHON) $(PATCH_DIRECTORS_SCRIPT) --file $(ST_WRAP)/$1.h
$(PYTHON) $(PATCH_DIRECTORS_SCRIPT) --file $(ST_WRAP)/$(1).h
endif
# The copying of the .py will preserve attributes (including timestamps).
# And, since we have patched $1.cpp, it'll be more recent than ida_$1.py,
# And, since we have patched $(1).cpp, it'll be more recent than ida_$(1).py,
# and make would keep copying the .py file at each invocation.
# To prevent that, let's make the source .py file more recent than .cpp.
@touch $(ST_WRAP)/ida_$1.py
# obj/x86_linux_gcc/X.o32
$(F)$1$(O): $(ST_WRAP)/$1.cpp
ifdef __CODE_CHECKER__
touch $$@
else
$(CXX) $(CFLAGS) $(MSRUNTIME) $(MSCLOPTS) $(NORTTI) -DPLUGIN_SUBMODULE -DSWIG_DIRECTOR_NORTTI -c $(OBJSW)$$@ $(ST_WRAP)/$1.cpp
ifndef __NT__
ifeq ($(OUT_OF_TREE_BUILD),)
@$(STRIPSYM_TOOL) $$@ $(STRIPSYMS) > /dev/null || ($(RM) $$@; false)
endif
endif
endif
# obj/x86_linux_gcc/_ida_X.so
$(F)_ida_$1$(MODULE_SFX): $(F)$1$(O) $(BINARY) $(IDAPYTHON_IMPLIB_DEF)
ifdef __NT__ # we repeat /map switch with the explicit file name because @F does not work inside macro
$(LINKER) $(LINKOPTS) /map:$(F)_ida_$1$(MODULE_SFX).map $(MSLDOPTS) /OPT:ICF /OPT:REF /INCREMENTAL:NO /STUB:../../plugins/stub /OUT:$$@ $$< $(IDALIB) user32.lib $(ADDITIONAL_LIBS_MODULE) $(IDAPYTHON_IMPLIB_PATH)
else
$(CCL) $(OUTDLL) $(OUTSW)$$@ $$< $(MODULE_LINKIDA) $(PLUGIN_SCRIPT) $(ADDITIONAL_LIBS_MODULE) $(STDLIBS)
endif
# ../../bin/x86_linux_gcc/python/lib/lib-dynload/ida_32/_ida_X.so
$(DEPLOY_LIBDIR)/_ida_$1$(MODULE_SFX): $(F)_ida_$1$(MODULE_SFX) | $(DEPLOY_LIBDIR)
@$(CP) $$< $$@
$(Q)touch $(ST_WRAP)/ida_$(1).py
endef
$(foreach mod,$(MODULES_NAMES),$(eval $(call make-module-rules,$(mod))))
# obj/x86_linux_gcc/X.o
X_O = $(call objs,$(MODULES_NAMES))
vpath %.cpp $(ST_WRAP)
ifdef __NT__
# remove warnings from generated code:
# error C4296: '<': expression is always false
# warning C4700: uninitialized local variable 'c_result' used
# warning C4706: assignment within conditional expression
$(X_O): CFLAGS += /wd4296 /wd4700 /wd4706
endif
# disable -fno-rtti
$(X_O): NORTTI =
$(X_O): CC_DEFS += PLUGIN_SUBMODULE
$(X_O): CC_DEFS += SWIG_DIRECTOR_NORTTI
ifdef __CODE_CHECKER__
$(X_O):
$(Q)touch $@
endif
# obj/x86_linux_gcc/_ida_X.so
_IDA_X_SO = $(addprefix $(F)_ida_,$(addsuffix $(MODULE_SFX),$(MODULES_NAMES)))
ifdef __NT__
$(_IDA_X_SO): STDLIBS += user32.lib
endif
# Note: On Windows, IDAPython's python.lib must come *after* python27.lib
# in the linking command line, otherwise Python will misdetect
# IDAPython's python.dll as the main "python" DLL, and IDAPython
# will fail to load with the following error:
# "Module use of python.dll conflicts with this version of Python."
# To achieve this, we add IDAPython's python.lib to STDLIBS, which
# is at the end of the link command.
# See Python's dynload_win.c:GetPythonImport() for more details.
$(_IDA_X_SO): STDLIBS += $(LINKIDAPYTHON)
$(_IDA_X_SO): LDFLAGS += $(PYTHON_LDFLAGS_RPATH_MODULE) $(OUTMAP)$(F)$(@F).map
$(F)_ida_%$(MODULE_SFX): $(F)%$(O) $(MODULE) $(IDAPYTHON_IMPLIB_DEF)
$(call link_dll, $<, $(LINKIDA))
ifdef __NT__
$(Q)$(RM) $(@:$(MODULE_SFX)=.exp) $(@:$(MODULE_SFX)=.lib)
endif
# ../../bin/x86_linux_gcc/python/lib/lib-dynload/ida_32/_ida_X.so
$(DEPLOY_LIBDIR)/_ida_%$(MODULE_SFX): $(F)_ida_%$(MODULE_SFX)
$(Q)$(CP) $< $@
#----------------------------------------------------------------------
API_CONTENTS = api_contents.txt
ST_API_CONTENTS = $(F)$(API_CONTENTS)
.PRECIOUS: $(ST_API_CONTENTS)
api_contents: $(ST_API_CONTENTS)
$(ST_API_CONTENTS): $(ALL_ST_WRAP_CPP)
$(PYTHON) tools/chkapi.py $(WITH_HEXRAYS_CHKAPI) -i $(subst $(_SPACE),$(_COMMA),$(ALL_ST_WRAP_CPP)) -p $(subst $(_SPACE),$(_COMMA),$(ALL_ST_WRAP_PY)) -r $(ST_API_CONTENTS)
$(QCHKAPI)$(PYTHON) tools/chkapi.py $(WITH_HEXRAYS_CHKAPI) -i $(subst $(space),$(comma),$(ALL_ST_WRAP_CPP)) -p $(subst $(space),$(comma),$(ALL_ST_WRAP_PY)) -r $(ST_API_CONTENTS)
ifeq ($(OUT_OF_TREE_BUILD),)
ifdef BC695 # turn off comparison when bw-compat is off, or api_contents will differ
@(diff -w $(API_CONTENTS) $(ST_API_CONTENTS)) > /dev/null || \
(echo "API CONTENTS CHANGED! update api_contents.txt or fix the API" && \
echo "(New API: $(ST_API_CONTENTS)) ***" && \
(diff -U 1 -w $(API_CONTENTS) $(ST_API_CONTENTS) && false))
$(Q)(diff -w $(API_CONTENTS) $(ST_API_CONTENTS)) > /dev/null || \
(echo "API CONTENTS CHANGED! update $(API_CONTENTS) or fix the API" && \
echo "(New API: $(ST_API_CONTENTS)) ***" && \
(diff -U 1 -w $(API_CONTENTS) $(ST_API_CONTENTS) && false))
endif
endif
#----------------------------------------------------------------------
# Check that doc injection is stable
PYDOC_INJECTIONS_RESULTS=$(MODULES_NAMES:%=$(ST_WRAP)/ida_%.pydoc_injection)
$(ST_PYDOC_INJECTIONS): tools/dumpdoc.py $(PYTHON_MODULES) $(PYTHON_BINARY_MODULES)
PYDOC_INJECTIONS = pydoc_injections.txt
ST_PYDOC_INJECTIONS = $(F)$(PYDOC_INJECTIONS)
.PRECIOUS: $(ST_PYDOC_INJECTIONS)
pydoc_injections: $(ST_PYDOC_INJECTIONS)
$(ST_PYDOC_INJECTIONS): tools/dumpdoc.py $(IDAPYTHON_MODULES) $(PYTHON_BINARY_MODULES)
ifdef __CODE_CHECKER__
@touch $@
$(Q)touch $@
else
ifeq ($(OUT_OF_TREE_BUILD),)
@$(IDA_CMD) $(BATCH_SWITCH) -OIDAPython:AUTOIMPORT_COMPAT_IDA695=NO -S"$< $@ $(ST_WRAP)" -t -L$(F)dumpdoc.log >/dev/null
@(diff -w $(PYDOC_INJECTIONS) $(ST_PYDOC_INJECTIONS)) > /dev/null || \
(echo "PYDOC INJECTION CHANGED! update $(PYDOC_INJECTIONS) or fix .. what needs fixing" && \
echo "(New API: $(ST_PYDOC_INJECTIONS)) ***" && \
(diff -U 1 -w $(PYDOC_INJECTIONS) $(ST_PYDOC_INJECTIONS) && false))
$(Q)$(IDA_CMD) $(BATCH_SWITCH) -OIDAPython:AUTOIMPORT_COMPAT_IDA695=NO -S"$< $@ $(ST_WRAP)" -t -L$(F)dumpdoc.log >/dev/null
$(Q)(diff -w $(PYDOC_INJECTIONS) $(ST_PYDOC_INJECTIONS)) > /dev/null || \
(echo "PYDOC INJECTION CHANGED! update $(PYDOC_INJECTIONS) or fix .. what needs fixing" && \
echo "(New API: $(ST_PYDOC_INJECTIONS)) ***" && \
(diff -U 1 -w $(PYDOC_INJECTIONS) $(ST_PYDOC_INJECTIONS) && false))
else
@touch $@
$(Q)touch $@
endif
endif
# Require a strict SWiG version (other versions might generate different code.)
SWIG_VERSION_ACTUAL=$(shell $(SWIG) -version | awk "/SWIG Version [0-9.]+/ { if (match(\$$0, /([0-9.]+)/)) { print substr(\$$0, RSTART, RLENGTH); } }")
# ST_WRAP_FILES=$(MODULES_NAMES:%=$(ST_WRAP)/%.cpp) $(MODULES_NAMES:%=$(ST_WRAP)/%.h) $(MODULES_NAMES:%=$(ST_WRAP)/ida_%.py)
# .PRECIOUS: $(ST_WRAP_FILES) $(MODULES_OBJECTS)
.PRECIOUS: $(ST_API_CONTENTS) $(ST_PYDOC_INJECTIONS)
DOCS_MODULES=$(MODULES_NAMES:%=ida_%)
#----------------------------------------------------------------------
DOCS_MODULES=$(foreach mod,$(MODULES_NAMES),ida_$(mod))
tools/docs/hrdoc.cfg: tools/docs/hrdoc.cfg.in
sed s/%IDA_MODULES%/"$(DOCS_MODULES)"/ < $? > $@
sed s/%IDA_MODULES%/"$(DOCS_MODULES)"/ < $^ > $@
# the html files are produced in docs\hr-html directory
docs: tools/docs/hrdoc.py tools/docs/hrdoc.cfg tools/docs/hrdoc.css
@@ -548,50 +603,52 @@ ifeq ($(OUT_OF_TREE_BUILD),)
endif
endif
#----------------------------------------------------------------------
# Test that all functions that are present in ftable.cpp
# are present in idc.py (and therefore made available by
# the idapython).
test_idc: $(TEST_IDC)
$(TEST_IDC): $(F)idctest.log
$(F)idctest.log: $(RS)idc/idc.idc | $(BINARY) pyfiles $(PRECOMPILED_COPY)
$(F)idctest.log: $(RS)idc/idc.idc | $(MODULE) pyfiles
ifneq ($(wildcard ../../tests),)
@$(RM) $(F)idctest.log
@$(IDA_CMD) $(BATCH_SWITCH) -S"test_idc.py $^" -t -L$(F)idctest.log >/dev/null || \
(echo "ERROR: The IDAPython IDC interface is incomplete. IDA log:" && cat $(F)idctest.log && false)
endif
package:
ifeq ($(OUT_OF_TREE_BUILD),)
-@if [ ! -d "$(DIST)" ] ; then mkdir -p 2>/dev/null $(DIST) ; fi
$(PYTHON) $(PKGBIN_SCRIPT) \
--input-binary-tree $(R) \
--output-dir $(DIST) \
--confirmed \
--component plugins/idapython
(cd $(DIST) && $(PYTHON) $(DBLZIP_SCRIPT) --once --output ../../../obj/$(PACKAGE_NAME))
$(Q)$(RM) $(F)idctest.log
$(Q)$(IDA_CMD) $(BATCH_SWITCH) -S"test_idc.py $^" -t -L$(F)idctest.log >/dev/null || \
(echo "ERROR: The IDAPython IDC interface is incomplete. IDA log:" && cat $(F)idctest.log && false)
endif
#----------------------------------------------------------------------
PUBTREE_DIR=$(F)/public_tree
public_tree: all
ifeq ($(OUT_OF_TREE_BUILD),)
-@if [ ! -d "$(PUBTREE_DIR)/out_of_tree" ] ; then mkdir -p 2>/dev/null $(PUBTREE_DIR)/out_of_tree ; fi
-$(Q)if [ ! -d "$(PUBTREE_DIR)/out_of_tree" ] ; then mkdir -p 2>/dev/null $(PUBTREE_DIR)/out_of_tree ; fi
rsync -a --exclude=obj/ \
--exclude=precompiled/ \
--exclude=repl.py \
--exclude=test_idc.py \
--exclude=RELEASE.md \
--exclude=docs/hr-html/ \
--exclude=**/*~ \
. $(PUBTREE_DIR)
--exclude=precompiled/ \
--exclude=repl.py \
--exclude=test_idc.py \
--exclude=RELEASE.md \
--exclude=docs/hr-html/ \
--exclude=**/*~ \
. $(PUBTREE_DIR)
(cd $(F) && zip -r ../../$(PUBTREE_DIR)/out_of_tree/parsed_notifications.zip parsed_notifications)
endif
#----------------------------------------------------------------------
# the 'echo_modules' target must be called explicitly
# Note: used by ida/build/pkgbin.py
echo_modules:
@echo $(MODULES_NAMES)
#----------------------------------------------------------------------
clean::
rm -rf obj/
# MAKEDEP dependency list ------------------
$(F)python$(O) : $(I)range.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)diskio.hpp $(I)expr.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)ida.hpp $(I)idp.hpp $(I)config.hpp $(I)kernwin.hpp \
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp $(I)nalt.hpp \
$(I)netnode.hpp $(I)pro.h $(I)segment.hpp $(I)ua.hpp \
$(I)gdl.hpp $(I)graph.hpp \
$(I)xref.hpp python.cpp pywraps.hpp pywraps.cpp | $(ST_SDK_TARGETS)
$(F)python$(O) : $(I)bitrange.hpp $(I)bytes.hpp $(I)config.hpp \
$(I)diskio.hpp $(I)expr.hpp $(I)fpro.h $(I)funcs.hpp \
$(I)gdl.hpp $(I)graph.hpp $(I)ida.hpp \
$(I)ida_highlighter.hpp $(I)idd.hpp $(I)idp.hpp \
$(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp $(I)llong.hpp \
$(I)loader.hpp $(I)nalt.hpp $(I)name.hpp $(I)netnode.hpp \
$(I)pro.h $(I)range.hpp $(I)segment.hpp $(I)typeinf.hpp \
$(I)ua.hpp $(I)xref.hpp python.cpp pywraps.cpp \
pywraps.hpp
Binary file not shown.
+3254 -495
View File
File diff suppressed because it is too large Load Diff
+89 -65
View File
@@ -70,6 +70,7 @@ static bool g_instance_initialized = false; // This instance of the plugin is th
static int g_run_when = -1;
static char g_run_script[QMAXPATH];
static char g_idapython_dir[QMAXPATH];
static qstring requested_plugin_path;
//-------------------------------------------------------------------------
// Prototypes and forward declarations
@@ -82,6 +83,8 @@ static char g_idapython_dir[QMAXPATH];
bool idaapi run(size_t);
static PyObject *get_module_globals_from_path(const char *path);
//lint -e818 could be pointer to const
//-------------------------------------------------------------------------
// This is a simple tracing code for debugging purposes.
// It might evolve into a tracing facility for user scripts.
@@ -90,23 +93,22 @@ static PyObject *get_module_globals_from_path(const char *path);
#ifdef ENABLE_PYTHON_PROFILING
#include "compile.h"
#include "frameobject.h"
int tracefunc(PyObject *obj, _frame *frame, int what, PyObject *arg)
static int tracefunc(PyObject *obj, _frame *frame, int what, PyObject *arg)
{
PyObject *str;
PyObject *str;
/* Catch line change events. */
/* Print the filename and line number */
if ( what == PyTrace_LINE )
/* Catch line change events. */
/* Print the filename and line number */
if ( what == PyTrace_LINE )
{
str = PyObject_Str(frame->f_code->co_filename);
if ( str != NULL )
{
str = PyObject_Str(frame->f_code->co_filename);
if ( str )
{
msg("PROFILING: %s:%d\n", PyString_AsString(str), frame->f_lineno);
Py_DECREF(str);
}
msg("PROFILING: %s:%d\n", PyString_AsString(str), frame->f_lineno);
Py_DECREF(str);
}
return 0;
}
return 0;
}
#endif
@@ -184,9 +186,9 @@ static execution_t execution;
//#define LOG_EXEC 1
#ifdef LOG_EXEC
#define LEXEC(Format, ...) msg("IDAPython exec: " Format, __VA_ARGS__)
#define LEXEC(...) msg("IDAPython exec: " __VA_ARGS__)
#else
#define LEXEC(Format, ...)
#define LEXEC(...)
#endif
//-------------------------------------------------------------------------
@@ -267,11 +269,18 @@ bool execution_t::can_interrupt_current(time_t now) const
int execution_t::on_trace(PyObject *obj, _frame *frame, int what, PyObject *arg)
{
LEXEC("on_trace() (steps=%d, nentries=%d)\n",
int(execution.steps_before_action), int(execution.entries.size()));
int(execution.steps_before_action),
int(execution.entries.size()));
// we don't want to query for time at every trace event
if ( execution.steps_before_action-- > 0 )
return 0;
if ( get_active_modal_widget() != NULL )
{
LEXEC("on_trace()::a modal widget is active. Not showing the wait dialog.\n");
return 0;
}
execution.reset_steps();
time_t now = time(NULL);
LEXEC("on_trace()::now: %d\n", int(now));
@@ -338,6 +347,12 @@ void ida_export set_interruptible_state(bool interruptible)
execution.set_interruptible(interruptible);
}
//-------------------------------------------------------------------------
void ida_export prepare_programmatic_plugin_load(const char *path)
{
requested_plugin_path = path;
}
//-------------------------------------------------------------------------
//lint -esym(714,disable_script_timeout) Symbol not referenced
idaman void ida_export disable_script_timeout()
@@ -576,7 +591,7 @@ static int PyRunFile(const char *FileName)
#endif
PYW_GIL_CHECK_LOCKED_SCOPE();
PyObject *file_obj = PyFile_FromString((char*)FileName, "r"); //lint !e605
PyObject *file_obj = PyFile_FromString((char*)FileName, "r"); //lint !e605 !e1776
PyObject *globals = get_module_globals();
if ( globals == NULL || file_obj == NULL )
{
@@ -810,14 +825,13 @@ static bool idaapi IDAPython_extlang_call_func(
if ( !ok )
break;
if ( imported_module )
const char *final_modname = imported_module ? modname : S_MAIN;
module = PyImport_ImportModule(final_modname);
if ( module == NULL )
{
module = PyImport_ImportModule(modname);
}
else
{
module = PyImport_AddModule(S_MAIN);
QASSERT(30156, module != NULL);
errbuf->sprnt("couldn't import module %s", final_modname);
ok = false;
break;
}
PyObject *globals = PyModule_GetDict(module);
@@ -1416,7 +1430,7 @@ static bool idaapi IDAPython_cli_find_completions(
if ( py_fc == NULL )
return false;
newref_t py_res(PyObject_CallFunction(py_fc.o, "si", line, x)); //lint !e605
newref_t py_res(PyObject_CallFunction(py_fc.o, "si", line, x)); //lint !e605 !e1776
if ( PyErr_Occurred() != NULL )
return false;
return idapython_convert_cli_completions(
@@ -1426,11 +1440,36 @@ static bool idaapi IDAPython_cli_find_completions(
py_res);
}
//-------------------------------------------------------------------------
static PyObject *get_module_globals_from_path_with_kind(const char *path, const char *kind)
{
const char *fname = qbasename(path);
if ( fname != NULL )
{
const char *ext = get_file_ext(fname);
if ( ext == NULL )
ext = tail(fname);
else
--ext;
if ( ext > fname )
{
int len = ext - fname;
qstring modname;
modname.sprnt("__%s__%*.*s", kind, len, len, fname);
return get_module_globals(modname.begin());
}
}
return NULL;
}
//-------------------------------------------------------------------------
static PyObject *get_module_globals_from_path(const char *path)
{
if ( (extlang_python.flags & EXTLANG_NS_AWARE) != 0 )
{
if ( requested_plugin_path == path )
return get_module_globals_from_path_with_kind(path, PLG_SUBDIR);
char dirpath[QMAXPATH];
if ( qdirname(dirpath, sizeof(dirpath), path) )
{
@@ -1439,22 +1478,7 @@ static PyObject *get_module_globals_from_path(const char *path)
|| streq(dirname, IDP_SUBDIR)
|| streq(dirname, LDR_SUBDIR) )
{
const char *fname = qbasename(path);
if ( fname != NULL )
{
const char *ext = get_file_ext(fname);
if ( ext == NULL )
ext = tail(fname);
else
--ext;
if ( ext > fname )
{
int len = ext - fname;
qstring modname;
modname.sprnt("__%s__%*.*s", dirname, len, len, fname);
return get_module_globals(modname.begin());
}
}
return get_module_globals_from_path_with_kind(path, dirname);
}
}
}
@@ -1464,15 +1488,15 @@ static PyObject *get_module_globals_from_path(const char *path)
//-------------------------------------------------------------------------
static const cli_t cli_python =
{
sizeof(cli_t),
0,
"Python",
"Python - IDAPython plugin",
"Enter any Python expression",
IDAPython_cli_execute_line,
NULL,
NULL,
IDAPython_cli_find_completions,
sizeof(cli_t),
0,
"Python",
"Python - IDAPython plugin",
"Enter any Python expression",
IDAPython_cli_execute_line,
NULL,
NULL,
IDAPython_cli_find_completions,
};
//-------------------------------------------------------------------------
@@ -1480,9 +1504,9 @@ static const cli_t cli_python =
idaman void ida_export enable_python_cli(bool enable)
{
if ( enable )
install_command_interpreter(&cli_python);
install_command_interpreter(&cli_python);
else
remove_command_interpreter(&cli_python);
remove_command_interpreter(&cli_python);
}
//------------------------------------------------------------------------
@@ -2018,21 +2042,21 @@ bool idaapi run(size_t arg)
{
switch ( arg )
{
case IDAPYTHON_RUNSTATEMENT:
IDAPython_RunStatement();
break;
case IDAPYTHON_ENABLE_EXTLANG:
enable_extlang_python(true);
break;
case IDAPYTHON_DISABLE_EXTLANG:
enable_extlang_python(false);
break;
default:
warning("IDAPython: unknown plugin argument %d", int(arg));
break;
case IDAPYTHON_RUNSTATEMENT:
IDAPython_RunStatement();
break;
case IDAPYTHON_ENABLE_EXTLANG:
enable_extlang_python(true);
break;
case IDAPYTHON_DISABLE_EXTLANG:
enable_extlang_python(false);
break;
default:
warning("IDAPython: unknown plugin argument %d", int(arg));
break;
}
}
catch(...)
catch(...) //lint !e1766 without preceding catch clause
{
warning("Exception in Python interpreter. Reloading...");
IDAPython_Term();
+5
View File
@@ -3,6 +3,11 @@ import sys
${IMPORTS}
# guerilla-patch a few unfortunate overrides
from ida_funcs import set_func_start
from ida_funcs import set_func_end
from ida_dbg import dbg_can_query
class idaapi_Cvar(object):
def __init__(self):
# prevent endless recursion
+18 -17
View File
@@ -118,29 +118,30 @@ def DataRefsFrom(ea):
return refs(ea, ida_xref.get_first_dref_from, ida_xref.get_next_dref_from)
# Xref type names table
_ref_types = {
ida_xref.fl_U : 'Data_Unknown',
ida_xref.dr_O : 'Data_Offset',
ida_xref.dr_W : 'Data_Write',
ida_xref.dr_R : 'Data_Read',
ida_xref.dr_T : 'Data_Text',
ida_xref.dr_I : 'Data_Informational',
ida_xref.fl_CF : 'Code_Far_Call',
ida_xref.fl_CN : 'Code_Near_Call',
ida_xref.fl_JF : 'Code_Far_Jump',
ida_xref.fl_JN : 'Code_Near_Jump',
20 : 'Code_User',
ida_xref.fl_F : 'Ordinary_Flow'
}
def XrefTypeName(typecode):
"""
Convert cross-reference type codes to readable names
@param typecode: cross-reference type code
"""
ref_types = {
0 : 'Data_Unknown',
1 : 'Data_Offset',
2 : 'Data_Write',
3 : 'Data_Read',
4 : 'Data_Text',
5 : 'Data_Informational',
16 : 'Code_Far_Call',
17 : 'Code_Near_Call',
18 : 'Code_Far_Jump',
19 : 'Code_Near_Jump',
20 : 'Code_User',
21 : 'Ordinary_Flow'
}
assert typecode in ref_types, "unknown reference type %d" % typecode
return ref_types[typecode]
assert typecode in _ref_types, "unknown reference type %d" % typecode
return _ref_types[typecode]
def _copy_xref(xref):
""" Make a private copy of the xref class to preserve its contents """
+18 -46
View File
@@ -68,7 +68,6 @@ import time
import types
import sys
__X64__ = sys.maxsize > 0xFFFFFFFF
__EA64__ = ida_idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
WORDMASK = 0xFFFFFFFFFFFFFFFF if __EA64__ else 0xFFFFFFFF
class DeprecatedIDCError(Exception):
@@ -2358,8 +2357,6 @@ def get_next_seg(ea):
else:
return nextseg.start_ea
return BADADDR
def get_segm_start(ea):
"""
@@ -2604,7 +2601,7 @@ def set_segm_addressing(ea, bitness):
def selector_by_name(segname):
"""
Get segment by name
Get segment selector by name
@param segname: name of segment
@@ -3070,53 +3067,28 @@ def set_func_attr(ea, attr, value):
FUNCATTR_START = 0 # readonly: function start address
FUNCATTR_END = 4 # readonly: function end address
FUNCATTR_FLAGS = 8 # function flags
FUNCATTR_FRAME = 12 # readonly: function frame id
FUNCATTR_FRSIZE = 16 # readonly: size of local variables
FUNCATTR_FRREGS = 20 # readonly: size of saved registers area
FUNCATTR_ARGSIZE = 24 # readonly: number of bytes purged from the stack
FUNCATTR_FPD = 28 # frame pointer delta
FUNCATTR_COLOR = 32 # function color code
FUNCATTR_OWNER = 12 # readonly: chunk owner (valid only for tail chunks)
FUNCATTR_REFQTY = 16 # readonly: number of chunk parents (valid only for tail chunks)
FUNCATTR_FRAME = 16 # readonly: function frame id
FUNCATTR_FRSIZE = 20 # readonly: size of local variables
FUNCATTR_FRREGS = 24 # readonly: size of saved registers area
FUNCATTR_ARGSIZE = 28 # readonly: number of bytes purged from the stack
FUNCATTR_FPD = 32 # frame pointer delta
FUNCATTR_COLOR = 36 # function color code
FUNCATTR_OWNER = 16 # readonly: chunk owner (valid only for tail chunks)
FUNCATTR_REFQTY = 20 # readonly: number of chunk parents (valid only for tail chunks)
if __X64__:
FUNCATTR_START = 0
FUNCATTR_END = 4
FUNCATTR_FLAGS = 8
FUNCATTR_FRAME = 16
FUNCATTR_FRSIZE = 20
FUNCATTR_FRREGS = 24
FUNCATTR_ARGSIZE = 28
FUNCATTR_FPD = 32
FUNCATTR_COLOR = 36
FUNCATTR_OWNER = 16
FUNCATTR_REFQTY = 20
# Redefining the constants for 64-bit
# Redefining the constants for ea64
if __EA64__:
FUNCATTR_START = 0
FUNCATTR_END = 8
FUNCATTR_FLAGS = 16
FUNCATTR_FRAME = 20
FUNCATTR_FRSIZE = 28
FUNCATTR_FRREGS = 36
FUNCATTR_ARGSIZE = 40
FUNCATTR_FPD = 48
FUNCATTR_COLOR = 56
FUNCATTR_OWNER = 20
FUNCATTR_REFQTY = 28
if __X64__:
FUNCATTR_START = 0
FUNCATTR_END = 8
FUNCATTR_FLAGS = 16
FUNCATTR_FRAME = 24
FUNCATTR_FRSIZE = 32
FUNCATTR_FRREGS = 40
FUNCATTR_ARGSIZE = 48
FUNCATTR_FPD = 56
FUNCATTR_COLOR = 64
FUNCATTR_OWNER = 24
FUNCATTR_REFQTY = 32
FUNCATTR_FRAME = 24
FUNCATTR_FRSIZE = 32
FUNCATTR_FRREGS = 40
FUNCATTR_ARGSIZE = 48
FUNCATTR_FPD = 56
FUNCATTR_COLOR = 64
FUNCATTR_OWNER = 24
FUNCATTR_REFQTY = 32
_FUNCATTRMAP = {
FUNCATTR_START : (True, 'start_ea'),
+1 -3
View File
@@ -47,8 +47,6 @@ except ImportError as e:
print "\t%s" % p
raise
# __EA64__ is set if IDA is running in 64-bit mode
__EA64__ = ida_idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
# -----------------------------------------------------------------------
# Take over the standard text outputs
@@ -86,7 +84,7 @@ def runscript(script):
def print_banner():
banner = [
"Python %s " % sys.version,
"IDAPython" + (" 64-bit" if __EA64__ else "") + " v%d.%d.%d %s (serial %d) (c) The IDAPython Team <idapython@googlegroups.com>" % IDAPYTHON_VERSION
"IDAPython" + (" 64-bit" if ida_idaapi.__EA64__ else "") + " v%d.%d.%d %s (serial %d) (c) The IDAPython Team <idapython@googlegroups.com>" % IDAPYTHON_VERSION
]
sepline = '-' * (max([len(s) for s in banner])+1)
+273 -240
View File
@@ -86,6 +86,17 @@ ref_t ida_export PyW_SizeVecToPyList(const sizevec_t &vec)
return ref_t(py_list);
}
//---------------------------------------------------------------------------
ref_t ida_export PyW_UvalVecToPyList(const uvalvec_t &vec)
{
size_t n = vec.size();
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_list(PyList_New(n));
for ( size_t i = 0; i < n; ++i )
PyList_SetItem(py_list.o, i, Py_BuildValue(PY_BV_UVAL, bvuval_t(vec[i])));
return ref_t(py_list);
}
//-------------------------------------------------------------------------
static Py_ssize_t pyvar_walk_list(
const ref_t &py_list,
@@ -495,93 +506,92 @@ int ida_export pyvar_to_idcvar(
//
// INT64
//
case PY_ICID_INT64:
{
// Get the value attribute
ref_t attr(PyW_TryGetAttrString(py_var.o, S_PY_IDCCVT_VALUE_ATTR));
if ( attr == NULL )
return false;
idc_var->set_int64(PyLong_AsLongLong(attr.o));
return CIP_OK;
}
case PY_ICID_INT64:
{
// Get the value attribute
ref_t attr(PyW_TryGetAttrString(py_var.o, S_PY_IDCCVT_VALUE_ATTR));
if ( attr == NULL )
return false;
idc_var->set_int64(PyLong_AsLongLong(attr.o));
return CIP_OK;
}
//
// BYREF
//
case PY_ICID_BYREF:
{
// BYREF always require this parameter
if ( gvar_sn == NULL )
return CIP_FAILED;
// Get the value attribute
ref_t attr(PyW_TryGetAttrString(py_var.o, S_PY_IDCCVT_VALUE_ATTR));
if ( attr == NULL )
return CIP_FAILED;
// Create a global variable
char buf[MAXSTR];
qsnprintf(buf, sizeof(buf), S_PY_IDC_GLOBAL_VAR_FMT, *gvar_sn);
idc_value_t *gvar = add_idc_gvar(buf);
// Convert the python value into the IDC global variable
bool ok = pyvar_to_idcvar(attr, gvar, gvar_sn) >= CIP_OK;
if ( ok )
case PY_ICID_BYREF:
{
(*gvar_sn)++;
// Create a reference to this global variable
create_idcv_ref(idc_var, gvar);
// BYREF always require this parameter
if ( gvar_sn == NULL )
return CIP_FAILED;
// Get the value attribute
ref_t attr(PyW_TryGetAttrString(py_var.o, S_PY_IDCCVT_VALUE_ATTR));
if ( attr == NULL )
return CIP_FAILED;
// Create a global variable
char buf[MAXSTR];
qsnprintf(buf, sizeof(buf), S_PY_IDC_GLOBAL_VAR_FMT, *gvar_sn);
idc_value_t *gvar = add_idc_gvar(buf);
// Convert the python value into the IDC global variable
bool ok = pyvar_to_idcvar(attr, gvar, gvar_sn) >= CIP_OK;
if ( ok )
{
(*gvar_sn)++;
// Create a reference to this global variable
create_idcv_ref(idc_var, gvar);
}
return ok ? CIP_OK : CIP_FAILED;
}
return ok ? CIP_OK : CIP_FAILED;
}
//
// OPAQUE
//
case PY_ICID_OPAQUE:
{
case PY_ICID_OPAQUE:
if ( !wrap_PyObject_ptr(py_var, idc_var) )
return CIP_FAILED;
return CIP_OK_OPAQUE;
}
//
// Other objects
//
default:
// A normal object?
newref_t py_dir(PyObject_Dir(py_var.o));
Py_ssize_t size = PyList_Size(py_dir.o);
if ( py_dir == NULL || !PyList_Check(py_dir.o) || size == 0 )
return CIP_FAILED;
// Create the IDC object
idcv_object(idc_var);
for ( Py_ssize_t i=0; i < size; i++ )
{
borref_t item(PyList_GetItem(py_dir.o, i));
const char *field_name = PyString_AsString(item.o);
if ( field_name == NULL )
continue;
size_t len = strlen(field_name);
// Skip private attributes
if ( (len > 2 )
&& (strncmp(field_name, "__", 2) == 0 )
&& (strncmp(field_name+len-2, "__", 2) == 0) )
{
continue;
}
idc_value_t v;
// Get the non-private attribute from the object
newref_t attr(PyObject_GetAttrString(py_var.o, field_name));
if ( attr == NULL
// Convert the attribute into an IDC value
|| pyvar_to_idcvar(attr, &v, gvar_sn) < CIP_OK )
{
default:
// A normal object?
newref_t py_dir(PyObject_Dir(py_var.o));
Py_ssize_t size = PyList_Size(py_dir.o);
if ( py_dir == NULL || !PyList_Check(py_dir.o) || size == 0 )
return CIP_FAILED;
}
// Create the IDC object
idcv_object(idc_var);
for ( Py_ssize_t i=0; i < size; i++ )
{
borref_t item(PyList_GetItem(py_dir.o, i));
const char *field_name = PyString_AsString(item.o);
if ( field_name == NULL )
continue;
// Store the attribute
set_idcv_attr(idc_var, field_name, v);
}
size_t len = strlen(field_name);
// Skip private attributes
if ( (len > 2 )
&& (strncmp(field_name, "__", 2) == 0 )
&& (strncmp(field_name+len-2, "__", 2) == 0) )
{
continue;
}
idc_value_t v;
// Get the non-private attribute from the object
newref_t attr(PyObject_GetAttrString(py_var.o, field_name));
if ( attr == NULL
// Convert the attribute into an IDC value
|| pyvar_to_idcvar(attr, &v, gvar_sn) < CIP_OK )
{
return CIP_FAILED;
}
// Store the attribute
set_idcv_attr(idc_var, field_name, v);
}
break;
}
}
return CIP_OK;
@@ -611,187 +621,187 @@ int ida_export idcvar_to_pyvar(
PYW_GIL_CHECK_LOCKED_SCOPE();
switch ( idc_var.vtype )
{
case VT_PVOID:
if ( *py_var == NULL )
{
newref_t nr(PyCObject_FromVoidPtr(idc_var.pvoid, NULL));
*py_var = nr;
}
else
{
return CIP_IMMUTABLE;
}
break;
case VT_INT64:
{
bool as_pylong = (flags & PYWCVTF_INT64_AS_UNSIGNED_PYLONG) != 0;
if ( as_pylong )
case VT_PVOID:
if ( *py_var == NULL )
{
QASSERT(30513, *py_var == NULL); // recycling not supported in this case
*py_var = newref_t(PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) idc_var.i64));
return CIP_OK;
newref_t nr(PyCObject_FromVoidPtr(idc_var.pvoid, NULL));
*py_var = nr;
}
else
{
// Recycle?
if ( *py_var != NULL )
return CIP_IMMUTABLE;
}
break;
case VT_INT64:
{
bool as_pylong = (flags & PYWCVTF_INT64_AS_UNSIGNED_PYLONG) != 0;
if ( as_pylong )
{
// Recycling an int64 object?
int t = get_pyidc_cvt_type(py_var->o);
if ( t != PY_ICID_INT64 )
return CIP_IMMUTABLE; // Cannot recycle immutable object
// Update the attribute
PyObject_SetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR, PyLong_FromLongLong(idc_var.i64));
QASSERT(30513, *py_var == NULL); // recycling not supported in this case
*py_var = newref_t(PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) idc_var.i64));
return CIP_OK;
}
ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_CVT_INT64));
if ( py_cls == NULL )
return CIP_FAILED;
*py_var = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, PyLong_FromLongLong(idc_var.i64), NULL));
if ( PyW_GetError() || *py_var == NULL )
return CIP_FAILED;
else
{
// Recycle?
if ( *py_var != NULL )
{
// Recycling an int64 object?
int t = get_pyidc_cvt_type(py_var->o);
if ( t != PY_ICID_INT64 )
return CIP_IMMUTABLE; // Cannot recycle immutable object
// Update the attribute
PyObject_SetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR, PyLong_FromLongLong(idc_var.i64));
return CIP_OK;
}
ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_CVT_INT64));
if ( py_cls == NULL )
return CIP_FAILED;
*py_var = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, PyLong_FromLongLong(idc_var.i64), NULL));
if ( PyW_GetError() || *py_var == NULL )
return CIP_FAILED;
}
break;
}
break;
}
case VT_STR:
if ( *py_var == NULL )
{
const qstring &s = idc_var.qstr();
*py_var = newref_t(PyString_FromStringAndSize(s.begin(), s.length()));
break;
}
else
return CIP_IMMUTABLE; // Cannot recycle immutable object
case VT_LONG:
// Cannot recycle immutable objects
if ( *py_var != NULL )
return CIP_IMMUTABLE;
*py_var = newref_t(cvt_to_pylong(idc_var.num));
break;
case VT_FLOAT:
if ( *py_var == NULL )
{
double x;
if ( ph.realcvt(&x, (uint16 *)idc_var.e, (sizeof(x)/2-1)|010) != 1 )
INTERR(30160);
*py_var = newref_t(PyFloat_FromDouble(x));
break;
}
else
return CIP_IMMUTABLE;
case VT_REF:
{
case VT_STR:
if ( *py_var == NULL )
{
ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_CVT_BYREF));
if ( py_cls == NULL )
return CIP_FAILED;
// Create a byref object with None value. We populate it later
*py_var = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, Py_None, NULL));
if ( PyW_GetError() || *py_var == NULL )
return CIP_FAILED;
}
int t = get_pyidc_cvt_type(py_var->o);
if ( t != PY_ICID_BYREF )
return CIP_FAILED;
// Dereference
// (Since we are not using VREF_COPY flag, we can safely const_cast)
idc_value_t *dref_v = deref_idcv(const_cast<idc_value_t *>(&idc_var), VREF_LOOP);
if ( dref_v == NULL )
return CIP_FAILED;
// Can we recycle the object?
ref_t new_py_val(PyW_TryGetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR));
if ( new_py_val != NULL )
{
// Recycle
t = idcvar_to_pyvar(*dref_v, &new_py_val);
// Success? Nothing more to be done
if ( t == CIP_OK )
return CIP_OK;
// Clear it so we don't recycle it
new_py_val = ref_t();
}
// Try to convert (not recycle)
if ( idcvar_to_pyvar(*dref_v, &new_py_val) != CIP_OK )
return CIP_FAILED;
// Update the attribute
PyObject_SetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR, new_py_val.o);
break;
}
// Can convert back into a Python object or Python dictionary
// (Depending if py_var will be recycled and it was a dictionary)
case VT_OBJ:
{
// Check if this IDC object has __cvt_id__ and the __idc_cvt_value__ fields
idc_value_t idc_val;
if ( get_idcv_attr(&idc_val, &idc_var, S_PY_IDCCVT_ID_ATTR) == eOk
&& get_idcv_attr(&idc_val, &idc_var, S_PY_IDCCVT_VALUE_ATTR) == eOk )
{
// Extract the object
*py_var = borref_t((PyObject *) idc_val.pvoid);
return CIP_OK_OPAQUE;
}
ref_t obj;
bool is_dict = false;
// Need to create a new object?
if ( *py_var == NULL )
{
// Get skeleton class reference
ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_APPCALL_SKEL_OBJ));
if ( py_cls == NULL )
return CIP_FAILED;
// Call constructor
obj = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, NULL));
if ( PyW_GetError() || obj == NULL )
return CIP_FAILED;
const qstring &s = idc_var.qstr();
*py_var = newref_t(PyString_FromStringAndSize(s.begin(), s.length()));
break;
}
else
{
// Recycle existing variable
obj = *py_var;
if ( PyDict_Check(obj.o) )
is_dict = true;
}
// Walk the IDC attributes and store into python
for ( const char *attr_name = first_idcv_attr(&idc_var);
attr_name != NULL;
attr_name = next_idcv_attr(&idc_var, attr_name) )
{
// Get the attribute
idc_value_t v;
get_idcv_attr(&v, &idc_var, attr_name, true);
// Convert attribute to a python value (recursively)
ref_t py_attr;
int cvt = idcvar_to_pyvar(v, &py_attr);
if ( cvt <= CIP_IMMUTABLE )
return CIP_FAILED;
if ( is_dict )
PyDict_SetItemString(obj.o, attr_name, py_attr.o);
else
PyObject_SetAttrString(obj.o, attr_name, py_attr.o);
}
*py_var = obj;
return CIP_IMMUTABLE; // Cannot recycle immutable object
case VT_LONG:
// Cannot recycle immutable objects
if ( *py_var != NULL )
return CIP_IMMUTABLE;
*py_var = newref_t(cvt_to_pylong(idc_var.num));
break;
}
// Unhandled type
default:
*py_var = ref_t();
return CIP_FAILED;
case VT_FLOAT:
if ( *py_var == NULL )
{
double x;
if ( ph.realcvt(&x, (uint16 *)idc_var.e, (sizeof(x)/2-1)|010) != 1 )
INTERR(30160);
*py_var = newref_t(PyFloat_FromDouble(x));
break;
}
else
return CIP_IMMUTABLE;
case VT_REF:
{
if ( *py_var == NULL )
{
ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_CVT_BYREF));
if ( py_cls == NULL )
return CIP_FAILED;
// Create a byref object with None value. We populate it later
*py_var = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, Py_None, NULL));
if ( PyW_GetError() || *py_var == NULL )
return CIP_FAILED;
}
int t = get_pyidc_cvt_type(py_var->o);
if ( t != PY_ICID_BYREF )
return CIP_FAILED;
// Dereference
// (Since we are not using VREF_COPY flag, we can safely const_cast)
idc_value_t *dref_v = deref_idcv(const_cast<idc_value_t *>(&idc_var), VREF_LOOP);
if ( dref_v == NULL )
return CIP_FAILED;
// Can we recycle the object?
ref_t new_py_val(PyW_TryGetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR));
if ( new_py_val != NULL )
{
// Recycle
t = idcvar_to_pyvar(*dref_v, &new_py_val);
// Success? Nothing more to be done
if ( t == CIP_OK )
return CIP_OK;
// Clear it so we don't recycle it
new_py_val = ref_t();
}
// Try to convert (not recycle)
if ( idcvar_to_pyvar(*dref_v, &new_py_val) != CIP_OK )
return CIP_FAILED;
// Update the attribute
PyObject_SetAttrString(py_var->o, S_PY_IDCCVT_VALUE_ATTR, new_py_val.o);
break;
}
// Can convert back into a Python object or Python dictionary
// (Depending if py_var will be recycled and it was a dictionary)
case VT_OBJ:
{
// Check if this IDC object has __cvt_id__ and the __idc_cvt_value__ fields
idc_value_t idc_val;
if ( get_idcv_attr(&idc_val, &idc_var, S_PY_IDCCVT_ID_ATTR) == eOk
&& get_idcv_attr(&idc_val, &idc_var, S_PY_IDCCVT_VALUE_ATTR) == eOk )
{
// Extract the object
*py_var = borref_t((PyObject *) idc_val.pvoid);
return CIP_OK_OPAQUE;
}
ref_t obj;
bool is_dict = false;
// Need to create a new object?
if ( *py_var == NULL )
{
// Get skeleton class reference
ref_t py_cls(get_idaapi_attr_by_id(PY_CLSID_APPCALL_SKEL_OBJ));
if ( py_cls == NULL )
return CIP_FAILED;
// Call constructor
obj = newref_t(PyObject_CallFunctionObjArgs(py_cls.o, NULL));
if ( PyW_GetError() || obj == NULL )
return CIP_FAILED;
}
else
{
// Recycle existing variable
obj = *py_var;
if ( PyDict_Check(obj.o) )
is_dict = true;
}
// Walk the IDC attributes and store into python
for ( const char *attr_name = first_idcv_attr(&idc_var);
attr_name != NULL;
attr_name = next_idcv_attr(&idc_var, attr_name) )
{
// Get the attribute
idc_value_t v;
get_idcv_attr(&v, &idc_var, attr_name, true);
// Convert attribute to a python value (recursively)
ref_t py_attr;
int cvt = idcvar_to_pyvar(v, &py_attr);
if ( cvt <= CIP_IMMUTABLE )
return CIP_FAILED;
if ( is_dict )
PyDict_SetItemString(obj.o, attr_name, py_attr.o);
else
PyObject_SetAttrString(obj.o, attr_name, py_attr.o);
}
*py_var = obj;
break;
}
// Unhandled type
default:
*py_var = ref_t();
return CIP_FAILED;
}
return CIP_OK;
}
@@ -1034,7 +1044,7 @@ static ref_t get_idaapi_attr_by_id(const int class_id)
return ref_t();
// Some class names. The array is parallel with the PY_CLSID_xxx consts
static const char *class_names[]=
static const char *class_names[] =
{
"PyIdc_cvt_int64__",
"object_t",
@@ -1092,7 +1102,7 @@ ref_t ida_export PyW_TryImportModule(const char *name)
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t result(PyImport_ImportModule(name));
if ( result == NULL && PyErr_Occurred() )
PyErr_Clear();
PyErr_Clear();
return result;
}
@@ -2119,6 +2129,29 @@ ref_t ida_export try_create_swig_wrapper(ref_t mod, const char *clsname, void *c
return res;
}
//-------------------------------------------------------------------------
ssize_t ida_export get_callable_arg_count(ref_t callable)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_module(PyImport_ImportModule("inspect"));
ssize_t cnt = -1;
if ( py_module != NULL )
{
ref_t py_fun = PyW_TryGetAttrString(py_module.o, "getargspec");
if ( py_fun != NULL )
{
newref_t py_tuple(PyObject_CallFunctionObjArgs(py_fun.o, callable.o, NULL));
if ( PyTuple_Check(py_tuple.o) )
{
borref_t py_args(PyTuple_GetItem(py_tuple.o, 0));
if ( py_args != NULL && PySequence_Check(py_args.o) )
cnt = PySequence_Length(py_args.o);
}
}
}
return cnt;
}
//-------------------------------------------------------------------------
typedef qvector<module_callbacks_t> modules_callbacks_t;
static modules_callbacks_t modules_callbacks;
+54 -62
View File
@@ -42,17 +42,7 @@ struct switch_info_t;
// mov %edx,0x4(%esp)
// call 2d <_Z3barPv+0x16>
#ifdef __X64__
#define PTR2U64(Binding) (uint64(Binding))
#else
#define PTR2U64(Binding) (uint64(uint32(Binding)))
#endif
#if defined(__LINUX__) || defined(__MAC__)
#define exported __attribute__((visibility("default")))
#else
#define exported
#endif
//------------------------------------------------------------------------
#define S_IDA_IDAAPI_MODNAME "ida_idaapi"
@@ -101,6 +91,7 @@ static const char S_ON_FIND_COMPLETIONS[] = "OnFindCompletions";
static const char S_ON_CREATE[] = "OnCreate";
static const char S_ON_POPUP[] = "OnPopup";
static const char S_ON_HINT[] = "OnHint";
static const char S_ON_EDGE_HINT[] = "OnEdgeHint";
static const char S_ON_POPUP_MENU[] = "OnPopupMenu";
static const char S_ON_EDIT_LINE[] = "OnEditLine";
static const char S_ON_INSERT_LINE[] = "OnInsertLine";
@@ -358,45 +349,45 @@ struct ref_vec_t : public qvector<ref_t>
// Tries to import a module and swallows the exception if it fails and returns NULL
// Return value: New reference.
exported ref_t ida_export PyW_TryImportModule(const char *name);
idaman ref_t ida_export PyW_TryImportModule(const char *name);
// Tries to get an attribute and swallows the exception if it fails and returns NULL
exported ref_t ida_export PyW_TryGetAttrString(PyObject *py_var, const char *attr);
idaman ref_t ida_export PyW_TryGetAttrString(PyObject *py_var, const char *attr);
// Converts a Python number (LONGLONG or normal integer) to an IDC variable (VT_LONG or VT_INT64)
exported bool ida_export PyW_GetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var);
idaman bool ida_export PyW_GetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var);
// Returns a qstring from a Python attribute string
exported bool ida_export PyW_GetStringAttr(
idaman bool ida_export PyW_GetStringAttr(
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
exported bool ida_export PyW_GetNumber(PyObject *py_var, uint64 *num, bool *is_64 = NULL);
idaman bool ida_export PyW_GetNumber(PyObject *py_var, uint64 *num, bool *is_64 = NULL);
// Checks if an Python object can be treated like a sequence
exported bool ida_export PyW_IsSequenceType(PyObject *obj);
idaman bool ida_export PyW_IsSequenceType(PyObject *obj);
// Returns an error string from the last exception (and clears it)
exported bool ida_export PyW_GetError(qstring *out = NULL, bool clear_err = true);
idaman bool ida_export PyW_GetError(qstring *out = NULL, bool clear_err = true);
// If an error occurred (it calls PyGetError) it displays it and return TRUE
// This function is used when calling callbacks
exported bool ida_export PyW_ShowCbErr(const char *cb_name);
idaman bool ida_export PyW_ShowCbErr(const char *cb_name);
// Utility function to create linked class instances
exported ref_t ida_export create_linked_class_instance(const char *modname, const char *clsname, void *lnk);
idaman ref_t ida_export create_linked_class_instance(const char *modname, const char *clsname, void *lnk);
// Returns the string representation of a PyObject
exported bool ida_export PyW_ObjectToString(PyObject *obj, qstring *out);
idaman bool ida_export PyW_ObjectToString(PyObject *obj, qstring *out);
// Utility function to convert a python object to an IDC object
// and sets a python exception on failure.
exported bool ida_export pyvar_to_idcvar_or_error(const ref_t &py_obj, idc_value_t *idc_obj);
idaman bool ida_export pyvar_to_idcvar_or_error(const ref_t &py_obj, idc_value_t *idc_obj);
// Creates and initializes an IDC exception
exported error_t ida_export PyW_CreateIdcException(idc_value_t *res, const char *msg);
idaman error_t ida_export PyW_CreateIdcException(idc_value_t *res, const char *msg);
//
// Conversion functions
@@ -405,7 +396,7 @@ exported error_t ida_export PyW_CreateIdcException(idc_value_t *res, const char
#define PYWCVTF_INT64_AS_UNSIGNED_PYLONG 0x2 // don't wrap int64 into 'PyIdc_cvt_int64__' objects, but make them 'long' instead
// Converts from IDC to Python
exported bool ida_export pyw_convert_idc_args(
idaman bool ida_export pyw_convert_idc_args(
const idc_value_t args[],
int nargs,
ref_vec_t &pargs,
@@ -414,7 +405,7 @@ exported bool ida_export pyw_convert_idc_args(
// Converts from IDC to Python
// We support converting VT_REF IDC variable types
exported int ida_export idcvar_to_pyvar(
idaman int ida_export idcvar_to_pyvar(
const idc_value_t &idc_var,
ref_t *py_var,
uint32 flags=0);
@@ -422,41 +413,42 @@ exported int ida_export idcvar_to_pyvar(
//-------------------------------------------------------------------------
// Converts Python variable to IDC variable
// gvar_sn is used in case the Python object was a created from a call to idcvar_to_pyvar and the IDC object was a VT_REF
exported int ida_export pyvar_to_idcvar(
idaman int ida_export pyvar_to_idcvar(
const ref_t &py_var,
idc_value_t *idc_var,
int *gvar_sn = NULL);
//-------------------------------------------------------------------------
// Walks a Python list or Sequence and calls the callback
exported Py_ssize_t ida_export pyvar_walk_list(
idaman Py_ssize_t ida_export pyvar_walk_list(
PyObject *py_list,
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud)=NULL,
void *ud = NULL);
// Converts a sizevec_t to a Python list object
exported ref_t ida_export PyW_SizeVecToPyList(const sizevec_t &vec);
// Converts a vector to a Python list object
idaman ref_t ida_export PyW_SizeVecToPyList(const sizevec_t &vec);
idaman ref_t ida_export PyW_UvalVecToPyList(const uvalvec_t &vec);
// Converts a Python list, to a vector of the given type.
// An exception will be raised in case:
// - py_list is not a sequence
// - a member of py_list cannot be converted to the numeric target type
exported Py_ssize_t ida_export PyW_PyListToSizeVec(sizevec_t *out, PyObject *py_list);
exported Py_ssize_t ida_export PyW_PyListToEaVec(eavec_t *out, PyObject *py_list);
exported Py_ssize_t ida_export PyW_PyListToStrVec(qstrvec_t *out, PyObject *py_list);
idaman Py_ssize_t ida_export PyW_PyListToSizeVec(sizevec_t *out, PyObject *py_list);
idaman Py_ssize_t ida_export PyW_PyListToEaVec(eavec_t *out, PyObject *py_list);
idaman Py_ssize_t ida_export PyW_PyListToStrVec(qstrvec_t *out, PyObject *py_list);
//-------------------------------------------------------------------------
exported bool ida_export PyWStringOrNone_Check(PyObject *tp);
idaman bool ida_export PyWStringOrNone_Check(PyObject *tp);
//-------------------------------------------------------------------------
#include <idd.hpp>
exported PyObject *ida_export meminfo_vec_t_to_py(meminfo_vec_t &ranges);
idaman PyObject *ida_export meminfo_vec_t_to_py(meminfo_vec_t &ranges);
//-------------------------------------------------------------------------
exported void ida_export PyW_register_compiled_form(PyObject *py_form);
idaman void ida_export PyW_register_compiled_form(PyObject *py_form);
//-------------------------------------------------------------------------
exported void ida_export PyW_unregister_compiled_form(PyObject *py_form);
idaman void ida_export PyW_unregister_compiled_form(PyObject *py_form);
//---------------------------------------------------------------------------
// notify_when()
@@ -487,7 +479,7 @@ public:
bool notify_va(int slot, va_list va);
pywraps_notify_when_t() : in_notify(false) {}
};
exported bool ida_export add_notify_when(int when, PyObject *py_callable);
idaman bool ida_export add_notify_when(int when, PyObject *py_callable);
// void hexrays_clear_python_cfuncptr_t_references(void);
@@ -594,7 +586,17 @@ private:
lookup_entries_t entries;
};
extern exported lookup_info_t ida_export_data pycim_lookup_info;
#ifdef __NT__
#ifdef PLUGIN_SUBMODULE
#define plugin_export_data __declspec(dllimport)
#else
#define plugin_export_data __declspec(dllexport)
#endif
#else // unix
#define plugin_export_data __attribute__((visibility("default")))
#endif
extern lookup_info_t plugin_export_data pycim_lookup_info;
//-------------------------------------------------------------------------
struct pycim_callback_id_t
@@ -710,7 +712,6 @@ class py_customidamemo_t
// View events
void on_view_mouse_moved(const view_mouse_event_t *event);
int get_py_method_arg_count(char *method_name);
// View events that are bound with 'set_custom_viewer_handler()'.
static void idaapi s_on_view_mouse_moved(
@@ -786,8 +787,8 @@ T *view_extract_this(PyObject *self)
//-------------------------------------------------------------------------
#include <typeinf.hpp>
#define DECL_REG_UNREG_REFCOUNTED(Type) \
exported void ida_export til_register_python_##Type##_instance(Type *inst); \
exported void ida_export til_deregister_python_##Type##_instance(Type *inst);
idaman void ida_export til_register_python_##Type##_instance(Type *inst); \
idaman void ida_export til_deregister_python_##Type##_instance(Type *inst);
DECL_REG_UNREG_REFCOUNTED(tinfo_t);
DECL_REG_UNREG_REFCOUNTED(ptr_type_data_t);
DECL_REG_UNREG_REFCOUNTED(array_type_data_t);
@@ -803,17 +804,20 @@ struct py_timer_ctx_t
qtimer_t timer_id;
PyObject *pycallback;
};
exported py_timer_ctx_t *ida_export python_timer_new(PyObject *py_callback);
exported void ida_export python_timer_del(py_timer_ctx_t *t);
idaman py_timer_ctx_t *ida_export python_timer_new(PyObject *py_callback);
idaman void ida_export python_timer_del(py_timer_ctx_t *t);
//-------------------------------------------------------------------------
exported ref_t ida_export try_create_swig_wrapper(ref_t mod, const char *clsname, void *cobj);
idaman ref_t ida_export try_create_swig_wrapper(ref_t mod, const char *clsname, void *cobj);
//-------------------------------------------------------------------------
idaman ssize_t ida_export get_callable_arg_count(ref_t callable);
//-------------------------------------------------------------------------
// Useful for small operations that must not be interrupted: e.g., when
// wrapping an insn_t into a SWiG proxy object, or when destroying
// such an instance from the kernel. Use 'uninterruptible_op_t' if you can.
exported void ida_export set_interruptible_state(bool interruptible);
idaman void ida_export set_interruptible_state(bool interruptible);
struct uninterruptible_op_t
{
uninterruptible_op_t() { set_interruptible_state(false); }
@@ -821,25 +825,11 @@ struct uninterruptible_op_t
};
// //-------------------------------------------------------------------------
// class py_custom_data_type_t;
// class py_custom_data_format_t;
// typedef void py_custom_data_type_t_unregisterer_t(py_custom_data_type_t *inst);
// typedef void py_custom_data_format_t_unregisterer_t(py_custom_data_format_t *inst);
// exported void ida_export register_py_custom_data_type_and_format_unregisterer(
// py_custom_data_type_t_unregisterer_t cdt_unregisterer,
// py_custom_data_format_t_unregisterer_t cdf_unregisterer);
// exported void ida_export register_py_custom_data_type_instance(py_custom_data_type_t *inst);
// exported void ida_export register_py_custom_data_format_instance(py_custom_data_format_t *inst);
// exported void ida_export unregister_py_custom_data_type_instance(py_custom_data_type_t *inst);
// exported void ida_export unregister_py_custom_data_format_instance(py_custom_data_format_t *inst);
// exported py_custom_data_type_t *py_custom_data_type_cast(data_type_t *inst);
// exported py_custom_data_format_t *py_custom_data_format_cast(data_format_t *inst);
exported bool ida_export idapython_hook_to_notification_point(
idaman bool ida_export idapython_hook_to_notification_point(
hook_type_t hook_type,
hook_cb_t *cb,
void *user_data);
exported bool ida_export idapython_unhook_from_notification_point(
idaman bool ida_export idapython_unhook_from_notification_point(
hook_type_t hook_type,
hook_cb_t *cb,
void *user_data);
@@ -847,7 +837,7 @@ exported bool ida_export idapython_unhook_from_notification_point(
#define unhook_from_notification_point USE_IDAPYTHON_UNHOOK_FROM_NOTIFICATION_POINT
//-------------------------------------------------------------------------
exported bool ida_export idapython_convert_cli_completions(
idaman bool ida_export idapython_convert_cli_completions(
qstrvec_t *out_completions,
int *out_match_start,
int *out_match_end,
@@ -861,7 +851,9 @@ struct module_callbacks_t
void (*term) (void);
};
DECLARE_TYPE_AS_MOVABLE(module_callbacks_t);
exported void register_module_lifecycle_callbacks(
idaman void register_module_lifecycle_callbacks(
const module_callbacks_t &cbs);
idaman void ida_export prepare_programmatic_plugin_load(const char *path);
#endif // __PYWRAPS_HPP__
+1 -5
View File
@@ -47,7 +47,6 @@ doYwrd=create_yword
doZwrd=create_zword
do_data_ex=create_data
do_unknown=del_items
@bc695redef
def do_unknown_range(ea, size, flags):
return del_items(ea, flags, size) # swap 2 last args
dwrdflag=dword_flag
@@ -88,10 +87,8 @@ get_flags_novalue=get_flags
get_hidden_area=get_hidden_range
get_hidden_area_num=get_hidden_range_num
get_hidden_area_qty=get_hidden_range_qty
@bc695redef
def get_many_bytes(ea, size):
return get_bytes(ea, size)
@bc695redef
def get_many_bytes_ex(ea, size):
return get_bytes_and_mask(ea, size)
get_max_ascii_length=get_max_strlit_length
@@ -180,7 +177,6 @@ def get_opinfo(*args):
else: # 7.00: buf, ea, n, flags
buf, ea, n, flags = args
return _ida_bytes.get_opinfo(buf, ea, n, flags)
@bc695redef
def doASCI(ea, length):
import ida_netnode
return create_data(ea, FF_STRLIT, length, ida_netnode.BADNODE)
@@ -222,7 +218,7 @@ stroffflag=stroff_flag
struflag=stru_flag
wordflag=word_flag
invalidate_visea_cache=ida_idaapi._BC695.false_p
@bc695redef_with_pydoc(op_stroff.__doc__)
@bc695redef
def op_stroff(*args):
insn, n, path, path_len, delta = args
import ida_ua
+3 -3
View File
@@ -76,13 +76,13 @@ public:
bool hook() { return idapython_hook_to_notification_point(HT_DBG, DBG_Callback, this); }
bool unhook() { return idapython_unhook_from_notification_point(HT_DBG, DBG_Callback, this); }
static int store_int(int rc, const debug_event_t *, int *warn)
static ssize_t store_int(int rc, const debug_event_t *, int *warn)
{
*warn = rc;
return 0;
}
static int store_int(int rc, thid_t, ea_t, int *warn)
static ssize_t store_int(int rc, thid_t, ea_t, int *warn)
{
*warn = rc;
return 0;
@@ -98,7 +98,7 @@ ssize_t idaapi DBG_Callback(void *ud, int notification_code, va_list va)
class DBG_Hooks *proxy = (class DBG_Hooks *)ud;
debug_event_t *event;
int ret = 0;
ssize_t ret = 0;
try
{
-3
View File
@@ -59,7 +59,6 @@ def send_dbg_command(command):
#<pycode_BC695(py_dbg)>
import ida_idd
@bc695redef
def get_process_info(n, pi):
pis = ida_idd.procinfo_vec_t()
cnt = get_processes(pis)
@@ -68,8 +67,6 @@ def get_process_info(n, pi):
pi.name = pis[n].name
pi.pid = pis[n].pid
return pi.pid
@bc695redef
def get_process_qty():
pis = ida_idd.procinfo_vec_t()
return get_processes(pis)
+1 -1
View File
@@ -127,7 +127,7 @@ static bool py_add_idc_func(
const idc_values_t &defvals,
int flags)
{
ext_idcfunc_t desc = { name, (idc_func_t *)fp_ptr, args, defvals.begin(), defvals.size(), flags };
ext_idcfunc_t desc = { name, (idc_func_t *)fp_ptr, args, defvals.begin(), (int)defvals.size(), flags };
return add_idc_func(desc);
}
-6
View File
@@ -138,7 +138,6 @@ VarCopy=copy_idcv
VarDelAttr=del_idcv_attr
VarDeref=deref_idcv
VarFirstAttr=first_idcv_attr
@bc695redef
def VarGetAttr(obj, attr, res, may_use_getattr=False):
return get_idcv_attr(res, obj, attr, may_use_getattr)
VarGetClassName=get_idcv_class_name
@@ -155,20 +154,15 @@ VarSetAttr=set_idcv_attr
VarSetSlice=set_idcv_slice
VarString2=idcv_string
VarSwap=swap_idcvs
@bc695redef
def calc_idc_expr(where, expr, res):
return eval_idc_expr(res, where, expr)
@bc695redef
def calcexpr(where, expr, res):
return eval_expr(res, where, expr)
@bc695redef
def dosysfile(complain_if_no_file, fname):
return exec_system_script(fname, complain_if_no_file)
@bc695redef
def execute(line):
return eval_idc_snippet(None, line)
py_set_idc_func_ex=py_add_idc_func
@bc695redef
def set_idc_func_ex(name, fp=None, args=(), flags=0):
return add_idc_func(name, fp, args, (), flags)
#</pycode_BC695(py_expr)>
+3
View File
@@ -4,6 +4,7 @@ add_auto_stkpnt2=add_auto_stkpnt
# in fact, we cannot simulate add_stkvar[23] here, because we simply
# don't have the insn_t object -- and no way of retrieving it, either,
# since cmd is gone
@bc695redef
def get_stkvar(*args):
if len(args) == 2:
import ida_ua
@@ -11,6 +12,8 @@ def get_stkvar(*args):
else:
insn, op, v = args
return _ida_frame.get_stkvar(insn, op, v)
@bc695redef
def get_frame_part(*args):
import ida_funcs
if isinstance(args[0], ida_funcs.func_t): # 6.95: pfn, part, range
+8 -8
View File
@@ -14,14 +14,14 @@ def get_fchunk_referer(ea, idx):
*/
static ea_t get_fchunk_referer(ea_t ea, size_t idx)
{
func_t *pfn = get_fchunk(ea);
if ( pfn == NULL )
return BADADDR;
func_parent_iterator_t dummy(pfn); // read referer info
if ( idx >= pfn->refqty || pfn->referers == NULL )
return BADADDR;
else
return pfn->referers[idx];
func_t *pfn = get_fchunk(ea);
if ( pfn == NULL )
return BADADDR;
func_parent_iterator_t dummy(pfn); // read referer info
if ( idx >= pfn->refqty || pfn->referers == NULL )
return BADADDR;
else
return pfn->referers[idx];
}
//-----------------------------------------------------------------------
+11 -2
View File
@@ -1,18 +1,27 @@
#<pycode(py_funcs)>
import ida_idaapi
@ida_idaapi.replfun
def calc_thunk_func_target(*args):
if len(args) == 2:
pfn, rawptr = args
target, fptr = calc_thunk_func_target.func_dict["orig"](pfn)
import ida_pro
ida_pro.ea_pointer.frompointer(rawptr).assign(fptr)
return target
else:
return calc_thunk_func_target.func_dict["orig"](*args)
#</pycode(py_funcs)>
#<pycode_BC695(py_funcs)>
FUNC_STATIC=FUNC_STATICDEF
add_regarg2=add_regarg
clear_func_struct=lambda *args: True
@bc695redef
def del_func_cmt(pfn, rpt):
set_func_cmt(pfn, "", rpt)
func_parent_iterator_set2=func_parent_iterator_set
func_setend=set_func_end
func_setstart=set_func_start
func_tail_iterator_set2=func_tail_iterator_set
@bc695redef
def get_func_limits(pfn, limits):
import ida_range
rs = ida_range.rangeset_t()
+48 -35
View File
@@ -12,15 +12,16 @@ protected:
private:
enum
{
GRCODE_HAVE_USER_HINT = 0x00010000,
GRCODE_HAVE_CLICKED = 0x00020000,
GRCODE_HAVE_DBL_CLICKED = 0x00040000,
GRCODE_HAVE_GOTFOCUS = 0x00080000,
GRCODE_HAVE_LOSTFOCUS = 0x00100000,
GRCODE_HAVE_CHANGED_CURRENT = 0x00200000,
GRCODE_HAVE_CREATING_GROUP = 0x00400000,
GRCODE_HAVE_DELETING_GROUP = 0x00800000,
GRCODE_HAVE_GROUP_VISIBILITY = 0x01000000,
GRCODE_HAVE_HINT = 0x00010000,
GRCODE_HAVE_EDGE_HINT = 0x00020000,
GRCODE_HAVE_CLICKED = 0x00040000,
GRCODE_HAVE_DBL_CLICKED = 0x00080000,
GRCODE_HAVE_GOTFOCUS = 0x00100000,
GRCODE_HAVE_LOSTFOCUS = 0x00200000,
GRCODE_HAVE_CHANGED_CURRENT = 0x00400000,
GRCODE_HAVE_CREATING_GROUP = 0x00800000,
GRCODE_HAVE_DELETING_GROUP = 0x01000000,
GRCODE_HAVE_GROUP_VISIBILITY = 0x02000000,
};
struct nodetext_cache_t
{
@@ -55,7 +56,7 @@ private:
// static callback
static ssize_t idaapi s_callback(void *obj, int code, va_list va)
{
{
// don't perform sanity check for 'grcode_destroyed', since if we called
// Close() on this object, it'll have been marked for later deletion in the
// UI, and thus when we end up here, the view has already been destroyed.
@@ -83,7 +84,9 @@ private:
// Retrieves the hint for the user-defined graph
// Calls Python and expects a string or None
int on_user_hint(mutable_graph_t *, int mousenode, int /*mouseedge_src*/, int /*mouseedge_dst*/, char **hint);
int on_hint(char **hint, int node);
int on_edge_hint(char **hint, int src, int dest);
int _on_hint_epilog(char **hint, ref_t result);
// graph is being destroyed
void on_graph_destroyed(mutable_graph_t * /*g*/ = NULL)
@@ -233,7 +236,7 @@ private:
{
TWidget *view;
if ( pycim_lookup_info.find_by_py_view(&view, this) )
display_widget(view, WOPN_TAB|WOPN_MENU);
display_widget(view, WOPN_TAB);
}
void jump_to_node(int nid)
@@ -282,7 +285,7 @@ private:
this->self = borref_t(self);
graph_viewer_t *pview = create_graph_viewer(title, id, s_callback, this, 0);
this->self = ref_t();
display_widget(pview, WOPN_TAB | WOPN_MENU);
display_widget(pview, WOPN_TAB);
newref_t ret(PyObject_CallMethod(self, "hook", NULL));
if ( pview != NULL )
viewer_fit_window(pview);
@@ -379,7 +382,8 @@ void py_graph_t::collect_class_callbacks_ids(pycim_callbacks_ids_t *out)
out->add(S_ON_GETTEXT, 0);
out->add(S_M_EDGES, -1);
out->add(S_M_NODES, -1);
out->add(S_ON_HINT, GRCODE_HAVE_USER_HINT);
out->add(S_ON_HINT, GRCODE_HAVE_HINT);
out->add(S_ON_EDGE_HINT, GRCODE_HAVE_EDGE_HINT);
out->add(S_ON_CLICK, GRCODE_HAVE_CLICKED);
out->add(S_ON_DBL_CLICK, GRCODE_HAVE_DBL_CLICKED);
out->add(S_ON_SELECT, GRCODE_HAVE_CHANGED_CURRENT);
@@ -508,25 +512,34 @@ bool py_graph_t::on_user_text(mutable_graph_t * /*g*/, int node, const char **st
}
//-------------------------------------------------------------------------
int py_graph_t::on_user_hint(mutable_graph_t *, int mousenode, int /*mouseedge_src*/, int /*mouseedge_dst*/, char **hint)
int py_graph_t::on_hint(char **hint, int node)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t result(PyObject_CallMethod(self.o, (char *)S_ON_HINT, "i", node));
PyW_ShowCbErr(S_ON_HINT);
return _on_hint_epilog(hint, result);
}
//-------------------------------------------------------------------------
int py_graph_t::on_edge_hint(char **hint, int src, int dest)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t result(PyObject_CallMethod(self.o, (char *)S_ON_EDGE_HINT, "ii", src, dest));
PyW_ShowCbErr(S_ON_EDGE_HINT);
return _on_hint_epilog(hint, result);
}
//-------------------------------------------------------------------------
int py_graph_t::_on_hint_epilog(char **hint, ref_t result)
{
// 'hint' must be allocated by qalloc() or qstrdup()
// out: 0-use default hint, 1-use proposed hint
// We dispatch hints over nodes only
if ( mousenode == -1 )
return 0;
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t result(PyObject_CallMethod(self.o, (char *)S_ON_HINT, "i", mousenode));
PyW_ShowCbErr(S_ON_HINT);
bool ok = result != NULL && PyString_Check(result.o);
if ( ok )
*hint = qstrdup(PyString_AsString(result.o));
return ok; // use our hint
return ok;
}
//-------------------------------------------------------------------------
ssize_t py_graph_t::gr_callback(int code, va_list va)
{
@@ -600,18 +613,18 @@ ssize_t py_graph_t::gr_callback(int code, va_list va)
break;
//
case grcode_user_hint:
if ( has_callback(GRCODE_HAVE_USER_HINT) )
{
mutable_graph_t *g = va_arg(va, mutable_graph_t *);
int mousenode = va_arg(va, int);
int mouseedge_src = va_arg(va, int);
int mouseedge_dest = va_arg(va, int);
char **hint = va_arg(va, char **);
ret = on_user_hint(g, mousenode, mouseedge_src, mouseedge_dest, hint);
}
else
{
ret = 0;
int node = va_arg(va, int);
int src = va_arg(va, int);
int dest = va_arg(va, int);
char **hint = va_arg(va, char **);
if ( node == -1 && has_callback(GRCODE_HAVE_EDGE_HINT) )
ret = on_edge_hint(hint, src, dest);
else if ( node >= 0 && has_callback(GRCODE_HAVE_HINT) )
ret = on_hint(hint, node);
else
ret = 0;
}
break;
//
+10
View File
@@ -44,6 +44,8 @@ class GraphViewer(ida_kernwin.CustomIDAMemo):
def AddEdge(self, src_node, dest_node):
"""Creates an edge between two given node ids"""
assert src_node < len(self._nodes), "Source node %d is out of bounds" % src_node
assert dest_node < len(self._nodes), "Destination node %d is out of bounds" % dest_node
self._edges.append( (src_node, dest_node) )
def Clear(self):
@@ -166,6 +168,14 @@ class GraphViewer(ida_kernwin.CustomIDAMemo):
# """
# return "hint for " + str(node_id)
#
# def OnEdgeHint(self, src, dst):
# """
# Triggered when the graph viewer wants to retrieve hint text associated with a edge
#
# @return: None if no hint is avail or a string designating the hint
# """
# return "hint for edge %d -> %d" % (src, dst)
#
# def OnClose(self):
# """Triggered when the graph viewer window is being closed
# @return: None
+25 -270
View File
@@ -26,7 +26,7 @@ static void debug_hexrays_ctree(const char *format, ...)
// The hexrays+IDAPython term sequence goes as follows:
// - hexrays is unloaded before IDAPython
// - we receive the notification about hexrays going away and:
// + call hexrays_clear_python_clearable_references();
// + call hexrays_unloading__clear_python_clearable_references();
// + set 'hexdsp = exit_time_dummy_hexdsp' (an NOP hexdsp)
// - we receive 'ui_term', and
// + set 'hexdsp = init_time_dummy_hexdsp'
@@ -113,241 +113,14 @@ static int hexrays_python_intcall(ref_t fct, ref_t args)
//---------------------------------------------------------------------
static bool idaapi __python_custom_viewer_popup_item_callback(void *ud)
{
PYW_GIL_GET;
int ret;
borref_t fct((PyObject *)ud);
newref_t nil(NULL);
ret = hexrays_python_intcall(fct, nil);
return ret ? true : false;
}
//---------------------------------------------------------------------
static ssize_t idaapi __hexrays_python_callback(void *ud, hexrays_event_t event, va_list va)
{
PYW_GIL_GET;
ssize_t ret;
int ret;
borref_t fct((PyObject *)ud);
switch ( event )
{
case hxe_maturity:
///< Ctree maturity level is being changed.
///< cfunc_t *cfunc
///< ctree_maturity_t new_maturity
{
cfunc_t *arg0 = va_arg(va, cfunc_t *);
ctree_maturity_t arg1 = va_argi(va, ctree_maturity_t);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
newref_t args(Py_BuildValue("(iOi)", event, arg0obj.o, arg1));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_interr:
///< Internal error has occurred.
///< int errcode
{
int arg0 = va_argi(va, int);
newref_t args(Py_BuildValue("(ii)", event, arg0));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_print_func:
///< Printing ctree and generating text.
///< cfunc_t *cfunc
///< vc_printer_t *vp
///< Returns: 1 if text has been generated by the plugin
{
cfunc_t *arg0 = va_arg(va, cfunc_t *);
vc_printer_t *arg1 = va_arg(va, vc_printer_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
newref_t arg1obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg1), SWIGTYPE_p_vc_printer_t, 0 ));
newref_t args(Py_BuildValue("(iOO)", event, arg0obj.o, arg1obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_func_printed:
///< Function text has been generated. Plugins may
///< modify the text in \ref sv.
///< cfunc_t *cfunc
{
cfunc_t *arg0 = va_arg(va, cfunc_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_cfunc_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
// User interface related events:
case hxe_open_pseudocode:
///< New pseudocode view has been opened.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_switch_pseudocode:
///< Existing pseudocode view has been reloaded
///< with a new function. Its text has not been
///< refreshed yet, only cfunc and mba pointers are ready.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_refresh_pseudocode:
///< Existing pseudocode text has been refreshed.
///< vdui_t *vu
///< See also hxe_text_ready, which happens earlier
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_close_pseudocode:
///< Pseudocode view is being closed.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_keyboard:
///< Keyboard has been hit.
///< vdui_t *vu
///< int key_code (VK_...)
///< int shift_state
///< Should return: 1 if the event has been handled
{
vdui_t *arg0 = va_arg(va, vdui_t *);
int arg1 = va_argi(va, int);
int arg2 = va_argi(va, int);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iOii)", event, arg0obj.o, arg1, arg2));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_right_click:
///< Mouse right click. We can add menu items now.
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_double_click:
///< Mouse double click.
///< vdui_t *vu
///< int shift_state
///< Should return: 1 if the event has been handled
{
vdui_t *arg0 = va_arg(va, vdui_t *);
int arg1 = va_argi(va, int);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iOi)", event, arg0obj.o, arg1));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_curpos:
///< Current cursor position has been changed.
///< (for example, by left-clicking or using keyboard)
///< vdui_t *vu
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_create_hint:
///< Create a hint for the current item.
///< vdui_t *vu
///< qstring *result_hint
///< int *implines
///< Possible return values:
///< 0: the event has not been handled
///< 1: hint has been created (should set *implines to nonzero as well)
///< 2: hint has been created but the standard hints must be
///< appended by the decompiler
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = 0;
ref_t resultobj = hexrays_python_call(fct, args);
if ( PyTuple_Check(resultobj.o) && PyTuple_Size(resultobj.o) == 3 )
{
borref_t i0 = PyTuple_GetItem(resultobj.o, 0);
borref_t i1 = PyTuple_GetItem(resultobj.o, 1);
borref_t i2 = PyTuple_GetItem(resultobj.o, 2);
if ( PyInt_Check(i0.o) && PyString_Check(i1.o) && PyInt_Check(i2.o) )
{
qstring *result_hint = va_arg(va, qstring *);
char *buf;
Py_ssize_t bufsize;
if ( PyString_AsStringAndSize(i1.o, &buf, &bufsize) > -1 )
{
ret = PyInt_AsLong(i0.o);
qstring tmp(buf, bufsize);
result_hint->swap(tmp);
int *implines = va_arg(va, int *);
*implines = PyInt_AsLong(i2.o);
}
}
}
}
break;
case hxe_text_ready:
///< Decompiled text is ready.
///< vdui_t *vu
///< This event can be used to modify the output text (sv).
///< The text uses regular color codes (see lines.hpp)
///< COLOR_ADDR is used to store pointers to ctree elements
{
vdui_t *arg0 = va_arg(va, vdui_t *);
newref_t arg0obj(SWIG_NewPointerObj(SWIG_as_voidptr(arg0), SWIGTYPE_p_vdui_t, 0 ));
newref_t args(Py_BuildValue("(iO)", event, arg0obj.o));
ret = hexrays_python_intcall(fct, args);
}
break;
case hxe_populating_popup:
///< Populating popup menu. We can add menu items now.
///< TWidget *widget
///< TPopupMenu *popup_handle
///< vdui_t *vu
{
TWidget *widget = va_arg(va, TWidget *);
TPopupMenu *pp = va_arg(va, TPopupMenu*);
vdui_t *vdui = va_arg(va, vdui_t *);
newref_t py_widget(SWIG_NewPointerObj(SWIG_as_voidptr(widget), SWIGTYPE_p_TWidget, 0));
newref_t py_popup(SWIG_NewPointerObj(SWIG_as_voidptr(pp), SWIGTYPE_p_TPopupMenu, 0));
newref_t py_vdui(SWIG_NewPointerObj(SWIG_as_voidptr(vdui), SWIGTYPE_p_vdui_t, 0 ));
newref_t py_args(Py_BuildValue("(iOOO)", event, py_widget.o, py_popup.o, py_vdui.o));
ret = hexrays_python_intcall(fct, py_args);
}
break;
default:
//~ msg("IDAPython: Unknown event `%u' occurred\n", event);
ret = 0;
break;
}
return ret;
newref_t nil(NULL);
ret = hexrays_python_intcall(fct, nil);
return ret ? true : false;
}
//-------------------------------------------------------------------------
@@ -374,9 +147,9 @@ DECLARE_TYPE_AS_MOVABLE(hx_clearable_t);
typedef qvector<hx_clearable_t> hx_clearables_t;
static hx_clearables_t python_clearables;
void hexrays_clear_python_clearable_references(void)
void hexrays_unloading__clear_python_clearable_references(void)
{
debug_hexrays_ctree("hexrays_clear_python_clearable_references()\n");
debug_hexrays_ctree("hexrays_unloading__clear_python_clearable_references()\n");
for ( size_t i = 0, n = python_clearables.size(); i < n; ++i )
{
const hx_clearable_t &hxc = python_clearables[i];
@@ -449,16 +222,16 @@ hx_clearable_type_t hexrays_is_registered_python_clearable_instance(
//-------------------------------------------------------------------------
cfuncptr_t _decompile(func_t *pfn, hexrays_failure_t *hf)
{
try
{
cfuncptr_t cfunc = decompile(pfn, hf);
return cfunc;
}
catch(...)
{
error("Hex-Rays Python: decompiler threw an exception.\n");
}
return cfuncptr_t(0);
try
{
cfuncptr_t cfunc = decompile(pfn, hf);
return cfunc;
}
catch(...)
{
error("Hex-Rays Python: decompiler threw an exception.\n");
}
return cfuncptr_t(0);
}
//-------------------------------------------------------------------------
@@ -505,6 +278,7 @@ inline bool hexdsp_inited()
}
//-------------------------------------------------------------------------
static void hexrays_unloading__unhook_hooks(void);
static ssize_t idaapi ida_hexrays_ui_notification(void *, int code, va_list va)
{
switch ( code )
@@ -521,12 +295,17 @@ static ssize_t idaapi ida_hexrays_ui_notification(void *, int code, va_list va)
case ui_plugin_unloading:
if ( hexdsp != NULL && hexdsp != init_time_dummy_hexdsp )
{
// Make sure all the refcounted objects are cleared right away.
const plugin_info_t *pi = va_arg(va, plugin_info_t *);
if ( is_hexrays_plugin(pi) )
{
QASSERT(30500, hexdsp != exit_time_dummy_hexdsp);
hexrays_clear_python_clearable_references();
// Make sure all the refcounted objects are cleared right away.
hexrays_unloading__clear_python_clearable_references();
// Make sure all hooks are unhooked
hexrays_unloading__unhook_hooks();
hexdsp = exit_time_dummy_hexdsp;
}
}
@@ -564,30 +343,6 @@ bool py_init_hexrays_plugin(int flags=0)
return hexdsp_inited() || init_hexrays_plugin(flags);
}
//---------------------------------------------------------------------
bool py_install_hexrays_callback(PyObject *hx_cblist_callback)
{
PYW_GIL_GET;
if ( install_hexrays_callback(__hexrays_python_callback, hx_cblist_callback) )
{
Py_INCREF(hx_cblist_callback);
return true;
}
return false;
}
//---------------------------------------------------------------------
int py_remove_hexrays_callback(PyObject *hx_cblist_callback)
{
PYW_GIL_GET;
int result, i;
result = remove_hexrays_callback(__hexrays_python_callback, hx_cblist_callback);
for ( i = 0; i < result; i++ )
Py_DECREF(hx_cblist_callback);
return result;
}
cfuncptr_t _decompile(func_t *pfn, hexrays_failure_t *hf);
//-------------------------------------------------------------------------
+156 -114
View File
@@ -257,119 +257,6 @@ lvar_t.is_spoiled_var = property(lvar_t.is_spoiled_var)
lvar_t.is_mapdst_var = property(lvar_t.is_mapdst_var)
# dictify all dict-like types
def _map___iter__(self):
""" Iterate over dictionary keys. """
return self.iterkeys()
def _map___getitem__(self, key):
""" Returns the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of key should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
return self.second(self.find(key))
def _map___setitem__(self, key, value):
""" Returns the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if not isinstance(value, self.valuetype):
raise KeyError('type of `value` should be ' + repr(self.valuetype) + ' but got ' + type(value))
self.insert(key, value)
return
def _map___delitem__(self, key):
""" Removes the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
self.erase(self.find(key))
return
def _map___contains__(self, key):
""" Returns true if the specified key exists in the . """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if self.find(key) != self.end():
return True
return False
def _map_clear(self):
self.clear()
return
def _map_copy(self):
ret = {}
for k in self.iterkeys():
ret[k] = self[k]
return ret
def _map_get(self, key, default=None):
if key in self:
return self[key]
return default
def _map_iterkeys(self):
iter = self.begin()
while iter != self.end():
yield self.first(iter)
iter = self.next(iter)
return
def _map_itervalues(self):
iter = self.begin()
while iter != self.end():
yield self.second(iter)
iter = self.next(iter)
return
def _map_iteritems(self):
iter = self.begin()
while iter != self.end():
yield (self.first(iter), self.second(iter))
iter = self.next(iter)
return
def _map_keys(self):
return list(self.iterkeys())
def _map_values(self):
return list(self.itervalues())
def _map_items(self):
return list(self.iteritems())
def _map_has_key(self, key):
return key in self
def _map_pop(self, key):
""" Sets the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
ret = self[key]
del self[key]
return ret
def _map_popitem(self):
""" Sets the value associated with the provided key. """
if len(self) == 0:
raise KeyError('key not found')
key = self.keys()[0]
return (key, self.pop(key))
def _map_setdefault(self, key, default=None):
""" Sets the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key in self:
return self[key]
self[key] = default
return default
def _map_as_dict(maptype, name, keytype, valuetype):
maptype.keytype = keytype
@@ -393,29 +280,141 @@ def _map_as_dict(maptype, name, keytype, valuetype):
maptype.erase = lambda self, *args: self.__erase(self, *args)
maptype.clear = lambda self, *args: self.__clear(self, *args)
maptype.size = lambda self, *args: self.__size(self, *args)
def _map___iter__(self):
""" Iterate over dictionary keys. """
return self.iterkeys()
maptype.__iter__ = _map___iter__
def _map___getitem__(self, key):
""" Returns the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of key should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
return self.second(self.find(key))
maptype.__getitem__ = _map___getitem__
def _map___setitem__(self, key, value):
""" Returns the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if not isinstance(value, self.valuetype):
raise KeyError('type of `value` should be ' + repr(self.valuetype) + ' but got ' + type(value))
self.insert(key, value)
return
maptype.__setitem__ = _map___setitem__
def _map___delitem__(self, key):
""" Removes the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
self.erase(self.find(key))
return
maptype.__delitem__ = _map___delitem__
def _map___contains__(self, key):
""" Returns true if the specified key exists in the . """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if self.find(key) != self.end():
return True
return False
maptype.__contains__ = _map___contains__
def _map_clear(self):
self.clear()
return
maptype.clear = _map_clear
def _map_copy(self):
ret = {}
for k in self.iterkeys():
ret[k] = self[k]
return ret
maptype.copy = _map_copy
def _map_get(self, key, default=None):
if key in self:
return self[key]
return default
maptype.get = _map_get
def _map_iterkeys(self):
iter = self.begin()
while iter != self.end():
yield self.first(iter)
iter = self.next(iter)
return
maptype.iterkeys = _map_iterkeys
def _map_itervalues(self):
iter = self.begin()
while iter != self.end():
yield self.second(iter)
iter = self.next(iter)
return
maptype.itervalues = _map_itervalues
def _map_iteritems(self):
iter = self.begin()
while iter != self.end():
yield (self.first(iter), self.second(iter))
iter = self.next(iter)
return
maptype.iteritems = _map_iteritems
def _map_keys(self):
return list(self.iterkeys())
maptype.keys = _map_keys
def _map_values(self):
return list(self.itervalues())
maptype.values = _map_values
def _map_items(self):
return list(self.iteritems())
maptype.items = _map_items
def _map_has_key(self, key):
return key in self
maptype.has_key = _map_has_key
def _map_pop(self, key):
""" Sets the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key not in self:
raise KeyError('key not found')
ret = self[key]
del self[key]
return ret
maptype.pop = _map_pop
def _map_popitem(self):
""" Sets the value associated with the provided key. """
if len(self) == 0:
raise KeyError('key not found')
key = self.keys()[0]
return (key, self.pop(key))
maptype.popitem = _map_popitem
def _map_setdefault(self, key, default=None):
""" Sets the value associated with the provided key. """
if not isinstance(key, self.keytype):
raise KeyError('type of `key` should be ' + repr(self.keytype) + ' but got ' + repr(type(key)))
if key in self:
return self[key]
self[key] = default
return default
maptype.setdefault = _map_setdefault
#_map_as_dict(user_labels_t, 'user_labels', (int, long), qstring)
_map_as_dict(user_cmts_t, 'user_cmts', treeloc_t, citem_cmt_t)
_map_as_dict(user_numforms_t, 'user_numforms', operand_locator_t, number_format_t)
_map_as_dict(user_iflags_t, 'user_iflags', citem_locator_t, (int, long))
_map_as_dict(user_iflags_t, 'user_iflags', citem_locator_t, int)
import ida_pro
_map_as_dict(user_unions_t, 'user_unions', (int, long), ida_pro.intvec_t)
_map_as_dict(eamap_t, 'eamap', long, cinsnptrvec_t)
@@ -477,6 +476,49 @@ def create_helper(*args):
res._own_and_register()
return res
# ----------------
class __cbhooks_t(Hexrays_Hooks):
instances = []
def __init__(self, callback):
self.callback = callback
self.instances.append(self)
Hexrays_Hooks.__init__(self)
def maturity(self, *args): return self.callback(hxe_maturity, *args)
def interr(self, *args): return self.callback(hxe_interr, **args)
def print_func(self, *args): return self.callback(hxe_print_func, *args)
def func_printed(self, *args): return self.callback(hxe_func_printed, *args)
def open_pseudocode(self, *args): return self.callback(hxe_open_pseudocode, *args)
def switch_pseudocode(self, *args): return self.callback(hxe_switch_pseudocode, *args)
def refresh_pseudocode(self, *args): return self.callback(hxe_refresh_pseudocode, *args)
def close_pseudocode(self, *args): return self.callback(hxe_close_pseudocode, *args)
def keyboard(self, *args): return self.callback(hxe_keyboard, *args)
def right_click(self, *args): return self.callback(hxe_right_click, *args)
def double_click(self, *args): return self.callback(hxe_double_click, *args)
def curpos(self, *args): return self.callback(hxe_curpos, *args)
def create_hint(self, *args): return self.callback(hxe_create_hint, *args)
def text_ready(self, *args): return self.callback(hxe_text_ready, *args)
def populating_popup(self, *args): return self.callback(hxe_populating_popup, *args)
def install_hexrays_callback(callback):
"Deprecated. Please use Hexrays_Hooks instead"
h = __cbhooks_t(callback)
h.hook()
return True
def remove_hexrays_callback(callback):
"Deprecated. Please use Hexrays_Hooks instead"
for inst in __cbhooks_t.instances:
if inst.callback == callback:
inst.unhook()
__cbhooks_t.instances.remove(inst)
return 1
return 0
#</pycode(py_hexrays)>
#<pycode_BC695(py_hexrays)>
+107
View File
@@ -0,0 +1,107 @@
//<code(py_hexrays_hooks)>
//---------------------------------------------------------------------------
ssize_t idaapi Hexrays_Callback(void *ud, hexrays_event_t event, va_list va)
{
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
class Hexrays_Hooks *proxy = (class Hexrays_Hooks *)ud;
ssize_t ret = 0;
try
{
switch ( event )
{
// hookgenHEXRAYS:notifications
}
}
catch (Swig::DirectorException &e)
{
msg("Exception in Hexrays Hook function: %s\n", e.getMessage());
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( PyErr_Occurred() )
PyErr_Print();
}
return ret;
}
//-------------------------------------------------------------------------
static qvector<Hexrays_Hooks*> hexrays_hooks_instances;
//-------------------------------------------------------------------------
static void hexrays_unloading__unhook_hooks(void)
{
for ( size_t i = 0, n = hexrays_hooks_instances.size(); i < n; ++i )
hexrays_hooks_instances[i]->unhook();
}
//-------------------------------------------------------------------------
Hexrays_Hooks::Hexrays_Hooks()
: hooked(false)
{
hexrays_hooks_instances.push_back(this);
}
//-------------------------------------------------------------------------
Hexrays_Hooks::~Hexrays_Hooks()
{
hexrays_hooks_instances.del(this);
unhook();
}
//</code(py_hexrays_hooks)>
//<inline(py_hexrays_hooks)>
//-------------------------------------------------------------------------
// Hexrays hooks
//---------------------------------------------------------------------------
ssize_t idaapi Hexrays_Callback(void *ud, hexrays_event_t event, va_list va);
class control_graph_t;
class Hexrays_Hooks
{
friend ssize_t idaapi Hexrays_Callback(void *ud, hexrays_event_t event, va_list va);
static ssize_t handle_create_hint_output(PyObject *o, vdui_t *, qstring *out_hint, int *out_implines)
{
ssize_t rc = 0;
if ( o != NULL && PySequence_Check(o) && PySequence_Size(o) == 3 )
{
newref_t py_rc(PySequence_GetItem(o, 0));
newref_t py_hint(PySequence_GetItem(o, 1));
newref_t py_implines(PySequence_GetItem(o, 2));
if ( PyInt_Check(py_rc.o) && PyString_Check(py_hint.o) && PyInt_Check(py_implines.o) )
{
char *buf;
Py_ssize_t bufsize;
if ( PyString_AsStringAndSize(py_hint.o, &buf, &bufsize) > -1 )
{
rc = PyInt_AsLong(py_rc.o);
qstring tmp(buf, bufsize);
out_hint->swap(tmp);
*out_implines = PyInt_AsLong(py_implines.o);
}
}
}
return rc;
}
bool hooked;
public:
Hexrays_Hooks();
virtual ~Hexrays_Hooks();
bool hook()
{
if ( !hooked )
hooked = install_hexrays_callback(Hexrays_Callback, this);
return hooked;
}
bool unhook()
{
if ( hooked )
hooked = !remove_hexrays_callback(Hexrays_Callback, this);
return !hooked;
}
// hookgenHEXRAYS:methods
};
//</inline(py_hexrays_hooks)>
+8
View File
@@ -88,4 +88,12 @@ def make_lflags_accessors(bit):
self.lflags &= ~bit
return getter, setter
idainfo.wide_high_byte_first = property(*make_lflags_accessors(LFLG_WIDE_HBF))
def make_obsolete_accessors():
def getter(self):
return False
def setter(self, value):
pass
return getter, setter
idainfo.allow_nonmatched_ops = property(*make_obsolete_accessors())
idainfo.check_manual_ops = property(*make_obsolete_accessors())
#</pycode_BC695(py_ida)>
+22
View File
@@ -12,6 +12,8 @@ import datetime
#<pycode(py_idaapi)>
__EA64__ = BADADDR == 0xFFFFFFFFFFFFFFFFL
import struct
import traceback
import os
@@ -56,6 +58,22 @@ def require(modulename, package=None):
sys.modules[modulename] = m
setattr(importer_module, modulename, m)
def _replace_module_function(replacement):
name = replacement.__name__
modname = replacement.__module__
assert(name)
assert(modname)
mod = sys.modules[modname]
orig = getattr(mod, name)
replacement.__doc__ = orig.__doc__
replacement.__name__ = name
replacement.func_dict["orig"] = orig
setattr(mod, name, replacement)
def replfun(func):
_replace_module_function(func)
return func
# -----------------------------------------------------------------------
@@ -629,6 +647,10 @@ class __BC695:
def dummy(self, *args):
pass
def replace_fun(self, new):
new.func_dict["bc695redef"] = True
_replace_module_function(new)
_BC695 = __BC695()
#</pycode(py_idaapi)>
+12 -12
View File
@@ -370,50 +370,50 @@ PyObject *py_appcall(
char get_event_module_name(const debug_event_t *ev, char *buf, size_t bufsize)
{
qstrncpy(buf, ev->modinfo().name.c_str(), bufsize);
return true;
qstrncpy(buf, ev->modinfo().name.c_str(), bufsize);
return true;
}
ea_t get_event_module_base(const debug_event_t *ev)
{
return ev->modinfo().base;
return ev->modinfo().base;
}
asize_t get_event_module_size(const debug_event_t *ev)
{
return ev->modinfo().size;
return ev->modinfo().size;
}
char get_event_exc_info(const debug_event_t *ev, char *buf, size_t bufsize)
{
qstrncpy(buf, ev->exc().info.c_str(), bufsize);
return true;
qstrncpy(buf, ev->exc().info.c_str(), bufsize);
return true;
}
char get_event_info(const debug_event_t *ev, char *buf, size_t bufsize)
{
qstrncpy(buf, ev->info().c_str(), bufsize);
return true;
qstrncpy(buf, ev->info().c_str(), bufsize);
return true;
}
ea_t get_event_bpt_hea(const debug_event_t *ev)
{
return ev->bpt().hea;
return ev->bpt().hea;
}
uint get_event_exc_code(const debug_event_t *ev)
{
return ev->exc().code;
return ev->exc().code;
}
ea_t get_event_exc_ea(const debug_event_t *ev)
{
return ev->exc().ea;
return ev->exc().ea;
}
bool can_exc_continue(const debug_event_t *ev)
{
return ev->exc().can_cont;
return ev->exc().can_cont;
}
//</inline(py_idd)>
+17 -17
View File
@@ -600,9 +600,9 @@ ssize_t idaapi IDP_Callback(void *ud, int notification_code, va_list va);
class IDP_Hooks
{
friend ssize_t idaapi IDP_Callback(void *ud, int notification_code, va_list va);
static int bool_to_insn_t_size(bool in, const insn_t *insn) { return in ? insn->size : 0; }
static int bool_to_1or0(bool in) { return in ? 1 : 0; }
static int cm_t_to_int(cm_t cm) { return int(cm); }
static ssize_t bool_to_insn_t_size(bool in, const insn_t *insn) { return in ? insn->size : 0; }
static ssize_t bool_to_1or0(bool in) { return in ? 1 : 0; }
static ssize_t cm_t_to_ssize_t(cm_t cm) { return ssize_t(cm); }
static bool _handle_qstring_output(PyObject *o, qstring *buf)
{
bool is_str = o != NULL && PyString_Check(o);
@@ -611,13 +611,13 @@ class IDP_Hooks
Py_XDECREF(o);
return is_str;
}
static int handle_custom_mnem_output(PyObject *o, qstring *out, const insn_t *)
static ssize_t handle_custom_mnem_output(PyObject *o, qstring *out, const insn_t *)
{
return _handle_qstring_output(o, out) && !out->empty() ? 1 : 0;
}
static int handle_assemble_output(PyObject *o, uchar *bin, ea_t /*ea*/, ea_t /*cs*/, ea_t /*ip*/, bool /*use32*/, const char */*line*/)
static ssize_t handle_assemble_output(PyObject *o, uchar *bin, ea_t /*ea*/, ea_t /*cs*/, ea_t /*ip*/, bool /*use32*/, const char */*line*/)
{
int rc = 0;
ssize_t rc = 0;
if ( o != NULL && PyString_Check(o) )
{
char *s;
@@ -628,20 +628,20 @@ class IDP_Hooks
len = MAXSTR;
memcpy(bin, s, len);
}
rc = int(len);
rc = ssize_t(len);
}
Py_XDECREF(o);
return rc;
}
static int handle_get_reg_name_output(PyObject *o, qstring *buf, int /*reg*/, size_t /*width*/, int /*reghi*/)
static ssize_t handle_get_reg_name_output(PyObject *o, qstring *buf, int /*reg*/, size_t /*width*/, int /*reghi*/)
{
return _handle_qstring_output(o, buf) ? buf->length() : 0;
}
static int handle_decorate_name3_output(PyObject *o, qstring *outbuf, const char * /*name*/, bool /*mangle*/, int /*cc*/, const tinfo_t * /*type*/)
static ssize_t handle_decorate_name3_output(PyObject *o, qstring *outbuf, const char * /*name*/, bool /*mangle*/, int /*cc*/, const tinfo_t * /*type*/)
{
return _handle_qstring_output(o, outbuf) ? 1 : 0;
}
static int handle_delay_slot_insn_output(PyObject *o, ea_t *pea, bool *pbexec, bool *pfexec)
static ssize_t handle_delay_slot_insn_output(PyObject *o, ea_t *pea, bool *pbexec, bool *pfexec)
{
if ( PySequence_Check(o) && PySequence_Size(o) == 3 )
{
@@ -664,9 +664,9 @@ class IDP_Hooks
}
return -1;
}
static int handle_use_regarg_type_output(PyObject *o, int *idx, ea_t, const funcargvec_t *)
static ssize_t handle_use_regarg_type_output(PyObject *o, int *idx, ea_t, const funcargvec_t *)
{
int rc = 0;
ssize_t rc = 0;
if ( PySequence_Check(o) && PySequence_Size(o) == 2 )
{
newref_t py_rc(PySequence_GetItem(o, 0));
@@ -679,7 +679,7 @@ class IDP_Hooks
}
return rc;
}
static int handle_demangle_name_output(
static ssize_t handle_demangle_name_output(
PyObject *o,
int32 *out_res,
qstring *out,
@@ -687,7 +687,7 @@ class IDP_Hooks
uint32 disable_mask,
demreq_type_t demreq)
{
int rc = 0;
ssize_t rc = 0;
if ( PySequence_Check(o) && PySequence_Size(o) == 3 )
{
newref_t py_rc(PySequence_GetItem(o, 0));
@@ -711,14 +711,14 @@ class IDP_Hooks
}
return rc;
}
static int handle_find_value_output(
static ssize_t handle_find_value_output(
PyObject *o,
uval_t *out,
const insn_t *pinsn,
int reg)
{
uint64 num;
int rc = PyW_GetNumber(o, &num);
ssize_t rc = PyW_GetNumber(o, &num);
if ( rc )
*out = num;
return rc;
@@ -751,7 +751,7 @@ ssize_t idaapi IDP_Callback(void *ud, int notification_code, va_list va)
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
IDP_Hooks *proxy = (IDP_Hooks *)ud;
int ret = 0;
ssize_t ret = 0;
try
{
switch ( notification_code )
+1 -60
View File
@@ -28,66 +28,7 @@ OP_SP_ADD = 0x00000000 # operand value is added to the pointer
OP_SP_SUB = 0x00000002 # operand value is substracted from the pointer
# processor_t.id
PLFM_386 = 0 # Intel 80x86
PLFM_Z80 = 1 # 8085, Z80
PLFM_I860 = 2 # Intel 860
PLFM_8051 = 3 # 8051
PLFM_TMS = 4 # Texas Instruments TMS320C5x
PLFM_6502 = 5 # 6502
PLFM_PDP = 6 # PDP11
PLFM_68K = 7 # Motoroal 680x0
PLFM_JAVA = 8 # Java
PLFM_6800 = 9 # Motorola 68xx
PLFM_ST7 = 10 # SGS-Thomson ST7
PLFM_MC6812 = 11 # Motorola 68HC12
PLFM_MIPS = 12 # MIPS
PLFM_ARM = 13 # Advanced RISC Machines
PLFM_TMSC6 = 14 # Texas Instruments TMS320C6x
PLFM_PPC = 15 # PowerPC
PLFM_80196 = 16 # Intel 80196
PLFM_Z8 = 17 # Z8
PLFM_SH = 18 # Renesas (formerly Hitachi) SuperH
PLFM_NET = 19 # Microsoft Visual Studio.Net
PLFM_AVR = 20 # Atmel 8-bit RISC processor(s)
PLFM_H8 = 21 # Hitachi H8/300, H8/2000
PLFM_PIC = 22 # Microchip's PIC
PLFM_SPARC = 23 # SPARC
PLFM_ALPHA = 24 # DEC Alpha
PLFM_HPPA = 25 # Hewlett-Packard PA-RISC
PLFM_H8500 = 26 # Hitachi H8/500
PLFM_TRICORE = 27 # Tasking Tricore
PLFM_DSP56K = 28 # Motorola DSP5600x
PLFM_C166 = 29 # Siemens C166 family
PLFM_ST20 = 30 # SGS-Thomson ST20
PLFM_IA64 = 31 # Intel Itanium IA64
PLFM_I960 = 32 # Intel 960
PLFM_F2MC = 33 # Fujistu F2MC-16
PLFM_TMS320C54 = 34 # Texas Instruments TMS320C54xx
PLFM_TMS320C55 = 35 # Texas Instruments TMS320C55xx
PLFM_TRIMEDIA = 36 # Trimedia
PLFM_M32R = 37 # Mitsubishi 32bit RISC
PLFM_NEC_78K0 = 38 # NEC 78K0
PLFM_NEC_78K0S = 39 # NEC 78K0S
PLFM_M740 = 40 # Mitsubishi 8bit
PLFM_M7700 = 41 # Mitsubishi 16bit
PLFM_ST9 = 42 # ST9+
PLFM_FR = 43 # Fujitsu FR Family
PLFM_MC6816 = 44 # Motorola 68HC16
PLFM_M7900 = 45 # Mitsubishi 7900
PLFM_TMS320C3 = 46 # Texas Instruments TMS320C3
PLFM_KR1878 = 47 # Angstrem KR1878
PLFM_AD218X = 48 # Analog Devices ADSP 218X
PLFM_OAKDSP = 49 # Atmel OAK DSP
PLFM_TLCS900 = 50 # Toshiba TLCS-900
PLFM_C39 = 51 # Rockwell C39
PLFM_CR16 = 52 # NSC CR16
PLFM_MN102L00 = 53 # Panasonic MN10200
PLFM_TMS320C1X = 54 # Texas Instruments TMS320C1x
PLFM_NEC_V850X = 55 # NEC V850 and V850ES/E1/E2
PLFM_SCR_ADPT = 56 # Processor module adapter for processor modules written in scripting languages
PLFM_EBC = 57 # EFI Bytecode
PLFM_MSP430 = 58 # Texas Instruments MSP430
PLFM_SPU = 59 # Cell Broadband Engine Synergistic Processor Unit
${PLFM_DECLS}
#
# processor_t.flag
+1 -1
View File
@@ -31,7 +31,7 @@ ssize_t idaapi IDB_Callback(void *ud, int notification_code, va_list va)
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
class IDB_Hooks *proxy = (class IDB_Hooks *)ud;
int ret = 0;
ssize_t ret = 0;
try
{
switch ( notification_code )
+89 -8
View File
@@ -55,7 +55,16 @@ static PyObject *py_register_timer(int interval, PyObject *py_callback)
PYW_GIL_GET;
py_timer_ctx_t *ctx = (py_timer_ctx_t *)ud;
newref_t py_result(PyObject_CallFunctionObjArgs(ctx->pycallback, NULL));
int ret = py_result == NULL ? -1 : PyLong_AsLong(py_result.o);
int ret = -1;
if ( PyErr_Occurred() )
{
msg("Exception in timer callback. This timer will be unregistered.\n");
PyErr_Print();
}
else if ( py_result != NULL )
{
ret = PyLong_AsLong(py_result.o);
}
// Timer has been unregistered?
if ( ret == -1 )
@@ -768,6 +777,43 @@ def is_idaq():
#</pydoc>
*/
struct jobj_wrapper_t
{
private:
const jobj_t *o;
public:
jobj_wrapper_t(const jobj_t *_o) : o(_o) {}
PyObject *get_dict()
{
newref_t json_module(PyImport_ImportModule("json"));
if ( json_module != NULL )
{
borref_t json_globals(PyModule_GetDict(json_module.o));
if ( json_globals != NULL )
{
borref_t json_loads(PyDict_GetItemString(json_globals.o, "loads"));
if ( json_loads != NULL )
{
qstring clob;
if ( serialize_json(&clob, o) )
{
newref_t dict(PyObject_CallFunction(json_loads.o, "s", clob.c_str()));
if ( dict != NULL )
{
dict.incref();
return dict.o;
}
}
}
}
}
Py_RETURN_NONE;
}
};
//---------------------------------------------------------------------------
// UI hooks
//---------------------------------------------------------------------------
@@ -903,9 +949,9 @@ public:
return idapython_unhook_from_notification_point(HT_UI, UI_Callback, this);
}
static int handle_get_ea_hint_output(PyObject *o, qstring *buf, ea_t)
static ssize_t handle_get_ea_hint_output(PyObject *o, qstring *buf, ea_t)
{
int rc = 0;
ssize_t rc = 0;
char *_buf;
Py_ssize_t _len;
if ( o != NULL && PyString_Check(o) && PyString_AsStringAndSize(o, &_buf, &_len) != -1 )
@@ -917,9 +963,9 @@ public:
return rc;
}
static int handle_hint_output(PyObject *o, qstring *hint, int *important_lines)
static ssize_t handle_hint_output(PyObject *o, qstring *hint, int *important_lines)
{
int rc = 0;
ssize_t rc = 0;
if ( o != NULL && PyTuple_Check(o) && PyTuple_Size(o) == 2 )
{
borref_t el0(PyTuple_GetItem(o, 0));
@@ -946,16 +992,32 @@ public:
return rc;
}
static int handle_hint_output(PyObject *o, qstring *hint, ea_t, int, int *important_lines)
static ssize_t handle_hint_output(PyObject *o, qstring *hint, ea_t, int, int *important_lines)
{
return handle_hint_output(o, hint, important_lines);
}
static int handle_hint_output(PyObject *o, qstring *hint, TWidget *, place_t *, int *important_lines)
static ssize_t handle_hint_output(PyObject *o, qstring *hint, TWidget *, place_t *, int *important_lines)
{
return handle_hint_output(o, hint, important_lines);
}
static jobj_wrapper_t wrap_widget_cfg(const jobj_t *jobj)
{
return jobj_wrapper_t(jobj);
}
static ssize_t handle_create_desktop_widget_output(PyObject *o)
{
if ( o == Py_None )
return 0;
TWidget *widget = NULL;
int cvt = SWIG_ConvertPtr(o, (void **) &widget, SWIGTYPE_p_TWidget, 0);
if ( !SWIG_IsOK(cvt) || widget == NULL )
return 0;
return ssize_t(widget);
}
// hookgenUI:methods
};
@@ -1206,6 +1268,11 @@ def error(format):
#</pydoc>
*/
static TWidget *TWidget__from_ptrval__(size_t ptrval)
{
return (TWidget *) ptrval;
}
//</inline(py_kernwin)>
//---------------------------------------------------------------------------
@@ -1216,7 +1283,7 @@ ssize_t idaapi UI_Callback(void *ud, int notification_code, va_list va)
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
UI_Hooks *proxy = (UI_Hooks *)ud;
int ret = 0;
ssize_t ret = 0;
try
{
switch ( notification_code )
@@ -1256,6 +1323,20 @@ bool idaapi py_menu_item_callback(void *userdata)
return PyObject_IsTrue(result.o) != 0;
}
/*
#<pydoc>
def get_navband_pixel(ea):
"""
Maps an address, onto a pixel coordinate within the navband
@param ea: The address to map
@return: a list [pixel, is_vertical]
"""
pass
#</pydoc>
*/
//</code(py_kernwin)>
#endif
+5 -8
View File
@@ -92,7 +92,7 @@ close_tform=close_widget
find_tform=find_widget
get_current_tform=get_current_widget
def get_highlighted_identifier():
thing = get_highlight(get_current_widget())
thing = get_highlight(get_current_viewer())
if thing and thing[1]:
return thing[0]
get_tform_title=get_widget_title
@@ -130,30 +130,27 @@ __wrap_uihooks_callback("populating_widget_popup", lambda cb, *args: cb(*args))
__wrap_uihooks_callback("finish_populating_widget_popup", lambda cb, *args: cb(*args))
__wrap_uihooks_callback("current_widget_changed", lambda cb, *args: cb(*args))
AskUsingForm=ask_form
AskUsingForm=_call_ask_form
HIST_ADDR=0
HIST_NUM=0
KERNEL_VERSION_MAGIC1=0
KERNEL_VERSION_MAGIC2=0
OpenForm=open_form
OpenForm=_call_open_form
_askaddr=_ida_kernwin._ask_addr
_asklong=_ida_kernwin._ask_long
_askseg=_ida_kernwin._ask_seg
askaddr=ask_addr
askbuttons_c=ask_buttons
askfile_c=ask_file
@bc695redef
def askfile2_c(forsave, defdir, filters, fmt):
if filters:
fmt = "FILTER %s\n%s" % (filters, fmt)
return ask_file(forsave, defdir, fmt)
askident=ask_ident
asklong=ask_long
@bc695redef
def askqstr(defval, fmt):
return ask_str(defval, 0, fmt)
askseg=ask_seg
@bc695redef
def askstr(hist, defval, fmt):
return ask_str(defval, hist, fmt)
asktext=ask_text
@@ -162,8 +159,8 @@ choose2_activate=choose_activate
choose2_close=choose_close
choose2_create=choose_create
choose2_find=choose_find
choose2_get_embedded=choose_get_embedded
choose2_get_embedded_selection=choose_get_embedded_selection
choose2_get_embedded=_choose_get_embedded_chobj_pointer
choose2_get_embedded_selection=lambda *args: None
choose2_refresh=choose_refresh
clearBreak=clr_cancelled
py_get_AskUsingForm=py_get_ask_form
+101 -113
View File
@@ -145,7 +145,6 @@ static PyObject *formchgcbfa_get_field_value(
{
// dropdown list
case 8:
{
// Readonly? Then return the selected index
if ( sz == 1 )
{
@@ -161,111 +160,101 @@ static PyObject *formchgcbfa_get_field_value(
return PyString_FromString(val.c_str());
}
break;
}
// multilinetext - tuple representing textctrl_info_t
case 7:
{
textctrl_info_t ti;
if ( fa->get_text_value(fid, &ti) )
return Py_BuildValue("(sII)", ti.text.c_str(), ti.flags, ti.tabsize);
break;
}
{
textctrl_info_t ti;
if ( fa->get_text_value(fid, &ti) )
return Py_BuildValue("(sII)", ti.text.c_str(), ti.flags, ti.tabsize);
break;
}
// button - uint32
case 4:
{
uval_t val;
if ( fa->get_unsigned_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
{
uval_t val;
if ( fa->get_unsigned_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
// ushort
case 2:
{
ushort val;
if ( fa->_get_field_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
{
ushort val;
if ( fa->_get_field_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
// string label
case 1:
{
char val[MAXSTR];
if ( fa->get_string_value(fid, val, sizeof(val)) )
return PyString_FromString(val);
break;
}
{
char val[MAXSTR];
if ( fa->get_string_value(fid, val, sizeof(val)) )
return PyString_FromString(val);
break;
}
// string input
case 3:
{
qstring val;
val.resize(sz + 1);
if ( fa->get_string_value(fid, val.begin(), val.size()) )
return PyString_FromString(val.begin());
break;
}
case 5:
{
sizevec_t selection;
if ( fa->get_chooser_value(fid, &selection) )
{
ref_t l(PyW_SizeVecToPyList(selection));
l.incref();
return l.o;
qstring val;
val.resize(sz + 1);
if ( fa->get_string_value(fid, val.begin(), val.size()) )
return PyString_FromString(val.begin());
break;
}
case 5:
{
sizevec_t selection;
if ( fa->get_chooser_value(fid, &selection) )
{
ref_t l(PyW_SizeVecToPyList(selection));
l.incref();
return l.o;
}
break;
}
break;
}
// Numeric control
case 6:
{
union
{
sel_t sel;
sval_t sval;
uval_t uval;
ulonglong ull;
} u;
switch ( sz )
{
case 'S': // sel_t
union
{
if ( fa->get_segment_value(fid, &u.sel) )
return Py_BuildValue(PY_BV_SEL, bvsel_t(u.sel));
break;
}
// sval_t
case 'n':
case 'D':
case 'O':
case 'Y':
case 'H':
sel_t sel;
sval_t sval;
uval_t uval;
ulonglong ull;
} u;
switch ( sz )
{
if ( fa->get_signed_value(fid, &u.sval) )
return Py_BuildValue(PY_BV_SVAL, bvsval_t(u.sval));
break;
}
case 'L': // uint64
case 'l': // int64
{
if ( fa->_get_field_value(fid, &u.ull) )
return Py_BuildValue("K", u.ull);
break;
}
case 'N':
case 'M': // uval_t
{
if ( fa->get_unsigned_value(fid, &u.uval) )
return Py_BuildValue(PY_BV_UVAL, bvuval_t(u.uval));
break;
}
case '$': // ea_t
{
if ( fa->get_ea_value(fid, &u.uval) )
return Py_BuildValue(PY_BV_UVAL, bvuval_t(u.uval));
break;
case 'S': // sel_t
if ( fa->get_segment_value(fid, &u.sel) )
return Py_BuildValue(PY_BV_SEL, bvsel_t(u.sel));
break;
// sval_t
case 'n':
case 'D':
case 'O':
case 'Y':
case 'H':
if ( fa->get_signed_value(fid, &u.sval) )
return Py_BuildValue(PY_BV_SVAL, bvsval_t(u.sval));
break;
case 'L': // uint64
case 'l': // int64
if ( fa->_get_field_value(fid, &u.ull) )
return Py_BuildValue("K", u.ull);
break;
case 'N':
case 'M': // uval_t
if ( fa->get_unsigned_value(fid, &u.uval) )
return Py_BuildValue(PY_BV_UVAL, bvuval_t(u.uval));
break;
case '$': // ea_t
if ( fa->get_ea_value(fid, &u.uval) )
return Py_BuildValue(PY_BV_UVAL, bvuval_t(u.uval));
break;
}
break;
}
break;
}
}
Py_RETURN_NONE;
}
@@ -284,7 +273,6 @@ static bool formchgcbfa_set_field_value(
{
// dropdown list
case 8:
{
// Editable dropdown list
if ( PyString_Check(py_val) )
{
@@ -298,47 +286,47 @@ static bool formchgcbfa_set_field_value(
return fa->set_combobox_value(fid, &sel_idx);
}
break;
}
// multilinetext - textctrl_info_t
case 7:
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(py_val);
return ti == NULL ? false : fa->set_text_value(fid, ti);
}
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(py_val);
return ti == NULL ? false : fa->set_text_value(fid, ti);
}
// button - uint32
case 4:
{
uval_t val = PyLong_AsUnsignedLong(py_val);
return fa->set_unsigned_value(fid, &val);
}
{
uval_t val = PyLong_AsUnsignedLong(py_val);
return fa->set_unsigned_value(fid, &val);
}
// ushort
case 2:
{
ushort val = PyLong_AsUnsignedLong(py_val) & 0xffff;
return fa->_set_field_value(fid, &val);
}
{
ushort val = PyLong_AsUnsignedLong(py_val) & 0xffff;
return fa->_set_field_value(fid, &val);
}
// strings
case 3:
case 1:
return fa->set_string_value(fid, PyString_AsString(py_val));
// intvec_t
case 5:
{
sizevec_t selection;
if ( !PySequence_Check(py_val)
|| PyW_PyListToSizeVec(&selection, py_val) < 0 )
{
break;
sizevec_t selection;
if ( !PySequence_Check(py_val)
|| PyW_PyListToSizeVec(&selection, py_val) < 0 )
{
break;
}
return fa->set_chooser_value(fid, &selection);
}
return fa->set_chooser_value(fid, &selection);
}
// Numeric
case 6:
{
uint64 num;
if ( PyW_GetNumber(py_val, &num) )
return fa->_set_field_value(fid, &num);
}
{
uint64 num;
if ( PyW_GetNumber(py_val, &num) )
return fa->_set_field_value(fid, &num);
}
}
return false;
}
+22 -20
View File
@@ -687,9 +687,12 @@ class Form(object):
# Construct input control
Form.InputControl.__init__(self, Form.FT_ECHOOSER, "", swidth)
self.selobj = ida_pro.sizevec_t()
# Get a pointer to the chooser_info_t and the selection vector
# (These two parameters are the needed arguments for the ask_form())
emb, sel = _ida_kernwin.choose_get_embedded(chooser)
emb = _ida_kernwin._choose_get_embedded_chobj_pointer(chooser)
sel = self.selobj.this.__long__()
# Get a pointer to a c_void_p constructed from an address
p_embedded = ctypes.pointer(ctypes.c_void_p.from_address(emb))
@@ -711,6 +714,14 @@ class Form(object):
value = property(lambda self: self.chooser)
"""Returns the embedded chooser instance"""
def __get_selection__(self):
if len(self.selobj):
out = []
for item in self.selobj:
out.append(int(item))
return out
selection = property(__get_selection__)
"""Returns the selection"""
def free(self):
"""
@@ -1179,7 +1190,7 @@ class Form(object):
if not self.modal:
raise SyntaxError("Form is not modal. Open() should be instead")
return ask_form(*self.__args)
return _call_ask_form(*self.__args)
def Open(self):
@@ -1190,7 +1201,7 @@ class Form(object):
if self.modal:
raise SyntaxError("Form is modal. Execute() should be instead")
open_form(*self.__args)
_call_open_form(*self.__args)
def EnableField(self, ctrl, enable):
@@ -1334,33 +1345,24 @@ try:
import ctypes
# Setup the numeric argument size
Form.NumericArgument.DefI64 = _ida_idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL
ask_form__ = ctypes.CFUNCTYPE(ctypes.c_long)(_ida_kernwin.py_get_ask_form())
open_form__ = ctypes.CFUNCTYPE(ctypes.c_long)(_ida_kernwin.py_get_open_form())
__ask_form_callable = ctypes.CFUNCTYPE(ctypes.c_long)(_ida_kernwin.py_get_ask_form())
__open_form_callable = ctypes.CFUNCTYPE(ctypes.c_long)(_ida_kernwin.py_get_open_form())
except:
def ask_form__(*args):
def __ask_form_callable(*args):
warning("ask_form() needs ctypes library in order to work")
return 0
def open_form__(*args):
def __open_form_callable(*args):
warning("open_form() needs ctypes library in order to work")
def ask_form(*args):
"""
Calls ask_form()
@param: Compiled Arguments obtain through the Form.Compile() function
@return: 1 = ok, 0 = cancel
"""
def _call_ask_form(*args):
old = _ida_idaapi.set_script_timeout(0)
r = ask_form__(*args)
r = __ask_form_callable(*args)
_ida_idaapi.set_script_timeout(old)
return r
def open_form(*args):
"""
Calls open_form()
@param: Compiled Arguments obtain through the Form.Compile() function
"""
def _call_open_form(*args):
old = _ida_idaapi.set_script_timeout(0)
r = open_form__(*args)
r = __open_form_callable(*args)
_ida_idaapi.set_script_timeout(old)
#</pycode(py_kernwin_askform)>
+8 -34
View File
@@ -28,7 +28,7 @@ void choose_del_instance(PyObject *self)
}
// set `prm` to the integer value of the `name` attribute
template<class T>
template <class T>
static void py_get_int(PyObject *self, T *prm, const char *name)
{
ref_t attr(PyW_TryGetAttrString(self, name));
@@ -66,8 +66,6 @@ public:
// One of CHOOSE_xxxx
uint32 cb_flags;
sizevec_t embedded_sel;
// Chooser title
qstring title;
@@ -243,11 +241,6 @@ public:
return chobj;
}
const sizevec_t *get_sel_vec() const
{
return &embedded_sel;
}
bool is_valid() const
{
return chobj != NULL;
@@ -781,33 +774,15 @@ void choose_activate(PyObject *self)
}
//------------------------------------------------------------------------
PyObject *choose_get_embedded_selection(PyObject *self)
// Return the C instance as 64bit number
uint64 _choose_get_embedded_chobj_pointer(PyObject *self)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
uint64 ptr = 0;
py_choose_t *pych = choose_find_instance(self);
if ( pych == NULL || !pych->is_valid() || !pych->is_embedded() )
Py_RETURN_NONE;
ref_t ret(PyW_SizeVecToPyList(*pych->get_sel_vec()));
ret.incref();
return ret.o;
}
//------------------------------------------------------------------------
// Return the C instances as 64bit numbers
PyObject *choose_get_embedded(PyObject *self)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
py_choose_t *pych = choose_find_instance(self);
if ( pych == NULL || !pych->is_valid() || !pych->is_embedded() )
Py_RETURN_NONE;
return Py_BuildValue(
"(KK)",
PTR2U64(pych->get_chobj()),
PTR2U64(pych->get_sel_vec()));
if ( pych != NULL && pych->is_valid() && pych->is_embedded() )
ptr = uint64(pych->get_chobj());
return ptr;
}
//------------------------------------------------------------------------
@@ -829,8 +804,7 @@ void choose_refresh(PyObject *self);
void choose_close(PyObject *self);
int choose_create(PyObject *self);
void choose_activate(PyObject *self);
PyObject *choose_get_embedded(PyObject *self);
PyObject *choose_get_embedded_selection(PyObject *self);
uint64 _choose_get_embedded_chobj_pointer(PyObject *self);
PyObject *py_get_chooser_data(const char *chooser_caption, int n)
{
+19 -14
View File
@@ -32,6 +32,18 @@ class Choose(object):
default one
"""
CH_CAN_INS = 0x000100
"""allow to insert new items"""
CH_CAN_DEL = 0x000200
"""allow to delete existing item(s)"""
CH_CAN_EDIT = 0x000400
"""allow to edit existing item(s)"""
CH_CAN_REFRESH = 0x000800
"""allow to refresh chooser"""
CH_QFLT = 0x1000
"""open with quick filter enabled and focused"""
@@ -43,14 +55,10 @@ class Choose(object):
CH_QFTYP_FUZZY = 4 << CH_QFTYP_SHIFT
CH_QFTYP_MASK = 0x7 << CH_QFTYP_SHIFT
CH_CAN_INS = 0x000100
"""allow to insert new items"""
CH_CAN_DEL = 0x000200
"""allow to delete existing item(s)"""
CH_CAN_EDIT = 0x000400
"""allow to edit existing item(s)"""
CH_CAN_REFRESH = 0x000800
"""allow to refresh chooser"""
CH_NO_STATUS_BAR = 0x00010000
"""don't show a status bar"""
CH_RESTORE = 0x00020000
"""restore floating position if present (equivalent of WOPN_RESTORE) (GUI version only)"""
CH_BUILTIN_SHIFT = 19
CH_BUILTIN_MASK = 0x1F << CH_BUILTIN_SHIFT
@@ -159,13 +167,10 @@ class Choose(object):
def GetEmbSelection(self):
"""
Returns the selection associated with an embedded chooser
@return:
- None if chooser is not embedded
- A list with selection indexes (0-based)
Deprecated. For embedded choosers, the selection is
available through 'Form.EmbeddedChooserControl.selection'
"""
return _ida_kernwin.choose_get_embedded_selection(self)
return None
def Show(self, modal=False):
+38 -62
View File
@@ -150,11 +150,10 @@ protected:
{
HAVE_HINT = 0x0001,
HAVE_KEYDOWN = 0x0002,
HAVE_POPUP = 0x0004,
HAVE_DBLCLICK = 0x0008,
HAVE_CURPOS = 0x0010,
HAVE_CLICK = 0x0020,
HAVE_CLOSE = 0x0040
HAVE_DBLCLICK = 0x0004,
HAVE_CURPOS = 0x0008,
HAVE_CLICK = 0x0010,
HAVE_CLOSE = 0x0020
};
private:
struct cvw_popupctx_t
@@ -179,14 +178,6 @@ private:
return _this->on_keydown(vk_key, shift);
}
// The popup menu is being constructed
static void idaapi s_cv_popup(TWidget * /*cv*/, void *ud)
{
PYW_GIL_GET;
customviewer_t *_this = (customviewer_t *)ud;
_this->on_popup();
}
// The user clicked
static bool idaapi s_cv_click(TWidget * /*cv*/, int shift, void *ud)
{
@@ -219,30 +210,33 @@ private:
customviewer_t *_this = (customviewer_t *)ud;
switch ( code )
{
case ui_get_custom_viewer_hint:
{
qstring &hint = *va_arg(va, qstring *);
TWidget *viewer = va_arg(va, TWidget *);
place_t *place = va_arg(va, place_t *);
int *important_lines = va_arg(va, int *);
if ( (_this->_features & HAVE_HINT) == 0 || place == NULL || _this->_cv != viewer )
return 0;
else
case ui_get_custom_viewer_hint:
{
qstring &hint = *va_arg(va, qstring *);
TWidget *viewer = va_arg(va, TWidget *);
place_t *place = va_arg(va, place_t *);
int *important_lines = va_arg(va, int *);
if ( (_this->_features & HAVE_HINT) == 0
|| place == NULL
|| _this->_cv != viewer )
{
return 0;
}
return _this->on_hint(place, important_lines, hint) ? 1 : 0;
}
}
case ui_widget_invisible:
{
TWidget *widget = va_arg(va, TWidget *);
if ( _this->_cv != widget )
break;
}
// fallthrough...
case ui_term:
idapython_unhook_from_notification_point(HT_UI, s_ui_cb, _this);
_this->on_close();
_this->on_post_close();
break;
case ui_widget_invisible:
{
TWidget *widget = va_arg(va, TWidget *);
if ( _this->_cv != widget )
break;
}
// fallthrough...
case ui_term:
idapython_unhook_from_notification_point(HT_UI, s_ui_cb, _this);
_this->on_close();
_this->on_post_close();
break;
}
return 0;
@@ -276,9 +270,6 @@ public:
// OnKeyDown
virtual bool on_keydown(int /*vk_key*/, int /*shift*/) { return false; }
// OnPopupShow
virtual bool on_popup() { return false; }
// OnHint
virtual bool on_hint(place_t * /*place*/, int * /*important_lines*/, qstring &/*hint*/) { return false; }
@@ -425,9 +416,6 @@ public:
if ( (features & HAVE_KEYDOWN) != 0 )
handlers.keyboard = s_cv_keydown;
if ( (features & HAVE_POPUP) != 0 )
handlers.popup = s_cv_popup;
if ( (features & HAVE_CLICK) != 0 )
handlers.click = s_cv_click;
@@ -461,7 +449,7 @@ public:
if ( _cv == NULL )
return false;
display_widget(_cv, WOPN_TAB|WOPN_MENU|WOPN_RESTORE);
display_widget(_cv, WOPN_TAB|WOPN_RESTORE);
return true;
}
};
@@ -554,12 +542,15 @@ private:
// OnHostFormClose
virtual void on_close()
{
// Call the close method if it is there and the object is still bound
if ( (features & HAVE_CLOSE) != 0 && py_self != NULL )
if ( py_self != NULL )
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_result(PyObject_CallMethod(py_self, (char *)S_ON_CLOSE, NULL));
PyW_ShowCbErr(S_ON_CLOSE);
// Call the close method if it is there and the object is still bound
if ( (features & HAVE_CLOSE) != 0 )
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_result(PyObject_CallMethod(py_self, (char *)S_ON_CLOSE, NULL));
PyW_ShowCbErr(S_ON_CLOSE);
}
// Cleanup
Py_DECREF(py_self);
@@ -584,20 +575,6 @@ private:
return py_result != NULL && PyObject_IsTrue(py_result.o);
}
//--------------------------------------------------------------------------
// OnPopupShow
virtual bool on_popup()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_result(
PyObject_CallMethod(
py_self,
(char *)S_ON_POPUP,
NULL));
PyW_ShowCbErr(S_ON_POPUP);
return py_result != NULL && PyObject_IsTrue(py_result.o);
}
//--------------------------------------------------------------------------
// OnHint
virtual bool on_hint(place_t *place, int *important_lines, qstring &hint)
@@ -763,7 +740,6 @@ public:
{ S_ON_CLOSE, HAVE_CLOSE },
{ S_ON_HINT, HAVE_HINT },
{ S_ON_KEYDOWN, HAVE_KEYDOWN },
{ S_ON_POPUP, HAVE_POPUP },
{ S_ON_DBL_CLICK, HAVE_DBLCLICK },
{ S_ON_CURSOR_POS_CHANGED, HAVE_CURPOS }
};
+26 -7
View File
@@ -2,8 +2,27 @@
#<pycode(py_kernwin_custview)>
class simplecustviewer_t(object):
"""The base class for implementing simple custom viewers"""
class UI_Hooks_Trampoline(UI_Hooks):
def __init__(self, v):
UI_Hooks.__init__(self)
self.hook()
import weakref
self.v = weakref.ref(v)
def populating_widget_popup(self, form, popup_handle):
my_form = self.v().GetWidget()
if form == my_form:
cb = self.v().OnPopup
from inspect import getargspec
if len(getargspec(cb).args) == 3:
cb(my_form, popup_handle)
else:
cb() # bw-compat
def __init__(self):
self.__this = None
self.ui_hooks_trampoline = self.UI_Hooks_Trampoline(self)
def __del__(self):
"""Destructor. It also frees the associated C++ object"""
@@ -16,6 +35,13 @@ class simplecustviewer_t(object):
def __make_sl_arg(line, fgcolor=None, bgcolor=None):
return line if (fgcolor is None and bgcolor is None) else (line, fgcolor, bgcolor)
def OnPopup(self, form, popup_handle):
"""
Context menu popup is about to be shown. Create items dynamically if you wish
@return: Boolean. True if you handled the event
"""
pass
def Create(self, title):
"""
Creates the custom view. This should be the first method called after instantiation
@@ -200,13 +226,6 @@ class simplecustviewer_t(object):
# print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# return False
#
# def OnPopup(self):
# """
# Context menu popup is about to be shown. Create items dynamically if you wish
# @return: Boolean. True if you handled the event
# """
# print "OnPopup"
#
# def OnHint(self, lineno):
# """
# Hint requested for the given line number.
+31 -25
View File
@@ -5,7 +5,6 @@
//---------------------------------------------------------------------------
class plgform_t
{
private:
ref_t py_obj;
TWidget *widget;
@@ -15,24 +14,7 @@ private:
PYW_GIL_GET;
plgform_t *_this = (plgform_t *)ud;
if ( notification_code == ui_widget_visible )
{
TWidget *widget = va_arg(va, TWidget *);
if ( widget == _this->widget )
{
// Qt: QWidget*
// G: HWND
// We wrap and pass as a CObject in the hope that a Python UI framework
// can unwrap a CObject and get the hwnd/widget back
newref_t py_result(
PyObject_CallMethod(
_this->py_obj.o,
(char *)S_ON_CREATE, "O",
PyCObject_FromVoidPtr(widget, NULL)));
PyW_ShowCbErr(S_ON_CREATE);
}
}
else if ( notification_code == ui_widget_invisible )
if ( notification_code == ui_widget_invisible )
{
TWidget *widget = va_arg(va, TWidget *);
if ( widget == _this->widget )
@@ -62,15 +44,15 @@ private:
}
public:
plgform_t(): widget(NULL)
{
}
plgform_t() : widget(NULL) {}
bool show(
PyObject *obj,
const char *caption,
int options)
{
const bool create_only = options == -1;
// Already displayed?
TWidget *f = find_widget(caption);
if ( f != NULL )
@@ -79,7 +61,8 @@ public:
if ( f == widget )
{
// Switch to it
activate_widget(widget, true);
if ( !create_only )
activate_widget(widget, true);
return true;
}
// Fail to create
@@ -100,7 +83,20 @@ public:
py_obj = borref_t(obj);
this->widget = widget;
display_widget(widget, options);
// Qt: QWidget*
// G: HWND
// We wrap and pass as a CObject in the hope that a Python UI framework
// can unwrap a CObject and get the hwnd/widget back
newref_t py_result(
PyObject_CallMethod(
py_obj.o,
(char *)S_ON_CREATE, "O",
PyCObject_FromVoidPtr(widget, NULL)));
PyW_ShowCbErr(S_ON_CREATE);
if ( !create_only )
display_widget(widget, options);
return true;
}
@@ -110,6 +106,8 @@ public:
close_widget(widget, options);
}
TWidget *get_widget() { return widget; }
static PyObject *create()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
@@ -135,7 +133,7 @@ static bool plgform_show(
PyObject *py_link,
PyObject *py_obj,
const char *caption,
int options = WOPN_TAB|WOPN_MENU|WOPN_RESTORE)
int options = WOPN_TAB|WOPN_RESTORE)
{
DECL_PLGFORM;
return plgform->show(py_obj, caption, options);
@@ -148,6 +146,14 @@ static void plgform_close(
DECL_PLGFORM;
plgform->close(options);
}
static TWidget *plgform_get_widget(
PyObject *py_link)
{
DECL_PLGFORM;
return plgform->get_widget();
}
#undef DECL_PLGFORM
//</inline(py_kernwin_plgform)>
+58 -24
View File
@@ -7,66 +7,90 @@ class PluginForm(object):
This form can be used to host additional controls. Please check the PyQt example.
"""
WOPN_MDI = 0x01
"""start by default as MDI (obsolete)"""
WOPN_MDI = 0x01 # no-op
WOPN_TAB = 0x02
"""attached by default to a tab"""
WOPN_RESTORE = 0x04
"""restore state from desktop config"""
WOPN_ONTOP = 0x08
"""form should be "ontop"""
WOPN_MENU = 0x10
"""form must be listed in the windows menu (automatically set for all plugins)"""
WOPN_CENTERED = 0x20
"""form will be centered on the screen"""
"""
if the widget is the only widget in a floating area when
it is closed, remember that area's geometry. The next
time that widget is created as floating (i.e., no WOPN_TAB)
its geometry will be restored (e.g., "Execute script"
"""
WOPN_ONTOP = 0x08 # no-op
WOPN_MENU = 0x10 # no-op
WOPN_CENTERED = 0x20 # no-op
WOPN_PERSIST = 0x40
"""form will persist until explicitly closed with Close()"""
WOPN_CREATE_ONLY = {}
def __init__(self):
"""
"""
self.__clink__ = _ida_kernwin.plgform_new()
def Show(self, caption, options = 0):
def Show(self, caption, options=0):
"""
Creates the form if not was not created or brings to front if it was already created
@param caption: The form caption
@param options: One of PluginForm.WOPN_ constants
"""
options |= PluginForm.WOPN_TAB|PluginForm.WOPN_MENU|PluginForm.WOPN_RESTORE
if options == self.WOPN_CREATE_ONLY:
options = -1
else:
options |= PluginForm.WOPN_TAB|PluginForm.WOPN_RESTORE
return _ida_kernwin.plgform_show(self.__clink__, self, caption, options)
@staticmethod
def FormToPyQtWidget(form, ctx = sys.modules['__main__']):
"""
Use this method to convert a TWidget* to a QWidget to be used by PyQt
def _ensure_widget_deps(ctx):
for key, modname in [("sip", "sip"), ("QtWidgets", "PyQt5.QtWidgets")]:
if not hasattr(ctx, key):
print "Note: importing '%s' module into %s" % (key, ctx)
import importlib
setattr(ctx, key, importlib.import_module(modname))
@param ctx: Context. Reference to a module that already imported SIP and QtGui modules
@staticmethod
def TWidgetToPyQtWidget(form, ctx = sys.modules['__main__']):
"""
Convert a TWidget* to a QWidget to be used by PyQt
@param ctx: Context. Reference to a module that already imported SIP and QtWidgets modules
"""
if type(form).__name__ == "SwigPyObject":
ptr_l = long(form)
else:
ptr_l = form
for key, modname in [("sip", "sip"), ("QtWidgets", "PyQt5.QtWidgets")]:
if not hasattr(ctx, key):
print "Note: FormToPyQtWidget: importing '%s' module into %s" % (key, ctx)
import importlib
setattr(ctx, key, importlib.import_module(modname))
PluginForm._ensure_widget_deps(ctx)
vptr = ctx.sip.voidptr(ptr_l)
return ctx.sip.wrapinstance(vptr.__int__(), ctx.QtWidgets.QWidget)
FormToPyQtWidget = TWidgetToPyQtWidget
@staticmethod
def FormToPySideWidget(form, ctx = sys.modules['__main__']):
def QtWidgetToTWidget(w, ctx = sys.modules['__main__']):
"""
Convert a QWidget to a TWidget* to be used by IDA
@param ctx: Context. Reference to a module that already imported SIP and QtWidgets modules
"""
PluginForm._ensure_widget_deps(ctx)
as_long = long(ctx.sip.unwrapinstance(w))
return TWidget__from_ptrval__(as_long)
@staticmethod
def TWidgetToPySideWidget(form, ctx = sys.modules['__main__']):
"""
Use this method to convert a TWidget* to a QWidget to be used by PySide
@param ctx: Context. Reference to a module that already imported QtGui module
@param ctx: Context. Reference to a module that already imported QtWidgets module
"""
if form is None:
return None
@@ -82,7 +106,7 @@ class PluginForm(object):
pythonapi.PyCObject_AsVoidPtr.argtypes = [c_void_p, c_void_p]
form = pythonapi.PyCObject_FromVoidPtr(ptr_l, 0)
return ctx.QtGui.QWidget.FromCObject(form)
FormToPySideWidget = TWidgetToPySideWidget
def OnCreate(self, form):
"""
@@ -113,6 +137,16 @@ class PluginForm(object):
"""
return _ida_kernwin.plgform_close(self.__clink__, options)
def GetWidget(self):
"""
Return the TWidget underlying this view.
@return: The TWidget underlying this view, or None.
"""
return _ida_kernwin.plgform_get_widget(self.__clink__)
WCLS_SAVE = 0x1
"""Save state in desktop config"""
+1 -1
View File
@@ -31,7 +31,7 @@ ssize_t idaapi View_Callback(void *ud, int notification_code, va_list va)
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
class View_Hooks *proxy = (class View_Hooks *)ud;
int ret = 0;
ssize_t ret = 0;
try
{
switch ( notification_code )
+13
View File
@@ -49,8 +49,11 @@ def load_plugin(name):
*/
static PyObject *py_load_plugin(const char *name)
{
if ( qfileexist(name) )
prepare_programmatic_plugin_load(name);
plugin_t *r = load_plugin(name);
PYW_GIL_CHECK_LOCKED_SCOPE();
prepare_programmatic_plugin_load(NULL);
if ( r == NULL )
Py_RETURN_NONE;
else
@@ -87,6 +90,16 @@ static bool py_run_plugin(PyObject *plg, int arg)
}
}
//------------------------------------------------------------------------
static bool py_load_and_run_plugin(const char *name, size_t arg)
{
if ( qfileexist(name) )
prepare_programmatic_plugin_load(name);
bool rc = load_and_run_plugin(name, arg);
prepare_programmatic_plugin_load(NULL);
return rc;
}
//</inline(py_loader)>
#endif
+3 -2
View File
@@ -6,6 +6,9 @@ def get_switch_info(*args):
else:
si, ea = args
return None if _real_get_switch_info(si, ea) <= 0 else si
def get_abi_name(*args):
import ida_typeinf
return ida_typeinf.get_abi_name(args)
#</pycode(py_nalt)>
#<pycode_BC695(py_nalt)>
@@ -28,7 +31,6 @@ SWI2_SUBTRACT=SWI_SUBTRACT >> 16
import ida_netnode
RIDX_AUTO_PLUGINS=ida_netnode.BADNODE
change_encoding_name=rename_encoding
@bc695redef
def del_tinfo2(ea, n=None):
if n is not None:
return del_op_tinfo(ea, n)
@@ -43,7 +45,6 @@ def get_op_tinfo(*args):
tif, ea, n = args
return _ida_nalt.get_op_tinfo(tif, ea, n)
get_op_tinfo2=get_op_tinfo
@bc695redef
def is_unicode(strtype):
return (strtype & STRWIDTH_MASK) > 0
set_op_tinfo2=set_op_tinfo
+1 -1
View File
@@ -5,7 +5,7 @@
//------------------------------------------------------------------------
//<inline(py_name)>
//------------------------------------------------------------------------
PyObject *py_get_debug_names(ea_t ea1, ea_t ea2)
PyObject *get_debug_names(ea_t ea1, ea_t ea2)
{
// Get debug names
ea_name_vec_t names;
+1 -6
View File
@@ -76,12 +76,10 @@ GN_INSNLOC=0
def demangle_name(name, mask, demreq=DQT_FULL): # make flag optional, so demangle_name & demangle_name2 can use it
return _ida_name.demangle_name(name, mask, demreq)
demangle_name2=demangle_name
@bc695redef
def do_name_anyway(ea, name, maxlen=0):
return force_name(ea, name)
extract_name2=extract_name
get_debug_name2=get_debug_name
@bc695redef
def get_true_name(ea0, ea1=None):
if ea1 is None:
ea = ea0
@@ -90,21 +88,18 @@ def get_true_name(ea0, ea1=None):
return get_name(ea)
is_ident_char=is_ident_cp
is_visible_char=is_visible_cp
@bc695redef
def make_visible_name(name, sz=0):
if sz > 0:
name = name[0:sz]
return _ida_name.validate_name(name, VNT_VISIBLE)
@bc695redef
def validate_name2(name, sz=0):
if sz > 0:
name = name[0:sz]
return _ida_name.validate_name(name, VNT_IDENT)
@bc695redef
def validate_name3(name):
return _ida_name.validate_name(name, VNT_IDENT)
isident=is_ident
@bc695redef_with_pydoc(get_name.__doc__)
@bc695redef
def get_name(*args):
if len(args) == 2:
if args[0] != _ida_idaapi.BADADDR:
-1
View File
@@ -2,7 +2,6 @@
#<pycode_BC695(py_offset)>
calc_reference_basevalue=calc_basevalue
calc_reference_target=calc_target
@bc695redef
def set_offset(ea, n, base):
import ida_idaapi
otype = get_default_reftype(ea)
+13 -4
View File
@@ -1,10 +1,21 @@
#<pycode(py_pro)>
import ida_idaapi
int64vec_t = longlongvec_t
uint64vec_t = ulonglongvec_t
if ida_idaapi.__EA64__:
svalvec_t = longlongvec_t
uvalvec_t = ulonglongvec_t
else:
svalvec_t = intvec_t
uvalvec_t = uintvec_t
ida_idaapi._listify_types(
uvalvec_t,
intvec_t,
int64vec_t,
uintvec_t,
longlongvec_t,
ulonglongvec_t,
boolvec_t,
strvec_t)
@@ -87,10 +98,8 @@ class _qstrvec_t(ida_idaapi.py_clinked_object_t):
#</pycode(py_pro)>
#<pycode_BC695(py_pro)>
@bc695redef
def strlwr(s):
return str(s).lower()
@bc695redef
def strupr(s):
return str(s).upper()
#</pycode_BC695(py_pro)>
-2
View File
@@ -23,10 +23,8 @@ QueueGetMessage=get_problem_desc
QueueGetType=get_problem
QueueIsPresent=is_problem_present
QueueSet=remember_problem
@bc695redef
def get_long_queue_name(t):
return get_problem_name(t, True)
@bc695redef
def get_short_queue_name(t):
return get_problem_name(t, False)
#</pycode_BC695(py_problems)>
+2 -2
View File
@@ -38,11 +38,11 @@ ea_t segment_t_end_ea_get(segment_t *segm)
//<inline(py_segment)>
sel_t get_defsr(segment_t *s, int reg)
{
return s->defsr[reg];
return s->defsr[reg];
}
void set_defsr(segment_t *s, int reg, sel_t value)
{
s->defsr[reg] = value;
s->defsr[reg] = value;
}
int py_rebase_program(PyObject *delta, int flags)
{
-1
View File
@@ -5,7 +5,6 @@ SEGDEL_KEEP=SEGMOD_KEEP
SEGDEL_KEEP0=SEGMOD_KEEP0
SEGDEL_PERM=SEGMOD_KILL
SEGDEL_SILENT=SEGMOD_SILENT
@bc695redef
def del_segment_cmt(s, rpt):
set_segment_cmt(s, "", rpt)
ask_selector=sel2para
+2 -2
View File
@@ -399,7 +399,7 @@ PyObject *py_pack_object_to_bv(
NULL,
pio_flags);
if ( err == eOk && !bytes.relocate(base_ea, inf.is_be()) )
err = -1;
err = -1;
Py_END_ALLOW_THREADS;
if ( err == eOk )
return Py_BuildValue("(is#)", 1, bytes.begin(), bytes.size());
@@ -481,7 +481,7 @@ int idc_set_local_type(int ordinal, const char *dcl, int flags)
if ( dcl == NULL || dcl[0] == '\0' )
{
if ( !del_numbered_type(NULL, ordinal) )
return 0;
return 0;
}
else
{
+1 -8
View File
@@ -17,7 +17,6 @@ TERR_TOOLONGNAME=TERR_WRONGNAME
def add_til(name, flags=0):
return _ida_typeinf.add_til(name, flags)
add_til2=add_til
@bc695redef
def apply_decl(arg0, arg1, arg2=None, arg3=0):
if type(arg0) in [int, long]: # old apply_cdecl()
return _ida_typeinf.apply_cdecl(cvar.idati, arg0, arg1, 0)
@@ -30,7 +29,6 @@ calc_c_cpp_name4=calc_c_cpp_name
import ida_idaapi
callregs_init_regs=ida_idaapi._BC695.dummy
choose_local_type=choose_local_tinfo
@bc695redef
def choose_named_type2(root_til, title, ntf_flags, func, out_sym):
class func_pred_t(predicate_t):
def __init__(self, func):
@@ -45,15 +43,13 @@ extract_varloc=extract_argloc
const_vloc_visitor_t=const_aloc_visitor_t
for_all_const_varlocs=for_all_const_arglocs
for_all_varlocs=for_all_arglocs
@bc695redef
def gen_decorate_name3(name, mangle, cc):
return gen_decorate_name(name, mangle, cc, None) # ATM gen_decorate_name doesn't use its tinfo_t
get_enum_member_expr2=get_enum_member_expr
get_idainfo_by_type3=get_idainfo_by_type
@bc695redef
def guess_func_tinfo2(pfn, tif):
return guess_tinfo(pfn.start_ea, tif)
@bc695redef_with_pydoc(load_til.__doc__)
@bc695redef
def load_til(name, tildir=None, *args):
# 6.95 C++ prototypes
# idaman til_t *ida_export load_til(const char *tildir, const char *name, char *errbuf, size_t bufsize);
@@ -76,7 +72,6 @@ def load_til(name, tildir=None, *args):
load_til2=load_til
lower_type2=lower_type
optimize_varloc=optimize_argloc
@bc695redef
def parse_decl2(til, decl, tif, flags):
return _ida_typeinf.parse_decl(tif, til, decl, flags)
@bc695redef
@@ -84,12 +79,10 @@ def print_type(ea, flags):
if isinstance(flags, bool):
flags = PRTYPE_1LINE if flags else 0
return _ida_typeinf.print_type(ea, flags)
@bc695redef
def print_type2(ea, flags):
return _ida_typeinf.print_type(ea, flags)
print_type3=_ida_typeinf.print_type
print_varloc=print_argloc
@bc695redef
def resolve_typedef2(til, p, *args):
return _ida_typeinf.resolve_typedef(til, p)
scattered_vloc_t=scattered_aloc_t
+21 -6
View File
@@ -83,16 +83,31 @@ static int py_get_dtype_by_size(asize_t size)
}
//-------------------------------------------------------------------------
PyObject *py_get_immvals(ea_t ea, int n)
PyObject *py_get_immvals(ea_t ea, int n, flags_t F=0)
{
uvalvec_t storage;
storage.resize(2 * UA_MAXOP);
flags_t F = get_flags(ea);
if ( F == 0 )
F = get_flags(ea);
size_t cnt = get_immvals(storage.begin(), ea, n, F);
PyObject *result = PyList_New(cnt);
for ( size_t i = 0; i < cnt; ++i )
PyList_SetItem(result, i, Py_BuildValue(PY_BV_UVAL, bvuval_t(storage[i])));
return result;
storage.resize(cnt);
ref_t result(PyW_UvalVecToPyList(storage));
result.incref();
return result.o;
}
//-------------------------------------------------------------------------
PyObject *py_get_printable_immvals(ea_t ea, int n, flags_t F=0)
{
uvalvec_t storage;
storage.resize(2 * UA_MAXOP);
if ( F == 0 )
F = get_flags(ea);
size_t cnt = get_printable_immvals(storage.begin(), ea, n, F);
storage.resize(cnt);
ref_t result(PyW_UvalVecToPyList(storage));
result.incref();
return result.o;
}
//-------------------------------------------------------------------------
+4 -12
View File
@@ -4,7 +4,6 @@ ua_mnem = print_insn_mnem
#<pycode_BC695(py_ua)>
import ida_idaapi
@bc695redef
def codeSeg(ea, opnum):
insn = insn_t()
if decode_insn(insn, ea):
@@ -17,7 +16,7 @@ get_dtyp_size=get_dtype_size
get_operand_immvals=get_immvals
op_t.dtyp = op_t.dtype
cmd = insn_t()
@bc695redef_with_pydoc(decode_insn.__doc__)
@bc695redef
def decode_insn(*args):
if len(args) == 1:
tmp = insn_t()
@@ -26,7 +25,7 @@ def decode_insn(*args):
return rc
else:
return _ida_ua.decode_insn(*args)
@bc695redef_with_pydoc(create_insn.__doc__)
@bc695redef
def create_insn(*args):
if len(args) == 1:
tmp = insn_t()
@@ -35,7 +34,7 @@ def create_insn(*args):
return rc
else:
return _ida_ua.create_insn(*args)
@bc695redef_with_pydoc(decode_prev_insn.__doc__)
@bc695redef
def decode_prev_insn(*args):
if len(args) == 1:
tmp = insn_t()
@@ -44,7 +43,7 @@ def decode_prev_insn(*args):
return rc
else:
return _ida_ua.decode_prev_insn(*args)
@bc695redef_with_pydoc(decode_preceding_insn.__doc__)
@bc695redef
def decode_preceding_insn(*args):
if len(args) == 1:
tmp = insn_t()
@@ -62,25 +61,18 @@ tbo_213=0
tbo_231=0
tbo_312=0
tbo_321=0
@bc695redef
def ua_add_cref(opoff, to, rtype):
return cmd.add_cref(to, opoff, rtype)
@bc695redef
def ua_add_dref(opoff, to, rtype):
return cmd.add_dref(to, opoff, rtype)
@bc695redef
def ua_add_off_drefs(x, rtype):
return cmd.add_off_drefs(x, rtype, 0)
@bc695redef
def ua_add_off_drefs2(x, rtype, outf):
return cmd.add_off_drefs(x, rtype, outf)
@bc695redef
def ua_dodata(ea, dtype):
return cmd.create_op_data(ea, 0, dtype)
@bc695redef
def ua_dodata2(opoff, ea, dtype):
return cmd.create_op_data(ea, opoff, dtype)
@bc695redef
def ua_stkvar2(x, v, flags):
return cmd.create_stkvar(x, v, flags)
#</pycode_BC695(py_ua)>
-1
View File
@@ -3,7 +3,6 @@
//<inline(py_xref)>
// important for SWiG to generate properly-wrapped vector classes
typedef qvector<sval_t> svalvec_t;
typedef qvector<svalvec_t> casevec_t;
typedef qvector<ea_t> eavec_t;
//
+6 -6
View File
@@ -50,7 +50,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\include;c:\python26\include"
PreprocessorDefinitions="_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;__PYWRAPS__;_PYWRAPS_DEBUG"
PreprocessorDefinitions="_DEBUG;__NT__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;__PYWRAPS__;_PYWRAPS_DEBUG"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -151,7 +151,7 @@
Optimization="0"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\include;c:\python26\include"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -250,7 +250,7 @@
Optimization="0"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\include;c:\Python26\include"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS;_PYWRAPS_DEBUG"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS;_PYWRAPS_DEBUG"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -350,7 +350,7 @@
Optimization="0"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include;c:\python26\include"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS;_PYWRAPS_DEBUG;__EA64__"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS;_PYWRAPS_DEBUG;__EA64__"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -451,7 +451,7 @@
Optimization="0"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\include;c:\python26\include"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS;__EA64__;_PYWRAPS_DEBUG;__PYWRAPS__"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS;__EA64__;_PYWRAPS_DEBUG;__PYWRAPS__"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -550,7 +550,7 @@
Optimization="0"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\..\include;c:\python26\include"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;MAXSTR=1024;_CRT_SECURE_NO_WARNINGS"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
+3
View File
@@ -181,6 +181,9 @@
}
}
//<typemaps(bytes)>
//</typemaps(bytes)>
%include "bytes.hpp"
%apply (char *STRING, int LENGTH) { (const uchar *image, size_t len) };
+17 -19
View File
@@ -8,7 +8,6 @@
%ignore dbg;
%ignore register_srcinfo_provider;
%ignore unregister_srcinfo_provider;
%ignore get_manual_regions;
%ignore internal_cleanup_appcall;
%ignore change_bptlocs;
%ignore movbpt_info_t;
@@ -27,31 +26,30 @@
%ignore bpt_t::get_cnd_elang;
%ignore bpt_t::set_cnd_elang;
%rename (get_manual_regions) py_get_manual_regions;
%ignore set_manual_regions;
// TODO: This could be fixed (if needed)
%ignore set_dbgmem_source;
// unusable functions because 'dbg' is not available:
%ignore have_set_options;
%ignore set_dbg_options;
%ignore set_int_dbg_options;
%ignore set_dbg_default_options;
/* %ignore invalidate_dbg_state; */
/* %ignore is_request_running; */
%rename (list_bptgrps) py_list_bptgrps;
%apply qstring *result { qstring *grp_name };
%ignore qvector<bpt_t>::operator==;
%ignore qvector<bpt_t>::operator!=;
%ignore qvector<bpt_t>::find;
%ignore qvector<bpt_t>::has;
%ignore qvector<bpt_t>::del;
%ignore qvector<bpt_t>::add_unique;
%template(bpt_vec_t) qvector<bpt_t>;
%uncomparable_elements_qvector(bpt_t, bpt_vec_t);
%ignore write_dbg_memory;
%rename (write_dbg_memory) py_write_dbg_memory;
%ignore qvector<memreg_info_t>::operator==;
%ignore qvector<memreg_info_t>::operator!=;
%ignore qvector<memreg_info_t>::find;
%ignore qvector<memreg_info_t>::has;
%ignore qvector<memreg_info_t>::del;
%ignore qvector<memreg_info_t>::add_unique;
%uncomparable_elements_qvector(tev_reg_value_t, tev_reg_values_t);
%uncomparable_elements_qvector(tev_info_reg_t, tevinforeg_vec_t);
%ignore memreg_info_t::bytes;
%rename (bytes) memreg_info_t_py_bytes;
%template(memreg_infos_t) qvector<memreg_info_t>;
%uncomparable_elements_qvector(memreg_info_t, memreg_infos_t);
%ignore internal_get_sreg_base;
%rename (internal_get_sreg_base) py_internal_get_sreg_base;
@@ -64,11 +62,11 @@
bool run_to(ea_t ea, pid_t pid = NO_PROCESS, thid_t tid = NO_THREAD);
bool request_run_to(ea_t ea, pid_t pid = NO_PROCESS, thid_t tid = NO_THREAD);
%ignore get_insn_tev_reg_val(int, const char *, uint64 *);
%ignore get_insn_tev_reg_result(int, const char *, uint64 *);
%thread;
%nonnul_argument_prototype(
inline bool idaapi load_debugger(const char *nonnul_dbgname, bool use_remote),
const char *nonnul_dbgname);
%nonnul_argument_prototype(
inline void idaapi set_debugger_event_cond(const char *nonnul_cond),
const char *nonnul_cond);
+1 -7
View File
@@ -94,13 +94,7 @@
}
}
%ignore qvector<idc_value_t>::operator==;
%ignore qvector<idc_value_t>::operator!=;
%ignore qvector<idc_value_t>::find;
%ignore qvector<idc_value_t>::has;
%ignore qvector<idc_value_t>::del;
%ignore qvector<idc_value_t>::add_unique;
%template(idc_values_t) qvector<idc_value_t>;
%uncomparable_elements_qvector(idc_value_t, idc_values_t);
%pythoncode %{
#<pycode(py_expr)>
+40
View File
@@ -1,6 +1,10 @@
%import "range.i"
%{
#include <frame.hpp>
%}
// FIXME: Are these really useful?
%ignore iterate_func_chunks;
%ignore get_idasgn_header_by_short_name;
@@ -17,6 +21,42 @@
%ignore func_md_t::cbsize;
%ignore func_pat_t::cbsize;
%template (stkpnt_array) dynamic_wrapped_array_t<stkpnt_t>;
%template (regvar_array) dynamic_wrapped_array_t<regvar_t>;
%template (range_array) dynamic_wrapped_array_t<range_t>;
%extend func_t
{
dynamic_wrapped_array_t<stkpnt_t> __get_points__()
{
return dynamic_wrapped_array_t<stkpnt_t>($self->points, $self->pntqty);
}
dynamic_wrapped_array_t<regvar_t> __get_regvars__()
{
if ( $self->regvarqty < 0 ) // force load
find_regvar($self, $self->start_ea, NULL);
return dynamic_wrapped_array_t<regvar_t>($self->regvars, $self->regvarqty);
}
dynamic_wrapped_array_t<range_t> __get_tails__()
{
return dynamic_wrapped_array_t<range_t>($self->tails, $self->tailqty);
}
%pythoncode {
points = property(__get_points__)
regvars = property(__get_regvars__)
tails = property(__get_tails__)
}
}
//<typemaps(funcs)>
//</typemaps(funcs)>
%apply ea_t *result { ea_t *fptr }; // calc_thunk_func_target()
%apply ea_t *appended_ea { ea_t *fptr };
%include "funcs.hpp"
%clear(char *buf);
+11 -6
View File
@@ -33,7 +33,8 @@
%ignore mutable_graph_t::del_edge;
%ignore mutable_graph_t::del_node;
%ignore mutable_graph_t::fix_collapsed_group_edges;
%ignore mutable_graph_t::get_edge;
%ignore mutable_graph_t::get_edge(edge_t);
%rename (get_edge) my_get_edge;
%ignore mutable_graph_t::groups_are_present;
%ignore mutable_graph_t::insert_simple_nodes;
%ignore mutable_graph_t::insert_visible_nodes;
@@ -55,18 +56,22 @@
%ignore selection_item_t::selection_item_t(class graph_item_t &);
%feature("nodirector") user_graph_place_t;
// Those were deprecated before they were available
// to IDAPython, so let's keep it that way.
%ignore viewer_add_menu_item;
%ignore viewer_del_menu_item;
%extend graph_visitor_t {
public:
virtual int idaapi visit_node(int /*n*/, rect_t & /*r*/) { return 0; }
virtual int idaapi visit_edge(edge_t /*e*/, edge_info_t * /*ei*/) { return 0; }
}
%extend mutable_graph_t {
public:
virtual edge_info_t my_get_edge(edge_t e)
{
return *($self->get_edge(e));
}
}
%template(node_layout_t) qvector<rect_t>;
%template(pointvec_t) qvector<point_t>;
%include "graph.hpp"
%ignore graph_visitor_t::visit_node;
+78 -35
View File
@@ -69,6 +69,7 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
%ignore casm_t::print;
%ignore cgoto_t::print;
%ignore cexpr_t::is_aliasable;
%ignore cexpr_t::like_boolean;
%ignore cexpr_t::contains_expr;
%ignore cexpr_t::contains_expr;
%ignore cexpr_t::cexpr_t(mbl_array_t *mba, const lvar_t &v);
@@ -96,19 +97,19 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
// ignore microcode related stuff for now
%ignore bitset_t;
%ignore ivlset_t;
%ignore ivl_t;
%ignore mlist_t;
%ignore rlist_t;
%ignore mbl_array_t;
%ignore mbl_graph_t;
%ignore mblock_t;
%ignore minsn_t;
%ignore mop_t;
%ignore mcode_t;
%ignore mop_addr_t;
%ignore mop_pair_t;
%ignore mcases_t;
%ignore mfuncarg_t;
%ignore mfuncinfo_t;
%ignore mcallarg_t;
%ignore mcallinfo_t;
%ignore mnumber_t;
%ignore lvar_ref_t;
%ignore stkvar_ref_t;
@@ -116,6 +117,7 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
%ignore op_parent_info_t;
%ignore scif_visitor_t;
%ignore mop_visitor_t;
%ignore mlist_mop_visitor_t;
%ignore minsn_visitor_t;
%ignore srcop_visitor_t;
%ignore chain_t;
@@ -126,21 +128,20 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
%ignore block_chains_end;
%ignore block_chains_erase;
%ignore block_chains_find;
%ignore block_chains_first;
%ignore block_chains_free;
%ignore block_chains_get;
%ignore block_chains_insert;
%ignore block_chains_new;
%ignore block_chains_next;
%ignore block_chains_prev;
%ignore block_chains_second;
%ignore block_chains_size;
%ignore graph_chains_t;
%ignore chain_visitor_t;
%ignore gctype_t;
%ignore simple_graph_t;
%ignore mcode_t;
%ignore get_signed_mcode;
%ignore get_unsigned_mcode;
%ignore is_dest_target_mcode;
%ignore mcode_modifies_d;
%ignore is_may_access;
%ignore is_mcode_addsub;
%ignore is_mcode_call;
@@ -158,6 +159,8 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
%ignore is_mcode_xdsu;
%ignore is_signed_mcode;
%ignore is_unsigned_mcode;
%ignore is_kreg;
%ignore get_first_stack_reg;
%ignore jcnd2set;
%ignore must_mcode_close_block;
%ignore negate_mcode_relation;
@@ -186,6 +189,24 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
%ignore mba_range_iterator_t;
%ignore mba_ranges_t;
%ignore deserialize_mbl_array;
%ignore get_temp_regs;
%ignore ivl_t;
%ignore ivlset_t;
%ignore ivl_with_name_t;
%ignore vivl_t;
%ignore voff_t;
%ignore voff_set_t;
%ignore gco_info_t;
%ignore get_current_operand;
%ignore valrng_t;
// "Warning 473: Returning a pointer or reference in a director method is not recommended."
// In this particular case, we are telling SWiG that the object is always a
// %newobject (thus: even for base classes), but it seems it's not enough to
// shut the warning up.
%warnfilter(473) codegen_t::emit_micro_mvm;
%newobject codegen_t::emit_micro_mvm;
%newobject codegen_t::emit;
%apply uchar { char ignore_micro };
%feature("nodirector") udc_filter_t::apply;
@@ -209,10 +230,19 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
%rename (_ll_make_num) make_num;
%rename (_ll_create_helper) create_helper;
%extend cfunc_t {
%immutable argidx;
PyObject *find_item_coords(const citem_t *item)
{
int px = 0;
int py = 0;
if ( $self->find_item_coords(item, &px, &py) )
return Py_BuildValue("(ii)", px, py);
else
return Py_BuildValue("(OO)", Py_None, Py_None);
}
qstring __str__() const {
qstring qs;
qstring_printer_t p($self, qs, 0);
@@ -241,26 +271,13 @@ static void _kludge_use_TPopupMenu(TPopupMenu *m);
%rename(dereference_uint16) operator uint16*;
%rename(dereference_const_uint16) operator const uint16*;
#if !defined(__MAC__) || (MACSDKVER >= 1006)
#define HAS_MAP_AT
#endif
// Provide trivial std::map facade so basic operations are available.
template<class key_type, class mapped_type> class std::map {
public:
#ifdef HAS_MAP_AT
mapped_type& at(const key_type& _Keyval);
#endif
size_t size() const;
};
#ifndef HAS_MAP_AT
#warning "std::map doesn't provide at(). Augmenting it."
%extend std::map {
mapped_type& at(const key_type& _Keyval) { return $self->operator[](_Keyval); }
}
#endif
//-------------------------------------------------------------------------
%typemap(check) citem_t *self
{
@@ -307,6 +324,11 @@ public:
_get_op,
lambda self, v: self._ensure_no_op() and self._set_op(v))
def _ensure_cond(self, ok, cond_str):
if not ok:
raise Exception("Condition \"%s\" not verified" % cond_str)
return True
def _ensure_no_op(self):
if self.op not in [cot_empty, cit_empty]:
raise Exception("%s has op %s; cannot be modified" % (self, self.op))
@@ -368,7 +390,8 @@ public:
%pythoncode { \
PName = property( \
lambda self: self._get_##PName() if Cond else Defval, \
lambda self, v: Cond \
lambda self, v: \
self._ensure_cond(Cond, #Cond) \
and self._ensure_no_obj(self._get_##PName(), #PName, Acquire) \
and self._acquire_ownership(v, Acquire) \
and self._set_##PName(v)) \
@@ -517,10 +540,10 @@ public:
/* for qvector instanciations where the class is a pointer (cinsn_t, citem_t) we need
to fix the at() return type, otherwise swig mistakenly thinks it is "cinsn_t *&" and nonsense ensues. */
%extend qvector< cinsn_t *> {
cinsn_t *at(size_t n) { return self->at(n); }
cinsn_t *at(size_t n) { return self->at(n); }
};
%extend qvector< citem_t *> {
citem_t *at(size_t n) { return self->at(n); }
citem_t *at(size_t n) { return self->at(n); }
};
// ignore future declarations of at() for these classes
@@ -531,11 +554,6 @@ public:
%ignore qvector< citem_t *>::grow;
%ignore qvector< cinsn_t *>::grow;
//~ %template(qwstrvec_t) qvector<qwstring>; // vector of unicode strings
typedef intvec_t svalvec_t; // vector of signed values
//typedef intvec_t eavec_t;// vector of addresses
// At this point, SWIG doesn't know about this
// type yet (kernwin.i is included later). Therefore,
// unless we do this, swig will consider 'strvec_t' to be
@@ -560,6 +578,15 @@ typedef qvector<simpleline_t> strvec_t;
%template(eamap_t) std::map<ea_t, cinsnptrvec_t>;
%template(boundaries_t) std::map<cinsn_t *, rangeset_t>;
%define %constify_iterator_value(NameBase, ReturnType)
%ignore NameBase ## _second;
%rename (NameBase ## _second) py_ ## NameBase ## _second;
%inline %{
inline const ReturnType &py_ ## NameBase ## _second(NameBase ## _iterator_t p) { return NameBase ## _second(p); }
%}
%enddef
%constify_iterator_value(user_iflags, int32);
%ignore boundaries_find;
%rename (boundaries_find) py_boundaries_find;
%ignore boundaries_insert;
@@ -605,7 +632,9 @@ typedef qlist<cinsn_t>::iterator qlist_cinsn_t_iterator;
class qlist_cinsn_t_iterator {};
%extend qlist_cinsn_t_iterator {
const cinsn_t &cur { return *(*self); }
qlist_cinsn_t_iterator &next(void) { (*self)++; return *self; }
void next(void) { (*self)++; }
bool operator==(const qlist_cinsn_t_iterator *x) const { return &(self->operator*()) == &(x->operator*()); }
bool operator!=(const qlist_cinsn_t_iterator *x) const { return &(self->operator*()) != &(x->operator*()); }
};
%extend qlist<cinsn_t> {
@@ -673,10 +702,7 @@ void qswap(cinsn_t &a, cinsn_t &b);
%rename(init_hexrays_plugin) py_init_hexrays_plugin;
%ignore install_hexrays_callback;
%rename(install_hexrays_callback) py_install_hexrays_callback;
%ignore remove_hexrays_callback;
%rename(remove_hexrays_callback) py_remove_hexrays_callback;
%ignore decompile_many;
%rename (decompile_many) py_decompile_many;
@@ -726,7 +752,7 @@ void qswap(cinsn_t &a, cinsn_t &b);
}
%enddef
%python_callback_in(PyObject *hx_cblist_callback);
%python_callback_in(PyObject *hx_callback);
%python_callback_in(PyObject *custom_viewer_popup_item_callback);
%ignore cexpr_t::get_1num_op(const cexpr_t **, const cexpr_t **) const;
@@ -766,10 +792,27 @@ void qswap(cinsn_t &a, cinsn_t &b);
//</inline(py_hexrays)>
%}
%ignore Hexrays_Callback;
%inline %{
//<inline(py_hexrays_hooks)>
//</inline(py_hexrays_hooks)>
%}
%{
//<code(py_hexrays_hooks)>
//</code(py_hexrays_hooks)>
%}
%include "hexrays.hpp"
%exception; // Delete & restore handlers
%exception_set_default_handlers();
// These are microcode-related. Let's not expose them right now.
/* %template(ivl_t) ivl_tpl<uval_t>; */
/* %template(ivlset_t) ivlset_tpl<ivl_t, uval_t>; */
/* %template(array_of_ivlsets) qvector<ivlset_t>; */
%pythoncode %{
#<pycode(py_hexrays)>
#</pycode(py_hexrays)>
+5 -17
View File
@@ -5,10 +5,11 @@
#include <err.h>
%}
%import "range.i"
%ignore free_debug_event;
%ignore copy_debug_event;
%ignore debugger_t;
%ignore memory_info_t;
%ignore lowcnd_t;
%ignore lowcnd_vec_t;
%ignore update_bpt_info_t;
@@ -20,23 +21,10 @@
%ignore debug_event_t::exit_code();
%apply unsigned char { op_dtype_t dtype };
%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>;
%ignore qvector<process_info_t>::operator==;
%ignore qvector<process_info_t>::operator!=;
%ignore qvector<process_info_t>::find;
%ignore qvector<process_info_t>::has;
%ignore qvector<process_info_t>::del;
%ignore qvector<process_info_t>::add_unique;
%template(procinfo_vec_t) qvector<process_info_t>;
%uncomparable_elements_qvector(exception_info_t, excvec_t);
%uncomparable_elements_qvector(process_info_t, procinfo_vec_t);
%template(call_stack_t) qvector<call_stack_info_t>;
%template(meminfo_vec_t) qvector<memory_info_t>;
%include "idd.hpp"
+35 -17
View File
@@ -1,5 +1,6 @@
%{
#include <kernwin.hpp>
#include <parsejson.hpp>
%}
%{
@@ -10,6 +11,13 @@ extern plugin_t PLUGIN;
#endif
%}
%typemap(out) void *get_window_id
{
// %typemap(out) void *get_window_id
$result = PyLong_FromUnsignedLongLong((unsigned long long) $1);
}
// Ignore the va_list functions
%ignore vask_form;
%ignore ask_form;
@@ -27,6 +35,18 @@ extern plugin_t PLUGIN;
%ignore vask_text;
%ignore ask_text;
%ignore vwarning;
// Note: don't do that for ask_form(), since that calls back into Python.
%thread ask_addr;
%thread ask_seg;
%thread ask_long;
%thread ask_yn;
%thread ask_buttons;
%thread ask_file;
%calls_execute_sync(clr_cancelled);
%calls_execute_sync(set_cancelled);
%calls_execute_sync(user_cancelled);
%calls_execute_sync(hide_wait_box);
%ignore choose_idasgn;
%rename (choose_idasgn) py_choose_idasgn;
@@ -40,9 +60,6 @@ extern plugin_t PLUGIN;
%ignore msg;
%rename (msg) py_msg;
%ignore umsg;
%rename (umsg) py_umsg;
%ignore vinfo;
%ignore UI_Callback;
%ignore vnomem;
@@ -110,18 +127,15 @@ extern plugin_t PLUGIN;
%rename (_ask_addr) ask_addr;
%rename (_ask_seg) ask_seg;
%ignore qvector<disasm_line_t>::operator==;
%ignore qvector<disasm_line_t>::operator!=;
%ignore qvector<disasm_line_t>::find;
%ignore qvector<disasm_line_t>::has;
%ignore qvector<disasm_line_t>::del;
%ignore qvector<disasm_line_t>::add_unique;
%ignore gen_disasm_text;
%rename (gen_disasm_text) py_gen_disasm_text;
%ignore UI_Hooks::handle_hint_output;
%ignore UI_Hooks::handle_get_ea_hint_output;
%ignore UI_Hooks::wrap_widget_cfg;
%ignore UI_Hooks::handle_create_desktop_widget_output;
%ignore jobj_wrapper_t::jobj_wrapper_t;
%ignore jobj_wrapper_t::~jobj_wrapper_t;
// We will %ignore those ATM, since they cannot be trivially
// wrapped: bytevec_t is not exposed.
@@ -176,7 +190,7 @@ struct py_action_handler_t : public action_handler_t
if ( !has_activate )
return 0;
PYW_GIL_GET_AND_REPORT_ERROR;
newref_t pyctx(SWIG_NewPointerObj(SWIG_as_voidptr(ctx), SWIGTYPE_p_action_activation_ctx_t, 0));
newref_t pyctx(SWIG_NewPointerObj(SWIG_as_voidptr(ctx), SWIGTYPE_p_action_ctx_base_t, 0));
newref_t pyres(PyObject_CallMethod(pyah.o, (char *)"activate", (char *) "O", pyctx.o));
return PyErr_Occurred() ? 0 : ((pyres != NULL && PyInt_Check(pyres.o)) ? PyInt_AsLong(pyres.o) : 0);
}
@@ -185,7 +199,7 @@ struct py_action_handler_t : public action_handler_t
if ( !has_update )
return AST_DISABLE;
PYW_GIL_GET_AND_REPORT_ERROR;
newref_t pyctx(SWIG_NewPointerObj(SWIG_as_voidptr(ctx), SWIGTYPE_p_action_update_ctx_t, 0));
newref_t pyctx(SWIG_NewPointerObj(SWIG_as_voidptr(ctx), SWIGTYPE_p_action_ctx_base_t, 0));
newref_t pyres(PyObject_CallMethod(pyah.o, (char *)"update", (char *) "O", pyctx.o));
return PyErr_Occurred() ? AST_DISABLE_ALWAYS : ((pyres != NULL && PyInt_Check(pyres.o)) ? action_state_t(PyInt_AsLong(pyres.o)) : AST_DISABLE);
}
@@ -207,9 +221,13 @@ void refresh_choosers(void)
}
%}
# This is for get_cursor()
// get_cursor()
%apply int *OUTPUT {int *x, int *y};
// get_navband_pixel()
%apply bool *OUTPUT {bool *out_is_vertical};
%ignore textctrl_info_t;
SWIG_DECLARE_PY_CLINKED_OBJECT(textctrl_info_t)
@@ -239,9 +257,12 @@ static void _py_unregister_compiled_form(PyObject *py_form, bool shutdown);
%ignore remove_command_interpreter;
%rename (remove_command_interpreter) py_remove_command_interpreter;
//<typemaps(kernwin)>
//</typemaps(kernwin)>
%include "kernwin.hpp"
%template(disasm_text_t) qvector<disasm_line_t>;
%uncomparable_elements_qvector(disasm_line_t, disasm_text_t);
%extend action_desc_t {
action_desc_t(
@@ -283,8 +304,6 @@ static void _py_unregister_compiled_form(PyObject *py_form, bool shutdown);
%extend action_ctx_base_t {
int _get_reg() const { return $self->reg; }
#ifdef BC695
TWidget *_get_form() const { return $self->widget; }
twidget_type_t _get_form_type() const { return $self->widget_type; }
@@ -292,7 +311,6 @@ static void _py_unregister_compiled_form(PyObject *py_form, bool shutdown);
#endif
%pythoncode {
reg = property(_get_reg)
#ifdef BC695
form = property(_get_form)
form_type = property(_get_form_type)
+18
View File
@@ -34,6 +34,24 @@
%ignore tag_advance;
%rename (tag_advance) py_tag_advance;
%typemap(argout) (qstring *buf, ea_t ea, int what)
{
// typemap(argout) (qstring *buf, ea_t ea, int what)
Py_XDECREF(resultobj);
if (result >= 0)
{
resultobj = PyString_FromStringAndSize((const char *) $1->c_str(), $1->length());
}
else
{
Py_INCREF(Py_None);
resultobj = Py_None;
}
}
//<typemaps(lines)>
//</typemaps(lines)>
%include "lines.hpp"
%{
+2
View File
@@ -77,6 +77,8 @@
%rename (load_plugin) py_load_plugin;
%ignore run_plugin;
%rename (run_plugin) py_run_plugin;
%ignore load_and_run_plugin;
%rename (load_and_run_plugin) py_load_and_run_plugin;
%extend qvector< snapshot_t *> {
snapshot_t *at(size_t n) { return self->at(n); }
+2 -4
View File
@@ -28,6 +28,8 @@
%ignore get_demangled_name(qstring *, ea_t, int32, int, int);
%ignore get_colored_demangled_name(qstring *, ea_t, int32, int, int);
%uncomparable_elements_qvector(ea_name_t, ea_name_vec_t);
// get_name & get_colored_name have prototypes such that,
// once converted to IDAPython, would be problematic because it'd
// be impossible for SWiG to tell apart the (ea_t, ea_t) version
@@ -50,10 +52,6 @@ inline qstring py_## FNAME(ea_t ea) { return FNAME(ea); }
%restrict_ambiguous_name_function(get_name);
%restrict_ambiguous_name_function(get_colored_name);
%ignore get_debug_names;
%rename (get_debug_names) py_get_debug_names;
%ignore validate_name;
%rename (validate_name) py_validate_name;
+27 -5
View File
@@ -21,6 +21,7 @@
%ignore utf8_wchar16;
%ignore utf8_wchar32;
%ignore skip_utf8;
%ignore qustrncpy;
%ignore expand_argv;
%ignore free_argv;
%ignore qwait;
@@ -28,6 +29,12 @@
%ignore qwait_timed;
%ignore ida_true_type;
%ignore ida_false_type;
%ignore bitcount;
%ignore round_up_power2;
%ignore round_down_power2;
//<typemaps(pro)>
//</typemaps(pro)>
%include "pro.h"
@@ -39,12 +46,27 @@
%import "netnode.hpp"
//
void qvector<int>::grow(const int &x=0);
%ignore qvector<int>::grow;
void qvector<unsigned int>::grow(const unsigned int &x=0);
%ignore qvector<unsigned int>::grow;
void qvector<long long>::grow(const long long &x=0);
%ignore qvector<long long>::grow;
void qvector<unsigned long long>::grow(const unsigned long long &x=0);
%ignore qvector<unsigned long long>::grow;
//---------------------------------------------------------------------
%template(uvalvec_t) qvector<uval_t>; // unsigned values
%template(intvec_t) qvector<int>;
%template(int64vec_t) qvector<long long>; // for EA64 svalvec_t objects
%template(boolvec_t) qvector<bool>;
%template(strvec_t) qvector<simpleline_t>;
%template(intvec_t) qvector<int>;
%template(uintvec_t) qvector<unsigned int>;
%template(longlongvec_t) qvector<long long>;
%template(ulonglongvec_t) qvector<unsigned long long>;
%template(boolvec_t) qvector<bool>;
%pythoncode %{
%}
%uncomparable_elements_qvector(simpleline_t, strvec_t);
%template(sizevec_t) qvector<size_t>;
typedef uvalvec_t eavec_t;// vector of addresses
+3
View File
@@ -46,4 +46,7 @@
//</inline(py_registry)>
%}
//<typemaps(registry)>
//</typemaps(registry)>
%include "registry.hpp"
+3
View File
@@ -40,6 +40,9 @@
*($2) = BADADDR;
}
//<typemaps(py_segment)>
//</typemaps(py_segment)>
%include "segment.hpp"
%inline %{
+1 -1
View File
@@ -37,7 +37,7 @@
%typemap(argout) struc_t **sptr_place {
if ( result )
{
%append_output(SWIG_NewPointerObj(SWIG_as_voidptr($1), SWIGTYPE_p_struc_t, 0 | 0 ));
%append_output(SWIG_NewPointerObj(SWIG_as_voidptr(*($1)), SWIGTYPE_p_struc_t, 0 | 0 ));
}
else
{
+23 -22
View File
@@ -32,7 +32,6 @@
%ignore til_next_macro;
%ignore parse_subtype;
%ignore calc_type_size;
%ignore descr_t;
@@ -94,7 +93,6 @@
%ignore max_ptr_size;
%ignore based_ptr_name_and_size;
%ignore apply_type;
%ignore apply_callee_type;
%ignore get_arg_addrs;
%rename (get_arg_addrs) py_get_arg_addrs;
@@ -103,7 +101,9 @@
%ignore idb_type_to_til;
%ignore get_idb_type;
%ignore calc_type_size;
%rename (calc_type_size) py_calc_type_size;
%ignore apply_type;
%rename (apply_type) py_apply_type;
%ignore use_regarg_type_cb;
@@ -128,6 +128,8 @@
%ignore func_type_data_t::serialize;
%ignore func_type_data_t::deserialize;
%ignore tinfo_t::serialize(qtype *, qtype *, qtype *, int) const;
%ignore name_requires_qualifier;
%ignore tinfo_visitor_t::level;
%ignore custloc_desc_t;
%ignore install_custom_argloc;
@@ -164,18 +166,6 @@
return $self->deserialize(til, &type, &fields, cmts == NULL ? NULL : &cmts);
}
bool deserialize(
const til_t *til,
const char *_type,
const char *_fields,
const char *_cmts = NULL)
{
const type_t *type = (const type_t *) _type;
const p_list *fields = (const p_list *) _fields;
const p_list *cmts = (const p_list *) _cmts;
return $self->deserialize(til, &type, &fields, cmts == NULL ? NULL : &cmts);
}
// The typemap in typeconv.i will take care of registering newly-constructed
// tinfo_t instances. However, there's no such thing as a destructor typemap.
// Therefore, we need to do the grunt work of de-registering ourselves.
@@ -215,7 +205,7 @@
}
}
%enddef
%simple_tinfo_t_container_lifecycle(ptr_type_data_t, (tinfo_t c=tinfo_t(), uchar bps=0), (c, bps));
%simple_tinfo_t_container_lifecycle(ptr_type_data_t, (tinfo_t c=tinfo_t(), uchar bps=0, tinfo_t p=tinfo_t(), int32 d=0), (c, bps, p, d));
%simple_tinfo_t_container_lifecycle(array_type_data_t, (size_t b=0, size_t n=0), (b, n));
%simple_tinfo_t_container_lifecycle(func_type_data_t, (), ());
%simple_tinfo_t_container_lifecycle(udt_type_data_t, (), ());
@@ -223,13 +213,7 @@
%template(funcargvec_t) qvector<funcarg_t>;
%template(udtmembervec_t) qvector<udt_member_t>;
%template(reginfovec_t) qvector<reg_info_t>;
%ignore qvector<type_attr_t>::operator==;
%ignore qvector<type_attr_t>::operator!=;
%ignore qvector<type_attr_t>::find;
%ignore qvector<type_attr_t>::has;
%ignore qvector<type_attr_t>::del;
%ignore qvector<type_attr_t>::add_unique;
%template(type_attrs_t) qvector<type_attr_t>;
%uncomparable_elements_qvector(type_attr_t, type_attrs_t);
%extend tinfo_t {
PyObject *get_attr(const qstring &key, bool all_attrs=true)
@@ -261,6 +245,23 @@
char *buf,
size_t bufsize); // idc_guess_type, idc_get_type
// set_numbered_type()
%typemap(in) const sclass_t * {
// %typemap(in) const sclass_t *
if ( $input == Py_None )
$1 = new sclass_t(sc_unk);
else if ( PyInt_Check($input) )
$1 = new sclass_t(sclass_t(PyInt_AsLong($input)));
else
SWIG_exception_fail(
SWIG_ValueError,
"invalid argument " "in method '" "$symname" "', argument " "$argnum"" of type '" "$1_type""'");
}
%typemap(freearg) const sclass_t * {
// %typemap(freearg) const sclass_t *
delete $1;
}
%include "typeinf.hpp"
// Custom wrappers
+3 -1
View File
@@ -10,6 +10,9 @@
%ignore decode_preceding_insn;
%ignore get_operand_immvals;
%ignore get_immvals;
%rename (get_immvals) py_get_immvals;
%ignore get_printable_immvals;
%rename (get_printable_immvals) py_get_printable_immvals;
%ignore get_immval;
%ignore insn_create_op_data;
@@ -142,7 +145,6 @@
%include "ua.hpp"
%rename (decode_preceding_insn) py_decode_preceding_insn;
%rename (get_immvals) py_get_immvals;
%{
//<code(py_ua)>

Some files were not shown because too many files have changed in this diff Show More