mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
IDAPython for IDA 8.3
This commit is contained in:
@@ -18,8 +18,6 @@ keywords: actions
|
||||
see_also: add_hotkey
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
|
||||
class SayHi(ida_kernwin.action_handler_t):
|
||||
|
||||
@@ -16,8 +16,6 @@ keywords: actions
|
||||
see_also: actions
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
|
||||
def hotkey_pressed():
|
||||
|
||||
@@ -11,8 +11,6 @@ keywords: actions
|
||||
see_also: actions, add_hotkey
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_expr
|
||||
import ida_kernwin
|
||||
|
||||
|
||||
@@ -15,9 +15,6 @@ description:
|
||||
encoding, or as UTF-16.)
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
import ida_kernwin
|
||||
import ida_bytes
|
||||
import ida_ida
|
||||
|
||||
@@ -16,9 +16,6 @@ keywords: coloring, idc
|
||||
see_also: colorize_disassembly_on_the_fly
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
BG_BLUE = 0xc02020
|
||||
BG_GREEN = 0x208020
|
||||
BG_RED = 0x2020c0
|
||||
|
||||
@@ -101,12 +101,13 @@ class on_the_fly_coloring_hooks_t(ida_kernwin.UI_Hooks):
|
||||
del self.by_widget[title]
|
||||
|
||||
|
||||
class carousel_color_ah_t():
|
||||
class carousel_color_ah_t(ida_kernwin.action_handler_t):
|
||||
"""
|
||||
The action that will be invoked by IDA when the user
|
||||
activates its shortcut.
|
||||
"""
|
||||
def __init__(self, hooks):
|
||||
ida_kernwin.action_handler_t.__init__(self)
|
||||
self.hooks = hooks
|
||||
|
||||
def activate(self, ctx):
|
||||
|
||||
@@ -8,7 +8,6 @@ description:
|
||||
author: Gergely Erdelyi (gergely.erdelyi@d-dome.net)
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
#---------------------------------------------------------------------
|
||||
# Structure test
|
||||
#
|
||||
|
||||
@@ -9,7 +9,6 @@ description:
|
||||
It provides an example tab completion support.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
# -----------------------------------------------------------------------
|
||||
# This is an example illustrating how to implement a CLI
|
||||
#
|
||||
|
||||
@@ -11,8 +11,6 @@ description:
|
||||
one format for a specific 'custom data type'.)
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_bytes
|
||||
import ida_idaapi
|
||||
import ida_lines
|
||||
|
||||
@@ -9,8 +9,6 @@ description:
|
||||
the previous and next extra comments.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_lines
|
||||
import ida_kernwin
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ description:
|
||||
`ida_gdl.FlowChart` type.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_gdl
|
||||
import ida_funcs
|
||||
import ida_kernwin
|
||||
|
||||
@@ -15,8 +15,6 @@ description:
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
import ida_lines
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ description:
|
||||
`pow(3, 7)`
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_expr
|
||||
|
||||
if ida_expr.add_idc_func(
|
||||
|
||||
@@ -8,8 +8,6 @@ description:
|
||||
`ida_lines.user_defined_prefix_t` helper type.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_lines
|
||||
import ida_idaapi
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ description:
|
||||
Using the API to enumerate file imports.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_nalt
|
||||
|
||||
nimps = ida_nalt.get_import_module_qty()
|
||||
|
||||
@@ -6,8 +6,6 @@ description:
|
||||
that were patched using IDA.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_bytes
|
||||
import ida_idaapi
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ keywords: xrefs
|
||||
see_also: list_segment_functions_using_idautils
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
#
|
||||
# Reference Lister
|
||||
#
|
||||
|
||||
@@ -13,7 +13,6 @@ keywords: xrefs
|
||||
see_also: list_segment_functions
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
#
|
||||
# Reference Lister
|
||||
#
|
||||
|
||||
@@ -9,7 +9,6 @@ description:
|
||||
see_also: show_selected_strings
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import ida_nalt
|
||||
import idautils
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ description:
|
||||
Register (possibly repeating) timers.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
@@ -15,8 +15,6 @@ description:
|
||||
keywords: actions
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
"""
|
||||
summary: This file contains the CVT64 examples.
|
||||
|
||||
description:
|
||||
For more infortmation see SDK/plugins/cvt64_sample example
|
||||
"""
|
||||
|
||||
import idaapi
|
||||
import ida_idaapi
|
||||
import ida_netnode
|
||||
|
||||
SAMPLE_NETNODE_NAME = "$ cvt64 py_sample netnode"
|
||||
DEVICE_INDEX = idaapi.BADADDR # -1
|
||||
IDPFLAGS_INDEX = idaapi.BADADDR # -1
|
||||
HASH_COMMENT = "Comment"
|
||||
HASH_ADDRESS = "Address"
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
class idp_listener_t(idaapi.IDP_Hooks):
|
||||
def __init__(self):
|
||||
idaapi.IDP_Hooks.__init__(self)
|
||||
|
||||
def ev_cvt64_hashval(self, node, tag, name, data):
|
||||
helper = idaapi.netnode(SAMPLE_NETNODE_NAME)
|
||||
if helper == node and tag == ida_netnode.htag:
|
||||
if name == HASH_COMMENT:
|
||||
comment = helper.hashstr(name)
|
||||
helper.hashset_buf(name, comment)
|
||||
return 1
|
||||
if name == HASH_ADDRESS:
|
||||
address = helper.hashval_long(name)
|
||||
if address == ida_idaapi.BADADDR32:
|
||||
address = ida_idaapi.BADADDR
|
||||
helper.hashset_idx(name, address)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def ev_cvt64_supval(self, node, tag, idx, data):
|
||||
helper = idaapi.netnode(SAMPLE_NETNODE_NAME)
|
||||
if helper == node:
|
||||
if tag == ida_netnode.stag and idx == ida_idaapi.BADADDR32:
|
||||
helper.supset(DEVICE_INDEX, data)
|
||||
return 1
|
||||
if tag == ida_netnode.atag and len(data):
|
||||
if idx == ida_idaapi.BADADDR32:
|
||||
idx = IDPFLAGS_INDEX
|
||||
val = int.from_bytes(data, 'little')
|
||||
if val == ida_idaapi.BADADDR32:
|
||||
val = ida_idaapi.BADADDR
|
||||
helper.altset(idx, val)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# This class is instantiated once per each opened database.
|
||||
class cvt64_ctx_t(idaapi.plugmod_t):
|
||||
|
||||
def __init__(self):
|
||||
self.prochook = idp_listener_t()
|
||||
self.prochook.hook()
|
||||
|
||||
def __del__(self):
|
||||
self.prochook.unhook()
|
||||
|
||||
def run(self, arg):
|
||||
pass
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# This class is instantiated when IDA loads the plugin.
|
||||
class cvt64_sample_t(idaapi.plugin_t):
|
||||
flags = idaapi.PLUGIN_MULTI | idaapi.PLUGIN_MOD
|
||||
comment = "IDAPython: An example how to implement CVT64 functionality"
|
||||
wanted_name = "IDAPython: CVT64 sample"
|
||||
wanted_hotkey = ""
|
||||
help = ""
|
||||
|
||||
def init(self):
|
||||
return cvt64_ctx_t()
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
def PLUGIN_ENTRY():
|
||||
return cvt64_sample_t()
|
||||
@@ -20,8 +20,6 @@ description:
|
||||
Note: the real body of code is in `simple_appcall_common.py`.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
@@ -20,8 +20,6 @@ description:
|
||||
Note: the real body of code is in `simple_appcall_common.py`.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
sys.path.append(os.path.dirname(__file__))
|
||||
|
||||
@@ -7,8 +7,6 @@ description:
|
||||
execution.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_dbg
|
||||
import ida_ida
|
||||
import ida_lines
|
||||
|
||||
@@ -6,8 +6,6 @@ description:
|
||||
symbols that the process being debugged, provides.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_dbg
|
||||
import ida_ida
|
||||
import ida_name
|
||||
|
||||
@@ -10,8 +10,6 @@ description:
|
||||
idat -Ldecompile.log -Sdecompile_entry_points.py -c file
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_ida
|
||||
import ida_auto
|
||||
import ida_loader
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
summary: decompile & print current function.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_hexrays
|
||||
import ida_lines
|
||||
import ida_funcs
|
||||
|
||||
@@ -33,8 +33,6 @@ description:
|
||||
author: EiNSTeiN_ (einstein@g3nius.org)
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import idautils
|
||||
|
||||
import ida_kernwin
|
||||
|
||||
@@ -15,8 +15,6 @@ description:
|
||||
author: EiNSTeiN_ (einstein@g3nius.org)
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
import ida_hexrays
|
||||
import ida_bytes
|
||||
|
||||
@@ -12,8 +12,6 @@ description:
|
||||
request that ida displays that using `ida_gdl.display_gdl`.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_pro
|
||||
import ida_hexrays
|
||||
import ida_kernwin
|
||||
|
||||
@@ -8,8 +8,6 @@ description:
|
||||
Note: this is rather crude, not quite "pythonic" code.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import idautils
|
||||
import idc
|
||||
import ida_idaapi
|
||||
|
||||
@@ -8,8 +8,6 @@ description:
|
||||
author: EiNSTeiN_ (einstein@g3nius.org)
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_hexrays
|
||||
|
||||
class cblock_visitor_t(ida_hexrays.ctree_visitor_t):
|
||||
|
||||
@@ -26,7 +26,7 @@ class hint_hooks_t(ida_hexrays.Hexrays_Hooks):
|
||||
elif cit == ida_hexrays.VDI_EXPR:
|
||||
ce = vu.item.e
|
||||
if ce.op == ida_hexrays.cot_call:
|
||||
return 2, "==> ", 1
|
||||
return 0, "==> ", 1
|
||||
if ce.op == ida_hexrays.cit_if:
|
||||
return 1, "condition", 1
|
||||
return 0
|
||||
|
||||
@@ -14,8 +14,6 @@ description:
|
||||
see_also: curpos_details
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import inspect
|
||||
|
||||
import ida_idaapi
|
||||
|
||||
@@ -10,7 +10,6 @@ description:
|
||||
|
||||
author: EiNSTeiN_ (einstein@g3nius.org)
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
import ida_hexrays
|
||||
@@ -168,13 +167,11 @@ class XrefsForm(ida_kernwin.PluginForm):
|
||||
addresses = []
|
||||
for ea in idautils.Functions():
|
||||
|
||||
cfunc = ida_hexrays.decompile(ea)
|
||||
cfunc = ida_hexrays.decompile(ea, flags=ida_hexrays.DECOMP_GXREFS_FORCE)
|
||||
if not cfunc:
|
||||
print('Decompilation of %x failed' % (ea, ))
|
||||
continue
|
||||
|
||||
print(str(cfunc)) # KLUDGE
|
||||
|
||||
for citem in cfunc.treeitems:
|
||||
citem = citem.to_specific_type
|
||||
if not (type(citem) == ida_hexrays.cexpr_t and citem.opname in ('memptr', 'memref')):
|
||||
|
||||
Binary file not shown.
@@ -9,8 +9,6 @@ description:
|
||||
See Linux/arch/arm/include/asm/bug.h for more info
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_idp
|
||||
import ida_bytes
|
||||
import ida_segregs
|
||||
|
||||
@@ -8,7 +8,6 @@ description:
|
||||
* "nothing" -> nop
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import ida_idp
|
||||
import idautils
|
||||
|
||||
|
||||
+98
-2
@@ -404,6 +404,7 @@ across 4 predefined colors (and return to the "no color" state.)
|
||||
<li>ida_kernwin.CK_EXTRA8</li>
|
||||
<li>ida_kernwin.UI_Hooks</li>
|
||||
<li>ida_kernwin.action_desc_t</li>
|
||||
<li>ida_kernwin.action_handler_t</li>
|
||||
<li>ida_kernwin.get_current_viewer</li>
|
||||
<li>ida_kernwin.get_custom_viewer_location</li>
|
||||
<li>ida_kernwin.get_custom_viewer_place_xcoord</li>
|
||||
@@ -1387,6 +1388,43 @@ menu, so as to keep focus on "IDA View-A" and have the
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<h2>Category: cvt64</h2>
|
||||
<div class="c_list" onclick="handle_click()">
|
||||
<div class="example-entry collapsed-entry" name="py_cvt64_sample">
|
||||
<div>
|
||||
<span class="exp-col expander">▹</span>
|
||||
<span class="exp-col collapser" style="display:none">▿</span>
|
||||
<a href="cvt64/py_cvt64_sample.py">py_cvt64_sample</a>: <i>This file contains the CVT64 examples.</i>
|
||||
</div>
|
||||
<div class="details" id="DIV_py_cvt64_sample">
|
||||
|
||||
<pre>
|
||||
For more infortmation see SDK/plugins/cvt64_sample example
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li>Category: cvt64</li>
|
||||
<li>Summary: This file contains the CVT64 examples.</li>
|
||||
<li>View on <a href="https://github.com/idapython/src/blob/master/examples/cvt64/py_cvt64_sample.py">GitHub</a></li>
|
||||
|
||||
|
||||
|
||||
<li>APIs used
|
||||
<ul>
|
||||
<li>ida_idaapi.BADADDR</li>
|
||||
<li>ida_idaapi.BADADDR32</li>
|
||||
<li>ida_netnode.atag</li>
|
||||
<li>ida_netnode.htag</li>
|
||||
<li>ida_netnode.stag</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<h2>Category: debugging</h2>
|
||||
<div class="c_list" onclick="handle_click()">
|
||||
@@ -2944,6 +2982,7 @@ pressed in the Decompiler window.
|
||||
<li>APIs used
|
||||
<ul>
|
||||
<li>ida_funcs.get_func_name</li>
|
||||
<li>ida_hexrays.DECOMP_GXREFS_FORCE</li>
|
||||
<li>ida_hexrays.Hexrays_Hooks</li>
|
||||
<li>ida_hexrays.USE_KEYBOARD</li>
|
||||
<li>ida_hexrays.VDI_EXPR</li>
|
||||
@@ -3418,6 +3457,64 @@ A few notes:
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="example-entry collapsed-entry" name="paint_over_graph">
|
||||
<div>
|
||||
<span class="exp-col expander">▹</span>
|
||||
<span class="exp-col collapser" style="display:none">▿</span>
|
||||
<a href="pyqt/paint_over_graph.py">paint_over_graph</a>: <i>Custom painting on top of graph view edges</i>
|
||||
</div>
|
||||
<div class="details" id="DIV_paint_over_graph">
|
||||
|
||||
<pre>
|
||||
This sample registers an action enabling painting of a recognizable
|
||||
string of text over horizontal nodes edge sections beyond a
|
||||
satisfying size threshold.
|
||||
|
||||
In a disassembly view, open the context menu and select
|
||||
"Paint on edges". This should work for both graph disassembly,
|
||||
and proximity browser.
|
||||
|
||||
Using an "event filter", we will intercept paint events
|
||||
targeted at the disassembly view, let it paint itself, and
|
||||
then add our own markers along.
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li>Category: pyqt</li>
|
||||
<li>Summary: Custom painting on top of graph view edges</li>
|
||||
<li>View on <a href="https://github.com/idapython/src/blob/master/examples/pyqt/paint_over_graph.py">GitHub</a></li>
|
||||
<li>Keywords:
|
||||
ctxmenu
|
||||
UI_Hooks
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li>APIs used
|
||||
<ul>
|
||||
<li>ida_graph.edge_t</li>
|
||||
<li>ida_graph.get_graph_viewer</li>
|
||||
<li>ida_graph.get_viewer_graph</li>
|
||||
<li>ida_graph.point_t</li>
|
||||
<li>ida_graph.viewer_get_gli</li>
|
||||
<li>ida_kernwin.AST_DISABLE_FOR_WIDGET</li>
|
||||
<li>ida_kernwin.AST_ENABLE_FOR_WIDGET</li>
|
||||
<li>ida_kernwin.BWN_DISASM</li>
|
||||
<li>ida_kernwin.PluginForm.FormToPyQtWidget</li>
|
||||
<li>ida_kernwin.UI_Hooks</li>
|
||||
<li>ida_kernwin.action_desc_t</li>
|
||||
<li>ida_kernwin.action_handler_t</li>
|
||||
<li>ida_kernwin.attach_action_to_popup</li>
|
||||
<li>ida_kernwin.get_widget_type</li>
|
||||
<li>ida_kernwin.register_action</li>
|
||||
<li>ida_moves.graph_location_info_t</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3430,7 +3527,7 @@ A few notes:
|
||||
<div class="details" id="DIV_paint_over_navbar">
|
||||
|
||||
<pre>
|
||||
Using an "event filter", we'll intercept paint events
|
||||
Using an "event filter", we will intercept paint events
|
||||
targeted at the navigation band widget, let it paint itself,
|
||||
and then add our own markers on top.
|
||||
</pre>
|
||||
@@ -3888,7 +3985,6 @@ The important bits to enable this are:
|
||||
<li>ida_kernwin.CH_CAN_INS</li>
|
||||
<li>ida_kernwin.CH_HAS_DIRTREE</li>
|
||||
<li>ida_kernwin.CH_MULTI</li>
|
||||
<li>ida_kernwin.CH_NOIDB</li>
|
||||
<li>ida_kernwin.Choose</li>
|
||||
<li>ida_kernwin.Choose.ALL_CHANGED</li>
|
||||
<li>ida_kernwin.Choose.CHCOL_DRAGHINT</li>
|
||||
|
||||
+81
-2
@@ -303,6 +303,7 @@ coloring UI_Hooks
|
||||
* ida_kernwin.CK_EXTRA8
|
||||
* ida_kernwin.UI_Hooks
|
||||
* ida_kernwin.action_desc_t
|
||||
* ida_kernwin.action_handler_t
|
||||
* ida_kernwin.get_current_viewer
|
||||
* ida_kernwin.get_custom_viewer_location
|
||||
* ida_kernwin.get_custom_viewer_place_xcoord
|
||||
@@ -1120,6 +1121,34 @@ actions
|
||||
* ida_kernwin.msg
|
||||
* ida_kernwin.process_ui_action
|
||||
|
||||
</blockquote>
|
||||
|
||||
</details>
|
||||
|
||||
## Category: cvt64
|
||||
|
||||
#### py_cvt64_sample
|
||||
<details>
|
||||
<summary>This file contains the CVT64 examples.</summary>
|
||||
|
||||
<blockquote>
|
||||
|
||||
#### Source code
|
||||
<a href="https://github.com/idapython/src/blob/master/examples/cvt64/py_cvt64_sample.py">cvt64/py_cvt64_sample.py</a>
|
||||
|
||||
#### Category
|
||||
cvt64
|
||||
|
||||
#### Description
|
||||
For more infortmation see SDK/plugins/cvt64_sample example
|
||||
|
||||
#### Uses
|
||||
* ida_idaapi.BADADDR
|
||||
* ida_idaapi.BADADDR32
|
||||
* ida_netnode.atag
|
||||
* ida_netnode.htag
|
||||
* ida_netnode.stag
|
||||
|
||||
</blockquote>
|
||||
|
||||
</details>
|
||||
@@ -2452,6 +2481,7 @@ ctxmenu Hexrays_Hooks
|
||||
|
||||
#### Uses
|
||||
* ida_funcs.get_func_name
|
||||
* ida_hexrays.DECOMP_GXREFS_FORCE
|
||||
* ida_hexrays.Hexrays_Hooks
|
||||
* ida_hexrays.USE_KEYBOARD
|
||||
* ida_hexrays.VDI_EXPR
|
||||
@@ -2859,6 +2889,56 @@ A few notes:
|
||||
* ida_kernwin.find_widget
|
||||
* ida_kernwin.process_ui_action
|
||||
|
||||
</blockquote>
|
||||
|
||||
</details>
|
||||
|
||||
#### paint_over_graph
|
||||
<details>
|
||||
<summary>Custom painting on top of graph view edges</summary>
|
||||
|
||||
<blockquote>
|
||||
|
||||
#### Source code
|
||||
<a href="https://github.com/idapython/src/blob/master/examples/pyqt/paint_over_graph.py">pyqt/paint_over_graph.py</a>
|
||||
|
||||
#### Category
|
||||
pyqt
|
||||
|
||||
#### Description
|
||||
This sample registers an action enabling painting of a recognizable
|
||||
string of text over horizontal nodes edge sections beyond a
|
||||
satisfying size threshold.
|
||||
|
||||
In a disassembly view, open the context menu and select
|
||||
"Paint on edges". This should work for both graph disassembly,
|
||||
and proximity browser.
|
||||
|
||||
Using an "event filter", we will intercept paint events
|
||||
targeted at the disassembly view, let it paint itself, and
|
||||
then add our own markers along.
|
||||
|
||||
#### Keywords
|
||||
ctxmenu UI_Hooks
|
||||
|
||||
#### Uses
|
||||
* ida_graph.edge_t
|
||||
* ida_graph.get_graph_viewer
|
||||
* ida_graph.get_viewer_graph
|
||||
* ida_graph.point_t
|
||||
* ida_graph.viewer_get_gli
|
||||
* ida_kernwin.AST_DISABLE_FOR_WIDGET
|
||||
* ida_kernwin.AST_ENABLE_FOR_WIDGET
|
||||
* ida_kernwin.BWN_DISASM
|
||||
* ida_kernwin.PluginForm.FormToPyQtWidget
|
||||
* ida_kernwin.UI_Hooks
|
||||
* ida_kernwin.action_desc_t
|
||||
* ida_kernwin.action_handler_t
|
||||
* ida_kernwin.attach_action_to_popup
|
||||
* ida_kernwin.get_widget_type
|
||||
* ida_kernwin.register_action
|
||||
* ida_moves.graph_location_info_t
|
||||
|
||||
</blockquote>
|
||||
|
||||
</details>
|
||||
@@ -2876,7 +2956,7 @@ A few notes:
|
||||
pyqt
|
||||
|
||||
#### Description
|
||||
Using an "event filter", we'll intercept paint events
|
||||
Using an "event filter", we will intercept paint events
|
||||
targeted at the navigation band widget, let it paint itself,
|
||||
and then add our own markers on top.
|
||||
|
||||
@@ -3242,7 +3322,6 @@ actions chooser folders
|
||||
* ida_kernwin.CH_CAN_INS
|
||||
* ida_kernwin.CH_HAS_DIRTREE
|
||||
* ida_kernwin.CH_MULTI
|
||||
* ida_kernwin.CH_NOIDB
|
||||
* ida_kernwin.Choose
|
||||
* ida_kernwin.Choose.ALL_CHANGED
|
||||
* ida_kernwin.Choose.CHCOL_DRAGHINT
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
"""
|
||||
summary: custom painting on top of graph view edges
|
||||
|
||||
description:
|
||||
This sample registers an action enabling painting of a recognizable
|
||||
string of text over horizontal nodes edge sections beyond a
|
||||
satisfying size threshold.
|
||||
|
||||
In a disassembly view, open the context menu and select
|
||||
"Paint on edges". This should work for both graph disassembly,
|
||||
and proximity browser.
|
||||
|
||||
Using an "event filter", we will intercept paint events
|
||||
targeted at the disassembly view, let it paint itself, and
|
||||
then add our own markers along.
|
||||
"""
|
||||
|
||||
from PyQt5 import QtCore
|
||||
from PyQt5 import QtGui
|
||||
from PyQt5 import QtWidgets
|
||||
|
||||
import ida_graph
|
||||
import ida_kernwin
|
||||
import ida_moves
|
||||
|
||||
edge_segment_threshold = 50
|
||||
text_color = QtGui.QColor(0, 0, 0)
|
||||
text_antialiasing = True
|
||||
verbose = False
|
||||
|
||||
class painter_t(QtCore.QObject):
|
||||
def __init__(self, w, verbose=False):
|
||||
QtCore.QObject.__init__(self)
|
||||
self.idaview = w
|
||||
self.idaview_pyqt = ida_kernwin.PluginForm.FormToPyQtWidget(w)
|
||||
self.target = self.idaview_pyqt.viewport()
|
||||
self.target.installEventFilter(self)
|
||||
self.painting = False
|
||||
|
||||
def eventFilter(self, receiver, event):
|
||||
if not self.painting and \
|
||||
receiver == self.target 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
|
||||
viewer = ida_graph.get_graph_viewer(self.idaview)
|
||||
graph = ida_graph.get_viewer_graph(viewer)
|
||||
if graph:
|
||||
painter = QtGui.QPainter(receiver)
|
||||
if text_antialiasing:
|
||||
painter.setRenderHints(QtGui.QPainter.TextAntialiasing)
|
||||
else:
|
||||
# this is primarily used for testing
|
||||
font = painter.font()
|
||||
font.setStyleStrategy(font.NoAntialias)
|
||||
painter.setFont(font)
|
||||
painter.setPen(text_color)
|
||||
|
||||
# The edge layout info we retrieve will be in "graph
|
||||
# coordinates". In order to transform those points to
|
||||
# view coordinates we will need the graph location info
|
||||
gli = ida_moves.graph_location_info_t()
|
||||
ida_graph.viewer_get_gli(gli, viewer);
|
||||
def to_view_coords(pt):
|
||||
x = int((pt.x - gli.orgx) * gli.zoom)
|
||||
y = int((pt.y - gli.orgy) * gli.zoom)
|
||||
return ida_graph.point_t(x, y)
|
||||
|
||||
# Let `src_node` be each visible node in the graph...
|
||||
for src_node in range(graph.size()):
|
||||
if not graph.is_visible_node(src_node):
|
||||
continue
|
||||
|
||||
# ...and `dst_node` be each visible node
|
||||
# to which `src_node` is connected
|
||||
for dst_node_idx in range(graph.nsucc(src_node)):
|
||||
dst_node = graph.succ(src_node, dst_node_idx)
|
||||
if not graph.is_visible_node(dst_node):
|
||||
continue
|
||||
|
||||
edge_info = graph.get_edge(ida_graph.edge_t(src_node, dst_node))
|
||||
if edge_info:
|
||||
|
||||
# For all horizontal edge segments satisfying the length requirements...
|
||||
for idx in range(len(edge_info.layout)-1):
|
||||
src = to_view_coords(edge_info.layout[idx])
|
||||
dst = to_view_coords(edge_info.layout[idx+1])
|
||||
if src.y == dst.y and abs(src.x - dst.x) > edge_segment_threshold:
|
||||
off = 6
|
||||
text = "%s -> %s (#%d)" % (src_node, dst_node, idx)
|
||||
if verbose:
|
||||
print("Painting \"%s\"" % text)
|
||||
painter.drawText(min(src.x, dst.x) + off, src.y - off, text)
|
||||
|
||||
painter.end()
|
||||
|
||||
# ...and prevent the widget form painting itself again
|
||||
return True
|
||||
return QtCore.QObject.eventFilter(self, receiver, event)
|
||||
|
||||
painter = None
|
||||
|
||||
class paint_on_edges_t(ida_kernwin.action_handler_t):
|
||||
def activate(self, ctx):
|
||||
if self.get_idaview(ctx):
|
||||
global painter
|
||||
painter = painter_t(ctx.widget)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def update(self, ctx):
|
||||
return ida_kernwin.AST_ENABLE_FOR_WIDGET \
|
||||
if self.get_idaview(ctx) \
|
||||
else ida_kernwin.AST_DISABLE_FOR_WIDGET
|
||||
|
||||
def get_idaview(self, ctx):
|
||||
return ctx.widget if ctx.widget_type == ida_kernwin.BWN_DISASM else None
|
||||
|
||||
action_name = "paint_over_graph:enable"
|
||||
ida_kernwin.register_action(
|
||||
ida_kernwin.action_desc_t(
|
||||
action_name,
|
||||
"Paint on edges",
|
||||
paint_on_edges_t()))
|
||||
|
||||
#
|
||||
# Make sure our action is available for all disassembly views
|
||||
#
|
||||
class context_menu_hooks_t(ida_kernwin.UI_Hooks):
|
||||
def finish_populating_widget_popup(self, widget, popup):
|
||||
if ida_kernwin.get_widget_type(widget) == ida_kernwin.BWN_DISASM:
|
||||
ida_kernwin.attach_action_to_popup(widget, popup, action_name, None)
|
||||
|
||||
hooks = context_menu_hooks_t()
|
||||
hooks.hook()
|
||||
@@ -2,7 +2,7 @@
|
||||
summary: custom painting on top of the navigation band
|
||||
|
||||
description:
|
||||
Using an "event filter", we'll intercept paint events
|
||||
Using an "event filter", we will intercept paint events
|
||||
targeted at the navigation band widget, let it paint itself,
|
||||
and then add our own markers on top.
|
||||
"""
|
||||
|
||||
@@ -6,8 +6,6 @@ description:
|
||||
dump their information to the "Output" window
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import inspect
|
||||
|
||||
import ida_kernwin
|
||||
|
||||
@@ -11,7 +11,6 @@ description:
|
||||
keywords: forms
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
# -----------------------------------------------------------------------
|
||||
# This is an example illustrating how to use the Form class
|
||||
# (c) Hex-Rays
|
||||
|
||||
@@ -8,7 +8,6 @@ description:
|
||||
keywords: graph, actions
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
# -----------------------------------------------------------------------
|
||||
# This is an example illustrating how to use the user graphing functionality
|
||||
# in Python
|
||||
|
||||
@@ -14,8 +14,6 @@ keywords: graph, idaview
|
||||
see_also: wrap_idaview
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
import ida_moves
|
||||
import ida_graph
|
||||
|
||||
@@ -10,8 +10,6 @@ keywords: idaview, graph
|
||||
see_also: custom_graph_with_actions, sync_two_graphs
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# (c) Hex-Rays
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@ description:
|
||||
keywords: listing, actions
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import ida_kernwin
|
||||
import ida_lines
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ keywords: chooser, actions
|
||||
see_also: choose_multi, chooser_with_folders
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import ida_kernwin
|
||||
from ida_kernwin import Choose
|
||||
|
||||
|
||||
@@ -9,10 +9,8 @@ keywords: chooser, actions
|
||||
see_also: choose, chooser_with_folders
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from ida_kernwin import Choose
|
||||
|
||||
|
||||
class MyChoose(Choose):
|
||||
|
||||
def __init__(self, title, nb = 5):
|
||||
|
||||
@@ -80,7 +80,6 @@ SUPVAL_COL2_DATA_TAG = '2'
|
||||
class base_idapython_tree_view_t(ida_kernwin.Choose):
|
||||
|
||||
def __init__(self, title, nitems=100, dirspec_log=True, flags=0):
|
||||
flags |= ida_kernwin.CH_NOIDB
|
||||
flags |= ida_kernwin.CH_MULTI
|
||||
flags |= ida_kernwin.CH_HAS_DIRTREE
|
||||
ida_kernwin.Choose.__init__(self,
|
||||
|
||||
@@ -10,7 +10,6 @@ keywords: chooser, functions
|
||||
see_also: choose, choose_multi, chooser_with_folders
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
import idautils
|
||||
import idc
|
||||
import ida_funcs
|
||||
|
||||
+2
-2
@@ -629,7 +629,7 @@ struct python_highlighter_t : public ida_syntax_highlighter_t
|
||||
int py_major = 0, py_minor= 0;
|
||||
qsscanf(Py_GetVersion(), "%d.%d", &py_major, &py_minor);
|
||||
if ( py_major >= 3 && py_minor >= 5 )
|
||||
add_keywords("async|await", HF_KEYWORD1);
|
||||
add_keywords("async|await", HF_KEYWORD1);
|
||||
if ( py_major >= 3 && py_minor >= 10 )
|
||||
add_keywords("match|case", HF_KEYWORD1);
|
||||
}
|
||||
@@ -984,7 +984,7 @@ bool idapython_plugin_t::init()
|
||||
|
||||
// add new Python keywords as needed
|
||||
python_highlighter.add_new_keywords();
|
||||
|
||||
|
||||
// remove current directory
|
||||
_prepare_sys_path();
|
||||
|
||||
|
||||
@@ -12,6 +12,10 @@ global:
|
||||
PyW_PyListToEa64Vec;
|
||||
PyW_PyListToSizeVec;
|
||||
PyW_PyListToStrVec;
|
||||
PyW_from_jvalue_t;
|
||||
PyW_to_jvalue_t;
|
||||
PyW_from_jobj_t;
|
||||
PyW_to_jobj_t;
|
||||
PyW_ShowCbErr;
|
||||
PyW_SizeVecToPyList;
|
||||
PyW_UvalVecToPyList;
|
||||
|
||||
@@ -13,6 +13,10 @@ EXPORTS
|
||||
PyW_PyListToEa64Vec
|
||||
PyW_PyListToSizeVec
|
||||
PyW_PyListToStrVec
|
||||
PyW_from_jvalue_t
|
||||
PyW_to_jvalue_t
|
||||
PyW_from_jobj_t
|
||||
PyW_to_jobj_t
|
||||
PyW_register_compiled_form
|
||||
PyW_ShowCbErr
|
||||
PyW_TryGetAttrString
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
--- !tapi-tbd
|
||||
tbd-version: 4
|
||||
targets: [ arm64-macos ]
|
||||
targets: [ arm64-macos, x86_64-macos ]
|
||||
install-name: '@executable_path/libpython3.link.dylib'
|
||||
current-version: 3.9
|
||||
compatibility-version: 3.9
|
||||
exports:
|
||||
- targets: [ arm64-macos ]
|
||||
- targets: [ arm64-macos, x86_64-macos ]
|
||||
symbols: [ _PyAST_CompileEx, _PyAST_CompileObject, _PyAST_FromNode, _PyAST_FromNodeObject,
|
||||
_PyAST_Validate, _PyArena_AddPyObject, _PyArena_Free, _PyArena_Malloc,
|
||||
_PyArena_New, _PyArg_Parse, _PyArg_ParseTuple, _PyArg_ParseTupleAndKeywords,
|
||||
|
||||
@@ -102,8 +102,8 @@ else
|
||||
endif
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
ifdef __APPLE_SILICON__
|
||||
# set up a stub .tbd library to link against, see tbd.readme
|
||||
ifdef __MAC__
|
||||
# use a stub .tbd library to link against, see tbd.md
|
||||
TBD_FILE = libpython$(PYTHON_VERSION_MAJOR).tbd
|
||||
# note: this path must be compatible with -L$(R) -lpython3 in pyplg.mak
|
||||
TBD_MODULE_DEP = $(R)$(TBD_FILE)
|
||||
@@ -149,7 +149,6 @@ ifdef DO_IDAMAKE_SIMPLIFY
|
||||
QGENIDAAPI = @echo $(call qcolor,genidaapi) $< && #
|
||||
QGENSWIGHEADER = @echo $(call qcolor,genswigheader) $< && #
|
||||
QINJECT_PYDOC = @echo $(call qcolor,inject_pydoc) $$< && #
|
||||
QINJECT_BASE_HOOKS_FLAGS = @echo $(call qcolor,inject_base_hooks_flags) $< && #
|
||||
QPATCH_CODEGEN = @echo $(call qcolor,patch_codegen) $$< && #
|
||||
QPATCH_H_CODEGEN = @echo $(call qcolor,patch_h_codegen) $$< && #
|
||||
QPATCH_PYTHON_CODEGEN = @echo $(call qcolor,patch_python_codegen) $$< && #
|
||||
@@ -190,7 +189,7 @@ endif
|
||||
ifeq ($(OUT_OF_TREE_BUILD),)
|
||||
IDAT_CMD=TVHEADLESS=1 $(IDAT_PATH)$(SUFF64)
|
||||
else
|
||||
IDAT_CMD=TVHEADLESS=1 IDAPYTHON_DYNLOAD_BASE=$(SDK_BIN_PATH) $(IDAT_PATH)$(SUFF64)
|
||||
IDAT_CMD=TVHEADLESS=1 IDAPYTHON_DYNLOAD_BASE=$(R) $(IDAT_PATH)$(SUFF64)
|
||||
endif
|
||||
|
||||
# envvar HAS_HEXRAYS must have been set by build.py if needed
|
||||
@@ -406,7 +405,7 @@ ifeq ($(OUT_OF_TREE_BUILD),)
|
||||
$(Q)$(CP) $? $@
|
||||
DEST_SIP += $(DEST_SIP310_PYDLL) $(DEST_SIP310_PYI)
|
||||
|
||||
# sip for Python [3.11, ...
|
||||
# sip for Python [3.11, 3.12)
|
||||
DEST_SIP311_DIR:=$(DEST_PYQT_DIR)/python_3.11
|
||||
$(DEST_SIP311_DIR):
|
||||
-$(Q)if [ ! -d "$(DEST_SIP311_DIR)" ] ; then mkdir -p 2>/dev/null $(DEST_SIP311_DIR) ; fi
|
||||
@@ -418,20 +417,36 @@ ifeq ($(OUT_OF_TREE_BUILD),)
|
||||
$(Q)$(CP) $? $@
|
||||
DEST_SIP += $(DEST_SIP311_PYDLL) $(DEST_SIP311_PYI)
|
||||
|
||||
# sip for Python [3.12, ...
|
||||
DEST_SIP312_DIR:=$(DEST_PYQT_DIR)/python_3.12
|
||||
$(DEST_SIP312_DIR):
|
||||
-$(Q)if [ ! -d "$(DEST_SIP312_DIR)" ] ; then mkdir -p 2>/dev/null $(DEST_SIP312_DIR) ; fi
|
||||
DEST_SIP312_PYDLL:=$(DEST_SIP312_DIR)/$(SIP_PYDLL_FNAME)
|
||||
DEST_SIP312_PYI:=$(DEST_SIP312_DIR)/$(SIP_PYI_FNAME)
|
||||
$(DEST_SIP312_PYDLL): $(wildcard $(SIP312_TREE)/lib/python*/PyQt5/$(SIP_PYDLL_FNAME)) | $(DEST_SIP312_DIR)
|
||||
$(Q)$(CP) $? $@
|
||||
$(DEST_SIP312_PYI): $(wildcard $(SIP312_TREE)/lib/python*/PyQt5/$(SIP_PYI_FNAME)) | $(DEST_SIP312_DIR)
|
||||
$(Q)$(CP) $? $@
|
||||
DEST_SIP += $(DEST_SIP312_PYDLL) $(DEST_SIP312_PYI)
|
||||
|
||||
# And pick the right sip.so now (Python3 only; for Python2, we already put it in the right place)
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 10; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP311_PYDLL)
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 11; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP312_PYDLL)
|
||||
else
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 9; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP310_PYDLL)
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 10; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP311_PYDLL)
|
||||
else
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 8; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP39_PYDLL)
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 9; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP310_PYDLL)
|
||||
else
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 7; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP38_PYDLL)
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 8; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP39_PYDLL)
|
||||
else
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP34_PYDLL)
|
||||
ifeq ($(shell test $(PYTHON_VERSION_MINOR) -gt 7; echo $$?),0) # ugh
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP38_PYDLL)
|
||||
else
|
||||
DEST_INSTALL_SIP_PYDLL:=$(DEST_SIP34_PYDLL)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@@ -652,11 +667,6 @@ find-pywraps-deps = $(wildcard pywraps/py_$(subst .i,,$(notdir $(1)))*.hpp) $(wi
|
||||
find-pydoc-patches-deps = $(wildcard tools/inject_pydoc/$(1).py)
|
||||
find-patch-codegen-deps = $(wildcard tools/patch_codegen/*$(1)*.py)
|
||||
|
||||
ADDITIONAL_PYWRAP_DEP_idaapi=$(ST_PYW)/py_idaapi.hpp
|
||||
$(ST_PYW)/py_idaapi.hpp: pywraps/py_idaapi.hpp.in tools/inject_base_hooks_flags.py pywraps.hpp
|
||||
$(QINJECT_BASE_HOOKS_FLAGS)$(PYTHON) tools/inject_base_hooks_flags.py -i $< -o $@ -f pywraps.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
|
||||
# so they will be picked by the auto-generated rules.
|
||||
@@ -706,7 +716,7 @@ define make-module-rules
|
||||
--verbose > $(ST_WRAP)/ida_$(1).pydoc_injection
|
||||
|
||||
# obj/x86_linux_gcc/swig/X.i
|
||||
$(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)
|
||||
$(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 $(PARSED_HEADERS_MARKER)
|
||||
$(QDEPLOY)$(PYTHON) tools/deploy.py \
|
||||
--pywraps $(ST_PYW) \
|
||||
--template $$(subst $(F),,$$@) \
|
||||
@@ -847,7 +857,11 @@ else
|
||||
DUMPDOC_IS_64:=False
|
||||
endif
|
||||
|
||||
PYDOC_INJECTIONS_IDAT_CMD=$(IDAT_CMD) $(BATCH_SWITCH) -S"$< $(ST_PYDOC_INJECTIONS) $(ST_WRAP) $(DUMPDOC_IS_64)" -t -L$(F)dumpdoc.log >/dev/null
|
||||
ifndef NOTEAMS
|
||||
VAULT_SERVER_OPTS=-Ovault:host=$(TEAMS_BUILD_HOST):port=$(TEAMS_BUILD_PORT):user=$(TEAMS_BUILD_USER):pass=$(TEAMS_BUILD_PASS)
|
||||
endif
|
||||
|
||||
PYDOC_INJECTIONS_IDAT_CMD=$(IDAT_CMD) $(BATCH_SWITCH) $(VAULT_SERVER_OPTS) -S"$< $(ST_PYDOC_INJECTIONS) $(ST_WRAP) $(DUMPDOC_IS_64)" -t -L$(F)dumpdoc.log >/dev/null
|
||||
pydoc_injections: $(ST_PYDOC_INJECTIONS_SUCCESS)
|
||||
$(ST_PYDOC_INJECTIONS_SUCCESS): tools/dumpdoc.py $(IDAPYTHON_MODULES) $(PYTHON_BINARY_MODULES)
|
||||
ifeq ($(or $(__CODE_CHECKER__),$(NO_CMP_API),$(__ASAN__),$(IDAHOME),$(DEMO_OR_FREE)),)
|
||||
@@ -922,7 +936,7 @@ endif
|
||||
$(R)idapyswitch$(B): $(call dumb_target, pro, $(IDAPYSWITCH_OBJS))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
ifdef __APPLE_SILICON__
|
||||
ifdef __MAC__
|
||||
tbd: $(TBD_MODULE_DEP)
|
||||
# copy the tbd library to idabin, and instruct idapyswitch to create the symlink to libpython
|
||||
$(TBD_MODULE_DEP): $(TBD_FILE) $(IDAPYSWITCH_DEP)
|
||||
@@ -993,10 +1007,10 @@ $(F)idapyswitch$(O): $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)exehdr.h $(I)fixup.hpp $(I)fpro.h $(I)funcs.hpp \
|
||||
$(I)ida.hpp $(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp \
|
||||
$(I)lines.hpp $(I)llong.hpp $(I)loader.hpp $(I)lzfse.h \
|
||||
$(I)lzvn_decode_base.h $(I)nalt.hpp $(I)name.hpp \
|
||||
$(I)netnode.hpp $(I)network.hpp $(I)offset.hpp $(I)pro.h \
|
||||
$(I)prodir.h $(I)range.hpp $(I)segment.hpp \
|
||||
$(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp \
|
||||
$(I)lzvn_decode_base.h $(I)md5.h $(I)nalt.hpp \
|
||||
$(I)name.hpp $(I)netnode.hpp $(I)network.hpp \
|
||||
$(I)offset.hpp $(I)pro.h $(I)prodir.h $(I)range.hpp \
|
||||
$(I)segment.hpp $(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp \
|
||||
../../ldr/ar/aixar.hpp ../../ldr/ar/ar.hpp \
|
||||
../../ldr/ar/arcmn.cpp ../../ldr/elf/../idaldr.h \
|
||||
../../ldr/elf/elf.h ../../ldr/elf/elfbase.h \
|
||||
@@ -1065,8 +1079,9 @@ $(F)idapython$(O): $(I)bitrange.hpp $(I)bytes.hpp $(I)config.hpp \
|
||||
$(I)diskio.hpp $(I)err.h $(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 extapi.cpp extapi.hpp \
|
||||
idapython.cpp pywraps.cpp pywraps.hpp
|
||||
$(I)ieee.h $(I)kernwin.hpp $(I)lex.hpp $(I)lines.hpp \
|
||||
$(I)llong.hpp $(I)loader.hpp $(I)nalt.hpp $(I)name.hpp \
|
||||
$(I)netnode.hpp $(I)parsejson.hpp $(I)pro.h \
|
||||
$(I)range.hpp $(I)segment.hpp $(I)typeinf.hpp $(I)ua.hpp \
|
||||
$(I)xref.hpp extapi.cpp \
|
||||
extapi.hpp idapython.cpp pywraps.cpp pywraps.hpp
|
||||
|
||||
+3
-1
@@ -1 +1,3 @@
|
||||
-esym(4100, obj) // unreferenced formal parameter
|
||||
-esym(4100, obj) // unreferenced formal parameter
|
||||
-esym(2586, PySys_SetPath) // w2586 Function 'PySys_SetPath' is deprecated
|
||||
|
||||
|
||||
Binary file not shown.
+800
-397
File diff suppressed because it is too large
Load Diff
+746
-395
File diff suppressed because it is too large
Load Diff
+5
-8
@@ -249,7 +249,10 @@ def Modules():
|
||||
mod = ida_idd.modinfo_t()
|
||||
result = ida_dbg.get_first_module(mod)
|
||||
while result:
|
||||
yield mod
|
||||
# Note: can't simply return `mod` here, since callers might
|
||||
# collect all modules in a list, and they would all re-use
|
||||
# the underlying C++ object.
|
||||
yield ida_idaapi.object_t(name=mod.name, size=mod.size, base=mod.base, rebase_to=mod.rebase_to)
|
||||
result = ida_dbg.get_next_module(mod)
|
||||
|
||||
|
||||
@@ -432,13 +435,7 @@ def MapDataList(ea, length, func, wordsize=1):
|
||||
PutDataList(ea, map(func, GetDataList(ea, length, wordsize)), wordsize)
|
||||
|
||||
|
||||
def GetInputFileMD5():
|
||||
"""
|
||||
Return the MD5 hash of the input binary file
|
||||
|
||||
@return: MD5 string or None on error
|
||||
"""
|
||||
return idc.retrieve_input_file_md5()
|
||||
GetInputFileMD5 = ida_nalt.retrieve_input_file_md5
|
||||
|
||||
|
||||
class Strings(object):
|
||||
|
||||
+18
-13
@@ -1027,13 +1027,13 @@ def split_sreg_range(ea, reg, value, tag=SR_user):
|
||||
|
||||
@note: IDA keeps tracks of all the points where segment register change their
|
||||
values. This function allows you to specify the correct value of a segment
|
||||
register if IDA is not able to find the corrent value.
|
||||
register if IDA is not able to find the correct value.
|
||||
"""
|
||||
reg = ida_idp.str2reg(reg);
|
||||
if reg >= 0:
|
||||
return ida_segregs.split_sreg_range(ea, reg, value, tag)
|
||||
else:
|
||||
return False
|
||||
rnames = [r.casefold() for r in ida_idp.ph_get_regnames()]
|
||||
for regno in range(ida_idp.ph_get_reg_first_sreg(), ida_idp.ph_get_reg_last_sreg()+1):
|
||||
if rnames[regno]==reg.casefold():
|
||||
return ida_segregs.split_sreg_range(ea, regno, value, tag)
|
||||
return False
|
||||
|
||||
|
||||
auto_mark_range = ida_auto.auto_mark_range
|
||||
@@ -2641,13 +2641,18 @@ MSF_NOFIX = 0x0002 # don't call the loader to fix relocations
|
||||
MSF_LDKEEP = 0x0004 # keep the loader in the memory (optimization)
|
||||
MSF_FIXONCE = 0x0008 # valid for rebase_program(): call loader only once
|
||||
|
||||
MOVE_SEGM_OK = 0 # all ok
|
||||
MOVE_SEGM_PARAM = -1 # The specified segment does not exist
|
||||
MOVE_SEGM_ROOM = -2 # Not enough free room at the target address
|
||||
MOVE_SEGM_IDP = -3 # IDP module forbids moving the segment
|
||||
MOVE_SEGM_CHUNK = -4 # Too many chunks are defined, can't move
|
||||
MOVE_SEGM_LOADER = -5 # The segment has been moved but the loader complained
|
||||
MOVE_SEGM_ODD = -6 # Can't move segments by an odd number of bytes
|
||||
MOVE_SEGM_OK = 0 # all ok
|
||||
MOVE_SEGM_PARAM = -1 # The specified segment does not exist
|
||||
MOVE_SEGM_ROOM = -2 # Not enough free room at the target address
|
||||
MOVE_SEGM_IDP = -3 # IDP module forbids moving the segment
|
||||
MOVE_SEGM_CHUNK = -4 # Too many chunks are defined, can't move
|
||||
MOVE_SEGM_LOADER = -5 # The segment has been moved but the loader complained
|
||||
MOVE_SEGM_ODD = -6 # Can't move segments by an odd number of bytes
|
||||
MOVE_SEGM_ORPHAN = -7, # Orphan bytes hinder segment movement
|
||||
MOVE_SEGM_DEBUG = -8, # Debugger segments cannot be moved
|
||||
MOVE_SEGM_SOURCEFILES = -9, # Source files ranges of addresses hinder segment movement
|
||||
MOVE_SEGM_MAPPING = -10, # Memory mapping ranges of addresses hinder segment movement
|
||||
MOVE_SEGM_INVAL = -11, # Invalid argument (delta/target does not fit the address space)
|
||||
|
||||
|
||||
rebase_program = ida_segment.rebase_program
|
||||
|
||||
+93
-2
@@ -1,6 +1,7 @@
|
||||
|
||||
#include <pro.h>
|
||||
#include <ieee.h>
|
||||
#include <parsejson.hpp>
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
@@ -267,6 +268,83 @@ Py_ssize_t ida_export PyW_PyListToStrVec(qstrvec_t *out, PyObject *py_list)
|
||||
return pyvar_walk_list(py_list, lambda_t::cvt, out);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *ida_export PyW_from_jvalue_t(const jvalue_t &v)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ( v.type() == JT_UNKNOWN )
|
||||
break;
|
||||
newref_t json_module(PyImport_ImportModule("json"));
|
||||
if ( !json_module )
|
||||
break;
|
||||
borref_t json_globals(PyModule_GetDict(json_module.o));
|
||||
if ( !json_globals )
|
||||
break;
|
||||
borref_t json_loads(PyDict_GetItemString(json_globals.o, "loads"));
|
||||
if ( !json_loads )
|
||||
break;
|
||||
qstring clob;
|
||||
if ( !serialize_json(&clob, v) )
|
||||
break;
|
||||
ref_t dict = newref_t(PyObject_CallFunction(json_loads.o, "s", clob.c_str()));
|
||||
if ( !dict )
|
||||
break;
|
||||
dict.incref();
|
||||
return dict.o;
|
||||
} while ( false );
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
bool ida_export PyW_to_jvalue_t(jvalue_t *out, PyObject *py)
|
||||
{
|
||||
do
|
||||
{
|
||||
newref_t json_module(PyImport_ImportModule("json"));
|
||||
if ( !json_module )
|
||||
break;
|
||||
borref_t json_globals(PyModule_GetDict(json_module.o));
|
||||
if ( !json_globals )
|
||||
break;
|
||||
borref_t json_dumps(PyDict_GetItemString(json_globals.o, "dumps"));
|
||||
if ( !json_dumps )
|
||||
break;
|
||||
newref_t str(PyObject_CallFunction(json_dumps.o, "O", py));
|
||||
qstring buf;
|
||||
if ( !PyUnicode_as_qstring(&buf, str.o) )
|
||||
break;
|
||||
if ( parse_json_string(out, buf.c_str()) != eOk )
|
||||
break;
|
||||
return true;
|
||||
} while ( false );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *ida_export PyW_from_jobj_t(const jobj_t &o)
|
||||
{
|
||||
jvalue_t v;
|
||||
v.set_obj((jobj_t *) &o);
|
||||
PyObject *rc = PyW_from_jvalue_t(v);
|
||||
v.extract_obj();
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
bool ida_export PyW_to_jobj_t(jobj_t *out, PyObject *py)
|
||||
{
|
||||
if ( !PyDict_Check(py) )
|
||||
return false;
|
||||
jvalue_t v;
|
||||
bool rc = PyW_to_jvalue_t(&v, py) && v.type() == JT_OBJ;
|
||||
if ( rc )
|
||||
out->swap(v.obj());
|
||||
return rc;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
PyObject *ida_export meminfo_vec_t_to_py(meminfo_vec_t &ranges)
|
||||
{
|
||||
@@ -1643,19 +1721,32 @@ bool ida_export py_customidamemo_t_bind(py_customidamemo_t *_this, PyObject *sel
|
||||
|
||||
_this->self = borref_t(self);
|
||||
_this->view = view;
|
||||
newref_t result(PyObject_CallMethod(self, (char *)"_OnBind", "O", Py_True));
|
||||
|
||||
if ( !result && PyErr_Occurred() != nullptr )
|
||||
{
|
||||
msg("WARNING: Couldn't bind form object at %p:\n", self);
|
||||
PyErr_Print();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
void ida_export py_customidamemo_t_unbind(py_customidamemo_t *_this, bool clear_view)
|
||||
void ida_export py_customidamemo_t_unbind(py_customidamemo_t *_this)
|
||||
{
|
||||
if ( _this->self == nullptr )
|
||||
return;
|
||||
PYGLOG("%p: py_customidamemo_t::unbind(); self.o=%p, view=%p\n", _this, _this->self.o, _this->view);
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
newref_t result(PyObject_CallMethod(_this->self.o, (char *)"_OnBind", "O", Py_False));
|
||||
if ( !result && PyErr_Occurred() != nullptr )
|
||||
{
|
||||
msg("WARNING: Couldn't unbind form object at %p:\n", _this->self.o);
|
||||
PyErr_Print();
|
||||
}
|
||||
|
||||
PyObject_SetAttrString(_this->self.o, S_M_THIS, Py_None);
|
||||
_this->self = newref_t(nullptr);
|
||||
if ( clear_view )
|
||||
_this->view = nullptr;
|
||||
}
|
||||
|
||||
|
||||
+14
-10
@@ -28,6 +28,9 @@ typedef PY_LONG_LONG bvsval_t;
|
||||
class insn_t;
|
||||
class op_t;
|
||||
struct switch_info_t;
|
||||
struct jobj_t;
|
||||
struct jarr_t;
|
||||
struct jvalue_t;
|
||||
|
||||
// "A pointer can be explicitly converted to any integral type large
|
||||
// enough to hold it. The mapping function is implementation-defined."
|
||||
@@ -507,6 +510,11 @@ idaman Py_ssize_t ida_export PyW_PyListToSizeVec(sizevec_t *out, PyObject *py_li
|
||||
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);
|
||||
|
||||
idaman PyObject *ida_export PyW_from_jvalue_t(const jvalue_t &v);
|
||||
idaman bool ida_export PyW_to_jvalue_t(jvalue_t *out, PyObject *py);
|
||||
idaman PyObject *ida_export PyW_from_jobj_t(const jobj_t &o);
|
||||
idaman bool ida_export PyW_to_jobj_t(jobj_t *out, PyObject *py);
|
||||
|
||||
#ifndef LUMINA_HPP // I'd rather put the def of ea64_t and ea64vec_t into pro.h...
|
||||
#ifdef __EA64__
|
||||
typedef ea_t ea64_t;
|
||||
@@ -682,9 +690,9 @@ struct pycim_callbacks_ids_t : public qvector<pycim_callback_id_t>
|
||||
#define PY_CIM_PARAMS_bind (PyObject *in_self, TWidget *in_view)
|
||||
#define PY_CIM_TRANSM_bind (this, in_self, in_view)
|
||||
|
||||
#define PY_CIM_HLPPRM_unbind (py_customidamemo_t *_this, bool clear_view)
|
||||
#define PY_CIM_PARAMS_unbind (bool clear_view)
|
||||
#define PY_CIM_TRANSM_unbind (this, clear_view)
|
||||
#define PY_CIM_HLPPRM_unbind (py_customidamemo_t *_this)
|
||||
#define PY_CIM_PARAMS_unbind ()
|
||||
#define PY_CIM_TRANSM_unbind (this)
|
||||
|
||||
#define DECL_CIM_HELPER(decl, RType, MName, MParams) \
|
||||
decl RType ida_export py_customidamemo_t_##MName MParams
|
||||
@@ -1093,7 +1101,7 @@ py_customidamemo_t::py_customidamemo_t()
|
||||
py_customidamemo_t::~py_customidamemo_t()
|
||||
{
|
||||
PYGLOG("%p: ~py_customidamemo_t()\n", this);
|
||||
unbind(true);
|
||||
unbind();
|
||||
get_plugin_instance()->pycim_lookup_info.del_by_py_view(this);
|
||||
}
|
||||
|
||||
@@ -1272,13 +1280,13 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TESTABLE_BUILD
|
||||
PyObject *dump_state(
|
||||
const event_code_to_method_name_t *mappings,
|
||||
size_t mappings_size,
|
||||
bool assert_all_reimplemented) const
|
||||
{
|
||||
qstring buf;
|
||||
#ifdef TESTABLE_BUILD
|
||||
qstrvec_t missing_reimpls;
|
||||
buf.sprnt("%s(this=%p) \"%s\" {type=%d, cb=%p, flags=%x}",
|
||||
class_name, this, identifier.c_str(), int(type), listener.cb, flags);
|
||||
@@ -1327,13 +1335,9 @@ protected:
|
||||
}
|
||||
if ( buf.last() != '\n' )
|
||||
buf.append('\n');
|
||||
#else
|
||||
qnotused(mappings);
|
||||
qnotused(mappings_size);
|
||||
qnotused(assert_all_reimplemented);
|
||||
#endif
|
||||
return PyUnicode_from_qstring(buf);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@@ -93,6 +93,38 @@ static bool py_do_get_bytes(
|
||||
|
||||
//<inline(py_bytes)>
|
||||
|
||||
#define MS_0TYPE 0x00F00000LU ///< Mask for 1st arg typing
|
||||
#define FF_0VOID 0x00000000LU ///< Void (unknown)?
|
||||
#define FF_0NUMH 0x00100000LU ///< Hexadecimal number?
|
||||
#define FF_0NUMD 0x00200000LU ///< Decimal number?
|
||||
#define FF_0CHAR 0x00300000LU ///< Char ('x')?
|
||||
#define FF_0SEG 0x00400000LU ///< Segment?
|
||||
#define FF_0OFF 0x00500000LU ///< Offset?
|
||||
#define FF_0NUMB 0x00600000LU ///< Binary number?
|
||||
#define FF_0NUMO 0x00700000LU ///< Octal number?
|
||||
#define FF_0ENUM 0x00800000LU ///< Enumeration?
|
||||
#define FF_0FOP 0x00900000LU ///< Forced operand?
|
||||
#define FF_0STRO 0x00A00000LU ///< Struct offset?
|
||||
#define FF_0STK 0x00B00000LU ///< Stack variable?
|
||||
#define FF_0FLT 0x00C00000LU ///< Floating point number?
|
||||
#define FF_0CUST 0x00D00000LU ///< Custom representation?
|
||||
|
||||
#define MS_1TYPE 0x0F000000LU ///< Mask for the type of other operands
|
||||
#define FF_1VOID 0x00000000LU ///< Void (unknown)?
|
||||
#define FF_1NUMH 0x01000000LU ///< Hexadecimal number?
|
||||
#define FF_1NUMD 0x02000000LU ///< Decimal number?
|
||||
#define FF_1CHAR 0x03000000LU ///< Char ('x')?
|
||||
#define FF_1SEG 0x04000000LU ///< Segment?
|
||||
#define FF_1OFF 0x05000000LU ///< Offset?
|
||||
#define FF_1NUMB 0x06000000LU ///< Binary number?
|
||||
#define FF_1NUMO 0x07000000LU ///< Octal number?
|
||||
#define FF_1ENUM 0x08000000LU ///< Enumeration?
|
||||
#define FF_1FOP 0x09000000LU ///< Forced operand?
|
||||
#define FF_1STRO 0x0A000000LU ///< Struct offset?
|
||||
#define FF_1STK 0x0B000000LU ///< Stack variable?
|
||||
#define FF_1FLT 0x0C000000LU ///< Floating point number?
|
||||
#define FF_1CUST 0x0D000000LU ///< Custom representation?
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
|
||||
@@ -324,9 +324,9 @@ public:
|
||||
|
||||
// Form already created? try to get associated py_graph instance
|
||||
// so that we reuse it
|
||||
TWidget *existing = find_widget(title.c_str());
|
||||
if ( existing != nullptr )
|
||||
get_plugin_instance()->pycim_lookup_info.find_by_view((py_customidamemo_t**) &py_graph, existing);
|
||||
TWidget *view = find_widget(title.c_str());
|
||||
if ( view != nullptr )
|
||||
get_plugin_instance()->pycim_lookup_info.find_by_view((py_customidamemo_t**) &py_graph, view);
|
||||
|
||||
if ( py_graph == nullptr )
|
||||
{
|
||||
@@ -335,8 +335,10 @@ public:
|
||||
else
|
||||
{
|
||||
// unbind so we are rebound
|
||||
py_graph->unbind(false);
|
||||
py_graph->unbind();
|
||||
py_graph->bind(self, view);
|
||||
py_graph->refresh_needed = true;
|
||||
refresh_viewer(view); // cfr graph.hpp how to refresh an existing mutable_graph_t
|
||||
}
|
||||
if ( py_graph->initialize(self, title.c_str()) < 0 )
|
||||
{
|
||||
|
||||
@@ -117,6 +117,12 @@ class GraphViewer(ida_kernwin.CustomIDAMemo):
|
||||
def OnCommand(self, cmd_id):
|
||||
return 0
|
||||
|
||||
def _OnBind(self, hook):
|
||||
if hook:
|
||||
self.ui_hooks_trampoline.hook()
|
||||
else:
|
||||
self.ui_hooks_trampoline.unhook()
|
||||
super()._OnBind(hook)
|
||||
|
||||
#<pydoc>
|
||||
# def OnGetText(self, node_id):
|
||||
|
||||
@@ -104,8 +104,9 @@ static void ida_idaapi_closebase(void) {}
|
||||
|
||||
|
||||
//<inline(py_idaapi)>
|
||||
|
||||
${BASE_HOOKS_FLAGS}
|
||||
// NOTE: See also `pywraps.hpp`
|
||||
#define HBF_CALL_WITH_NEW_EXEC 0x00000001
|
||||
#define HBF_VOLATILE_METHOD_SET 0x00000002
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
+2
-71
@@ -346,25 +346,6 @@ PyObject *py_ask_str(qstring *defval, int hist, const char *prompt)
|
||||
return py_ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
def str2ea(addr):
|
||||
"""
|
||||
Converts a string express to EA. The expression evaluator may be called as well.
|
||||
|
||||
@return: BADADDR or address value
|
||||
"""
|
||||
pass
|
||||
#</pydoc>
|
||||
*/
|
||||
ea_t py_str2ea(const char *str, ea_t screenEA = BADADDR)
|
||||
{
|
||||
ea_t ea;
|
||||
bool ok = str2ea(&ea, str, screenEA);
|
||||
return ok ? ea : BADADDR;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
@@ -771,62 +752,12 @@ public:
|
||||
|
||||
PyObject *get_dict()
|
||||
{
|
||||
do
|
||||
{
|
||||
newref_t json_module(PyImport_ImportModule("json"));
|
||||
if ( !json_module )
|
||||
break;
|
||||
borref_t json_globals(PyModule_GetDict(json_module.o));
|
||||
if ( !json_globals )
|
||||
break;
|
||||
borref_t json_loads(PyDict_GetItemString(json_globals.o, "loads"));
|
||||
if ( !json_loads )
|
||||
break;
|
||||
|
||||
qstring clob;
|
||||
if ( !serialize_json(&clob, o) )
|
||||
break;
|
||||
|
||||
if ( ref_t dict = newref_t(PyObject_CallFunction(json_loads.o, "s", clob.c_str())) )
|
||||
{
|
||||
dict.incref();
|
||||
return dict.o;
|
||||
}
|
||||
|
||||
} while ( false );
|
||||
Py_RETURN_NONE;
|
||||
return PyW_from_jobj_t(*o);
|
||||
}
|
||||
|
||||
static bool fill_jobj_from_dict(jobj_t *out, PyObject *dict)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ( !PyDict_Check(dict) )
|
||||
break;
|
||||
newref_t json_module(PyImport_ImportModule("json"));
|
||||
if ( !json_module )
|
||||
break;
|
||||
borref_t json_globals(PyModule_GetDict(json_module.o));
|
||||
if ( !json_globals )
|
||||
break;
|
||||
|
||||
borref_t json_dumps(PyDict_GetItemString(json_globals.o, "dumps"));
|
||||
if ( !json_dumps )
|
||||
break;
|
||||
|
||||
newref_t str(PyObject_CallFunction(json_dumps.o, "O", dict));
|
||||
qstring buf;
|
||||
if ( PyUnicode_as_qstring(&buf, str.o) )
|
||||
{
|
||||
jvalue_t tmp;
|
||||
if ( parse_json_string(&tmp, buf.c_str()) == eOk )
|
||||
{
|
||||
out->swap(tmp.obj());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} while ( false );
|
||||
return false;
|
||||
return PyW_to_jobj_t(out, dict);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -995,6 +995,8 @@ PyObject *py_get_chooser_data(const char *chooser_caption, int n)
|
||||
return py_list;
|
||||
}
|
||||
|
||||
#define CH_NOIDB 0x00000040 // bw-compat
|
||||
|
||||
//</inline(py_kernwin_choose)>
|
||||
|
||||
#endif // __PY_KERNWIN_CHOOSE__
|
||||
|
||||
@@ -57,7 +57,7 @@ bool py_idaview_t::Unbind(PyObject *self)
|
||||
py_idaview_t *_this = (py_idaview_t *) view_extract_this(self);
|
||||
if ( _this == nullptr )
|
||||
return false;
|
||||
_this->unbind(true);
|
||||
_this->unbind();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -96,6 +96,12 @@ class CustomIDAMemo(View_Hooks):
|
||||
gitpl = self._graph_item_tuple(ve)
|
||||
return cb(ve.x, ve.y, ve.state, len(gitpl), gitpl, ve.renderer_pos)
|
||||
|
||||
def _OnBind(self, hook):
|
||||
if hook:
|
||||
self.hook()
|
||||
else:
|
||||
self.unhook()
|
||||
|
||||
# End of hooks->wrapper trampolines
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
|
||||
#<pycode(py_lumina)>
|
||||
import ida_bytes
|
||||
import ida_typeinf
|
||||
import ida_ida
|
||||
import ida_pro
|
||||
|
||||
class simple_idb_diff_handler_t(func_md_diff_handler_t):
|
||||
|
||||
NO_DATA_MARKER = None
|
||||
|
||||
class indenter_t(object):
|
||||
def __init__(self, handler):
|
||||
self.handler = handler
|
||||
self.handler.indent += 1
|
||||
def __del__(self):
|
||||
self.handler.indent -= 1
|
||||
|
||||
def __init__(self, pfn):
|
||||
super(self.__class__, self).__init__()
|
||||
self.pfn = pfn
|
||||
self.header_generated = False
|
||||
self.lines = []
|
||||
self.indent = 0
|
||||
|
||||
def on_score_changed(self, l, r):
|
||||
self.put2(str(l), str(r), "Score")
|
||||
|
||||
def on_name_changed(self, l, r):
|
||||
self.put2(l, r, "Name")
|
||||
|
||||
def on_proto_changed(self, l, r):
|
||||
self.put2(self.format_type(l), self.format_type(r), "Prototype")
|
||||
|
||||
def on_function_comment_changed(self, l, r, rep):
|
||||
self.put2(l, r, "Function comment (%s)" % ("repeatable" if rep else "regular"))
|
||||
|
||||
def on_comment_changed(self, fchunk_nr, fchunk_off, l, r, rep):
|
||||
loc = self.where(fchunk_nr, fchunk_off)
|
||||
self.put2(l, r, "%s comment @ %s" % ("repeatable" if rep else "regular", loc))
|
||||
|
||||
def on_extra_comment_changed(self, fchunk_nr, fchunk_off, l, r, is_prev):
|
||||
loc = self.where(fchunk_nr, fchunk_off)
|
||||
self.put2(self.format_extra_cmt(l),
|
||||
self.format_extra_cmt(r),
|
||||
"%sterior extra comment @ %s" % ("An" if is_prev else "Pos", loc))
|
||||
|
||||
def on_user_stkpnt_changed(self, fchunk_nr, fchunk_off, l, r):
|
||||
loc = self.where(fchunk_nr, fchunk_off)
|
||||
self.put2(self.format_stkpnt(l),
|
||||
self.format_stkpnt(r),
|
||||
"User stack point @ %s" % loc)
|
||||
|
||||
def on_frame_member_changed(self, offset, l, r):
|
||||
self.ensure_header_generated()
|
||||
self.put("Member @ 0x%X" % offset)
|
||||
|
||||
indenter = self.indenter_t(self)
|
||||
ltype, loprepr, lcmt, lrptcmt = self.format_frame_member(l)
|
||||
rtype, roprepr, rcmt, rrptcmt = self.format_frame_member(r)
|
||||
|
||||
cmp_put = lambda l, r, topic: self.put2(l, r, topic) if l != r else None
|
||||
cmp_put(ltype, rtype, ".type")
|
||||
cmp_put(loprepr, roprepr, ".opinfo")
|
||||
cmp_put(lcmt, rcmt, ".cmt")
|
||||
cmp_put(lrptcmt, rrptcmt, ".rptcmt")
|
||||
|
||||
def on_insn_ops_repr_changed(self, fchunk_nr, fchunk_off, l, r):
|
||||
loc = self.where(fchunk_nr, fchunk_off)
|
||||
ls, rs = self.format_insn_ops(l), self.format_insn_ops(r)
|
||||
self.put2(ls, rs, "Insn operands @ %s" % loc)
|
||||
|
||||
# --- helpers ---
|
||||
|
||||
def ensure_header_generated(self):
|
||||
if not self.header_generated:
|
||||
self.lines.append("")
|
||||
self.lines.append("Function 0x%X" % self.pfn.start_ea)
|
||||
self.header_generated = True
|
||||
|
||||
def where(self, fchunk_nr, fchunk_off):
|
||||
site = insn_site_t()
|
||||
site.fchunk_nr = fchunk_nr
|
||||
site.fchunk_off = fchunk_off
|
||||
return "0x%X" % site.toea(self.pfn)
|
||||
|
||||
def format_type(self, type_parts):
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if tif.deserialize(None, type_parts.type, type_parts.fields):
|
||||
return tif._print()
|
||||
|
||||
def format_extra_cmt(self, cmt):
|
||||
if cmt:
|
||||
cmt = ida_pro.str2user(cmt)
|
||||
return cmt
|
||||
|
||||
def format_stkpnt(self, stkpnt):
|
||||
if stkpnt is not None:
|
||||
return "%d" % stkpnt
|
||||
|
||||
def format_frame_member(self, m):
|
||||
_type = self.NO_DATA_MARKER
|
||||
_oprepr = self.NO_DATA_MARKER
|
||||
_cmt = self.NO_DATA_MARKER
|
||||
_rptcmt = self.NO_DATA_MARKER
|
||||
if m:
|
||||
if len(m.type.type):
|
||||
_type = self.format_type(m.type)
|
||||
if ida_bytes.is_off0(m.info.flags):
|
||||
_oprepr = '{"target" : 0x%X, "base" : 0x%X, "tdelta" : 0x%X, "flags" : 0x%08x}' % (
|
||||
m.info.opinfo.ri.target,
|
||||
m.info.opinfo.ri.base,
|
||||
m.info.opinfo.ri.tdelta,
|
||||
m.info.opinfo.ri.flags)
|
||||
_cmt = m.cmt
|
||||
_rptcmt = m.rptcmt
|
||||
return (_type, _oprepr, _cmt, _rptcmt)
|
||||
|
||||
def format_insn_ops(self, ro):
|
||||
if not ro:
|
||||
return "[<no ops repr>]"
|
||||
parts = []
|
||||
for i in range(ida_ida.UA_MAXOP):
|
||||
parts.append("op%d=0x%X" % (i, (ro.flags >> ida_bytes.get_operand_type_shift(i)) & 0xF))
|
||||
return "[%s]" % ", ".join(parts)
|
||||
|
||||
def put(self, msg):
|
||||
self.lines.append(" " * self.indent + msg)
|
||||
|
||||
def put2(self, l, r, topic):
|
||||
self.ensure_header_generated()
|
||||
if l is None: l = self.NO_DATA_MARKER
|
||||
if r is None: r = self.NO_DATA_MARKER
|
||||
|
||||
self.put(topic)
|
||||
indenter = self.indenter_t(self)
|
||||
self.put("- %s" % l)
|
||||
self.put("+ %s" % r)
|
||||
|
||||
#</pycode(py_lumina)>
|
||||
+710
-216
File diff suppressed because it is too large
Load Diff
+681
-214
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@
|
||||
%ignore add_stkvar;
|
||||
|
||||
%ignore delete_wrong_frame_info;
|
||||
%ignore get_frame(ea_t);
|
||||
|
||||
%template(xreflist_t) qvector<xreflist_entry_t>;
|
||||
|
||||
|
||||
@@ -5,14 +5,6 @@ hexdsp_t *get_idapython_hexdsp();
|
||||
#include <hexrays.hpp>
|
||||
%}
|
||||
|
||||
|
||||
// Functions accepting a `func_t *` can also derive it from an `ea_t`
|
||||
%typemap(in, fragment="cvt_func_t") func_t *pfn
|
||||
{ // %typemap(in) func_t *pfn
|
||||
if ( !cvt_func_t(&$1, $input) )
|
||||
SWIG_exception_fail(SWIG_ValueError, "in method '" "$symname" "', argument " "$argnum"" of type '" "func_t const *""' (or an address from which it can be derived)");
|
||||
}
|
||||
|
||||
%{
|
||||
SWIGINTERN void __raise_vdf(const vd_failure_t &e)
|
||||
{
|
||||
|
||||
+20
@@ -117,6 +117,25 @@
|
||||
%ignore setflag(ushort &where,ushort bit,int value);
|
||||
%ignore setflag(uint32 &where,uint32 bit,int value);
|
||||
|
||||
/* // `config.hpp` - note: ideally, this should be in its own module, */
|
||||
/* // but it might be an overkill to have an `ida_config` module for */
|
||||
/* // just one function (as of this writing in any case.) */
|
||||
/* %ignore cfgopt_t; */
|
||||
/* %ignore cfgopt_t::params_t; */
|
||||
/* %ignore cfgopt_t::num_range_t; */
|
||||
/* %ignore read_config; */
|
||||
/* %ignore read_config2; */
|
||||
/* %ignore read_config_file; */
|
||||
/* %ignore read_config_file2; */
|
||||
/* %ignore read_config_string; */
|
||||
/* %ignore register_cfgopts; */
|
||||
/* %ignore parse_config_value; */
|
||||
/* %ignore cfgopt_t__apply; */
|
||||
/* %ignore cfgopt_t__apply2; */
|
||||
/* %ignore cfgopt_t__apply3; */
|
||||
/* %ignore cfgopt_set_t; */
|
||||
/* %ignore cfgopt_set_vec_t; */
|
||||
|
||||
// Make idainfo::get_proc_name() work
|
||||
%include "cstring.i"
|
||||
%cstring_bounded_output(char *buf, 8);
|
||||
@@ -127,6 +146,7 @@
|
||||
%predefine_uint32_macro(AF_FINAL, 0x80000000);
|
||||
|
||||
%include "ida.hpp"
|
||||
/* %include "config.hpp" */
|
||||
|
||||
%clear(char *buf);
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
%rename (parse_command_line3) py_parse_command_line;
|
||||
|
||||
%constant ea_t BADADDR = ea_t(-1);
|
||||
%constant ea32_t BADADDR32 = ea32_t(-1ULL);
|
||||
%constant ea64_t BADADDR64 = ea64_t(-1ULL);
|
||||
%constant sel_t BADSEL = sel_t(-1);
|
||||
%constant size_t SIZE_MAX = size_t(-1);
|
||||
/* %constant nodeidx_t BADNODE = nodeidx_t(-1); */
|
||||
|
||||
+43
@@ -129,6 +129,49 @@ struct undo_records_t;
|
||||
%apply size_t *OUTPUT { size_t *out_consumed };
|
||||
%apply bytevec_t *vout { bytevec_t *out_relbits };
|
||||
|
||||
// ev_cvt64_supval, ev_cvt64_hashval, ev_privrange_changed
|
||||
%const_pointer_and_size(uchar, data, datlen, bytevec_t, PyBytes_as_bytevec_t, size);
|
||||
%typemap(argout) (qstring *errbuf)
|
||||
{
|
||||
// %typemap(argout) (qstring *errbuf)
|
||||
if ( result < 0 )
|
||||
{
|
||||
Py_XDECREF($result);
|
||||
if ( $1 != nullptr )
|
||||
$result = PyUnicode_from_qstring(*$1);
|
||||
else
|
||||
$result = PyUnicode_FromString("Unknown error");
|
||||
}
|
||||
}
|
||||
|
||||
%define %fill_director_method_errbuf(METHOD_NAME)
|
||||
%typemap(directorout) int METHOD_NAME
|
||||
{
|
||||
// %typemap(directorout) int METHOD_NAME
|
||||
if ( PyString_Check(result) )
|
||||
{
|
||||
if ( errbuf != nullptr )
|
||||
{
|
||||
PyUnicode_as_qstring(errbuf, result);
|
||||
}
|
||||
$result = -1;
|
||||
}
|
||||
else if ( PyLong_Check(result) )
|
||||
{
|
||||
$result = PyLong_AsLong(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
Swig::DirectorTypeMismatchException::raise(
|
||||
SWIG_ErrorType(SWIG_TypeError),
|
||||
"in output value of type '" "int" "'" " in method '$symname'");
|
||||
}
|
||||
}
|
||||
%enddef
|
||||
%fill_director_method_errbuf(ev_cvt64_supval);
|
||||
%fill_director_method_errbuf(ev_cvt64_hashval);
|
||||
%fill_director_method_errbuf(ev_privrange_changed);
|
||||
|
||||
// @arnaud ditch this once all modules are ported
|
||||
// temporary:
|
||||
%ignore out_old_data;
|
||||
|
||||
+2
-1
@@ -120,13 +120,14 @@ struct dirspec_t;
|
||||
|
||||
%rename (ask_text) py_ask_text;
|
||||
%rename (ask_str) py_ask_str;
|
||||
%rename (str2ea) py_str2ea;
|
||||
%ignore process_ui_action;
|
||||
%rename (process_ui_action) py_process_ui_action;
|
||||
%ignore execute_sync;
|
||||
%ignore exec_request_t;
|
||||
%rename (execute_sync) py_execute_sync;
|
||||
|
||||
%ignore ea2str(char *, size_t, ea_t);
|
||||
|
||||
%ignore ui_request_t;
|
||||
%ignore execute_ui_requests;
|
||||
%rename (execute_ui_requests) py_execute_ui_requests;
|
||||
|
||||
+6
-7
@@ -36,13 +36,6 @@
|
||||
%rename (extract_type_from_metadata) py_extract_type_from_metadata;
|
||||
%rename (split_metadata) py_split_metadata;
|
||||
|
||||
|
||||
%feature("nodirector") simple_diff_handler_t;
|
||||
%ignore simple_diff_handler_t::simple_diff_handler_t;
|
||||
|
||||
%feature("nodirector") simple_idb_diff_handler_t;
|
||||
%ignore simple_idb_diff_handler_t::simple_idb_diff_handler_t;
|
||||
|
||||
%ignore serialized_tinfo::empty;
|
||||
|
||||
%define %rpc_packet_data_t(TYPE, ENUMERATOR)
|
||||
@@ -57,6 +50,7 @@
|
||||
%rpc_packet_data_t(pkt_rpc_fail_t, PKT_RPC_FAIL);
|
||||
%rpc_packet_data_t(pkt_rpc_notify_t, PKT_RPC_NOTIFY);
|
||||
%rpc_packet_data_t(pkt_helo_t, PKT_HELO);
|
||||
%rpc_packet_data_t(pkt_helo_result_t, PKT_HELO_RESULT);
|
||||
%rpc_packet_data_t(pkt_pull_md_t, PKT_PULL_MD);
|
||||
%rpc_packet_data_t(pkt_pull_md_result_t, PKT_PULL_MD_RESULT);
|
||||
%rpc_packet_data_t(pkt_push_md_t, PKT_PUSH_MD);
|
||||
@@ -192,3 +186,8 @@
|
||||
//<inline(py_lumina)>
|
||||
//</inline(py_lumina)>
|
||||
%}
|
||||
|
||||
%pythoncode %{
|
||||
#<pycode(py_lumina)>
|
||||
#</pycode(py_lumina)>
|
||||
%}
|
||||
|
||||
@@ -70,15 +70,24 @@
|
||||
self.template.set_place(idap)
|
||||
|
||||
def __iter__(self):
|
||||
"""
|
||||
Iterate on bookmarks present for the widget.
|
||||
"""
|
||||
p = self.template.place()
|
||||
if p is not None:
|
||||
for idx in range(bookmarks_t.size(self.template, self.userdata)):
|
||||
yield self[idx]
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Get the number of bookmarks for the widget.
|
||||
"""
|
||||
return bookmarks_t.size(self.template, self.userdata)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
"""
|
||||
Get the n-th bookmark for the widget.
|
||||
"""
|
||||
p = self.template.place()
|
||||
if p is not None:
|
||||
if isinstance(idx, int) and idx >= 0 and idx < len(self):
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
%ignore refinfo_desc_t;
|
||||
%ignore get_refinfo_descs;
|
||||
|
||||
%ignore printop_t::unused;
|
||||
|
||||
%ignore write_struc_path;
|
||||
%ignore read_struc_path;
|
||||
%ignore del_struc_path;
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
%ignore netnode_altshift;
|
||||
%ignore netnode_charshift;
|
||||
%ignore netnode_supshift;
|
||||
%ignore netnode_blobshift;
|
||||
%ignore netnode_altadjust;
|
||||
%ignore netnode_altadjust2;
|
||||
%ignore altadjust_visitor_t;
|
||||
|
||||
@@ -88,6 +88,7 @@
|
||||
%ignore get_default_align;
|
||||
%ignore align_size;
|
||||
%ignore align_size;
|
||||
%ignore fix_type_align;
|
||||
%ignore get_arg_align;
|
||||
%ignore align_stkarg_up;
|
||||
%ignore get_default_enum_size;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
%ignore outctx_base_t::regname_idx;
|
||||
%ignore outctx_base_t::suspop;
|
||||
%ignore outctx_base_t::F;
|
||||
%ignore outctx_base_t::F_unused;
|
||||
%ignore outctx_base_t::outvalues;
|
||||
%ignore outctx_base_t::outvalue_getn_flags;
|
||||
%ignore outctx_base_t::user_data;
|
||||
|
||||
@@ -37,7 +37,7 @@ Generating TBD Files
|
||||
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/tapi
|
||||
|
||||
For example, this is how you can recreate libpython3.tbd on an Apple Silicon machine:
|
||||
For example, this is how you can recreate libpython3.tbd:
|
||||
|
||||
$ alias tapi='/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/tapi'
|
||||
$ cp /Library/Frameworks/Python.framework/Versions/3.9/Python /tmp/
|
||||
@@ -61,14 +61,14 @@ with newer versions of the macOS linker (no surprise, the format is really unsta
|
||||
|
||||
So far it seems that only the following options are required:
|
||||
|
||||
--- !tapi-tbd
|
||||
tbd-version: 4
|
||||
targets: [ arm64-macos ]
|
||||
install-name: '@executable_path/libpython3.link.dylib'
|
||||
current-version: 3.9
|
||||
compatibility-version: 3.9
|
||||
exports:
|
||||
<list of exports>
|
||||
...
|
||||
--- !tapi-tbd
|
||||
tbd-version: 4
|
||||
targets: [ arm64-macos, x86_64-macos ]
|
||||
install-name: '@executable_path/libpython3.link.dylib'
|
||||
current-version: 3.9
|
||||
compatibility-version: 3.9
|
||||
exports:
|
||||
- targets: [ arm64-macos, x86_64-macos ]
|
||||
symbols: [ _PyAST_CompileEx, ...
|
||||
|
||||
Everything else can be removed.
|
||||
|
||||
+1
-2
@@ -5,7 +5,6 @@ import sys
|
||||
import os
|
||||
import argparse
|
||||
import re
|
||||
import six
|
||||
import pprint
|
||||
|
||||
mydir, _ = os.path.split(__file__)
|
||||
@@ -260,7 +259,7 @@ def check_cpp(args):
|
||||
if parser.text.find("""in output value of type '""int""'");""") > -1:
|
||||
raise Exception("Director output value type reporting doesn't appear to be patched")
|
||||
|
||||
for fname, fdef in six.iteritems(functions):
|
||||
for fname, fdef in functions.items():
|
||||
|
||||
if fdef.api_function_name:
|
||||
api_functions_names.append(fdef.api_function_name)
|
||||
|
||||
+48
-12
@@ -10,6 +10,7 @@
|
||||
#define USE_DANGEROUS_FUNCTIONS 1
|
||||
#endif
|
||||
#include <pro.h>
|
||||
#include <parsejson.hpp>
|
||||
#undef DEPRECATED
|
||||
#define DEPRECATED
|
||||
%}
|
||||
@@ -800,7 +801,7 @@ SWIGINTERN PyObject *_maybe_byte_array_or_none_result(
|
||||
}
|
||||
%fragment("cvt_" #CONTAINER_TYPE, "header")
|
||||
{
|
||||
CONTAINER_TYPE *cvt_##CONTAINER_TYPE(PyObject *obj, bool can_be_none=false)
|
||||
int cvt_##CONTAINER_TYPE(CONTAINER_TYPE **pout, PyObject *obj, bool can_be_none=false)
|
||||
{
|
||||
CONTAINER_TYPE *out = nullptr;
|
||||
if ( can_be_none && obj == Py_None )
|
||||
@@ -813,38 +814,39 @@ SWIGINTERN PyObject *_maybe_byte_array_or_none_result(
|
||||
out = new CONTAINER_TYPE;
|
||||
IN_CONVERTER(out, obj);
|
||||
}
|
||||
return out;
|
||||
*pout = out;
|
||||
return out != nullptr ? SWIG_NEWOBJ : SWIG_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
%typemap(in, fragment="cvt_" #CONTAINER_TYPE) REFTYPE
|
||||
%typemap(in, fragment="cvt_" #CONTAINER_TYPE) REFTYPE (int res=0)
|
||||
{ // bytes_container REFTYPE, CONTAINER_TYPE typemap(in)
|
||||
$1 = cvt_ ## CONTAINER_TYPE($input);
|
||||
if ( $1 == nullptr )
|
||||
res = cvt_ ## CONTAINER_TYPE(&$1, $input);
|
||||
if ( !SWIG_IsOK(res) )
|
||||
SWIG_exception_fail(
|
||||
SWIG_ValueError,
|
||||
"Expected " ELTYPE_TO_REPORT1 " " "in method '" "$symname" "', argument " "$argnum"" of type '" ELTYPE_TO_REPORT2 "'");
|
||||
}
|
||||
|
||||
%typemap(in) const REFTYPE _type_or_none
|
||||
%typemap(in) const REFTYPE _type_or_none (int res=0)
|
||||
{ // bytes_container REFTYPE _type_or_none, CONTAINER_TYPE typemap(in)
|
||||
$1 = cvt_ ## CONTAINER_TYPE($input, /*can_be_none=*/ true);
|
||||
if ( $1 == nullptr )
|
||||
res = cvt_ ## CONTAINER_TYPE(&$1, $input, /*can_be_none=*/ true);
|
||||
if ( !SWIG_IsOK(res) )
|
||||
SWIG_exception_fail(
|
||||
SWIG_ValueError,
|
||||
"Expected " ELTYPE_TO_REPORT1 " " "in method '" "$symname" "', argument " "$argnum"" of type '" ELTYPE_TO_REPORT2 "'");
|
||||
}
|
||||
%typemap(in) const REFTYPE _fields
|
||||
%typemap(in) const REFTYPE _fields (int res=0)
|
||||
{ // bytes_container REFTYPE _fields, CONTAINER_TYPE typemap(in)
|
||||
$1 = cvt_ ## CONTAINER_TYPE($input, /*can_be_none=*/ true);
|
||||
if ( $1 == nullptr )
|
||||
res = cvt_ ## CONTAINER_TYPE(&$1, $input, /*can_be_none=*/ true);
|
||||
if ( !SWIG_IsOK(res) )
|
||||
SWIG_exception_fail(
|
||||
SWIG_ValueError,
|
||||
"Expected " ELTYPE_TO_REPORT1 " " "in method '" "$symname" "', argument " "$argnum"" of type '" ELTYPE_TO_REPORT2 "'");
|
||||
}
|
||||
%typemap(freearg) REFTYPE
|
||||
{ // bytes_container REFTYPE typemap(freearg)
|
||||
delete $1;
|
||||
if ( SWIG_IsNewObj(res$argnum) ) delete $1;
|
||||
}
|
||||
%typemap(out) REFTYPE // e.g., %typemap(out) qstring*
|
||||
{ // bytes_container typemap(out) REFTYPE
|
||||
@@ -1319,6 +1321,19 @@ struct dynamic_wrapped_array_t {
|
||||
{
|
||||
// typemap(freearg) (const PTRTYPE *BUFNAME, size_t SIZENAME)
|
||||
}
|
||||
%typemap(directorin) (const uchar *data, size_t datlen)
|
||||
{
|
||||
// typemap(directorin) (const PTRTYPE *BUFNAME, size_t SIZENAME)
|
||||
if ( $1 != nullptr )
|
||||
{
|
||||
$input = PyBytes_FromStringAndSize((const char *) $1, $2);
|
||||
}
|
||||
else
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
$input = Py_None;
|
||||
}
|
||||
}
|
||||
%enddef
|
||||
|
||||
%define %const_void_pointer_and_size(PTRTYPE, BUFNAME, SIZENAME)
|
||||
@@ -2059,5 +2074,26 @@ TRY_RAW_LONG:
|
||||
}
|
||||
}
|
||||
|
||||
// Functions accepting a `func_t *` can also derive it from an `ea_t`
|
||||
%typemap(in, fragment="cvt_func_t") func_t *
|
||||
{ // %typemap(in) func_t *
|
||||
if ( !cvt_func_t(&$1, $input) )
|
||||
SWIG_exception_fail(SWIG_ValueError, "in method '" "$symname" "', argument " "$argnum"" of type '" "func_t const *""' (or an address from which it can be derived)");
|
||||
}
|
||||
|
||||
|
||||
%typemap(in,numinputs=0) jvalue_t *out (jvalue_t temp)
|
||||
{
|
||||
// %typemap(in,numinputs=0) jvalue_t *out (jvalue_t temp)
|
||||
$1 = &temp;
|
||||
}
|
||||
|
||||
%typemap(argout) jvalue_t *out
|
||||
{
|
||||
// %typemap(argout) jvalue_t *out
|
||||
Py_XDECREF($result);
|
||||
$result = PyW_from_jvalue_t(*$1);
|
||||
}
|
||||
|
||||
#endif // __HEADER_I__
|
||||
// END: auto-inserted header
|
||||
|
||||
@@ -326,6 +326,30 @@ all_specific_translations = {
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_kernwin.atoea" : [
|
||||
((
|
||||
"-> 'uint32 *'",
|
||||
"-> 'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_kernwin.str2ea" : [
|
||||
((
|
||||
"-> 'uint32 *'",
|
||||
"-> 'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_kernwin.str2ea_ex" : [
|
||||
((
|
||||
"-> 'uint32 *'",
|
||||
"-> 'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_kernwin.PluginForm" : [
|
||||
((
|
||||
"module '__main__' from 'tools/dumpdoc.py'",
|
||||
"module '__main__' (built-in)",
|
||||
), "module 'main'", False),
|
||||
],
|
||||
}
|
||||
|
||||
if is_64:
|
||||
|
||||
@@ -9,7 +9,6 @@ from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import six
|
||||
|
||||
dirname, _ = os.path.split(__file__)
|
||||
parent_dirname, _ = os.path.split(dirname)
|
||||
@@ -69,7 +68,7 @@ def gen_methods(out):
|
||||
retbody = "return %s;" % rdata["default"]
|
||||
arg_strs = []
|
||||
for p in (recipe_data["call_params"] if "call_params" in recipe_data else params[1:]):
|
||||
if isinstance(p, six.string_types):
|
||||
if isinstance(p, str):
|
||||
assert(p[0] == "@")
|
||||
synth_info = recipe["synthetic_params"][p]
|
||||
ptype = synth_info["type"]
|
||||
@@ -148,7 +147,7 @@ def gen_notifications(out):
|
||||
argstr = [] # arguments to pass to the call, minus those explicitly suppressed
|
||||
argstr_all = [] # all arguments
|
||||
for p in (recipe_data["call_params"] if "call_params" in recipe_data else params[1:]):
|
||||
if isinstance(p, six.string_types):
|
||||
if isinstance(p, str):
|
||||
assert(p[0] == "@")
|
||||
synth_info = recipe["synthetic_params"][p]
|
||||
ptype = synth_info["type"]
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import re
|
||||
import string
|
||||
from argparse import ArgumentParser
|
||||
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument("-i", "--input", required=True)
|
||||
parser.add_argument("-o", "--output", required=True)
|
||||
parser.add_argument("-f", "--file-with-flags", required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
with open(args.input) as fin:
|
||||
template = string.Template(fin.read())
|
||||
|
||||
with open(args.file_with_flags) as fin:
|
||||
raw = fin.read()
|
||||
pat = re.compile(r"^#\s*define\s+(HBF_[A-Za-z0-9_]*)\s+([0-9x]*)\s*(.*)$")
|
||||
decls = []
|
||||
for line in raw.split("\n"):
|
||||
m = pat.match(line)
|
||||
if m:
|
||||
decls.append(line)
|
||||
kvps = {
|
||||
"BASE_HOOKS_FLAGS" : "\n".join(decls)
|
||||
}
|
||||
|
||||
with open(args.output, "w") as fout:
|
||||
fout.write(template.substitute(kvps))
|
||||
|
||||
@@ -3,7 +3,6 @@ from __future__ import print_function
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import six
|
||||
import xml.etree.ElementTree as ET
|
||||
from argparse import ArgumentParser
|
||||
|
||||
@@ -349,7 +348,7 @@ with open(args.input) as f:
|
||||
current_function_proto = None
|
||||
|
||||
if subst is not None:
|
||||
if isinstance(subst, six.string_types):
|
||||
if isinstance(subst, str):
|
||||
subst = [subst]
|
||||
all_lines.extend(map(lambda l: "%s\n" % l, subst))
|
||||
else:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import six
|
||||
|
||||
from argparse import ArgumentParser
|
||||
|
||||
@@ -23,7 +22,7 @@ if os.path.isfile(args.patches):
|
||||
|
||||
all_lines = []
|
||||
for l in lines:
|
||||
for patch_kind, patch_data in six.iteritems(patches):
|
||||
for patch_kind, patch_data in patches.items():
|
||||
if patch_kind == "repl_line":
|
||||
for from_, to in patch_data:
|
||||
if l == from_:
|
||||
|
||||
Reference in New Issue
Block a user