mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
IDAPython for IDA 8.4
This commit is contained in:
@@ -4,7 +4,7 @@ A script that tries to determine the call stack
|
||||
|
||||
Run the application with the debugger, suspend the debugger, select a thread and finally run the script.
|
||||
|
||||
Copyright (c) 1990-2023 Hex-Rays
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
"""
|
||||
import ida_ua
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
A script to demonstrate how to send commands to the debugger and then parse and use the output in IDA
|
||||
|
||||
Copyright (c) 1990-2023 Hex-Rays
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
|
||||
"""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This script shows how to send debugger commands and use the result in IDA
|
||||
|
||||
Copyright (c) 1990-2023 Hex-Rays
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
|
||||
"""
|
||||
|
||||
@@ -13,7 +13,7 @@ The general syntax is:
|
||||
* To specify in which context the instructions should be assembled, pass asm_where=ea:
|
||||
find("jmp dword ptr [esp]", asm_where=here())
|
||||
|
||||
Copyright (c) 1990-2023 Hex-Rays
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ A script that graphs all the exception handlers in a given process
|
||||
|
||||
It will be easy to see what thread uses what handler and what handlers are commonly used between threads
|
||||
|
||||
Copyright (c) 1990-2023 Hex-Rays
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
This script shows how to send debugger commands and use the result in IDA
|
||||
|
||||
Copyright (c) 1990-2023 Hex-Rays
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
|
||||
"""
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import print_function
|
||||
# -----------------------------------------------------------------------
|
||||
# VirusTotal IDA Plugin
|
||||
# By Elias Bachaalany <elias at hex-rays.com>
|
||||
# (c) Hex-Rays 2011-2023
|
||||
# (c) Hex-Rays 2011-2024
|
||||
#
|
||||
# Special thanks:
|
||||
# - VirusTotal team
|
||||
|
||||
+14561
File diff suppressed because it is too large
Load Diff
+68992
File diff suppressed because it is too large
Load Diff
-12514
File diff suppressed because it is too large
Load Diff
+14228
File diff suppressed because it is too large
Load Diff
+67968
File diff suppressed because it is too large
Load Diff
-12356
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -53,7 +53,7 @@ To achieve that, you want to use the `directorargout` typemap:
|
||||
|
||||
%typemap(directorargout) qstrvec_t * (qstrvec_t tmp)
|
||||
{ // %typemap(directorargout) qstrvec_t *
|
||||
if ( PyW_PyListToStrVec(&tmp, $result) >= 0 )
|
||||
if ( PyW_PySeqToStrVec(&tmp, $result) >= 0 )
|
||||
{
|
||||
$1->swap(tmp);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ act_name = "example:add_action"
|
||||
|
||||
if ida_kernwin.register_action(ida_kernwin.action_desc_t(
|
||||
act_name, # Name. Acts as an ID. Must be unique.
|
||||
"Say hi!", # Label. That's what users see.
|
||||
"Say ~h~i!", # Label. That's what users see. Can have an accelerator key specified between '~'
|
||||
SayHi("developer"), # Handler. Called when activated, and for updating
|
||||
"Ctrl+F12", # Shortcut (optional)
|
||||
"Greets the user", # Tooltip (optional)
|
||||
|
||||
@@ -15,53 +15,113 @@ author: Gergely Erdelyi (gergely.erdelyi@d-dome.net)
|
||||
# with members of different types.
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
import ida_struct
|
||||
import ida_idaapi
|
||||
import ida_bytes
|
||||
import ida_nalt
|
||||
import ida_typeinf
|
||||
|
||||
import idc
|
||||
|
||||
sid = ida_struct.get_struc_id("mystr1")
|
||||
if sid != -1:
|
||||
idc.del_struc(sid)
|
||||
sid = ida_struct.add_struc(ida_idaapi.BADADDR, "mystr1", 0)
|
||||
print("%x" % sid)
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if tif.get_named_type(None, "mystr1"):
|
||||
ida_typeinf.del_named_type(None, "mystr1", ida_typeinf.NTF_TYPE)
|
||||
ida_typeinf.idc_parse_types('struct mystr1 { };', 0)
|
||||
if not tif.get_named_type(None, "mystr1"):
|
||||
print("Error retrieving mystr1")
|
||||
print("%x" % tif.get_ordinal())
|
||||
|
||||
# Test simple data types
|
||||
simple_types_data = [
|
||||
(ida_bytes.FF_BYTE, 1),
|
||||
(ida_bytes.FF_WORD, 2),
|
||||
(ida_bytes.FF_DWORD, 4),
|
||||
(ida_bytes.FF_QWORD, 8),
|
||||
(ida_bytes.FF_TBYTE, 10),
|
||||
(ida_bytes.FF_OWORD, 16),
|
||||
(ida_bytes.FF_FLOAT, 4),
|
||||
(ida_bytes.FF_DOUBLE, 8),
|
||||
(ida_bytes.FF_PACKREAL, 10),
|
||||
(ida_typeinf.BTF_BYTE, 1),
|
||||
(ida_typeinf.BTF_INT16, 2),
|
||||
(ida_typeinf.BTF_UINT32, 4),
|
||||
(ida_typeinf.BTF_INT64, 8),
|
||||
(ida_typeinf.BTF_INT128, 16),
|
||||
(ida_typeinf.BTF_FLOAT, 4),
|
||||
(ida_typeinf.BTF_DOUBLE, 8),
|
||||
(ida_typeinf.BTF_TBYTE, 10),
|
||||
]
|
||||
|
||||
udm = ida_typeinf.udm_t()
|
||||
for i, tpl in enumerate(simple_types_data):
|
||||
t, nsize = tpl
|
||||
print("t%x:"% ((t|ida_bytes.FF_DATA) & 0xFFFFFFFF),
|
||||
idc.add_struc_member(sid, "t%02d"%i, ida_idaapi.BADADDR, (t|ida_bytes.FF_DATA )&0xFFFFFFFF, -1, nsize))
|
||||
udm.name = "t%02d" % i
|
||||
udm.size = nsize * 8
|
||||
udm.type = ida_typeinf.tinfo_t(t)
|
||||
udm.offset = tif.get_unpadded_size() * 8
|
||||
print("t%x:"% t,
|
||||
ida_typeinf.tinfo_errstr(tif.add_udm(udm)) )
|
||||
|
||||
repr = ida_typeinf.value_repr_t()
|
||||
repr.set_vtype(ida_typeinf.FRB_NUMO)
|
||||
print("Set member representation to octal:",
|
||||
ida_typeinf.tinfo_errstr(tif.set_udm_repr(3, repr)) )
|
||||
|
||||
# Test ASCII type
|
||||
print("ASCII:", idc.add_struc_member(sid, "tascii", -1, ida_bytes.FF_STRLIT|ida_bytes.FF_DATA, ida_nalt.STRTYPE_C, 8))
|
||||
udm = ida_typeinf.udm_t()
|
||||
udm.name = "tascii"
|
||||
udm.size = 8 * 8
|
||||
udm.type.parse('char tascii[8] __strlit(C,"windows-1252");') # no other way?
|
||||
udm.offset = tif.get_size() * 8
|
||||
print("%s:"% udm.name,
|
||||
ida_typeinf.tinfo_errstr(tif.add_udm(udm)) )
|
||||
|
||||
# Test struc member type
|
||||
msid = ida_struct.get_struc_id("mystr2")
|
||||
if msid != -1:
|
||||
idc.del_struc(msid)
|
||||
msid = idc.add_struc(-1, "mystr2", 0)
|
||||
print(idc.add_struc_member(msid, "member1", -1, (ida_bytes.FF_DWORD|ida_bytes.FF_DATA )&0xFFFFFFFF, -1, 4))
|
||||
print(idc.add_struc_member(msid, "member2", -1, (ida_bytes.FF_DWORD|ida_bytes.FF_DATA )&0xFFFFFFFF, -1, 4))
|
||||
# Test struct member type by preparing the whole structure at once
|
||||
mtif = ida_typeinf.tinfo_t()
|
||||
if mtif.get_named_type(None, "mystr2"):
|
||||
ida_typeinf.del_named_type(None, "mystr2", ida_typeinf.NTF_TYPE)
|
||||
|
||||
msize = ida_struct.get_struc_size(msid)
|
||||
print("Struct:", idc.add_struc_member(sid, "tstruct", -1, ida_bytes.FF_STRUCT|ida_bytes.FF_DATA, msid, msize))
|
||||
print("Stroff:", idc.add_struc_member(sid, "tstroff", -1, ida_bytes.stroff_flag()|ida_bytes.FF_DWORD, msid, 4))
|
||||
mudt = ida_typeinf.udt_type_data_t()
|
||||
mudt.name="mystr2"
|
||||
mudm = ida_typeinf.udm_t()
|
||||
mudm.name="member1"
|
||||
mudm.type = ida_typeinf.tinfo_t(ida_typeinf.BTF_INT)
|
||||
mudt.push_back(mudm)
|
||||
mudm.name="member2"
|
||||
mudt.push_back(mudm)
|
||||
mtif.create_udt(mudt)
|
||||
print("Struct 2:", ida_typeinf.tinfo_errstr(mtif.set_named_type(None, "mystr2")) )
|
||||
|
||||
#Test structure member
|
||||
udm.size = mtif.get_size() * 8
|
||||
udm.offset = tif.get_unpadded_size() * 8
|
||||
udm.name = "tstruct"
|
||||
udm.type = mtif
|
||||
print("Struct member:", ida_typeinf.tinfo_errstr(tif.add_udm(udm)) )
|
||||
|
||||
#Test pointer to structure
|
||||
udm.name = "strptr"
|
||||
udm.size = 32
|
||||
udm.offset = tif.get_unpadded_size() * 8
|
||||
if not mtif.create_ptr(mtif):
|
||||
print("Error while creating structure pointer")
|
||||
udm.type = mtif
|
||||
print("Strptr:", ida_typeinf.tinfo_errstr(tif.add_udm(udm)) )
|
||||
|
||||
#Test structure offset
|
||||
udm.name = "tstroff"
|
||||
udm.size = 32
|
||||
udm.offset = tif.get_unpadded_size() * 8
|
||||
udm.type.parse("int tstroff __stroff(mystr2);")
|
||||
print("Stroff:", ida_typeinf.tinfo_errstr(tif.add_udm(udm)) )
|
||||
|
||||
# Test offset types
|
||||
print("Offset:", idc.add_struc_member(sid, "toffset", -1, ida_bytes.off_flag()|ida_bytes.FF_DATA|ida_bytes.FF_DWORD, 0, 4))
|
||||
print("Offset:", idc.set_member_type(sid, 0, ida_bytes.off_flag()|ida_bytes.FF_DATA|ida_bytes.FF_DWORD, 0, 4))
|
||||
udm.name = "toffset"
|
||||
udm.size = 32
|
||||
udm.offset = tif.get_unpadded_size() * 8
|
||||
udm.type.parse("void *toffset;")
|
||||
print("Offset:", ida_typeinf.tinfo_errstr(tif.add_udm(udm)) )
|
||||
|
||||
# Test C bitfield types
|
||||
udm.name = "tbitfield"
|
||||
udm.offset = tif.get_unpadded_size() * 8
|
||||
btif = ida_typeinf.tinfo_t()
|
||||
btif.create_bitfield(4, 2, True) # unsigned __int32 : 2
|
||||
udm.size = 2
|
||||
udm.type = btif
|
||||
print("Bitfield:", ida_typeinf.tinfo_errstr(tif.add_udm(udm)) )
|
||||
|
||||
# Print the expanded structure
|
||||
pflags = ida_typeinf.PRTYPE_TYPE|ida_typeinf.PRTYPE_DEF|ida_typeinf.PRTYPE_MULTI
|
||||
print(tif._print(tif.get_type_name(), pflags))
|
||||
if mtif.get_named_type(None, "mystr2"):
|
||||
print(mtif._print(mtif.get_type_name(), pflags))
|
||||
|
||||
print("Done")
|
||||
|
||||
@@ -14,9 +14,9 @@ description:
|
||||
import ida_bytes
|
||||
import ida_idaapi
|
||||
import ida_lines
|
||||
import ida_struct
|
||||
import ida_netnode
|
||||
import ida_nalt
|
||||
import ida_typeinf
|
||||
|
||||
import sys
|
||||
import struct
|
||||
@@ -37,7 +37,8 @@ class pascal_data_type(ida_bytes.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 ida_struct.is_member_id(ea):
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if tif.get_udm_by_tid(None, ea) != -1:
|
||||
return 1
|
||||
|
||||
# get the length byte
|
||||
@@ -87,7 +88,8 @@ class simplevm_data_type(ida_bytes.data_type_t):
|
||||
asm_keyword)
|
||||
|
||||
def calc_item_size(self, ea, maxsize):
|
||||
if ida_struct.is_member_id(ea):
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if tif.get_udm_by_tid(None, ea) != -1:
|
||||
return 1
|
||||
# get the opcode and see if it has an imm
|
||||
n = 5 if (ida_bytes.get_byte(ea) & 3) == 0 else 1
|
||||
|
||||
@@ -12,32 +12,37 @@ description:
|
||||
* select some text in one of the listing widgets (i.e.,
|
||||
"IDA View-*", "Enums", "Structures", "Pseudocode-*")
|
||||
* press Ctrl+Shift+S to dump the selection
|
||||
|
||||
"""
|
||||
|
||||
import ida_kernwin
|
||||
import ida_lines
|
||||
|
||||
def get_widget_lines(widget, tp0, tp1):
|
||||
"""
|
||||
get lines between places tp0 and tp1 in widget
|
||||
"""
|
||||
ud = ida_kernwin.get_viewer_user_data(widget)
|
||||
lnar = ida_kernwin.linearray_t(ud)
|
||||
lnar.set_place(tp0.at)
|
||||
lines = []
|
||||
while True:
|
||||
cur_place = lnar.get_place()
|
||||
first_line_ref = ida_kernwin.l_compare2(cur_place, tp0.at, ud)
|
||||
last_line_ref = ida_kernwin.l_compare2(cur_place, tp1.at, ud)
|
||||
if last_line_ref > 0: # beyond last line
|
||||
break
|
||||
line = ida_lines.tag_remove(lnar.down())
|
||||
if last_line_ref == 0: # at last line
|
||||
line = line[0:tp1.x]
|
||||
elif first_line_ref == 0: # at first line
|
||||
line = ' ' * tp0.x + line[tp0.x:]
|
||||
lines.append(line)
|
||||
return lines
|
||||
|
||||
class dump_selection_handler_t(ida_kernwin.action_handler_t):
|
||||
def activate(self, ctx):
|
||||
if ctx.has_flag(ida_kernwin.ACF_HAS_SELECTION):
|
||||
tp0, tp1 = ctx.cur_sel._from, ctx.cur_sel.to
|
||||
ud = ida_kernwin.get_viewer_user_data(ctx.widget)
|
||||
lnar = ida_kernwin.linearray_t(ud)
|
||||
lnar.set_place(tp0.at)
|
||||
lines = []
|
||||
while True:
|
||||
cur_place = lnar.get_place()
|
||||
first_line_ref = ida_kernwin.l_compare2(cur_place, tp0.at, ud)
|
||||
last_line_ref = ida_kernwin.l_compare2(cur_place, tp1.at, ud)
|
||||
if last_line_ref > 0: # beyond last line
|
||||
break
|
||||
line = ida_lines.tag_remove(lnar.down())
|
||||
if last_line_ref == 0: # at last line
|
||||
line = line[0:tp1.x]
|
||||
elif first_line_ref == 0: # at first line
|
||||
line = ' ' * tp0.x + line[tp0.x:]
|
||||
lines.append(line)
|
||||
lines = get_widget_lines(ctx.widget, ctx.cur_sel._from, ctx.cur_sel.to)
|
||||
for line in lines:
|
||||
print(line)
|
||||
return 1
|
||||
@@ -69,3 +74,12 @@ if ida_kernwin.register_action(
|
||||
dump_selection_handler_t(),
|
||||
ACTION_SHORTCUT)):
|
||||
print("Registered action \"%s\"" % ACTION_NAME)
|
||||
|
||||
# dump current selection
|
||||
p0 = ida_kernwin.twinpos_t()
|
||||
p1 = ida_kernwin.twinpos_t()
|
||||
view = ida_kernwin.get_current_viewer()
|
||||
if ida_kernwin.read_selection(view, p0, p1):
|
||||
lines = get_widget_lines(view, p0, p1)
|
||||
print("\n".join(lines))
|
||||
|
||||
|
||||
+31
-13
@@ -14,8 +14,11 @@ import ida_idaapi
|
||||
import ida_hexrays
|
||||
import ida_lines
|
||||
|
||||
do_dbg = False
|
||||
|
||||
def dbg(msg):
|
||||
#print(msg)
|
||||
if do_dbg:
|
||||
print(msg)
|
||||
pass
|
||||
|
||||
def is_cident_char(c):
|
||||
@@ -23,13 +26,19 @@ def is_cident_char(c):
|
||||
|
||||
def my_tag_skipcodes(l, storage):
|
||||
n = ida_lines.tag_skipcodes(l)
|
||||
dbg("Skipping %d chars ('%s')" % (n, l[0:n]))
|
||||
storage.append(l[0:n])
|
||||
if n > 0:
|
||||
dbg("Skipping %d chars ('%s')" % (n, l[0:n]))
|
||||
storage.append(l[0:n])
|
||||
return l[n:]
|
||||
|
||||
def remove_spaces(sl):
|
||||
|
||||
dbg("*" * 80)
|
||||
l = sl.line
|
||||
|
||||
global do_dbg
|
||||
# do_dbg = l.find("const char *") > -1
|
||||
|
||||
out = []
|
||||
|
||||
def push(c):
|
||||
@@ -37,25 +46,34 @@ def remove_spaces(sl):
|
||||
out.append(c)
|
||||
|
||||
# skip initial spaces, do not compress them
|
||||
while True:
|
||||
l = my_tag_skipcodes(l, out)
|
||||
if not l:
|
||||
break
|
||||
c = l[0]
|
||||
if not c.isspace():
|
||||
break
|
||||
push(c)
|
||||
l = l[1:]
|
||||
def eat_spaces(l):
|
||||
while True:
|
||||
l = my_tag_skipcodes(l, out)
|
||||
if not l:
|
||||
break
|
||||
c = l[0]
|
||||
if not c.isspace():
|
||||
break
|
||||
push(c)
|
||||
l = l[1:]
|
||||
return l
|
||||
l = eat_spaces(l)
|
||||
|
||||
# remove all spaces except in string and char constants
|
||||
delim = None # if not None, then we are skipping until 'delim'
|
||||
last = None # last seen character
|
||||
|
||||
while True:
|
||||
dbg("-" * 60)
|
||||
dbg("l: '%s'" % l)
|
||||
dbg("d: '%s'" % delim)
|
||||
dbg("out: '%s'" % out)
|
||||
|
||||
# go until comments
|
||||
l = my_tag_skipcodes(l, out)
|
||||
if l.startswith("//"):
|
||||
push(l)
|
||||
break
|
||||
dbg("-" * 60)
|
||||
nchars = ida_lines.tag_advance(l, 1)
|
||||
push(l[0:nchars])
|
||||
l = l[nchars:]
|
||||
|
||||
@@ -163,7 +163,13 @@ class vds_hooks_t(ida_hexrays.Hexrays_Hooks):
|
||||
def cmt_changed(self, cfunc, loc, cmt):
|
||||
return self._log()
|
||||
|
||||
def build_callinfo(self, *args):
|
||||
def build_callinfo(self, blk, type):
|
||||
return self._log()
|
||||
|
||||
def callinfo_built(self, blk):
|
||||
return self._log()
|
||||
|
||||
def calls_done(self, mba):
|
||||
return self._log()
|
||||
|
||||
vds_hooks = vds_hooks_t()
|
||||
|
||||
@@ -21,6 +21,10 @@ class my_modifier_t(ida_hexrays.user_lvar_modifier_t):
|
||||
def modify_lvars(self, lvars):
|
||||
def log(msg):
|
||||
print("modify_lvars: %s" % msg)
|
||||
"""Note: lvars.lvvec contains only variables modified from the defaults.
|
||||
To change other variables, you can, for example, first use rename_lvar()
|
||||
so they get added to this list, then use modify_user_lvar_info() or modify_lvars().
|
||||
"""
|
||||
log("len(lvars.lvvec) = %d" % len(lvars.lvvec))
|
||||
log("lvars.lmaps.size() = %d" % lvars.lmaps.size())
|
||||
log("lvars.stkoff_delta = %d" % lvars.stkoff_delta)
|
||||
@@ -36,9 +40,7 @@ class my_modifier_t(ida_hexrays.user_lvar_modifier_t):
|
||||
varlog("flags = %x" % one.flags)
|
||||
new_type = self.new_types.get(one.name)
|
||||
if new_type:
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
ida_typeinf.parse_decl(tif, None, new_type, 0)
|
||||
one.type = tif
|
||||
ida_typeinf.parse_decl(one.type, None, new_type, 0)
|
||||
one.name = self.name_prefix + one.name
|
||||
one.cmt = self.cmt_prefix + one.cmt
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import ida_kernwin
|
||||
import ida_hexrays
|
||||
import ida_typeinf
|
||||
import ida_idaapi
|
||||
import ida_struct
|
||||
import ida_funcs
|
||||
|
||||
import idautils
|
||||
@@ -66,12 +65,17 @@ class XrefsForm(ida_kernwin.PluginForm):
|
||||
xtype = x.type
|
||||
xtype.remove_ptr_or_array()
|
||||
typename = ida_typeinf.print_tinfo('', 0, 0, ida_typeinf.PRTYPE_1LINE, xtype, '', '')
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if not tif.get_named_type(None, typename):
|
||||
print("Error while retrieving %s type.", typename)
|
||||
return typename
|
||||
udm = ida_typeinf.udm_t()
|
||||
udm.offset = m
|
||||
if tif.find_udm(udm, ida_typeinf.STRMEM_OFFSET) == -1:
|
||||
print("Error while retrieving %s member.", typename)
|
||||
return typename
|
||||
|
||||
sid = ida_struct.get_struc_id(typename)
|
||||
sptr = ida_struct.get_struc(sid)
|
||||
member = ida_struct.get_member(sptr, m)
|
||||
|
||||
return '%s::%s' % (typename, member)
|
||||
return '%s::%s' % (typename, udm.name)
|
||||
|
||||
def OnCreate(self, widget):
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ class idb_logger_hooks_t(ida_idp.IDB_Hooks):
|
||||
def loader_finished(self, li, neflags, filetypename):
|
||||
return self._log()
|
||||
|
||||
def local_types_changed(self):
|
||||
def local_types_changed(self, ltc, ordinal, name):
|
||||
return self._log()
|
||||
|
||||
def make_code(self, insn):
|
||||
|
||||
@@ -11,8 +11,7 @@ import binascii
|
||||
import ida_idp
|
||||
import ida_bytes
|
||||
import ida_nalt
|
||||
import ida_struct
|
||||
import ida_enum
|
||||
import ida_typeinf
|
||||
|
||||
class operand_changed_t(ida_idp.IDB_Hooks):
|
||||
def log(self, msg):
|
||||
@@ -26,9 +25,14 @@ class operand_changed_t(ida_idp.IDB_Hooks):
|
||||
opi = ida_bytes.get_opinfo(buf, ea, n, flags)
|
||||
if opi:
|
||||
if ida_bytes.is_struct(flags):
|
||||
self.log("New struct: 0x%08X (name=%s)" % (
|
||||
opi.tid,
|
||||
ida_struct.get_struc_name(opi.tid)))
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if tif.get_type_by_tid(opi.tid):
|
||||
self.log("New struct: 0x%08X ordinal: %d (name=%s)" % (
|
||||
tif.get_tid(),
|
||||
tif.get_ordinal(),
|
||||
tif.get_type_name()))
|
||||
else:
|
||||
self.log("Failed tif")
|
||||
elif ida_bytes.is_strlit(flags):
|
||||
encidx = ida_nalt.get_str_encoding_idx(opi.strtype)
|
||||
if encidx == ida_nalt.STRENC_DEFAULT:
|
||||
@@ -50,16 +54,21 @@ class operand_changed_t(ida_idp.IDB_Hooks):
|
||||
opi.ri.tdelta,
|
||||
opi.ri.flags))
|
||||
elif ida_bytes.is_enum(flags, n):
|
||||
self.log("New enum: 0x%08X (enum=%s), serial=%d" % (
|
||||
opi.ec.tid,
|
||||
ida_enum.get_enum_name(opi.ec.tid),
|
||||
opi.ec.serial))
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if tif.get_type_by_tid(opi.ec.tid):
|
||||
self.log("New enum: 0x%08X ordinal: %d (enum=%s), serial=%d" % (
|
||||
opi.ec.tid,
|
||||
tif.get_ordinal(),
|
||||
tif.get_type_name(),
|
||||
opi.ec.serial))
|
||||
else:
|
||||
self.log("Failed tif")
|
||||
pass
|
||||
elif ida_bytes.is_stroff(flags, n):
|
||||
parts = []
|
||||
for i in range(opi.path.len):
|
||||
tid = opi.path.ids[i]
|
||||
parts.append("0x%08X (name=%s)" % (tid, ida_struct.get_struc_name(tid)))
|
||||
parts.append("0x%08X (name=%s)" % (tid, ida_typeinf.get_tid_name(tid)))
|
||||
self.log("New stroff: path=[%s] (len=%d, delta=0x%08X)" % (
|
||||
", ".join(parts),
|
||||
opi.path.len,
|
||||
|
||||
+31
-30
@@ -446,29 +446,27 @@ members of different types.
|
||||
|
||||
<li>APIs used
|
||||
<ul>
|
||||
<li>ida_bytes.FF_BYTE</li>
|
||||
<li>ida_bytes.FF_DATA</li>
|
||||
<li>ida_bytes.FF_DOUBLE</li>
|
||||
<li>ida_bytes.FF_DWORD</li>
|
||||
<li>ida_bytes.FF_FLOAT</li>
|
||||
<li>ida_bytes.FF_OWORD</li>
|
||||
<li>ida_bytes.FF_PACKREAL</li>
|
||||
<li>ida_bytes.FF_QWORD</li>
|
||||
<li>ida_bytes.FF_STRLIT</li>
|
||||
<li>ida_bytes.FF_STRUCT</li>
|
||||
<li>ida_bytes.FF_TBYTE</li>
|
||||
<li>ida_bytes.FF_WORD</li>
|
||||
<li>ida_bytes.off_flag</li>
|
||||
<li>ida_bytes.stroff_flag</li>
|
||||
<li>ida_idaapi.BADADDR</li>
|
||||
<li>ida_nalt.STRTYPE_C</li>
|
||||
<li>ida_struct.add_struc</li>
|
||||
<li>ida_struct.get_struc_id</li>
|
||||
<li>ida_struct.get_struc_size</li>
|
||||
<li>idc.add_struc</li>
|
||||
<li>idc.add_struc_member</li>
|
||||
<li>idc.del_struc</li>
|
||||
<li>idc.set_member_type</li>
|
||||
<li>ida_typeinf.BTF_BYTE</li>
|
||||
<li>ida_typeinf.BTF_DOUBLE</li>
|
||||
<li>ida_typeinf.BTF_FLOAT</li>
|
||||
<li>ida_typeinf.BTF_INT</li>
|
||||
<li>ida_typeinf.BTF_INT128</li>
|
||||
<li>ida_typeinf.BTF_INT16</li>
|
||||
<li>ida_typeinf.BTF_INT64</li>
|
||||
<li>ida_typeinf.BTF_TBYTE</li>
|
||||
<li>ida_typeinf.BTF_UINT32</li>
|
||||
<li>ida_typeinf.FRB_NUMO</li>
|
||||
<li>ida_typeinf.NTF_TYPE</li>
|
||||
<li>ida_typeinf.PRTYPE_DEF</li>
|
||||
<li>ida_typeinf.PRTYPE_MULTI</li>
|
||||
<li>ida_typeinf.PRTYPE_TYPE</li>
|
||||
<li>ida_typeinf.del_named_type</li>
|
||||
<li>ida_typeinf.idc_parse_types</li>
|
||||
<li>ida_typeinf.tinfo_errstr</li>
|
||||
<li>ida_typeinf.tinfo_t</li>
|
||||
<li>ida_typeinf.udm_t</li>
|
||||
<li>ida_typeinf.udt_type_data_t</li>
|
||||
<li>ida_typeinf.value_repr_t</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -561,7 +559,7 @@ one format for a specific 'custom data type'.)
|
||||
<li>ida_lines.SCOLOR_REG</li>
|
||||
<li>ida_nalt.get_input_file_path</li>
|
||||
<li>ida_netnode.netnode</li>
|
||||
<li>ida_struct.is_member_id</li>
|
||||
<li>ida_typeinf.tinfo_t</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -700,10 +698,13 @@ After running this script:
|
||||
<li>ida_kernwin.BWN_STRUCTS</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_viewer_user_data</li>
|
||||
<li>ida_kernwin.l_compare2</li>
|
||||
<li>ida_kernwin.linearray_t</li>
|
||||
<li>ida_kernwin.read_selection</li>
|
||||
<li>ida_kernwin.register_action</li>
|
||||
<li>ida_kernwin.twinpos_t</li>
|
||||
<li>ida_kernwin.unregister_action</li>
|
||||
<li>ida_lines.tag_remove</li>
|
||||
</ul>
|
||||
@@ -2940,7 +2941,6 @@ comments and/or types of local variables.
|
||||
<li>ida_hexrays.modify_user_lvars</li>
|
||||
<li>ida_hexrays.user_lvar_modifier_t</li>
|
||||
<li>ida_typeinf.parse_decl</li>
|
||||
<li>ida_typeinf.tinfo_t</li>
|
||||
<li>idc.here</li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -3006,11 +3006,11 @@ pressed in the Decompiler window.
|
||||
<li>ida_kernwin.action_handler_t</li>
|
||||
<li>ida_kernwin.attach_action_to_popup</li>
|
||||
<li>ida_kernwin.register_action</li>
|
||||
<li>ida_struct.get_member</li>
|
||||
<li>ida_struct.get_struc</li>
|
||||
<li>ida_struct.get_struc_id</li>
|
||||
<li>ida_typeinf.PRTYPE_1LINE</li>
|
||||
<li>ida_typeinf.STRMEM_OFFSET</li>
|
||||
<li>ida_typeinf.print_tinfo</li>
|
||||
<li>ida_typeinf.tinfo_t</li>
|
||||
<li>ida_typeinf.udm_t</li>
|
||||
<li>idautils.Functions</li>
|
||||
<li>idautils.XrefsTo</li>
|
||||
</ul>
|
||||
@@ -3096,7 +3096,6 @@ an instruction's operand, or a data item.
|
||||
<li>ida_bytes.is_strlit</li>
|
||||
<li>ida_bytes.is_stroff</li>
|
||||
<li>ida_bytes.is_struct</li>
|
||||
<li>ida_enum.get_enum_name</li>
|
||||
<li>ida_idp.IDB_Hooks</li>
|
||||
<li>ida_nalt.STRENC_DEFAULT</li>
|
||||
<li>ida_nalt.get_default_encoding_idx</li>
|
||||
@@ -3104,7 +3103,8 @@ an instruction's operand, or a data item.
|
||||
<li>ida_nalt.get_str_encoding_idx</li>
|
||||
<li>ida_nalt.get_strtype_bpu</li>
|
||||
<li>ida_nalt.opinfo_t</li>
|
||||
<li>ida_struct.get_struc_name</li>
|
||||
<li>ida_typeinf.get_tid_name</li>
|
||||
<li>ida_typeinf.tinfo_t</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -4145,6 +4145,7 @@ IDA, with a custom widget.
|
||||
<li>ida_kernwin.Choose.CHCOL_FNAME</li>
|
||||
<li>ida_kernwin.Choose.CHCOL_HEX</li>
|
||||
<li>ida_kernwin.Choose.CHCOL_PLAIN</li>
|
||||
<li>ida_kernwin.get_icon_id_by_name</li>
|
||||
<li>idautils.Functions</li>
|
||||
<li>idc.del_func</li>
|
||||
</ul>
|
||||
|
||||
+31
-30
@@ -336,29 +336,27 @@ Usage of the API to create & populate a structure with
|
||||
members of different types.
|
||||
|
||||
#### Uses
|
||||
* ida_bytes.FF_BYTE
|
||||
* ida_bytes.FF_DATA
|
||||
* ida_bytes.FF_DOUBLE
|
||||
* ida_bytes.FF_DWORD
|
||||
* ida_bytes.FF_FLOAT
|
||||
* ida_bytes.FF_OWORD
|
||||
* ida_bytes.FF_PACKREAL
|
||||
* ida_bytes.FF_QWORD
|
||||
* ida_bytes.FF_STRLIT
|
||||
* ida_bytes.FF_STRUCT
|
||||
* ida_bytes.FF_TBYTE
|
||||
* ida_bytes.FF_WORD
|
||||
* ida_bytes.off_flag
|
||||
* ida_bytes.stroff_flag
|
||||
* ida_idaapi.BADADDR
|
||||
* ida_nalt.STRTYPE_C
|
||||
* ida_struct.add_struc
|
||||
* ida_struct.get_struc_id
|
||||
* ida_struct.get_struc_size
|
||||
* idc.add_struc
|
||||
* idc.add_struc_member
|
||||
* idc.del_struc
|
||||
* idc.set_member_type
|
||||
* ida_typeinf.BTF_BYTE
|
||||
* ida_typeinf.BTF_DOUBLE
|
||||
* ida_typeinf.BTF_FLOAT
|
||||
* ida_typeinf.BTF_INT
|
||||
* ida_typeinf.BTF_INT128
|
||||
* ida_typeinf.BTF_INT16
|
||||
* ida_typeinf.BTF_INT64
|
||||
* ida_typeinf.BTF_TBYTE
|
||||
* ida_typeinf.BTF_UINT32
|
||||
* ida_typeinf.FRB_NUMO
|
||||
* ida_typeinf.NTF_TYPE
|
||||
* ida_typeinf.PRTYPE_DEF
|
||||
* ida_typeinf.PRTYPE_MULTI
|
||||
* ida_typeinf.PRTYPE_TYPE
|
||||
* ida_typeinf.del_named_type
|
||||
* ida_typeinf.idc_parse_types
|
||||
* ida_typeinf.tinfo_errstr
|
||||
* ida_typeinf.tinfo_t
|
||||
* ida_typeinf.udm_t
|
||||
* ida_typeinf.udt_type_data_t
|
||||
* ida_typeinf.value_repr_t
|
||||
|
||||
#### Author
|
||||
Gergely Erdelyi (gergely.erdelyi@d-dome.net)
|
||||
@@ -439,7 +437,7 @@ one format for a specific 'custom data type'.)
|
||||
* ida_lines.SCOLOR_REG
|
||||
* ida_nalt.get_input_file_path
|
||||
* ida_netnode.netnode
|
||||
* ida_struct.is_member_id
|
||||
* ida_typeinf.tinfo_t
|
||||
|
||||
</blockquote>
|
||||
|
||||
@@ -556,10 +554,13 @@ Ctrl+Shift+S
|
||||
* ida_kernwin.BWN_STRUCTS
|
||||
* ida_kernwin.action_desc_t
|
||||
* ida_kernwin.action_handler_t
|
||||
* ida_kernwin.get_current_viewer
|
||||
* ida_kernwin.get_viewer_user_data
|
||||
* ida_kernwin.l_compare2
|
||||
* ida_kernwin.linearray_t
|
||||
* ida_kernwin.read_selection
|
||||
* ida_kernwin.register_action
|
||||
* ida_kernwin.twinpos_t
|
||||
* ida_kernwin.unregister_action
|
||||
* ida_lines.tag_remove
|
||||
|
||||
@@ -2447,7 +2448,6 @@ comments and/or types of local variables.
|
||||
* ida_hexrays.modify_user_lvars
|
||||
* ida_hexrays.user_lvar_modifier_t
|
||||
* ida_typeinf.parse_decl
|
||||
* ida_typeinf.tinfo_t
|
||||
* idc.here
|
||||
|
||||
</blockquote>
|
||||
@@ -2505,11 +2505,11 @@ ctxmenu Hexrays_Hooks
|
||||
* ida_kernwin.action_handler_t
|
||||
* ida_kernwin.attach_action_to_popup
|
||||
* ida_kernwin.register_action
|
||||
* ida_struct.get_member
|
||||
* ida_struct.get_struc
|
||||
* ida_struct.get_struc_id
|
||||
* ida_typeinf.PRTYPE_1LINE
|
||||
* ida_typeinf.STRMEM_OFFSET
|
||||
* ida_typeinf.print_tinfo
|
||||
* ida_typeinf.tinfo_t
|
||||
* ida_typeinf.udm_t
|
||||
* idautils.Functions
|
||||
* idautils.XrefsTo
|
||||
|
||||
@@ -2581,7 +2581,6 @@ IDB_Hooks
|
||||
* ida_bytes.is_strlit
|
||||
* ida_bytes.is_stroff
|
||||
* ida_bytes.is_struct
|
||||
* ida_enum.get_enum_name
|
||||
* ida_idp.IDB_Hooks
|
||||
* ida_nalt.STRENC_DEFAULT
|
||||
* ida_nalt.get_default_encoding_idx
|
||||
@@ -2589,7 +2588,8 @@ IDB_Hooks
|
||||
* ida_nalt.get_str_encoding_idx
|
||||
* ida_nalt.get_strtype_bpu
|
||||
* ida_nalt.opinfo_t
|
||||
* ida_struct.get_struc_name
|
||||
* ida_typeinf.get_tid_name
|
||||
* ida_typeinf.tinfo_t
|
||||
|
||||
</blockquote>
|
||||
|
||||
@@ -3454,6 +3454,7 @@ chooser functions
|
||||
* ida_kernwin.Choose.CHCOL_FNAME
|
||||
* ida_kernwin.Choose.CHCOL_HEX
|
||||
* ida_kernwin.Choose.CHCOL_PLAIN
|
||||
* ida_kernwin.get_icon_id_by_name
|
||||
* idautils.Functions
|
||||
* idc.del_func
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class my_funcs_t(ida_kernwin.Choose):
|
||||
[ ["Address", 10 | ida_kernwin.Choose.CHCOL_HEX],
|
||||
["Name", 30 | ida_kernwin.Choose.CHCOL_PLAIN | ida_kernwin.Choose.CHCOL_FNAME] ])
|
||||
self.items = []
|
||||
self.icon = 41
|
||||
self.icon = ida_kernwin.get_icon_id_by_name("resources/menu/OpenFunctions.svg")
|
||||
|
||||
def OnInit(self):
|
||||
self.items = [ [hex(x), ida_funcs.get_func_name(x), x]
|
||||
|
||||
@@ -149,3 +149,6 @@ void ext_api_t::clear()
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
ext_api_t extapi;
|
||||
|
||||
|
||||
@@ -59,4 +59,6 @@ struct ext_api_t
|
||||
void clear();
|
||||
};
|
||||
|
||||
extern ext_api_t extapi;
|
||||
|
||||
#endif // EXTAPI_HPP
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
#include "extapi.hpp"
|
||||
#include "extapi.cpp"
|
||||
|
||||
ext_api_t extapi;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
idapython_plugin_t *idapython_plugin_t::instance = nullptr;
|
||||
|
||||
@@ -620,7 +618,6 @@ struct python_highlighter_t : public ida_syntax_highlighter_t
|
||||
"raise|return|try|while|with|yield|"
|
||||
"None|True|False",HF_KEYWORD1);
|
||||
add_keywords("self", HF_KEYWORD2);
|
||||
add_keywords("def", HF_KEYWORD3);
|
||||
}
|
||||
|
||||
void add_new_keywords()
|
||||
|
||||
+6
-5
@@ -8,10 +8,11 @@ global:
|
||||
PyW_GetStringAttr;
|
||||
PyW_IsSequenceType;
|
||||
PyW_ObjectToString;
|
||||
PyW_PyListToEaVec;
|
||||
PyW_PyListToEa64Vec;
|
||||
PyW_PyListToSizeVec;
|
||||
PyW_PyListToStrVec;
|
||||
PyW_PySeqToEaVec;
|
||||
PyW_PySeqToTidVec;
|
||||
PyW_PySeqToEa64Vec;
|
||||
PyW_PySeqToSizeVec;
|
||||
PyW_PySeqToStrVec;
|
||||
PyW_from_jvalue_t;
|
||||
PyW_to_jvalue_t;
|
||||
PyW_from_jobj_t;
|
||||
@@ -56,7 +57,7 @@ global:
|
||||
python_timer_new;
|
||||
pyvar_to_idcvar;
|
||||
pyvar_to_idcvar_or_error;
|
||||
pyvar_walk_list;
|
||||
pyvar_walk_seq;
|
||||
pyw_convert_idc_args;
|
||||
register_module_lifecycle_callbacks;
|
||||
set_script_timeout;
|
||||
|
||||
@@ -9,10 +9,11 @@ EXPORTS
|
||||
PyW_StrVecToPyList
|
||||
PyW_IsSequenceType
|
||||
PyW_ObjectToString
|
||||
PyW_PyListToEaVec
|
||||
PyW_PyListToEa64Vec
|
||||
PyW_PyListToSizeVec
|
||||
PyW_PyListToStrVec
|
||||
PyW_PySeqToEaVec
|
||||
PyW_PySeqToTidVec
|
||||
PyW_PySeqToEa64Vec
|
||||
PyW_PySeqToSizeVec
|
||||
PyW_PySeqToStrVec
|
||||
PyW_from_jvalue_t
|
||||
PyW_to_jvalue_t
|
||||
PyW_from_jobj_t
|
||||
@@ -47,7 +48,7 @@ EXPORTS
|
||||
python_timer_del
|
||||
pyvar_to_idcvar
|
||||
pyvar_to_idcvar_or_error
|
||||
pyvar_walk_list
|
||||
pyvar_walk_seq
|
||||
pyw_convert_idc_args
|
||||
set_script_timeout
|
||||
set_interruptible_state
|
||||
|
||||
@@ -18,13 +18,36 @@ include ../../allmake.mak
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# default goals
|
||||
.PHONY: configs modules pyfiles deployed_modules idapython_modules api_contents pydoc_injections pyqt sip bins public_tree test_idc docs tbd examples_index
|
||||
all: configs modules pyfiles deployed_modules idapython_modules api_contents pydoc_injections pyqt sip bins examples_index # public_tree test_idc docs
|
||||
.PHONY: configs modules pyfiles deployed_modules idapython_modules api_check api_contents pyqt sip bins public_tree test_idc docs tbd examples_index test_pywraps
|
||||
all: configs modules pyfiles deployed_modules idapython_modules api_check api_contents pyqt sip bins examples_index test_pywraps # public_tree test_idc docs
|
||||
|
||||
ifeq ($(OUT_OF_TREE_BUILD),)
|
||||
IDAPYSWITCH:=$(R)idapyswitch$(B)
|
||||
IDAPYSWITCH_DEP:=$(IDAPYSWITCH)
|
||||
IDAPYSWITCH_PATH:=$(IDAPYSWITCH)
|
||||
TEST_PYWRAPS_RESULT_FNAME:=test_pywraps$(ADRSIZE).txt
|
||||
ifdef __NT__
|
||||
# On Windows, we cannot afford to use `test_pywraps` during a
|
||||
# debug build: since `test_pywraps.exe` relies on `python3.dll`
|
||||
# (and corresponding headers), Python will force optimized
|
||||
# iterators resulting in errors such as:
|
||||
# dumb.obj : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in test_pywraps.obj
|
||||
|
||||
# And as it turns out, doing it during an optimized build
|
||||
# is problematic as well, because it'll typically not find
|
||||
# `python3.dll`. I tried to support it by patching `PATH`,
|
||||
# but now we're dealing with cygwin confusion...
|
||||
ifdef NDEBUG
|
||||
HAS_TEST_PYWRAPS:=1
|
||||
PYTHON_ROOT_CYGPATH:=$(shell cygpath $(PYTHON_ROOT))
|
||||
TEST_PYWRAPS_ENV:=PATH="$$PATH:$(PYTHON_ROOT_CYGPATH)"
|
||||
endif
|
||||
else
|
||||
HAS_TEST_PYWRAPS:=1
|
||||
endif
|
||||
ifeq ($(HAS_TEST_PYWRAPS),1)
|
||||
TEST_PYWRAPS:=$(F)$(TEST_PYWRAPS_RESULT_FNAME).marker
|
||||
endif
|
||||
BINS += $(IDAPYSWITCH)
|
||||
else
|
||||
ifdef __NT__
|
||||
@@ -127,6 +150,7 @@ PYTHON_OBJS += $(F)idapython$(O)
|
||||
$(MODULE): MODULE_OBJS += $(PYTHON_OBJS)
|
||||
$(MODULE): $(PYTHON_OBJS) $(IDAPYSWITCH_MODULE_DEP) $(TBD_MODULE_DEP)
|
||||
ifdef __NT__
|
||||
$(MODULE): OUTDLL = /DLL /NOEXP
|
||||
$(MODULE): LDFLAGS += /DEF:$(IDAPYTHON_IMPLIB_DEF) /IMPLIB:$(IDAPYTHON_IMPLIB_PATH)
|
||||
endif
|
||||
|
||||
@@ -143,6 +167,7 @@ PATCH_CONST=$(Q)$(PYTHON) tools/patch_constants.py -i $(1) -o $(2)
|
||||
# TODO move this below, but it might be necessary before the defines-*
|
||||
ifdef DO_IDAMAKE_SIMPLIFY
|
||||
QCHKAPI = @echo $(call qcolor,chkapi) && #
|
||||
QDUMPAPI = @echo $(call qcolor,dumpapi) && #
|
||||
QDEPLOY = @echo $(call qcolor,deploy) $$< && #
|
||||
QGENDOXYCFG = @echo $(call qcolor,gendoxycfg) $@ && #
|
||||
QGENHOOKS = @echo $(call qcolor,genhooks) $< && #
|
||||
@@ -155,7 +180,6 @@ ifdef DO_IDAMAKE_SIMPLIFY
|
||||
QSWIG = @echo $(call qcolor,swig) $$< && #
|
||||
QUPDATE_SDK = @echo $(call qcolor,update_sdk) $< && #
|
||||
QSPLIT_HEXRAYS_TEMPLATES = @echo $(call qcolor,split_hexrays_templates) $< && #
|
||||
QPYDOC_INJECTIONS = @echo $(call qcolor,check_injections) $@ && #
|
||||
QGEN_EXAMPLES_INDEX = @echo $(call qcolor,gen_examples_index) $@ && #
|
||||
endif
|
||||
|
||||
@@ -187,9 +211,9 @@ else
|
||||
endif
|
||||
|
||||
ifeq ($(OUT_OF_TREE_BUILD),)
|
||||
IDAT_CMD=TVHEADLESS=1 $(IDAT_PATH)$(SUFF64)
|
||||
IDAT_CMD=TVHEADLESS=1 "$(IDAT_PATH)$(SUFF64)"
|
||||
else
|
||||
IDAT_CMD=TVHEADLESS=1 IDAPYTHON_DYNLOAD_BASE=$(R) $(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
|
||||
@@ -274,6 +298,7 @@ MODULES_NAMES += pro
|
||||
MODULES_NAMES += problems
|
||||
MODULES_NAMES += range
|
||||
MODULES_NAMES += registry
|
||||
MODULES_NAMES += regfinder
|
||||
MODULES_NAMES += search
|
||||
MODULES_NAMES += segment
|
||||
MODULES_NAMES += segregs
|
||||
@@ -291,6 +316,7 @@ endif
|
||||
|
||||
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)
|
||||
ALL_ST_WRAP_PY_FINAL = $(foreach mod,$(MODULES_NAMES),$(ST_WRAP)/ida_$(mod).py.final)
|
||||
DEPLOYED_MODULES = $(foreach mod,$(MODULES_NAMES),$(DEPLOY_LIBDIR)/_ida_$(mod)$(PYDLL_EXT))
|
||||
IDAPYTHON_MODULES = $(foreach mod,$(MODULES_NAMES),$(DEPLOY_PYDIR)/ida_$(mod).py)
|
||||
PYTHON_BINARY_MODULES = $(foreach mod,$(MODULES_NAMES),$(DEPLOY_LIBDIR)/_ida_$(mod)$(PYDLL_EXT))
|
||||
@@ -617,8 +643,8 @@ CC_DEFS += MISSED_BC695
|
||||
CC_DEFS += $(DEF_TYPE_TABLE)
|
||||
CC_DEFS += $(WITH_HEXRAYS_DEF)
|
||||
CC_DEFS += USE_STANDARD_FILE_FUNCTIONS
|
||||
CC_DEFS += VER_MAJOR="7"
|
||||
CC_DEFS += VER_MINOR="4"
|
||||
CC_DEFS += VER_MAJOR=$(IDAVER_MAJOR)
|
||||
CC_DEFS += VER_MINOR=$(IDAVER_MINOR)
|
||||
CC_DEFS += VER_PATCH="0"
|
||||
CC_DEFS += __EXPR_SRC
|
||||
CC_INCP += $(F)
|
||||
@@ -702,8 +728,12 @@ define make-module-rules
|
||||
# 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 tools/inject_pydoc.py $(PARSED_HEADERS_MARKER) $(call find-pydoc-patches-deps,$(1)) $(call find-patch-codegen-deps,$(1))
|
||||
# ../../bin/x86_linux_gcc/python/ida_$(1).py
|
||||
$(DEPLOY_PYDIR)/ida_$(1).py: $(ST_WRAP)/ida_$(1).py.final
|
||||
$(Q)$(CP) $$< $$@
|
||||
|
||||
# obj/x86_linux_gcc/wrappers/ida_X.py.final (note: dep. on .cpp. See note above.)
|
||||
$(ST_WRAP)/ida_$(1).py.final: $(ST_WRAP)/$(1).cpp tools/inject_pydoc.py $(PARSED_HEADERS_MARKER) $(call find-pydoc-patches-deps,$(1)) $(call find-patch-codegen-deps,$(1))
|
||||
$(QINJECT_PYDOC)$(PYTHON) tools/inject_pydoc.py \
|
||||
--xml-doc-directory $(ST_PARSED_HEADERS) \
|
||||
--module $(1) \
|
||||
@@ -817,63 +847,47 @@ endif
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
ifdef TESTABLE_BUILD
|
||||
API_CONTENTS = api_contents$(EXTRASUF1)$(PYTHON_VERSION_MAJOR).txt
|
||||
API_CONTENTS = api_contents$(EXTRASUF1).brief
|
||||
else
|
||||
API_CONTENTS = release_api_contents$(EXTRASUF1)$(PYTHON_VERSION_MAJOR).txt
|
||||
API_CONTENTS = api_contents$(EXTRASUF1).full
|
||||
API_CONTENTS_OPTS := --dump-doc
|
||||
endif
|
||||
ST_API_CONTENTS = $(F)$(API_CONTENTS)
|
||||
ST_API_CONTENTS_SUCCESS = $(ST_API_CONTENTS).success
|
||||
.PRECIOUS: $(ST_API_CONTENTS)
|
||||
|
||||
api_contents: $(ST_API_CONTENTS_SUCCESS)
|
||||
$(ST_API_CONTENTS_SUCCESS): $(ALL_ST_WRAP_CPP)
|
||||
ifeq ($(or $(__CODE_CHECKER__),$(NO_CMP_API),$(__ASAN__),$(IDAHOME),$(DEMO_OR_FREE)),)
|
||||
$(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)
|
||||
$(ST_API_CONTENTS_SUCCESS): $(ALL_ST_WRAP_PY_FINAL) $(API_CONTENTS) tools/py_scanner.py
|
||||
$(QDUMPAPI)$(PYTHON) tools/py_scanner.py --dump-kind $(API_CONTENTS_OPTS) --paths $(subst $(space),$(comma),$(ALL_ST_WRAP_PY_FINAL)) > $(ST_API_CONTENTS)
|
||||
ifeq ($(OUT_OF_TREE_BUILD),)
|
||||
ifdef CMP_API # turn off comparison when bw-compat is off, or api_contents will differ
|
||||
$(Q)(diff -w $(API_CONTENTS) $(ST_API_CONTENTS)) > /dev/null || \
|
||||
$(Q)((diff -w $(API_CONTENTS) $(ST_API_CONTENTS)) > /dev/null && touch $@) || \
|
||||
(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
|
||||
(diff -U 1 -w $(API_CONTENTS) $(ST_API_CONTENTS); true))
|
||||
else
|
||||
$(Q)touch $@
|
||||
endif
|
||||
else
|
||||
$(ST_API_CONTENTS_SUCCESS): $(ALL_ST_WRAP_PY_FINAL) tools/py_scanner.py
|
||||
$(Q)touch $@
|
||||
endif
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
ST_API_CHECK_SUCCESS := $(F)api_check.success
|
||||
api_check: $(ST_API_CHECK_SUCCESS)
|
||||
$(ST_API_CHECK_SUCCESS): $(ALL_ST_WRAP_CPP)
|
||||
ifeq ($(or $(__CODE_CHECKER__),$(NO_CMP_API),$(__ASAN__),$(IDAHOME),$(DEMO_OR_FREE)),)
|
||||
$(QCHKAPI)$(PYTHON) tools/chkapi.py $(WITH_HEXRAYS_CHKAPI) -i $(subst $(space),$(comma),$(ALL_ST_WRAP_CPP)) -p $(subst $(space),$(comma),$(ALL_ST_WRAP_PY))
|
||||
endif
|
||||
$(Q)touch $@
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# Check that doc injection is stable
|
||||
ifdef TESTABLE_BUILD
|
||||
PYDOC_INJECTIONS = pydoc_injections$(EXTRASUF1)$(PYTHON_VERSION_MAJOR).txt
|
||||
else
|
||||
PYDOC_INJECTIONS = release_pydoc_injections$(EXTRASUF1)$(PYTHON_VERSION_MAJOR).txt
|
||||
endif
|
||||
ST_PYDOC_INJECTIONS = $(F)$(PYDOC_INJECTIONS)
|
||||
ST_PYDOC_INJECTIONS_SUCCESS = $(ST_PYDOC_INJECTIONS).success
|
||||
.PRECIOUS: $(ST_PYDOC_INJECTIONS)
|
||||
|
||||
ifdef __EA64__
|
||||
DUMPDOC_IS_64:=True
|
||||
else
|
||||
DUMPDOC_IS_64:=False
|
||||
endif
|
||||
|
||||
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)),)
|
||||
$(QPYDOC_INJECTIONS)$(PYDOC_INJECTIONS_IDAT_CMD) || \
|
||||
(echo "Command \"$(PYDOC_INJECTIONS_IDAT_CMD)\" failed. Check \"$(F)dumpdoc.log\" for details." && false)
|
||||
$(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))
|
||||
endif
|
||||
$(Q)touch $@
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
DOCS_MODULES=$(foreach mod,$(MODULES_NAMES),ida_$(mod))
|
||||
SORTED_DOCS_MODULES=$(sort $(DOCS_MODULES))
|
||||
@@ -935,6 +949,34 @@ ifdef __NT__
|
||||
endif
|
||||
$(R)idapyswitch$(B): $(call dumb_target, pro, $(IDAPYSWITCH_OBJS))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
TEST_PYWRAPS_OBJS += $(F)test_pywraps$(O)
|
||||
TEST_PYWRAPS_DEPS := pywraps.cpp pywraps.hpp extapi.cpp extapi.hpp
|
||||
$(F)test_pywraps$(O): $(PARSED_HEADERS_MARKER) $(TEST_PYWRAPS_DEPS)
|
||||
ifdef __NT__
|
||||
ifneq ($(OUT_OF_TREE_BUILD),)
|
||||
# SDK provides only MT libraries
|
||||
$(F)test_pywraps$(O): RUNTIME_LIBSW=/MT
|
||||
endif
|
||||
endif
|
||||
$(R)test_pywraps$(B): $(call dumb_target, json idc unicode pro, $(TEST_PYWRAPS_OBJS)) $(PYTHON_LDFLAGS)
|
||||
|
||||
$(F)$(TEST_PYWRAPS_RESULT_FNAME).marker: $(R)test_pywraps$(B)
|
||||
$(Q)$(TEST_PYWRAPS_ENV) $(R)test_pywraps$(B) > $(F)$(TEST_PYWRAPS_RESULT_FNAME)
|
||||
ifeq ($(OUT_OF_TREE_BUILD),)
|
||||
$(Q)((diff -w $(TEST_PYWRAPS_RESULT_FNAME) $(F)$(TEST_PYWRAPS_RESULT_FNAME)) > /dev/null && touch $@) || \
|
||||
(echo "$(TEST_PYWRAPS_RESULT_FNAME) changed" && \
|
||||
(diff -U 1 -w $(TEST_PYWRAPS_RESULT_FNAME) $(F)$(TEST_PYWRAPS_RESULT_FNAME); true))
|
||||
else
|
||||
$(Q)touch $@
|
||||
endif
|
||||
|
||||
ifdef __CODE_CHECKER__
|
||||
test_pywraps: ;
|
||||
else
|
||||
test_pywraps: $(TEST_PYWRAPS)
|
||||
endif
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
ifdef __MAC__
|
||||
tbd: $(TBD_MODULE_DEP)
|
||||
@@ -1071,6 +1113,7 @@ $(F)idapyswitch$(O): $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
../../ldr/mach-o/h/sys/_symbol_aliasing.h \
|
||||
../../ldr/mach-o/h/sys/cdefs.h \
|
||||
../../ldr/mach-o/macho_node.h \
|
||||
../../ldr/mach-o/strtab_reader_t.h \
|
||||
../../ldr/mach-o/uncompress.cpp ../../ldr/pe/../idaldr.h \
|
||||
../../ldr/pe/common.cpp ../../ldr/pe/common.h \
|
||||
../../ldr/pe/pe.h idapyswitch.cpp idapyswitch_linux.cpp \
|
||||
@@ -1083,5 +1126,14 @@ $(F)idapython$(O): $(I)bitrange.hpp $(I)bytes.hpp $(I)config.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
|
||||
$(I)xref.hpp extapi.hpp idapython.cpp pywraps.cpp \
|
||||
pywraps.hpp
|
||||
$(F)test_pywraps$(O): $(I)bitrange.hpp $(I)bytes.hpp $(I)config.hpp \
|
||||
$(I)err.h $(I)expr.hpp $(I)fpro.h $(I)funcs.hpp \
|
||||
$(I)gdl.hpp $(I)graph.hpp $(I)ida.hpp $(I)idd.hpp \
|
||||
$(I)idp.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 pywraps.cpp \
|
||||
pywraps.hpp test_pywraps.cpp
|
||||
|
||||
Binary file not shown.
-116572
File diff suppressed because it is too large
Load Diff
-115125
File diff suppressed because it is too large
Load Diff
+46
-10
@@ -790,7 +790,7 @@ def define_local_var(start, end, location, name):
|
||||
return 0
|
||||
|
||||
# Find out if location is in the [bp+xx] form
|
||||
r = re.compile("\[([a-z]+)([-+][0-9a-fx]+)", re.IGNORECASE)
|
||||
r = re.compile(r"\[([a-z]+)([-+][0-9a-fx]+)", re.IGNORECASE)
|
||||
m = r.match(location)
|
||||
|
||||
if m:
|
||||
@@ -4520,7 +4520,7 @@ def __m1tol(v):
|
||||
Otherwise, return 'v'.
|
||||
"""
|
||||
if v == -1:
|
||||
return ida_netnode.BADNODE
|
||||
return ida_netnode.BADNODE
|
||||
else:
|
||||
return v
|
||||
|
||||
@@ -4978,13 +4978,38 @@ def get_type(ea):
|
||||
"""
|
||||
return ida_typeinf.idc_get_type(ea)
|
||||
|
||||
def SizeOf(typestr):
|
||||
def sizeof(typestr):
|
||||
"""
|
||||
Returns the size of the type. It is equivalent to IDC's sizeof().
|
||||
Use name, tp, fld = idc.parse_decl() ; SizeOf(tp) to retrieve the size
|
||||
@return: -1 if typestring is not valid otherwise the size of the type
|
||||
@param typestr: can be specified as a typeinfo tuple (e.g. the result of get_tinfo()),
|
||||
serialized type byte string,
|
||||
or a string with C declaration (e.g. "int")
|
||||
@return: -1 if typestring is not valid or has no size. otherwise size of the type
|
||||
"""
|
||||
return ida_typeinf.calc_type_size(None, typestr)
|
||||
if isinstance(typestr, tuple):
|
||||
if len(typestr) == 3:
|
||||
# result of idc.parse_decl() ?
|
||||
tp = typestr[1]
|
||||
elif len(typestr) == 2:
|
||||
# reult of idc.get_tinfo() ?
|
||||
tp = typestr[0]
|
||||
else:
|
||||
tp = None
|
||||
elif isinstance(typestr, bytes):
|
||||
# raw serialized byte string ?
|
||||
tp = typestr
|
||||
elif isinstance(typestr, str):
|
||||
# C declaration ?
|
||||
name, tp, _ = parse_decl(typestr, 0)
|
||||
|
||||
# here, 'tp' should be the serialized type string
|
||||
if isinstance(tp, bytes):
|
||||
r = ida_typeinf.calc_type_size(None, tp)
|
||||
return -1 if r is None else r
|
||||
else:
|
||||
raise TypeError("idc.sizeof(): expected type tuple, serialized type string, or C declaration")
|
||||
|
||||
SizeOf = sizeof
|
||||
|
||||
def get_tinfo(ea):
|
||||
"""
|
||||
@@ -5182,10 +5207,21 @@ def GetLocalType(ordinal, flags):
|
||||
return ida_typeinf.idc_print_type(type, fields, name, flags)
|
||||
return ""
|
||||
|
||||
PRTYPE_1LINE = 0x0000 # print to one line
|
||||
PRTYPE_MULTI = 0x0001 # print to many lines
|
||||
PRTYPE_TYPE = 0x0002 # print type declaration (not variable declaration)
|
||||
PRTYPE_PRAGMA = 0x0004 # print pragmas for alignment
|
||||
PRTYPE_1LINE = 0x0000 # print to one line
|
||||
PRTYPE_MULTI = 0x0001 # print to many lines
|
||||
PRTYPE_TYPE = 0x0002 # print type declaration (not variable declaration)
|
||||
PRTYPE_PRAGMA = 0x0004 # print pragmas for alignment
|
||||
PRTYPE_SEMI = 0x0008 # append ; to the end
|
||||
PRTYPE_CPP = 0x0010 # use c++ name (only for print_type())
|
||||
PRTYPE_DEF = 0x0020 # tinfo_t: print definition, if available
|
||||
PRTYPE_NOARGS = 0x0040 # tinfo_t: do not print function argument names
|
||||
PRTYPE_NOARRS = 0x0080 # tinfo_t: print arguments with #FAI_ARRAY as pointers
|
||||
PRTYPE_NORES = 0x0100 # tinfo_t: never resolve types (meaningful with PRTYPE_DEF)
|
||||
PRTYPE_RESTORE = 0x0200 # tinfo_t: print restored types for #FAI_ARRAY and #FAI_STRUCT
|
||||
PRTYPE_NOREGEX = 0x0400 # do not apply regular expressions to beautify name
|
||||
PRTYPE_COLORED = 0x0800 # add color tag COLOR_SYMBOL for any parentheses, commas and colons
|
||||
PRTYPE_METHODS = 0x1000 # tinfo_t: print udt methods
|
||||
PRTYPE_1LINCMT = 0x2000 # print comments in one line mode
|
||||
|
||||
|
||||
def get_numbered_type_name(ordinal):
|
||||
|
||||
+79
-88
@@ -114,10 +114,11 @@ ref_t ida_export PyW_StrVecToPyList(const qstrvec_t &vec)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static Py_ssize_t pyvar_walk_list(
|
||||
static Py_ssize_t pyvar_walk_seq(
|
||||
const ref_t &py_list,
|
||||
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud),
|
||||
void *ud)
|
||||
void *ud,
|
||||
size_t maxsize)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
|
||||
@@ -130,6 +131,8 @@ static Py_ssize_t pyvar_walk_list(
|
||||
|
||||
bool is_seq = !PyList_CheckExact(o);
|
||||
Py_ssize_t seqsz = is_seq ? PySequence_Size(o) : PyList_Size(o);
|
||||
if ( maxsize < seqsz )
|
||||
seqsz = maxsize;
|
||||
for ( Py_ssize_t i = 0; i < seqsz; ++i )
|
||||
{
|
||||
// Get the item
|
||||
@@ -162,17 +165,18 @@ static Py_ssize_t pyvar_walk_list(
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
Py_ssize_t ida_export pyvar_walk_list(
|
||||
Py_ssize_t ida_export pyvar_walk_seq(
|
||||
PyObject *py_list,
|
||||
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud),
|
||||
void *ud)
|
||||
void *ud,
|
||||
size_t maxsize)
|
||||
{
|
||||
borref_t r(py_list);
|
||||
return pyvar_walk_list(r, cb, ud);
|
||||
return pyvar_walk_seq(r, cb, ud, maxsize);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
Py_ssize_t ida_export PyW_PyListToSizeVec(sizevec_t *out, PyObject *py_list)
|
||||
Py_ssize_t ida_export PyW_PySeqToSizeVec(sizevec_t *out, PyObject *py_list, size_t maxsize)
|
||||
{
|
||||
out->clear();
|
||||
struct ida_local lambda_t
|
||||
@@ -187,11 +191,14 @@ Py_ssize_t ida_export PyW_PyListToSizeVec(sizevec_t *out, PyObject *py_list)
|
||||
return CIP_OK;
|
||||
}
|
||||
};
|
||||
return pyvar_walk_list(py_list, lambda_t::cvt, out);
|
||||
return pyvar_walk_seq(py_list, lambda_t::cvt, out, maxsize);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
Py_ssize_t ida_export PyW_PyListToEaVec(eavec_t *out, PyObject *py_list)
|
||||
Py_ssize_t ida_export PyW_PySeqToEaVec(
|
||||
eavec_t *out,
|
||||
PyObject *py_list,
|
||||
size_t maxsize)
|
||||
{
|
||||
out->clear();
|
||||
struct ida_local lambda_t
|
||||
@@ -217,11 +224,20 @@ Py_ssize_t ida_export PyW_PyListToEaVec(eavec_t *out, PyObject *py_list)
|
||||
return CIP_OK;
|
||||
}
|
||||
};
|
||||
return pyvar_walk_list(py_list, lambda_t::cvt, out);
|
||||
return pyvar_walk_seq(py_list, lambda_t::cvt, out, maxsize);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
Py_ssize_t ida_export PyW_PyListToEa64Vec(ea64vec_t *out, PyObject *py_list)
|
||||
Py_ssize_t ida_export PyW_PySeqToTidVec(
|
||||
qvector<tid_t> *out,
|
||||
PyObject *py_list,
|
||||
size_t maxsize)
|
||||
{
|
||||
return PyW_PySeqToEaVec((eavec_t *) out, py_list, maxsize);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
Py_ssize_t ida_export PyW_PySeqToEa64Vec(ea64vec_t *out, PyObject *py_list, size_t maxsize)
|
||||
{
|
||||
out->clear();
|
||||
struct ida_local lambda_t
|
||||
@@ -247,11 +263,11 @@ Py_ssize_t ida_export PyW_PyListToEa64Vec(ea64vec_t *out, PyObject *py_list)
|
||||
return CIP_OK;
|
||||
}
|
||||
};
|
||||
return pyvar_walk_list(py_list, lambda_t::cvt, out);
|
||||
return pyvar_walk_seq(py_list, lambda_t::cvt, out, maxsize);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
Py_ssize_t ida_export PyW_PyListToStrVec(qstrvec_t *out, PyObject *py_list)
|
||||
Py_ssize_t ida_export PyW_PySeqToStrVec(qstrvec_t *out, PyObject *py_list, size_t maxsize)
|
||||
{
|
||||
out->clear();
|
||||
struct ida_local lambda_t
|
||||
@@ -265,7 +281,7 @@ Py_ssize_t ida_export PyW_PyListToStrVec(qstrvec_t *out, PyObject *py_list)
|
||||
return CIP_OK;
|
||||
}
|
||||
};
|
||||
return pyvar_walk_list(py_list, lambda_t::cvt, out);
|
||||
return pyvar_walk_seq(py_list, lambda_t::cvt, out, maxsize);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -1315,96 +1331,71 @@ bool ida_export PyW_GetNumberAsIDC(PyObject *py_var, idc_value_t *idc_var)
|
||||
bool is_64;
|
||||
if ( !PyW_GetNumber(py_var, &num, &is_64) )
|
||||
return false;
|
||||
if ( !is_64 || int64(num) >= SVAL_MIN && int64(num) <= SVAL_MAX ) //-V560 is always true
|
||||
idc_var->set_long(sval_t(num));
|
||||
else
|
||||
if ( is_64 )
|
||||
idc_var->set_int64(int64(num));
|
||||
else
|
||||
idc_var->set_long(sval_t(num));
|
||||
return true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Parses a Python object as a long or long long
|
||||
CASSERT(sizeof(PY_LONG_LONG) == 8);
|
||||
bool ida_export PyW_GetNumber(PyObject *py_var, uint64 *num, bool *is_64)
|
||||
{
|
||||
PYW_GIL_CHECK_LOCKED_SCOPE();
|
||||
bool rc = true;
|
||||
#define SETNUM(numexpr, is64_expr) \
|
||||
do \
|
||||
{ \
|
||||
if ( num != nullptr ) \
|
||||
*num = numexpr; \
|
||||
if ( is_64 != nullptr ) \
|
||||
*is_64 = is64_expr; \
|
||||
} while ( false )
|
||||
uint64 _num = 0;
|
||||
bool _is_64 = false;
|
||||
if ( num == nullptr )
|
||||
num = &_num;
|
||||
if ( is_64 == nullptr )
|
||||
is_64 = &_is_64;
|
||||
|
||||
do
|
||||
*is_64 = false;
|
||||
|
||||
if ( !PyLong_CheckExact(py_var) )
|
||||
return false;
|
||||
|
||||
// Try to convert to a signed long long
|
||||
PY_LONG_LONG ll = PyLong_AsLongLong(py_var);
|
||||
if ( PyErr_Occurred() == nullptr )
|
||||
{
|
||||
if ( !PyLong_CheckExact(py_var) )
|
||||
{
|
||||
rc = false;
|
||||
break;
|
||||
}
|
||||
if ( ll < int64(INT_MIN) || ll > int64(INT_MAX) )
|
||||
*is_64 = true;
|
||||
*num = uint64(ll);
|
||||
return true;
|
||||
}
|
||||
|
||||
constexpr bool is_long_64 = sizeof(long) > 4;
|
||||
// Not a signed long long. Try unsigned long long
|
||||
PyErr_Clear();
|
||||
unsigned PY_LONG_LONG ull = PyLong_AsUnsignedLongLong(py_var);
|
||||
if ( PyErr_Occurred() == nullptr )
|
||||
{
|
||||
*is_64 = true;
|
||||
*num = uint64(ull);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Can we convert to C long?
|
||||
long l = PyLong_AsLong(py_var);
|
||||
if ( PyErr_Occurred() == nullptr )
|
||||
{
|
||||
SETNUM(uint64(l), is_long_64);
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear last error
|
||||
// Binary AND it with uint64(-1)
|
||||
if ( PyErr_Occurred() == PyExc_TypeError )
|
||||
{
|
||||
PyErr_Clear();
|
||||
|
||||
// Can be fit into a C unsigned long?
|
||||
unsigned long ul = PyLong_AsUnsignedLong(py_var);
|
||||
if ( PyErr_Occurred() == nullptr ) //-V547 'PyErr_Occurred() == nullptr' is always false
|
||||
newref_t py_mask(Py_BuildValue("K", 0xFFFFFFFFFFFFFFFFull));
|
||||
newref_t py_num(PyNumber_And(py_var, py_mask.o));
|
||||
if ( py_num && py_mask )
|
||||
{
|
||||
SETNUM(uint64(ul), is_long_64);
|
||||
break;
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
// Try to parse as int64
|
||||
PY_LONG_LONG ll = PyLong_AsLongLong(py_var);
|
||||
if ( PyErr_Occurred() == nullptr ) //-V547 'PyErr_Occurred() == nullptr' is always false
|
||||
{
|
||||
SETNUM(uint64(ll), true);
|
||||
break;
|
||||
}
|
||||
PyErr_Clear();
|
||||
|
||||
// Try to parse as uint64
|
||||
unsigned PY_LONG_LONG ull = PyLong_AsUnsignedLongLong(py_var);
|
||||
PyObject *err = PyErr_Occurred();
|
||||
if ( err == nullptr ) //-V547 'err == 0' is always false
|
||||
{
|
||||
SETNUM(uint64(ull), true);
|
||||
break;
|
||||
}
|
||||
// Negative number? _And_ it with uint64(-1)
|
||||
rc = false;
|
||||
if ( err == PyExc_TypeError )
|
||||
{
|
||||
newref_t py_mask(Py_BuildValue("K", 0xFFFFFFFFFFFFFFFFull));
|
||||
newref_t py_num(PyNumber_And(py_var, py_mask.o));
|
||||
if ( py_num && py_mask )
|
||||
ull = PyLong_AsUnsignedLongLong(py_num.o);
|
||||
if ( PyErr_Occurred() == nullptr ) //-V547 'PyErr_Occurred() == nullptr' is always false
|
||||
{
|
||||
PyErr_Clear();
|
||||
ull = PyLong_AsUnsignedLongLong(py_num.o);
|
||||
if ( PyErr_Occurred() == nullptr ) //-V547 'PyErr_Occurred() == nullptr' is always false
|
||||
{
|
||||
SETNUM(uint64(ull), true);
|
||||
rc = true;
|
||||
}
|
||||
*is_64 = true;
|
||||
*num = uint64(ull);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
PyErr_Clear();
|
||||
} while ( false );
|
||||
return rc;
|
||||
#undef SETNUM
|
||||
}
|
||||
|
||||
PyErr_Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -1747,7 +1738,7 @@ void ida_export py_customidamemo_t_unbind(py_customidamemo_t *_this)
|
||||
|
||||
PyObject_SetAttrString(_this->self.o, S_M_THIS, Py_None);
|
||||
_this->self = newref_t(nullptr);
|
||||
_this->view = nullptr;
|
||||
_this->view = nullptr;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -2033,7 +2024,7 @@ bool ida_export idapython_convert_cli_completions(
|
||||
ok = PyList_Check(i0.o) && PyLong_Check(i1.o) && PyLong_Check(i2.o);
|
||||
if ( ok )
|
||||
{
|
||||
ok = PyW_PyListToStrVec(out_completions, i0.o) > 0;
|
||||
ok = PyW_PySeqToStrVec(out_completions, i0.o) > 0;
|
||||
if ( ok )
|
||||
{
|
||||
*out_match_start = PyLong_AsLong(i1.o);
|
||||
@@ -2042,7 +2033,7 @@ bool ida_export idapython_convert_cli_completions(
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear the error that was set by PyW_PyListToStrVec()
|
||||
// Clear the error that was set by PyW_PySeqToStrVec()
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
+9
-7
@@ -492,11 +492,12 @@ idaman int ida_export pyvar_to_idcvar(
|
||||
int *gvar_sn=nullptr);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Walks a Python list or Sequence and calls the callback
|
||||
idaman Py_ssize_t ida_export pyvar_walk_list(
|
||||
// Walks a Python sequence and calls the callback
|
||||
idaman Py_ssize_t ida_export pyvar_walk_seq(
|
||||
PyObject *py_list,
|
||||
int (idaapi *cb)(const ref_t &py_item, Py_ssize_t index, void *ud)=nullptr,
|
||||
void *ud = nullptr);
|
||||
void *ud = nullptr,
|
||||
size_t maxsize=size_t(-1));
|
||||
|
||||
// Converts a vector to a Python list object
|
||||
idaman ref_t ida_export PyW_SizeVecToPyList(const sizevec_t &vec);
|
||||
@@ -507,9 +508,10 @@ idaman ref_t ida_export PyW_StrVecToPyList(const qstrvec_t &vec);
|
||||
// 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
|
||||
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);
|
||||
idaman Py_ssize_t ida_export PyW_PySeqToSizeVec(sizevec_t *out, PyObject *py_list, size_t maxsize=size_t(-1));
|
||||
idaman Py_ssize_t ida_export PyW_PySeqToEaVec(eavec_t *out, PyObject *py_list, size_t maxsize=size_t(-1));
|
||||
idaman Py_ssize_t ida_export PyW_PySeqToStrVec(qstrvec_t *out, PyObject *py_list, size_t maxsize=size_t(-1));
|
||||
idaman Py_ssize_t ida_export PyW_PySeqToTidVec(qvector<tid_t> *out, PyObject *py_list, size_t maxsize=size_t(-1));
|
||||
|
||||
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);
|
||||
@@ -524,7 +526,7 @@ typedef uint64 ea64_t;
|
||||
#endif
|
||||
typedef qvector<ea64_t> ea64vec_t;
|
||||
#endif // LUMINA_HPP
|
||||
idaman Py_ssize_t ida_export PyW_PyListToEa64Vec(ea64vec_t *out, PyObject *py_list);
|
||||
idaman Py_ssize_t ida_export PyW_PySeqToEa64Vec(ea64vec_t *out, PyObject *py_list, size_t maxsize=size_t(-1));
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
#include <idd.hpp>
|
||||
|
||||
+40
-30
@@ -93,37 +93,37 @@ 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_0TYPE 0x00F00000 ///< Mask for 1st arg typing
|
||||
#define FF_0VOID 0x00000000 ///< Void (unknown)?
|
||||
#define FF_0NUMH 0x00100000 ///< Hexadecimal number?
|
||||
#define FF_0NUMD 0x00200000 ///< Decimal number?
|
||||
#define FF_0CHAR 0x00300000 ///< Char ('x')?
|
||||
#define FF_0SEG 0x00400000 ///< Segment?
|
||||
#define FF_0OFF 0x00500000 ///< Offset?
|
||||
#define FF_0NUMB 0x00600000 ///< Binary number?
|
||||
#define FF_0NUMO 0x00700000 ///< Octal number?
|
||||
#define FF_0ENUM 0x00800000 ///< Enumeration?
|
||||
#define FF_0FOP 0x00900000 ///< Forced operand?
|
||||
#define FF_0STRO 0x00A00000 ///< Struct offset?
|
||||
#define FF_0STK 0x00B00000 ///< Stack variable?
|
||||
#define FF_0FLT 0x00C00000 ///< Floating point number?
|
||||
#define FF_0CUST 0x00D00000 ///< 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?
|
||||
#define MS_1TYPE 0x0F000000 ///< Mask for the type of other operands
|
||||
#define FF_1VOID 0x00000000 ///< Void (unknown)?
|
||||
#define FF_1NUMH 0x01000000 ///< Hexadecimal number?
|
||||
#define FF_1NUMD 0x02000000 ///< Decimal number?
|
||||
#define FF_1CHAR 0x03000000 ///< Char ('x')?
|
||||
#define FF_1SEG 0x04000000 ///< Segment?
|
||||
#define FF_1OFF 0x05000000 ///< Offset?
|
||||
#define FF_1NUMB 0x06000000 ///< Binary number?
|
||||
#define FF_1NUMO 0x07000000 ///< Octal number?
|
||||
#define FF_1ENUM 0x08000000 ///< Enumeration?
|
||||
#define FF_1FOP 0x09000000 ///< Forced operand?
|
||||
#define FF_1STRO 0x0A000000 ///< Struct offset?
|
||||
#define FF_1STK 0x0B000000 ///< Stack variable?
|
||||
#define FF_1FLT 0x0C000000 ///< Floating point number?
|
||||
#define FF_1CUST 0x0D000000 ///< Custom representation?
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
/*
|
||||
@@ -313,6 +313,16 @@ static PyObject *py_get_8bit(ea_t ea, uint32 v, int nbit)
|
||||
return Py_BuildValue("(i" PY_BV_EA "ki)", int(uint32(octet)), bvea_t(ea), v, nbit);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static bool ida_export py_op_stroff(
|
||||
const insn_t &insn,
|
||||
int n,
|
||||
const qvector<tid_t> &path,
|
||||
adiff_t delta)
|
||||
{
|
||||
return op_stroff(insn, n, path.begin(), path.size(), delta);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
/*
|
||||
#<pydoc>
|
||||
|
||||
@@ -426,7 +426,8 @@ class __cbhooks_t(Hexrays_Hooks):
|
||||
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)
|
||||
|
||||
# NOTE: Do not add support for new notifications here;
|
||||
# non-Hexrays_Hooks callbacks are deprecated.
|
||||
|
||||
def install_hexrays_callback(callback):
|
||||
"Deprecated. Please use Hexrays_Hooks instead"
|
||||
|
||||
@@ -685,7 +685,7 @@ static bool py_execute_ui_requests(PyObject *py_list)
|
||||
// Walk the list and extract all callables
|
||||
bool init(PyObject *py_list)
|
||||
{
|
||||
Py_ssize_t count = pyvar_walk_list(
|
||||
Py_ssize_t count = pyvar_walk_seq(
|
||||
py_list,
|
||||
s_py_list_walk_cb,
|
||||
this);
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
//<inline(py_kernwin_askform)>
|
||||
#define DECLARE_FORM_ACTIONS form_actions_t *fa = (form_actions_t *)p_fa;
|
||||
|
||||
#ifdef TESTABLE_BUILD
|
||||
#include <features.hpp>
|
||||
#endif
|
||||
//---------------------------------------------------------------------------
|
||||
static bool textctrl_info_t_assign(PyObject *self, PyObject *other)
|
||||
{
|
||||
@@ -313,7 +316,7 @@ static bool formchgcbfa_set_field_value(
|
||||
{
|
||||
sizevec_t selection;
|
||||
if ( !PySequence_Check(py_val)
|
||||
|| PyW_PyListToSizeVec(&selection, py_val) < 0 )
|
||||
|| PyW_PySeqToSizeVec(&selection, py_val) < 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -350,6 +353,9 @@ static size_t py_get_open_form()
|
||||
|
||||
static void py_register_compiled_form(PyObject *py_form)
|
||||
{
|
||||
#ifdef TESTABLE_BUILD
|
||||
add_test_feature("idapy:askform");
|
||||
#endif
|
||||
PyW_register_compiled_form(py_form);
|
||||
}
|
||||
|
||||
|
||||
@@ -746,7 +746,7 @@ class py_chooser_multi_t : public chooser_multi_t, public py_chooser_mixin_t
|
||||
cbres_t res;
|
||||
// this is an easy but not an optimal way of converting
|
||||
if ( !PySequence_Check(pyres.result.o)
|
||||
|| PyW_PyListToSizeVec(sel, pyres.result.o) <= 0 )
|
||||
|| PyW_PySeqToSizeVec(sel, pyres.result.o) <= 0 )
|
||||
{
|
||||
sel->clear();
|
||||
res = NOTHING_CHANGED;
|
||||
@@ -886,7 +886,7 @@ PyObject *choose_choose(PyObject *self)
|
||||
ref_t deflt_attr(PyW_TryGetAttrString(self, "deflt"));
|
||||
if ( deflt_attr != nullptr
|
||||
&& PyList_Check(deflt_attr.o)
|
||||
&& PyW_PyListToSizeVec(&deflt, deflt_attr.o) < 0 )
|
||||
&& PyW_PySeqToSizeVec(&deflt, deflt_attr.o) < 0 )
|
||||
{
|
||||
deflt.clear();
|
||||
}
|
||||
@@ -989,10 +989,9 @@ PyObject *py_get_chooser_data(const char *chooser_caption, int n)
|
||||
qstrvec_t data;
|
||||
if ( !get_chooser_data(&data, chooser_caption, n) )
|
||||
Py_RETURN_NONE;
|
||||
PyObject *py_list = PyList_New(data.size());
|
||||
for ( size_t i = 0; i < data.size(); ++i )
|
||||
PyList_SetItem(py_list, i, PyUnicode_FromString(data[i].c_str()));
|
||||
return py_list;
|
||||
ref_t py_list_ref = PyW_StrVecToPyList(data);
|
||||
py_list_ref.incref();
|
||||
return py_list_ref.o;
|
||||
}
|
||||
|
||||
#define CH_NOIDB 0x00000040 // bw-compat
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ static bool qstrvec_t_from_list(
|
||||
qstrvec_t *sv = qstrvec_t_get_clink(self);
|
||||
return (sv == nullptr || !PySequence_Check(py_list))
|
||||
? false
|
||||
: (PyW_PyListToStrVec(sv, py_list) >= 0);
|
||||
: (PyW_PySeqToStrVec(sv, py_list) >= 0);
|
||||
}
|
||||
|
||||
static size_t qstrvec_t_size(PyObject *self)
|
||||
|
||||
@@ -27,8 +27,8 @@ PyObject *idc_parse_decl(til_t *ti, const char *decl, int flags)
|
||||
def calc_type_size(ti, tp):
|
||||
"""
|
||||
Returns the size of a type
|
||||
@param ti: Type info. 'None' can be passed.
|
||||
@param tp: type string
|
||||
@param ti: Type info library. 'None' can be passed.
|
||||
@param tp: serialized type byte string
|
||||
@return:
|
||||
- None on failure
|
||||
- The size of the type
|
||||
@@ -56,7 +56,7 @@ PyObject *py_calc_type_size(const til_t *ti, PyObject *tp)
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError, "String expected!");
|
||||
PyErr_SetString(PyExc_ValueError, "serialized type byte sequence expected!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@@ -517,7 +517,7 @@ PyObject *py_get_named_type(const til_t *til, const char *name, int ntf_flags)
|
||||
const type_t *type = nullptr;
|
||||
const p_list *fields = nullptr, *field_cmts = nullptr;
|
||||
const char *cmt = nullptr;
|
||||
sclass_t sclass = sc_unk;
|
||||
sclass_t sclass = SC_UNK;
|
||||
uint64 value = 0;
|
||||
int code = get_named_type(til, name, ntf_flags, &type, &fields, &cmt, &field_cmts, &sclass, (uint32 *) &value);
|
||||
if ( code == 0 )
|
||||
|
||||
@@ -23,4 +23,28 @@ class _wrap_cvar(object):
|
||||
|
||||
cvar = _wrap_cvar()
|
||||
|
||||
# for compatilibity:
|
||||
sc_auto = SC_AUTO
|
||||
sc_ext = SC_EXT
|
||||
sc_friend = SC_FRIEND
|
||||
sc_reg = SC_REG
|
||||
sc_stat = SC_STAT
|
||||
sc_type = SC_TYPE
|
||||
sc_unk = SC_UNK
|
||||
sc_virt = SC_VIRT
|
||||
|
||||
TERR_SAVE = TERR_SAVE_ERROR
|
||||
TERR_WRONGNAME = TERR_BAD_NAME
|
||||
TERR_BADSYNC = TERR_BAD_SYNC
|
||||
|
||||
BADORD = 0xFFFFFFFF
|
||||
|
||||
enum_member_vec_t = edmvec_t
|
||||
enum_member_t = edm_t
|
||||
udt_member_t = udm_t
|
||||
tinfo_t.find_udt_member = tinfo_t.find_udm
|
||||
|
||||
IMPTYPE_VERBOSE = 0x0001
|
||||
IMPTYPE_OVERRIDE = 0x0002
|
||||
|
||||
#</pycode(py_typeinf)>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -38,6 +38,7 @@
|
||||
%ignore bin_search; // we redefine our own, w/ 2 params swapped, so we can apply the typemaps below
|
||||
%rename (bin_search) py_bin_search;
|
||||
%rename (bin_search) bin_search2;
|
||||
%rename (op_stroff) py_op_stroff;
|
||||
%ignore bin_search2(ea_t, ea_t, const uchar *, const uchar *, size_t, int);
|
||||
%ignore bytes_match_for_bin_search;
|
||||
|
||||
|
||||
@@ -87,6 +87,11 @@
|
||||
%get_process_options_out_qstring(sdir);
|
||||
%get_process_options_out_qstring(host);
|
||||
%get_process_options_out_qstring(pass);
|
||||
%typemap(in, numinputs=0) launch_env_t *envs (launch_env_t temp)
|
||||
{
|
||||
// %typemap(in, numinputs=0) launch_env_t *envs (launch_envs_t temp)
|
||||
$1 = &temp;
|
||||
}
|
||||
%apply int *OUTPUT { int *port };
|
||||
|
||||
// specialize for 'get_process_options()'s first output
|
||||
|
||||
+1
-1
@@ -804,7 +804,7 @@ cexpr_t *citem_t_cexpr_get(citem_t *item) { return (cexpr_t *) item; }
|
||||
|
||||
|
||||
%extend ctree_item_t {
|
||||
CTREE_ITEM_MEMBER_REF(citem_t *, it);
|
||||
CTREE_CONDITIONAL_ITEM_MEMBER_REF(citem_t *, it, VDI_EXPR);
|
||||
CTREE_CONDITIONAL_ITEM_MEMBER_REF(cexpr_t*, e, VDI_EXPR);
|
||||
CTREE_CONDITIONAL_ITEM_MEMBER_REF(cinsn_t*, i, VDI_EXPR);
|
||||
CTREE_CONDITIONAL_ITEM_MEMBER_REF(lvar_t*, l, VDI_LVAR);
|
||||
|
||||
@@ -58,6 +58,7 @@ struct undo_records_t;
|
||||
%ignore processor_t::ensure_processor;
|
||||
%ignore processor_t::lvar_off;
|
||||
%ignore processor_t::is_lumina_usable;
|
||||
%ignore processor_t::get_regfinder();
|
||||
// The following are queried by the "scripting" processor module support
|
||||
%ignore processor_t::id;
|
||||
%ignore processor_t::flag;
|
||||
|
||||
@@ -68,6 +68,13 @@ struct dirspec_t;
|
||||
%ignore get_chooser_data;
|
||||
%rename (get_chooser_data) py_get_chooser_data;
|
||||
|
||||
%template(chooser_row_info_vec_t) qvector<chooser_row_info_t>;
|
||||
%typemap(out) qstrvec_t *
|
||||
{
|
||||
Py_XDECREF($result);
|
||||
$result = qstrvec2pylist(*$1);
|
||||
}
|
||||
|
||||
%rename (del_hotkey) py_del_hotkey;
|
||||
%rename (add_hotkey) py_add_hotkey;
|
||||
|
||||
@@ -427,11 +434,13 @@ SWIG_DECLARE_PY_CLINKED_OBJECT(textctrl_info_t)
|
||||
%newobject place_t::as_enumplace_t;
|
||||
%newobject place_t::as_structplace_t;
|
||||
%newobject place_t::as_simpleline_place_t;
|
||||
%newobject place_t::as_tiplace_t;
|
||||
%extend place_t {
|
||||
static idaplace_t *as_idaplace_t(place_t *p) { return p != nullptr ? (idaplace_t *) p->clone() : nullptr; }
|
||||
static enumplace_t *as_enumplace_t(place_t *p) { return p != nullptr ? (enumplace_t *) p->clone() : nullptr; }
|
||||
static structplace_t *as_structplace_t(place_t *p) { return p != nullptr ? (structplace_t *) p->clone() : nullptr; }
|
||||
static simpleline_place_t *as_simpleline_place_t(place_t *p) { return p != nullptr ? (simpleline_place_t *) p->clone() : nullptr; }
|
||||
static tiplace_t *as_tiplace_t(place_t *p) { return p != nullptr ? (tiplace_t *) p->clone() : nullptr; }
|
||||
|
||||
PyObject *py_generate(void *ud, int maxsize)
|
||||
{
|
||||
@@ -460,6 +469,8 @@ SWIG_DECLARE_PY_CLINKED_OBJECT(textctrl_info_t)
|
||||
return place_t.as_structplace_t(self.at)
|
||||
def place_as_simpleline_place_t(self):
|
||||
return place_t.as_simpleline_place_t(self.at)
|
||||
def place_as_tiplace_t(self):
|
||||
return place_t.as_tiplace_t(self.at)
|
||||
|
||||
def place(self, view):
|
||||
ptype = get_viewer_place_type(view)
|
||||
@@ -471,6 +482,8 @@ SWIG_DECLARE_PY_CLINKED_OBJECT(textctrl_info_t)
|
||||
return self.place_as_structplace_t()
|
||||
elif ptype == TCCPT_SIMPLELINE_PLACE:
|
||||
return self.place_as_simpleline_place_t()
|
||||
elif ptype == TCCPT_TIPLACE:
|
||||
return self.place_as_simpleline_place_t()
|
||||
else:
|
||||
return self.at
|
||||
}
|
||||
|
||||
+1
-1
@@ -178,7 +178,7 @@
|
||||
resultobj = qstrvec2pylist(*($1));
|
||||
}
|
||||
|
||||
%numbers_list_to_values_vec(ea64vec_t, SWIGTYPE_p_qvectorT_unsigned_long_long_t, PyW_PyListToEa64Vec);
|
||||
%numbers_list_to_values_vec(ea64vec_t, SWIGTYPE_p_qvectorT_unsigned_long_long_t, PyW_PySeqToEa64Vec);
|
||||
|
||||
%include "lumina.hpp"
|
||||
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ typedef int diff_source_idx_t;
|
||||
{ // %typemap(directorargout) qstrvec_t *
|
||||
if ( $result != Py_None )
|
||||
{
|
||||
if ( PyW_PyListToStrVec(&tmp, $result) >= 0 )
|
||||
if ( PyW_PySeqToStrVec(&tmp, $result) >= 0 )
|
||||
{
|
||||
$1->insert($1->end(), tmp.begin(), tmp.end());
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
%ignore qhandle_t;
|
||||
%ignore qstrlen;
|
||||
%ignore qstrcmp;
|
||||
%ignore qstrncmp;
|
||||
%ignore qstrstr;
|
||||
%ignore qstrchr;
|
||||
%ignore qstrrchr;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
%ignore rangeset_t::upper_bound;
|
||||
%ignore rangeset_t::move_chunk;
|
||||
%ignore rangeset_t::check_move_args;
|
||||
%ignore range64_t;
|
||||
%ignore range64vec_t;
|
||||
|
||||
%template(rangevec_base_t) qvector<range_t>;
|
||||
%template(array_of_rangesets) qvector<rangeset_t>;
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
%{
|
||||
#include <regfinder.hpp>
|
||||
%}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ignore not published structs
|
||||
%ignore reg_finder_op_t;
|
||||
%ignore reg_finder_t;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
%immutable reg_value_def_t::SHORT_INSN;
|
||||
%immutable reg_value_def_t::PC_BASED;
|
||||
%immutable reg_value_def_t::LIKE_GOT;
|
||||
%ignore reg_value_def_t::val_eq;
|
||||
%ignore reg_value_def_t::val_less;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// dstr() as str()
|
||||
%ignore reg_value_info_t::dstr;
|
||||
%extend reg_value_info_t
|
||||
{
|
||||
inline qstring __str__() const { return $self->dstr(); }
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// ignore helpers
|
||||
%ignore reg_finder_invalidate_cache(reg_finder_t *_this, ea_t ea);
|
||||
%ignore reg_finder_find(reg_finder_t *_this, reg_value_info_t *out, ea_t ea, ea_t ds, reg_finder_op_t op, int max_depth);
|
||||
%ignore reg_finder_calc_op_addr(reg_finder_t *_this, reg_value_info_t *addr, const op_t *memop, const insn_t *insn, ea_t ea, ea_t ds);
|
||||
%ignore reg_finder_emulate_mem_read(reg_finder_t *_this, reg_value_info_t *value, const reg_value_info_t *addr, int width, bool is_signed, const insn_t *insn);
|
||||
%ignore reg_finder_emulate_binary_op(reg_finder_t *_this, reg_value_info_t *value, int aop, const op_t *op1, const op_t *op2, const insn_t *insn, ea_t ea, ea_t ds, reg_finder_binary_ops_adjust_fun adjust, void *ud);
|
||||
%ignore reg_finder_emulate_unary_op(reg_finder_t *_this, reg_value_info_t *value, int aop, int reg, const insn_t *insn, ea_t ea, ea_t ds);
|
||||
%ignore reg_finder_may_modify_stkvars(const reg_finder_t *_this, reg_finder_op_t op, const insn_t *insn);
|
||||
%ignore reg_finder_ctr(reg_finder_t *_this);
|
||||
%ignore reg_finder_dtr(reg_finder_t *_this);
|
||||
%ignore reg_value_def_dstr(const reg_value_def_t *_this, qstring *vout, int how, const procmod_t *pm);
|
||||
%ignore reg_value_info_dstr(const reg_value_info_t *_this, qstring *vout, const procmod_t *pm);
|
||||
%ignore reg_value_info_vals_union(reg_value_info_t *_this, const reg_value_info_t *r);
|
||||
%ignore reg_finder_op_make_rfop(func_t *pfn, const insn_t *insn, const op_t *op);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// add access to reg_value_info_t::vals
|
||||
%ignore reg_value_info_t::vals_begin;
|
||||
%ignore reg_value_info_t::vals_end;
|
||||
%ignore reg_value_info_t::vals_size;
|
||||
%extend reg_value_info_t
|
||||
{
|
||||
inline size_t __len__() const { return $self->vals_size(); }
|
||||
inline const reg_value_def_t &__getitem__(size_t i) const
|
||||
{
|
||||
if ( i >= $self->vals_size() )
|
||||
throw std::out_of_range("out of bounds access");
|
||||
return $self->vals_begin()[i];
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// For 'find_reg_value()'
|
||||
%define %val_t_result_as_output(TYPE, CONVFUNC, NAME)
|
||||
%typemap(in,numinputs=0) TYPE *NAME (TYPE temp = 0)
|
||||
{
|
||||
// %val_t_result_as_output(TYPE, CONVFUNC, NAME) %typemap(in,numinputs=0)
|
||||
$1 = &temp;
|
||||
}
|
||||
%typemap(argout) TYPE *NAME
|
||||
{
|
||||
// %val_t_result_as_output(TYPE, CONVFUNC, NAME) %typemap(argout)
|
||||
Py_XDECREF(resultobj);
|
||||
if ( result == 1 )
|
||||
{
|
||||
resultobj = CONVFUNC(*(TYPE *) $1);
|
||||
}
|
||||
else if ( result == 0 )
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
resultobj = Py_None;
|
||||
}
|
||||
else
|
||||
{
|
||||
SWIG_exception_fail(SWIG_RuntimeError, "The processor module does not support a register tracker");
|
||||
}
|
||||
}
|
||||
%enddef
|
||||
%val_t_result_as_output(uint32, PyLong_FromUnsignedLong, uval);
|
||||
%val_t_result_as_output(uint64, PyLong_FromUnsignedLongLong, uval);
|
||||
%val_t_result_as_output(int32, PyLong_FromLong, sval);
|
||||
%val_t_result_as_output(int64, PyLong_FromLongLong, sval);
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// For 'find_nearest_rvi()'
|
||||
%typemap(in) int reg[2] (int temp[2])
|
||||
{
|
||||
// %typemap(in) int reg[2] (int temp[2])
|
||||
if ( !PyTuple_Check($input)
|
||||
|| PyTuple_Size($input) != 2
|
||||
|| !PyLong_Check(PyTuple_GetItem($input, 0))
|
||||
|| !PyLong_Check(PyTuple_GetItem($input, 1)) )
|
||||
{
|
||||
SWIG_exception_fail(
|
||||
SWIG_TypeError,
|
||||
"in method '" "$symname" "', argument " "$argnum"" of type (long, long)");
|
||||
}
|
||||
|
||||
temp[0] = PyLong_AsLong(PyTuple_GetItem($input, 0));
|
||||
temp[1] = PyLong_AsLong(PyTuple_GetItem($input, 1));
|
||||
$1 = temp;
|
||||
}
|
||||
|
||||
%include "regfinder.hpp"
|
||||
+40
-8
@@ -3,6 +3,8 @@
|
||||
#include <struct.hpp>
|
||||
%}
|
||||
|
||||
%constant bmask64_t DEFMASK64 = bmask64_t(-1);
|
||||
|
||||
// Most of these could be wrapped if needed
|
||||
%ignore get_cc;
|
||||
%ignore get_effective_cc;
|
||||
@@ -48,6 +50,8 @@
|
||||
%ignore get_numbered_type(const til_t *, uint32, const type_t **, const p_list **, const char **, const p_list **, sclass_t *);
|
||||
%rename (get_numbered_type) py_get_numbered_type;
|
||||
|
||||
%ignore NTF_NOSYNC;
|
||||
|
||||
%ignore skipName;
|
||||
%ignore extract_comment;
|
||||
%ignore skipComment;
|
||||
@@ -112,7 +116,6 @@
|
||||
%ignore is_stkarg_load_t;
|
||||
%ignore has_delay_slot_t;
|
||||
%ignore gen_use_arg_types;
|
||||
%ignore enable_numbered_types;
|
||||
%ignore compact_numbered_types;
|
||||
|
||||
%ignore callregs_t::findreg;
|
||||
@@ -129,15 +132,34 @@
|
||||
%ignore bitfield_type_data_t::serialize;
|
||||
%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 tinfo_t::deserialize(const til_t *, const qtype *, const qtype *, const qtype *);
|
||||
%ignore tinfo_t::serialize(qtype *, qtype *, qtype *, int) const;
|
||||
%ignore tinfo_t::deserialize(const til_t *, const qtype *, const qtype *, const qtype *, const char *);
|
||||
%ignore tinfo_get_innermost_udm;
|
||||
%ignore save_tinfo2;
|
||||
// Let's declare our own version of `deserialize_tinfo2` before
|
||||
// SWiG hits the one that's in `typeinf.hpp` (and cannot, alas,
|
||||
// enjoy the addition of the default value.)
|
||||
%rename (deserialize_tinfo) deserialize_tinfo2;
|
||||
%inline %{
|
||||
idaman bool ida_export deserialize_tinfo2(tinfo_t *tif, const til_t *til, const type_t **ptype, const p_list **pfields, const p_list **pfldcmts, const char *cmt=nullptr);
|
||||
%}
|
||||
%ignore deserialize_tinfo;
|
||||
%ignore deserialize_tinfo2;
|
||||
%ignore get_udm_by_tid(tinfo_t *tif, udm_t *udm, tid_t tid);
|
||||
%ignore get_edm_by_tid(tinfo_t *tif, edm_t *edm, tid_t tid);
|
||||
%ignore get_type_by_tid(tinfo_t *tif, tid_t tid);
|
||||
%ignore get_tinfo_by_edm_name(tinfo_t *tif, til_t *til, const char *mname);
|
||||
%ignore value_repr_t__parse_value_repr;
|
||||
%ignore enum_type_data_t__set_value_repr;
|
||||
|
||||
%ignore custloc_desc_t;
|
||||
%ignore install_custom_argloc;
|
||||
%ignore remove_custom_argloc;
|
||||
%ignore retrieve_custom_argloc;
|
||||
%ignore enum_type_visitor_t;
|
||||
%ignore visit_edms;
|
||||
|
||||
%make_argout_errbuf_raise_when_null_result();
|
||||
|
||||
@@ -192,6 +214,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
%apply size_t *OUTPUT {size_t *out_index};
|
||||
%apply uint64 *OUTPUT {uint64 *out_bitoffset};
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
%define %tinfo_t_or_simple_tinfo_t_container_lifecycle(Type)
|
||||
// Instead of re-defining all constructors, add the registering
|
||||
@@ -219,23 +244,30 @@
|
||||
// as it would call til_register_python_tinfo_t_instance() a second time
|
||||
// after '%typemap(out) tinfo_t *' already did it.
|
||||
%extend tinfo_t {
|
||||
~tinfo_t(void)
|
||||
~tinfo_t()
|
||||
{
|
||||
til_deregister_python_tinfo_t_instance($self);
|
||||
delete $self;
|
||||
}
|
||||
}
|
||||
|
||||
%ignore tinfo_t::~tinfo_t(void);
|
||||
%ignore tinfo_t::~tinfo_t();
|
||||
|
||||
%template(funcargvec_t) qvector<funcarg_t>;
|
||||
%template(reginfovec_t) qvector<reg_info_t>;
|
||||
%template(enum_member_vec_t) qvector<enum_member_t>;
|
||||
%template(edmvec_t) qvector<edm_t>;
|
||||
%template(argpartvec_t) qvector<argpart_t>;
|
||||
%uncomparable_elements_qvector(valstr_t, valstrvec_t);
|
||||
%uncomparable_elements_qvector(regobj_t, regobjvec_t);
|
||||
%uncomparable_elements_qvector(type_attr_t, type_attrs_t);
|
||||
%template(udtmembervec_template_t) qvector<udt_member_t>;
|
||||
|
||||
%extend value_repr_t
|
||||
{
|
||||
inline qstring __str__() const { qstring tmp; $self->print(&tmp); return tmp; }
|
||||
}
|
||||
%template(udtmembervec_template_t) qvector<udm_t>;
|
||||
%ignore udt_type_data_t::VERSION;
|
||||
%ignore udt_type_data_old_t;
|
||||
|
||||
%extend tinfo_t {
|
||||
PyObject *get_attr(const qstring &key, bool all_attrs=true)
|
||||
@@ -264,7 +296,7 @@
|
||||
%typemap(in) const sclass_t * {
|
||||
// %typemap(in) const sclass_t *
|
||||
if ( $input == Py_None )
|
||||
$1 = new sclass_t(sc_unk);
|
||||
$1 = new sclass_t(SC_UNK);
|
||||
else if ( PyLong_Check($input) )
|
||||
$1 = new sclass_t(sclass_t(PyLong_AsLong($input)));
|
||||
else
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
|
||||
#include <pro.h>
|
||||
#include <expr.hpp>
|
||||
|
||||
#include "extapi.hpp"
|
||||
#include "extapi.cpp"
|
||||
#include "pywraps.hpp"
|
||||
#include "pywraps.cpp"
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
idapython_plugin_t *ida_export get_plugin_instance() { return nullptr; }
|
||||
void ida_export set_interruptible_state(bool) {}
|
||||
ssize_t ida_export invoke_callbacks(hook_type_t, int, va_list) { return 0; }
|
||||
bool ida_export hook_to_notification_point(hook_type_t, hook_cb_t *, void *) { return false; }
|
||||
int ida_export unhook_from_notification_point(hook_type_t, hook_cb_t *, void *) { return false; }
|
||||
void ida_export cleanup_argloc(argloc_t *) { INTERR(30755); }
|
||||
void ida_export clear_tinfo_t(tinfo_t *) { INTERR(30756); }
|
||||
fpvalue_error_t ida_export ieee_realcvt(void *, fpvalue_t *, uint16) { return REAL_ERROR_FORMAT; }
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static qvector<void*> prevent_warnings()
|
||||
{
|
||||
qvector<void *> buf;
|
||||
buf.push_back((void *) &clear_python_timer_instances);
|
||||
buf.push_back((void *) &til_clear_python_tinfo_t_instances);
|
||||
buf.push_back((void *) &deinit_pywraps);
|
||||
buf.push_back((void *) &init_pywraps);
|
||||
buf.push_back((void *) &pywraps_check_autoscripts);
|
||||
buf.push_back((void *) &free_compiled_form_instances);
|
||||
return buf;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
idcfuncs_t idc_func_table = { 0 };
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static const char *inifile = "test_pywraps.ini";
|
||||
static size_t lnnum = 0;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
AS_PRINTF(1, 2) NORETURN static void fatal(const char *format, ...)
|
||||
{
|
||||
if ( lnnum != 0 )
|
||||
qeprintf("%s:%" FMT_Z ": ", inifile, lnnum);
|
||||
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
qstring buf;
|
||||
buf.vsprnt(format, va);
|
||||
qeprintf("%s\n", buf.c_str());
|
||||
va_end(va);
|
||||
qexit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static bool read_test_case(qstring *out, FILE *fp)
|
||||
{
|
||||
out->qclear();
|
||||
char buf[MAXSTR];
|
||||
bool printed_header = false;
|
||||
while ( qfgets(buf, sizeof(buf), fp) )
|
||||
{
|
||||
++lnnum;
|
||||
// msg("%s", buf);
|
||||
if ( buf[0] == '\0' )
|
||||
continue;
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
char *ptr = skip_spaces(buf);
|
||||
if ( *ptr == '\0' || *ptr == ';' )
|
||||
continue;
|
||||
if ( !printed_header )
|
||||
{
|
||||
msg("--- TEST: %s\n", buf);
|
||||
printed_header = true;
|
||||
}
|
||||
*out = buf;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static void run_test_case(
|
||||
qstrvec_t *out,
|
||||
const qstring &expr,
|
||||
PyObject *globals)
|
||||
{
|
||||
qstrvec_t argv;
|
||||
expr.split(&argv, " ");
|
||||
|
||||
QASSERT(30757, argv.size() == 2);
|
||||
newref_t py_arg1(extapi.PyRun_StringFlags_ptr(
|
||||
argv[1].c_str(),
|
||||
Py_eval_input,
|
||||
globals,
|
||||
globals,
|
||||
nullptr));
|
||||
QASSERT(30758, py_arg1 != nullptr);
|
||||
if ( argv[0] == "READ_NUM" )
|
||||
{
|
||||
{
|
||||
qstring &buf = out->push_back();
|
||||
buf = "PyW_GetNumber : ";
|
||||
uint64 num = 0;
|
||||
bool is_64 = false;
|
||||
if ( PyW_GetNumber(py_arg1.o, &num, &is_64) )
|
||||
{
|
||||
buf.cat_sprnt("is_64: %s, unsigned: %llu; signed: %lld; hex: 0x%llx",
|
||||
is_64 ? "true" : "false", uint64(num), int64(num), uint64(num));
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append("Could not convert to a number");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
qstring &buf = out->push_back();
|
||||
buf = "PyW_GetNumberAsIDC: ";
|
||||
idc_value_t idcv;
|
||||
if ( PyW_GetNumberAsIDC(py_arg1.o, &idcv) )
|
||||
{
|
||||
switch ( idcv.vtype )
|
||||
{
|
||||
case VT_LONG:
|
||||
#ifdef __EA64__
|
||||
buf.cat_sprnt("(64-bit sval_t) unsigned: %llu; signed: %lld; hex: 0x%llx",
|
||||
uval_t(idcv.num), idcv.num, uval_t(idcv.num));
|
||||
#else
|
||||
buf.cat_sprnt("(32-bit sval_t) unsigned: %u; signed: %d; hex: 0x%x",
|
||||
uval_t(idcv.num), idcv.num, idcv.num);
|
||||
#endif
|
||||
break;
|
||||
case VT_INT64:
|
||||
buf.cat_sprnt("(int64) unsigned: %llu; signed: %lld; hex: 0x%llx",
|
||||
uint64(idcv.i64), idcv.i64, uint64(idcv.i64));
|
||||
break;
|
||||
default:
|
||||
INTERR(30759);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buf.append("Could not convert to an IDC value");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INTERR(30760);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if ( argc > 1 )
|
||||
inifile = argv[1];
|
||||
|
||||
prevent_warnings();
|
||||
|
||||
FILE *fp = qfopen(inifile, "rt");
|
||||
if ( fp == nullptr )
|
||||
fatal("%s: %s", inifile, qerrstr(-1));
|
||||
|
||||
Py_InitializeEx(0 /* Don't catch SIGPIPE, SIGXFZ, SIGXFSZ & SIGINT signals */);
|
||||
qstring errbuf;
|
||||
QASSERT(30761, extapi.load(&errbuf));
|
||||
|
||||
PyObject *module = PyImport_AddModule("__main__");
|
||||
PyObject *globals = PyModule_GetDict(module);
|
||||
|
||||
qstring req;
|
||||
while ( read_test_case(&req, fp) )
|
||||
{
|
||||
qstrvec_t resp;
|
||||
run_test_case(&resp, req, globals);
|
||||
for ( const auto &r : resp )
|
||||
msg(" => %s\n", r.c_str());
|
||||
}
|
||||
|
||||
Py_Finalize();
|
||||
|
||||
qfclose(fp);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
READ_NUM 12
|
||||
READ_NUM 0xFFFF
|
||||
READ_NUM 0xFFFFFFFF
|
||||
READ_NUM 0x00000FFFFFFF
|
||||
READ_NUM 0x0000FFFFFFFF
|
||||
READ_NUM 0x0000FFFFFFFFFFFF
|
||||
READ_NUM 0x0000FFFFFFFFFFFF1234
|
||||
READ_NUM 0x00000000FFFFFFFF
|
||||
READ_NUM 0x00000000FFFFFFFF1234
|
||||
READ_NUM 0xFFFFFFFFFFFF0000
|
||||
READ_NUM 0x1234FFFFFFFFFFFF0000
|
||||
READ_NUM 0xFFFFFFFF00000000
|
||||
READ_NUM 0x1234FFFFFFFF00000000
|
||||
READ_NUM 0xFFFFFFFF0000
|
||||
READ_NUM 0x1234FFFFFFFF0000
|
||||
READ_NUM 0xFFFFFFFF00001234
|
||||
READ_NUM -0xFFFF
|
||||
READ_NUM -0xFFFFFFFF
|
||||
READ_NUM -0x00000FFFFFFF
|
||||
READ_NUM -0x0000FFFFFFFF
|
||||
READ_NUM -0x0000FFFFFFFFFFFF
|
||||
READ_NUM -0x0000FFFFFFFFFFFF1234
|
||||
READ_NUM -0x00000000FFFFFFFF
|
||||
READ_NUM -0x00000000FFFFFFFF1234
|
||||
READ_NUM -0xFFFFFFFFFFFF0000
|
||||
READ_NUM -0x1234FFFFFFFFFFFF0000
|
||||
READ_NUM -0xFFFFFFFF00000000
|
||||
READ_NUM -0x1234FFFFFFFF00000000
|
||||
READ_NUM -0x1234FFFFFFFF0000
|
||||
READ_NUM -0xFFFFFFFF0000
|
||||
READ_NUM -0xFFFFFFFF00001234
|
||||
READ_NUM "Hello"
|
||||
READ_NUM "None"
|
||||
READ_NUM True
|
||||
@@ -0,0 +1,102 @@
|
||||
--- TEST: READ_NUM 12
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 12; signed: 12; hex: 0xc
|
||||
=> PyW_GetNumberAsIDC: (32-bit sval_t) unsigned: 12; signed: 12; hex: 0xc
|
||||
--- TEST: READ_NUM 0xFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 65535; signed: 65535; hex: 0xffff
|
||||
=> PyW_GetNumberAsIDC: (32-bit sval_t) unsigned: 65535; signed: 65535; hex: 0xffff
|
||||
--- TEST: READ_NUM 0xFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
--- TEST: READ_NUM 0x00000FFFFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 268435455; signed: 268435455; hex: 0xfffffff
|
||||
=> PyW_GetNumberAsIDC: (32-bit sval_t) unsigned: 268435455; signed: 268435455; hex: 0xfffffff
|
||||
--- TEST: READ_NUM 0x0000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
--- TEST: READ_NUM 0x0000FFFFFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 281474976710655; signed: 281474976710655; hex: 0xffffffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 281474976710655; signed: 281474976710655; hex: 0xffffffffffff
|
||||
--- TEST: READ_NUM 0x0000FFFFFFFFFFFF1234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744073709490740; signed: -60876; hex: 0xffffffffffff1234
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744073709490740; signed: -60876; hex: 0xffffffffffff1234
|
||||
--- TEST: READ_NUM 0x00000000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
--- TEST: READ_NUM 0x00000000FFFFFFFF1234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 281474976649780; signed: 281474976649780; hex: 0xffffffff1234
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 281474976649780; signed: 281474976649780; hex: 0xffffffff1234
|
||||
--- TEST: READ_NUM 0xFFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744073709486080; signed: -65536; hex: 0xffffffffffff0000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744073709486080; signed: -65536; hex: 0xffffffffffff0000
|
||||
--- TEST: READ_NUM 0x1234FFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM 0xFFFFFFFF00000000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584320; signed: -4294967296; hex: 0xffffffff00000000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584320; signed: -4294967296; hex: 0xffffffff00000000
|
||||
--- TEST: READ_NUM 0x1234FFFFFFFF00000000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM 0xFFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 281474976645120; signed: 281474976645120; hex: 0xffffffff0000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 281474976645120; signed: 281474976645120; hex: 0xffffffff0000
|
||||
--- TEST: READ_NUM 0x1234FFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 1311954866448302080; signed: 1311954866448302080; hex: 0x1234ffffffff0000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 1311954866448302080; signed: 1311954866448302080; hex: 0x1234ffffffff0000
|
||||
--- TEST: READ_NUM 0xFFFFFFFF00001234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414588980; signed: -4294962636; hex: 0xffffffff00001234
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414588980; signed: -4294962636; hex: 0xffffffff00001234
|
||||
--- TEST: READ_NUM -0xFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 18446744073709486081; signed: -65535; hex: 0xffffffffffff0001
|
||||
=> PyW_GetNumberAsIDC: (32-bit sval_t) unsigned: 4294901761; signed: -65535; hex: 0xffff0001
|
||||
--- TEST: READ_NUM -0xFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
--- TEST: READ_NUM -0x00000FFFFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 18446744073441116161; signed: -268435455; hex: 0xfffffffff0000001
|
||||
=> PyW_GetNumberAsIDC: (32-bit sval_t) unsigned: 4026531841; signed: -268435455; hex: 0xf0000001
|
||||
--- TEST: READ_NUM -0x0000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
--- TEST: READ_NUM -0x0000FFFFFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446462598732840961; signed: -281474976710655; hex: 0xffff000000000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446462598732840961; signed: -281474976710655; hex: 0xffff000000000001
|
||||
--- TEST: READ_NUM -0x0000FFFFFFFFFFFF1234
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x00000000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
--- TEST: READ_NUM -0x00000000FFFFFFFF1234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446462598732901836; signed: -281474976649780; hex: 0xffff00000000edcc
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446462598732901836; signed: -281474976649780; hex: 0xffff00000000edcc
|
||||
--- TEST: READ_NUM -0xFFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x1234FFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0xFFFFFFFF00000000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x1234FFFFFFFF00000000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x1234FFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 17134789207261249536; signed: -1311954866448302080; hex: 0xedcb000000010000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 17134789207261249536; signed: -1311954866448302080; hex: 0xedcb000000010000
|
||||
--- TEST: READ_NUM -0xFFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446462598732906496; signed: -281474976645120; hex: 0xffff000000010000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446462598732906496; signed: -281474976645120; hex: 0xffff000000010000
|
||||
--- TEST: READ_NUM -0xFFFFFFFF00001234
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM "Hello"
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM "None"
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM True
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
@@ -0,0 +1,102 @@
|
||||
--- TEST: READ_NUM 12
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 12; signed: 12; hex: 0xc
|
||||
=> PyW_GetNumberAsIDC: (64-bit sval_t) unsigned: 12; signed: 12; hex: 0xc
|
||||
--- TEST: READ_NUM 0xFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 65535; signed: 65535; hex: 0xffff
|
||||
=> PyW_GetNumberAsIDC: (64-bit sval_t) unsigned: 65535; signed: 65535; hex: 0xffff
|
||||
--- TEST: READ_NUM 0xFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
--- TEST: READ_NUM 0x00000FFFFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 268435455; signed: 268435455; hex: 0xfffffff
|
||||
=> PyW_GetNumberAsIDC: (64-bit sval_t) unsigned: 268435455; signed: 268435455; hex: 0xfffffff
|
||||
--- TEST: READ_NUM 0x0000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
--- TEST: READ_NUM 0x0000FFFFFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 281474976710655; signed: 281474976710655; hex: 0xffffffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 281474976710655; signed: 281474976710655; hex: 0xffffffffffff
|
||||
--- TEST: READ_NUM 0x0000FFFFFFFFFFFF1234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744073709490740; signed: -60876; hex: 0xffffffffffff1234
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744073709490740; signed: -60876; hex: 0xffffffffffff1234
|
||||
--- TEST: READ_NUM 0x00000000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 4294967295; signed: 4294967295; hex: 0xffffffff
|
||||
--- TEST: READ_NUM 0x00000000FFFFFFFF1234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 281474976649780; signed: 281474976649780; hex: 0xffffffff1234
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 281474976649780; signed: 281474976649780; hex: 0xffffffff1234
|
||||
--- TEST: READ_NUM 0xFFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744073709486080; signed: -65536; hex: 0xffffffffffff0000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744073709486080; signed: -65536; hex: 0xffffffffffff0000
|
||||
--- TEST: READ_NUM 0x1234FFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM 0xFFFFFFFF00000000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584320; signed: -4294967296; hex: 0xffffffff00000000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584320; signed: -4294967296; hex: 0xffffffff00000000
|
||||
--- TEST: READ_NUM 0x1234FFFFFFFF00000000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM 0xFFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 281474976645120; signed: 281474976645120; hex: 0xffffffff0000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 281474976645120; signed: 281474976645120; hex: 0xffffffff0000
|
||||
--- TEST: READ_NUM 0x1234FFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 1311954866448302080; signed: 1311954866448302080; hex: 0x1234ffffffff0000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 1311954866448302080; signed: 1311954866448302080; hex: 0x1234ffffffff0000
|
||||
--- TEST: READ_NUM 0xFFFFFFFF00001234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414588980; signed: -4294962636; hex: 0xffffffff00001234
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414588980; signed: -4294962636; hex: 0xffffffff00001234
|
||||
--- TEST: READ_NUM -0xFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 18446744073709486081; signed: -65535; hex: 0xffffffffffff0001
|
||||
=> PyW_GetNumberAsIDC: (64-bit sval_t) unsigned: 18446744073709486081; signed: -65535; hex: 0xffffffffffff0001
|
||||
--- TEST: READ_NUM -0xFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
--- TEST: READ_NUM -0x00000FFFFFFF
|
||||
=> PyW_GetNumber : is_64: false, unsigned: 18446744073441116161; signed: -268435455; hex: 0xfffffffff0000001
|
||||
=> PyW_GetNumberAsIDC: (64-bit sval_t) unsigned: 18446744073441116161; signed: -268435455; hex: 0xfffffffff0000001
|
||||
--- TEST: READ_NUM -0x0000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
--- TEST: READ_NUM -0x0000FFFFFFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446462598732840961; signed: -281474976710655; hex: 0xffff000000000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446462598732840961; signed: -281474976710655; hex: 0xffff000000000001
|
||||
--- TEST: READ_NUM -0x0000FFFFFFFFFFFF1234
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x00000000FFFFFFFF
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446744069414584321; signed: -4294967295; hex: 0xffffffff00000001
|
||||
--- TEST: READ_NUM -0x00000000FFFFFFFF1234
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446462598732901836; signed: -281474976649780; hex: 0xffff00000000edcc
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446462598732901836; signed: -281474976649780; hex: 0xffff00000000edcc
|
||||
--- TEST: READ_NUM -0xFFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x1234FFFFFFFFFFFF0000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0xFFFFFFFF00000000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x1234FFFFFFFF00000000
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM -0x1234FFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 17134789207261249536; signed: -1311954866448302080; hex: 0xedcb000000010000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 17134789207261249536; signed: -1311954866448302080; hex: 0xedcb000000010000
|
||||
--- TEST: READ_NUM -0xFFFFFFFF0000
|
||||
=> PyW_GetNumber : is_64: true, unsigned: 18446462598732906496; signed: -281474976645120; hex: 0xffff000000010000
|
||||
=> PyW_GetNumberAsIDC: (int64) unsigned: 18446462598732906496; signed: -281474976645120; hex: 0xffff000000010000
|
||||
--- TEST: READ_NUM -0xFFFFFFFF00001234
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM "Hello"
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM "None"
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
--- TEST: READ_NUM True
|
||||
=> PyW_GetNumber : Could not convert to a number
|
||||
=> PyW_GetNumberAsIDC: Could not convert to an IDC value
|
||||
+1
-1
@@ -67,7 +67,7 @@ else:
|
||||
|
||||
# creates a regular expression
|
||||
def make_re(tag, module, prefix):
|
||||
s = '%(p)s<%(tag)s\(%(m)s\)>(.+?)%(p)s</%(tag)s\(%(m)s\)>' % {'m': module, 'tag': tag, 'p': prefix}
|
||||
s = r'%(p)s<%(tag)s\(%(m)s\)>(.+?)%(p)s</%(tag)s\(%(m)s\)>' % {'m': module, 'tag': tag, 'p': prefix}
|
||||
return (s, re.compile(s, re.DOTALL))
|
||||
|
||||
|
||||
|
||||
+91
-61
@@ -39,6 +39,7 @@ extern plugin_t PLUGIN;
|
||||
%feature("nodirector") generic_linput_t;
|
||||
%feature("nodirector") place_t;
|
||||
%feature("nodirector") idaplace_t;
|
||||
%feature("nodirector") tiplace_t;
|
||||
%feature("nodirector") qrefcnt_obj_t;
|
||||
%feature("nodirector") qstring_printer_t;
|
||||
%feature("nodirector") simpleline_place_t;
|
||||
@@ -438,61 +439,44 @@ static PyObject *type##_get_clink_ptr(PyObject *self)
|
||||
%enddef
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Convert an incoming Python list to a tid_t[] array
|
||||
%typemap(in) tid_t[ANY](tid_t temp[$1_dim0]) {
|
||||
int i, len;
|
||||
%typemap(in) tid_t[ANY] (qvector<tid_t> temp)
|
||||
{
|
||||
// %typemap(in) tid_t[ANY] (qvector<tid_t> temp)
|
||||
Py_ssize_t len = PyW_PySeqToTidVec(&temp, $input, $1_dim0);
|
||||
if ( len == CIP_FAILED )
|
||||
return nullptr;
|
||||
|
||||
if (!PySequence_Check($input))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Cap the number of elements to copy */
|
||||
len = PySequence_Length($input) < $1_dim0 ? PySequence_Length($input) : $1_dim0;
|
||||
|
||||
for (i =0; i < len; i++)
|
||||
{
|
||||
newref_t item(PySequence_GetItem($input,i));
|
||||
if (!PyLong_Check(item.o))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of long integers");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
temp[i] = PyLong_AsUnsignedLong(item.o);
|
||||
}
|
||||
$1 = &temp[0];
|
||||
temp.resize($1_dim0, 0); // make sure we have enough memory allocated
|
||||
$1 = temp.begin();
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Same, but with non-fixed sized arrays.
|
||||
%typemap(in) (const tid_t *path, int plen) (qvector<tid_t> temp) {
|
||||
if (!PySequence_Check($input))
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
|
||||
return nullptr;
|
||||
}
|
||||
int plen = PySequence_Length($input);
|
||||
if ( plen <= 0 )
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "Sequence must have at least 1 item");
|
||||
return nullptr;
|
||||
}
|
||||
temp.resize(plen);
|
||||
for ( int i =0; i < plen; ++i )
|
||||
{
|
||||
newref_t item(PySequence_GetItem($input,i));
|
||||
if (!PyLong_Check(item.o))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,"Expecting a sequence of long integers");
|
||||
return nullptr;
|
||||
}
|
||||
%typemap(in) (const tid_t *path, int plen) (qvector<tid_t> temp)
|
||||
{
|
||||
// %typemap(in) (const tid_t *path, int plen/path_len) (qvector<tid_t> temp),
|
||||
Py_ssize_t len = PyW_PySeqToTidVec(&temp, $input);
|
||||
if ( len == CIP_FAILED )
|
||||
return nullptr;
|
||||
|
||||
temp[i] = PyLong_AsUnsignedLong(item.o);
|
||||
}
|
||||
$1 = temp.begin();
|
||||
$2 = int(temp.size());
|
||||
$1 = temp.begin();
|
||||
$2 = int(temp.size());
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) const qvector<tid_t> &path
|
||||
{
|
||||
// %typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) const qvector<tid_t> &path
|
||||
$1 = PyW_IsSequenceType($input);
|
||||
}
|
||||
|
||||
%typemap(in) (const qvector<tid_t> &path) (qvector<tid_t> temp)
|
||||
{
|
||||
// %typemap(in) (const qvector<tid_t> &path)
|
||||
Py_ssize_t len = PyW_PySeqToTidVec(&temp, $input);
|
||||
if ( len == CIP_FAILED )
|
||||
return nullptr;
|
||||
|
||||
$1 = &temp;
|
||||
}
|
||||
|
||||
%{
|
||||
@@ -1031,7 +1015,7 @@ SWIGINTERN PyObject *_maybe_byte_array_or_none_result(
|
||||
//-------------------------------------------------------------------------
|
||||
%fragment("cvt_const_insn_t_ref", "header")
|
||||
{
|
||||
bool convert_const_insn_t_ref(insn_t *out, PyObject *in)
|
||||
bool convert_const_insn_t_ref(insn_t *out, PyObject *in, swig_type_info *ty)
|
||||
{
|
||||
uint64 ea;
|
||||
bool ok = PyW_GetNumber(in, &ea);
|
||||
@@ -1039,14 +1023,14 @@ SWIGINTERN PyObject *_maybe_byte_array_or_none_result(
|
||||
{
|
||||
insn_t tmp;
|
||||
ok = decode_insn(&tmp, ea_t(ea)) > 0;
|
||||
if ( ok )
|
||||
if ( ok && out != nullptr )
|
||||
*out = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
insn_t *p_insn = nullptr;
|
||||
ok = SWIG_ConvertPtr(in, (void **) &p_insn, SWIGTYPE_p_insn_t, 0) >= 0 && p_insn != nullptr;
|
||||
if ( ok )
|
||||
ok = SWIG_ConvertPtr(in, (void **) &p_insn, ty, 0) >= 0 && p_insn != nullptr;
|
||||
if ( ok && out != nullptr )
|
||||
*out = *p_insn;
|
||||
}
|
||||
return ok;
|
||||
@@ -1057,10 +1041,14 @@ SWIGINTERN PyObject *_maybe_byte_array_or_none_result(
|
||||
%typemap(in, fragment="cvt_const_insn_t_ref") (const insn_t &) (insn_t lins)
|
||||
{
|
||||
// %typemap(in) (const insn_t &)
|
||||
if ( !convert_const_insn_t_ref(&lins, $input) )
|
||||
if ( !convert_const_insn_t_ref(&lins, $input, $1_descriptor) )
|
||||
SWIG_exception_fail(SWIG_ValueError, "Expected either an address, or a non-null ida_ua.insn_t instance");
|
||||
$1 = &lins;
|
||||
}
|
||||
%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, fragment="cvt_const_insn_t_ref") const insn_t &
|
||||
{ // %typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER) const insn_t &
|
||||
$1 = convert_const_insn_t_ref(nullptr, $input, $1_descriptor);
|
||||
}
|
||||
%typemap(doc) (const insn_t &) "$1_name: an ida_ua.insn_t, or an address (C++: const insn_t &)"
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
@@ -1132,6 +1120,7 @@ typedef int ui_notification_t;
|
||||
%apply long long { qoff64_t };
|
||||
|
||||
%apply qstring *result { qstring *out };
|
||||
%apply qstring *result { qstring *out_name };
|
||||
%apply qstring *result { qstring *buf };
|
||||
%apply qstring *result { qstring *errbuf };
|
||||
%apply int *OUTPUT { int *icon };
|
||||
@@ -1262,15 +1251,13 @@ struct dynamic_wrapped_array_t {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
#if SWIG_VERSION == 0x40000 || SWIG_VERSION == 0x40001
|
||||
%typemap(out) tinfo_t {}
|
||||
%typemap(ret) tinfo_t
|
||||
%typemap(out) tinfo_t
|
||||
{
|
||||
// %typemap(ret) tinfo_t
|
||||
// %typemap(out) tinfo_t
|
||||
tinfo_t *ni = new tinfo_t($1);
|
||||
til_register_python_tinfo_t_instance(ni);
|
||||
$result = SWIG_NewPointerObj(ni, $&1_descriptor, SWIG_POINTER_OWN | 0);
|
||||
}
|
||||
|
||||
%typemap(check) tinfo_t *
|
||||
{
|
||||
// %typemap(check) tinfo_t *
|
||||
@@ -1290,6 +1277,25 @@ struct dynamic_wrapped_array_t {
|
||||
// %typemap(newfree) tinfo_t *
|
||||
delete $1;
|
||||
}
|
||||
|
||||
// Specialization for member `tinfo_t`'s, which we want to return as-is
|
||||
%typemap(out) tinfo_t *type,
|
||||
tinfo_t *tif,
|
||||
tinfo_t *obj_type,
|
||||
tinfo_t *closure,
|
||||
tinfo_t *parent,
|
||||
tinfo_t *elem_type,
|
||||
tinfo_t *rettype,
|
||||
tinfo_t *return_type,
|
||||
tinfo_t *idb_type,
|
||||
tinfo_t *formal_type,
|
||||
tinfo_t *functype,
|
||||
tinfo_t *idb_type
|
||||
{
|
||||
// %typemap(out) tinfo_t *type (specialization for member tinfo_t)
|
||||
$result = SWIG_NewPointerObj($1, $1_descriptor, 0);
|
||||
}
|
||||
|
||||
#else
|
||||
#error Ensure tinfo_t wrapping is compatible with this version of SWIG
|
||||
#endif
|
||||
@@ -1581,9 +1587,9 @@ SWIGINTERN PyObject *qstrvec2pylist(const qstrvec_t &vec, int flags=0)
|
||||
%numbers_list_to_values_vec_helper(VECTYPE, SWIGTYPE, PYLIST_CONVERTOR, &);
|
||||
%enddef
|
||||
#ifdef __EA64__
|
||||
%numbers_list_to_values_vec(eavec_t, SWIGTYPE_p_qvectorT_unsigned_long_long_t, PyW_PyListToEaVec);
|
||||
%numbers_list_to_values_vec(eavec_t, SWIGTYPE_p_qvectorT_unsigned_long_long_t, PyW_PySeqToEaVec);
|
||||
#else
|
||||
%numbers_list_to_values_vec(eavec_t, SWIGTYPE_p_qvectorT_unsigned_int_t, PyW_PyListToEaVec);
|
||||
%numbers_list_to_values_vec(eavec_t, SWIGTYPE_p_qvectorT_unsigned_int_t, PyW_PySeqToEaVec);
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
@@ -1799,6 +1805,30 @@ ${NONNULL_TYPEMAPS}
|
||||
$2 = $input;
|
||||
}
|
||||
|
||||
%typemap(in) (printer_t *printer)
|
||||
{
|
||||
// %typemap(in) (printer_t *printer)
|
||||
if ( $input == Py_None )
|
||||
{
|
||||
$1 = nullptr;
|
||||
}
|
||||
else if ( PyBool_Check($input) )
|
||||
{
|
||||
$1 = $input == Py_True ? msg : nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
int res = SWIG_ConvertFunctionPtr($input, (void**)(&$1), SWIGTYPE_p_f_p_q_const__char_v_______int);
|
||||
if ( !SWIG_IsOK(res) )
|
||||
{
|
||||
SWIG_exception_fail(SWIG_ArgError(res), "in method '" "parse_decls" "', argument " "3"" of type '" "printer_t *""'");
|
||||
SWIG_exception_fail(
|
||||
SWIG_TypeError,
|
||||
"in method '" "$symname" "', argument " "$argnum"" of type 'printer_t *'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%define %define_regval_python_accessors()
|
||||
%{
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@@ -1,544 +0,0 @@
|
||||
|
||||
import __future__
|
||||
import re
|
||||
import sys
|
||||
import inspect
|
||||
import types
|
||||
import ast
|
||||
import os
|
||||
import argparse
|
||||
|
||||
sys.stdout.write("### dumpdoc here!\n")
|
||||
for key in os.environ:
|
||||
sys.stdout.write("### %s = \"%s\"\n" % (key, os.environ[key]))
|
||||
|
||||
if sys.version_info[0] == 3:
|
||||
# for Python3, we always use the same pydoc module from Python3.5. this keeps the output consistent across different Python3 versions.
|
||||
import imp
|
||||
inspect = imp.load_source('inspect', os.path.join("tools", "inspect.py"))
|
||||
pydoc = imp.load_source('pydoc', os.path.join("tools", "pydoc.py"))
|
||||
|
||||
import inspect
|
||||
import pydoc
|
||||
|
||||
import idc
|
||||
output, wrappers_dir, is_64 = idc.ARGV[1], idc.ARGV[2], idc.ARGV[3] == "True"
|
||||
|
||||
sys.stdout.write("### Parameter \"output\" = \"%s\"\n" % output)
|
||||
sys.stdout.write("### Parameter \"wrappers_dir\" = \"%s\"\n" % wrappers_dir)
|
||||
sys.stdout.write("### Parameter \"is_64\" = \"%s\"\n" % is_64)
|
||||
|
||||
try:
|
||||
from cStringIO import StringIO
|
||||
except:
|
||||
from io import StringIO
|
||||
|
||||
import ida_hexrays
|
||||
def dummy_replacement():
|
||||
pass
|
||||
ida_hexrays.DecompilationFailure.add_note = dummy_replacement
|
||||
idc.DeprecatedIDCError.add_note = dummy_replacement
|
||||
|
||||
ignore_types = (int, float, str, bool, dict, list, tuple, bytes, types.ModuleType, __future__._Feature)
|
||||
TRANSLATED_MARKER = b"\xE2\x86\x97"
|
||||
|
||||
if sys.version_info.major < 3:
|
||||
string_types = (str, unicode)
|
||||
ignore_types = ignore_types + (long, types.NoneType)
|
||||
else:
|
||||
string_types = (str,)
|
||||
ignore_types = ignore_types + (type(None),)
|
||||
TRANSLATED_MARKER = TRANSLATED_MARKER.decode("UTF-8")
|
||||
|
||||
ignore_names = [
|
||||
"_IDCFUNC_CB_T",
|
||||
"call_idc_func__",
|
||||
"_BUTTONCB_T",
|
||||
"_FORMCHGCB_T",
|
||||
"__ask_form_callable",
|
||||
"__open_form_callable",
|
||||
"_notify_when_dispatcher",
|
||||
"_make_badattr_property",
|
||||
"long_type",
|
||||
"cvar",
|
||||
"__spec__",
|
||||
"SourceFileLoader",
|
||||
"__loader__",
|
||||
"_make_badattr_property",
|
||||
re.compile("_Swig.*"),
|
||||
re.compile("_swig.*"),
|
||||
"SWIG_PyInstanceMethod_New",
|
||||
"svalvec_t", # aliased with intvec_t or int64vec_t
|
||||
"uvalvec_t", # aliased with uintvec_t or uint64vec_t
|
||||
"eavec_t", # aliased with uvalvec_t
|
||||
("ida_ida", "__getattr__"),
|
||||
("idc", "__getattr__"),
|
||||
("__future__", "_Feature"),
|
||||
]
|
||||
|
||||
def should_ignore_name(namespace_name, name):
|
||||
for ign in ignore_names:
|
||||
if isinstance(ign, tuple):
|
||||
if ign == (namespace_name, name):
|
||||
return True
|
||||
elif isinstance(ign, string_types):
|
||||
if ign == name:
|
||||
return True
|
||||
else:
|
||||
if ign.match(name):
|
||||
return True
|
||||
return False
|
||||
|
||||
def apply_translations(translations, input):
|
||||
lines = input.split("\n")
|
||||
out = []
|
||||
for l in lines:
|
||||
for all_frm, dst, marker in translations:
|
||||
assert(isinstance(all_frm, tuple))
|
||||
for frm in all_frm:
|
||||
idx = l.find(frm)
|
||||
if idx > -1:
|
||||
# sys.stderr.write("SPOTTED '%s' in '%s', position %s\n" % (frm, l, idx))
|
||||
l = l[0:idx] + dst + l[idx+len(frm):]
|
||||
if marker:
|
||||
l += TRANSLATED_MARKER
|
||||
# sys.stderr.write("ADDING '%s'\n" % l)
|
||||
out.append(l)
|
||||
return '\n'.join(out)
|
||||
|
||||
all_specific_translations = {
|
||||
"ida_hexrays.casm_t" : [
|
||||
((
|
||||
"uintvec_t",
|
||||
"uint64vec_t"
|
||||
), "eavec_t", True),
|
||||
((
|
||||
"unsigned int *",
|
||||
"unsigned long long *"
|
||||
), "unsigned-ea-like-numeric-type *", True),
|
||||
((
|
||||
"unsigned int &",
|
||||
"unsigned long long &"
|
||||
), "unsigned-ea-like-numeric-type &", True),
|
||||
((
|
||||
"unsigned int const &",
|
||||
"unsigned long long const &"
|
||||
), "unsigned-ea-like-numeric-type const &", True),
|
||||
((
|
||||
"qvector< unsigned int >::",
|
||||
"qvector< unsigned long long >::"
|
||||
), "qvector< unsigned-ea-like-numeric-type >::", True),
|
||||
((
|
||||
"qvector< unsigned int > &",
|
||||
"qvector< unsigned long long > &"
|
||||
), "qvector< unsigned-ea-like-numeric-type > &", True),
|
||||
],
|
||||
"ida_hexrays.ivl_t" : [
|
||||
((
|
||||
") -> 'unsigned int'",
|
||||
") -> 'unsigned long long'", # py3
|
||||
), ") -> 'unsigned-ea-like-numeric-type'", True),
|
||||
((
|
||||
") -> unsigned int",
|
||||
") -> unsigned long long", # py3
|
||||
), ") -> unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.uval_ivl_t" : [
|
||||
((
|
||||
") -> 'unsigned int'",
|
||||
") -> 'unsigned long long'", # py3
|
||||
), ") -> 'unsigned-ea-like-numeric-type'", True),
|
||||
((
|
||||
") -> unsigned int",
|
||||
") -> unsigned long long", # py3
|
||||
), ") -> unsigned-ea-like-numeric-type", True),
|
||||
((
|
||||
"_off: unsigned int",
|
||||
"_off: unsigned long long", # py3
|
||||
), "_off: unsigned-ea-like-numeric-type", True),
|
||||
((
|
||||
"_size: unsigned int",
|
||||
"_size: unsigned long long", # py3
|
||||
), "_size: unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.ivlset_t" : [
|
||||
((
|
||||
"ivlset_tpl< ivl_t,unsigned int >::",
|
||||
"ivlset_tpl< ivl_t,unsigned long long >::", # py3
|
||||
), "ivlset_tpl< ivl_t,unsigned-ea-like-numeric-type >::", True),
|
||||
((
|
||||
"v: unsigned int",
|
||||
"v: unsigned long long"
|
||||
), "v: unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.uval_ivl_ivlset_t" : [
|
||||
((
|
||||
"ivlset_tpl< ivl_t,unsigned int >::",
|
||||
"ivlset_tpl< ivl_t,unsigned long long >::",
|
||||
), "ivlset_tpl< ivl_t,unsigned-ea-like-numeric-type >::", True),
|
||||
((
|
||||
"v: unsigned int",
|
||||
"v: unsigned long long"
|
||||
), "v: unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_segment.segment_defsr_array" : [
|
||||
((
|
||||
"unsigned int const &",
|
||||
"unsigned long long const &",
|
||||
), "unsigned-ea-like-numeric-type const &", True),
|
||||
((
|
||||
"data: unsigned int (&)",
|
||||
"data: unsigned long long (&)",
|
||||
), "data: unsigned-ea-like-numeric-type (&)", True),
|
||||
],
|
||||
"ida_nalt.strpath_ids_array" : [
|
||||
# py3
|
||||
((
|
||||
"unsigned int const &",
|
||||
"unsigned long long const &",
|
||||
), "unsigned-ea-like-numeric-type const &", True),
|
||||
# py3
|
||||
((
|
||||
"data: unsigned int (&)",
|
||||
"data: unsigned long long (&)",
|
||||
), "data: unsigned-ea-like-numeric-type (&)", True),
|
||||
],
|
||||
"idc.add_func" : [
|
||||
(("add_func(start, end=4294967295)",
|
||||
"add_func(start, end=4294967295L)",
|
||||
"add_func(start, end=18446744073709551615)", # py3
|
||||
"add_func(start, end=18446744073709551615L)",
|
||||
), "add_func(start, end=BADADDR)", True),
|
||||
],
|
||||
"idc.next_head" : [
|
||||
(("next_head(ea, maxea=4294967295)",
|
||||
"next_head(ea, maxea=4294967295L)",
|
||||
"next_head(ea, maxea=18446744073709551615)", # py3
|
||||
"next_head(ea, maxea=18446744073709551615L)",
|
||||
), "next_head(ea, maxea=BADADDR)", True),
|
||||
],
|
||||
"ida_xref.casevec_t" : [
|
||||
((
|
||||
"qvector< int >",
|
||||
"qvector< long long >",
|
||||
), "qvector< signed-ea-like-numeric-type >", True),
|
||||
],
|
||||
|
||||
# all that follows is for py3
|
||||
"ida_dbg.dbg_bin_search" : [
|
||||
((
|
||||
"'uint32 *, qstring *'",
|
||||
"'uint64 *, qstring *'",
|
||||
), "'unsigned-ea-like-numeric-type *, qstring *'", True),
|
||||
],
|
||||
"ida_dbg.get_ip_val" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_dbg.get_sp_val" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_funcs.dyn_ea_array" : [
|
||||
((
|
||||
"-> unsigned int const &",
|
||||
"-> unsigned long long const &",
|
||||
), "-> unsigned-ea-like-numeric-type const &", True),
|
||||
((
|
||||
"-> unsigned int *",
|
||||
"-> unsigned long long *",
|
||||
), "-> unsigned-ea-like-numeric-type *", True),
|
||||
((
|
||||
"_data: unsigned int *",
|
||||
"_data: unsigned long long *",
|
||||
), "_data: unsigned-ea-like-numeric-type *", True),
|
||||
((
|
||||
"v: unsigned int const &",
|
||||
"v: unsigned long long const &",
|
||||
), "v: unsigned-ea-like-numeric-type const &", True),
|
||||
# Python3
|
||||
((
|
||||
"-> 'unsigned int const &'",
|
||||
"-> 'unsigned long long const &'",
|
||||
), "-> 'unsigned-ea-like-numeric-type const &'", True),
|
||||
],
|
||||
"ida_idp.ph_find_op_value" : [
|
||||
((
|
||||
"uint32",
|
||||
"uint64",
|
||||
), "unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_idp.ph_find_reg_value" : [
|
||||
((
|
||||
"uint32",
|
||||
"uint64",
|
||||
), "unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.user_iflags_t" : [
|
||||
((
|
||||
"int([x]) -> integer",
|
||||
), "int(x=0) -> integer", False),
|
||||
],
|
||||
"ida_hexrays.eamap_t" : [
|
||||
((
|
||||
"int([x]) -> integer",
|
||||
), "int(x=0) -> integer", False),
|
||||
((
|
||||
"_Keyval: unsigned int const &",
|
||||
"_Keyval: unsigned long long const &"
|
||||
), "_Keyval: unsigned-ea-like-numeric-type const &", True),
|
||||
],
|
||||
"ida_hexrays.user_unions_t" : [
|
||||
((
|
||||
"_Keyval: unsigned int const &",
|
||||
"_Keyval: unsigned long long const &"
|
||||
), "_Keyval: unsigned-ea-like-numeric-type const &", True),
|
||||
],
|
||||
"ida_hexrays.DecompilationFailure" : [
|
||||
((
|
||||
"Helper for pickle.",
|
||||
), "helper for pickle", False),
|
||||
],
|
||||
"idc.DeprecatedIDCError" : [
|
||||
((
|
||||
"Helper for pickle.",
|
||||
), "helper for pickle", False),
|
||||
],
|
||||
"ida_idp._processor_t" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_idp._processor_t_find_op_value" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_idp._processor_t_find_reg_value" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'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:
|
||||
all_specific_translations["ida_dirtree.direntry_t"] = [
|
||||
((
|
||||
"BADIDX = 18446744073709551615L",
|
||||
"BADIDX = 18446744073709551615",
|
||||
), "BADIDX = unsigned-ea-like-numeric-type(-1)", False),
|
||||
]
|
||||
else:
|
||||
all_specific_translations["ida_dirtree.direntry_t"] = [
|
||||
((
|
||||
"BADIDX = 4294967295L",
|
||||
"BADIDX = 4294967295",
|
||||
), "BADIDX = unsigned-ea-like-numeric-type(-1)", False),
|
||||
]
|
||||
|
||||
def dump_namespace(namespace, namespace_name, keys, vec_info=None):
|
||||
spotted_things = []
|
||||
for thing_name in keys:
|
||||
# sys.stderr.write("THING NAME: %s\n" % thing_name)
|
||||
if should_ignore_name(namespace_name, thing_name):
|
||||
continue
|
||||
thing = getattr(namespace, thing_name)
|
||||
if isinstance(thing, ignore_types):
|
||||
continue
|
||||
if thing in spotted_things:
|
||||
continue
|
||||
specific_translations = all_specific_translations.get(
|
||||
"%s.%s" % (namespace_name, thing_name),
|
||||
None)
|
||||
if specific_translations:
|
||||
was_stdout = sys.stdout
|
||||
sys.stdout = StringIO()
|
||||
pydoc.help(thing)
|
||||
# sys.stderr.write("VALUE FOR %s.%s: %s" % (namespace_name, thing_name, sys.stdout.getvalue()))
|
||||
translated = apply_translations(specific_translations, sys.stdout.getvalue())
|
||||
# sys.stderr.write("TRANSLATED %s.%s: %s" % (namespace_name, thing_name, translated))
|
||||
sys.stdout = was_stdout
|
||||
sys.stdout.write(translated)
|
||||
else:
|
||||
pydoc.help(thing)
|
||||
spotted_things.append(thing)
|
||||
|
||||
class variable_collector_t(ast.NodeVisitor):
|
||||
OUTSIDE = 0
|
||||
IN_CLASS = 1
|
||||
IN_FUNCTION = 2
|
||||
|
||||
def __init__(self, variables, module_name):
|
||||
self.variables = variables
|
||||
self.module_name = module_name
|
||||
self.context = self.OUTSIDE
|
||||
self.class_name = ""
|
||||
self.assign_last_line = -1
|
||||
|
||||
super(variable_collector_t, self).__init__()
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
old_context = self.context
|
||||
self.context = self.IN_FUNCTION
|
||||
self.generic_visit(node)
|
||||
self.context = old_context
|
||||
|
||||
def visit_ClassDef(self, node):
|
||||
if self.context == self.IN_FUNCTION:
|
||||
return
|
||||
if self.context == self.IN_CLASS:
|
||||
prefix = self.class_name + "."
|
||||
else:
|
||||
prefix = ""
|
||||
self.class_name = prefix + node.name
|
||||
|
||||
old_context = self.context
|
||||
self.context = self.IN_CLASS
|
||||
self.generic_visit(node)
|
||||
self.context = old_context
|
||||
|
||||
def visit_Assign(self, node):
|
||||
if self.context == self.IN_FUNCTION:
|
||||
return
|
||||
if self.context == self.IN_CLASS:
|
||||
prefix = self.class_name + "."
|
||||
else:
|
||||
prefix = ""
|
||||
|
||||
if len(node.targets) == 1:
|
||||
target = node.targets[0]
|
||||
if isinstance(target, ast.Name):
|
||||
self.assign_variable = prefix + target.id
|
||||
self.assign_last_line = self._highest_lineno(node)
|
||||
|
||||
def _highest_lineno(self, node):
|
||||
if hasattr(node, "end_lineno"):
|
||||
return node.end_lineno
|
||||
|
||||
highest = node.lineno
|
||||
for child in ast.walk(node):
|
||||
if hasattr(child, "lineno") and child.lineno > highest:
|
||||
highest = child.lineno
|
||||
return highest
|
||||
|
||||
def visit_Expr(self, node):
|
||||
if not isinstance(node.value, ast.Str):
|
||||
return
|
||||
|
||||
if hasattr(node, "end_lineno"):
|
||||
line_before = node.lineno - 1 # in this case, lineno = start
|
||||
else:
|
||||
# hack until Python 3.8; if <3.8, lineno = end
|
||||
line_before = node.lineno - len(node.value.s.split("\n"))
|
||||
|
||||
if line_before == self.assign_last_line:
|
||||
self.variables.append(
|
||||
"\nDocumentation on variable %s in module %s:\n\n%s\n" \
|
||||
% (self.assign_variable,
|
||||
self.module_name,
|
||||
self._cleandoc(node.value.s)))
|
||||
|
||||
def _cleandoc(self, docstring):
|
||||
if docstring:
|
||||
docstring = inspect.cleandoc(docstring)
|
||||
|
||||
# 4-blanks indent
|
||||
docstring = "\n".join(" " + line for line in docstring.split("\n"))
|
||||
|
||||
return docstring
|
||||
|
||||
def collect_variables(variables, module_name, filename):
|
||||
with open(filename, "r") as f:
|
||||
tree = ast.parse(f.read())
|
||||
|
||||
visitor = variable_collector_t(variables, module_name)
|
||||
visitor.visit(tree)
|
||||
|
||||
# By default, pydoc.help() hides members that start with "_"
|
||||
# unless they start and end with "__" (with an exception for
|
||||
# __doc__ and __module__)
|
||||
# We want those "_" members, since there are important
|
||||
# things such as tinfo_t._print in there.
|
||||
orig_visiblename = pydoc.visiblename
|
||||
def my_visiblename(name, all=None, obj=None):
|
||||
v = orig_visiblename(name, all=all, obj=obj)
|
||||
if not v and name.startswith("_") and name not in ["__doc__", "__module__"]:
|
||||
v = True
|
||||
return v
|
||||
pydoc.visiblename = my_visiblename
|
||||
|
||||
def iter_modules():
|
||||
for mname in sorted(sys.modules):
|
||||
if mname.startswith("ida_") or mname == "idc":
|
||||
yield mname, sys.modules[mname]
|
||||
|
||||
sys.stdout.write("### Before collecting help\n")
|
||||
old_stdout = sys.stdout ### debug
|
||||
|
||||
sys.stdout = StringIO()
|
||||
for mname, module in iter_modules():
|
||||
print("Module \"%s\"s docstring:\n\"\"\"%s\"\"\"\n" % (mname, module.__doc__))
|
||||
dump_namespace(module, mname, sorted(dir(module)))
|
||||
|
||||
old_stdout.write("### After collecting help\n")
|
||||
|
||||
final = apply_translations([], sys.stdout.getvalue())
|
||||
|
||||
old_stdout.write("### After applying translations\n")
|
||||
|
||||
def module_file(module):
|
||||
name, ext = os.path.splitext(module.__file__)
|
||||
if ext == ".pyc":
|
||||
ext = ".py"
|
||||
return name + ext
|
||||
|
||||
old_stdout.write("### Before collecting variables\n")
|
||||
|
||||
variables = ["\n=== DOCUMENTATION FOR VARIABLES ===\n"]
|
||||
for mname, module in iter_modules():
|
||||
collect_variables(variables, mname, module_file(module))
|
||||
|
||||
old_stdout.write("### After collecting variables (%d of them)\n" % len(variables))
|
||||
|
||||
final += "".join(variables)
|
||||
|
||||
with open(output, "wb") as f:
|
||||
if sys.version_info.major <= 2:
|
||||
f.write(final)
|
||||
else:
|
||||
f.write(final.encode("utf-8"))
|
||||
|
||||
old_stdout.write("### Wrote output (%d chars), end of script\n" % len(final))
|
||||
|
||||
idaapi.qexit(0)
|
||||
@@ -43,7 +43,7 @@ def read_config():
|
||||
global config
|
||||
|
||||
config_path = os.path.join(prog_dir, prog_name + ".cfg")
|
||||
with open(config_path, "r") as f:
|
||||
with open(config_path, "r", encoding="UTF-8", errors="surrogateescape") as f:
|
||||
config = ast.literal_eval(f.read())
|
||||
|
||||
config["exclude"] = set(config["exclude"])
|
||||
@@ -73,7 +73,7 @@ class Examples(object):
|
||||
|
||||
for relpath, path in self._files_with_extension(".py", args.examples_dir):
|
||||
verb("Processing \"%s\"" % path)
|
||||
with open(path, "r") as f:
|
||||
with open(path, "r", encoding="UTF-8", errors="surrogateescape") as f:
|
||||
self._load_ast(relpath, ast.parse(f.read(), path))
|
||||
|
||||
self._post_read_processing()
|
||||
@@ -649,11 +649,11 @@ class ExamplesIndex(object):
|
||||
def __init__(self):
|
||||
self.replacer = TemplateReplacer()
|
||||
|
||||
with open(args.template, "r") as f:
|
||||
with open(args.template, "r", encoding="UTF-8", errors="surrogateescape") as f:
|
||||
self.replacer.template(f.read())
|
||||
|
||||
def produce(self, examples, all_keywords):
|
||||
with open(args.output, "w") as f:
|
||||
with open(args.output, "w", encoding="UTF-8") as f:
|
||||
self.replacer.expand(examples, all_keywords, f)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@@ -123,10 +123,11 @@ def gen_notifications(out):
|
||||
pname = recipe_data.get("params", {}).get(pname, {}).get("rename", pname)
|
||||
ptype = p["type"]
|
||||
pick_type = ptype
|
||||
# instead of va_argi() we jst promote the type to "int"
|
||||
if ptype in ["bool", "char", "uchar", "uint16", "cref_t",
|
||||
"dref_t", "cm_t", "ui_notification_t", "dbg_notification_t",
|
||||
"tcc_renderer_type_t", "range_kind_t", "demreq_type_t",
|
||||
"ctree_maturity_t", "comp_t"]:
|
||||
"ctree_maturity_t", "comp_t", "local_type_change_t"]:
|
||||
cast = ptype
|
||||
pick_type = "int"
|
||||
else:
|
||||
|
||||
@@ -5,6 +5,7 @@ recipe = {
|
||||
"ev_last_cb_before_type_callbacks" : {"ignore" : True},
|
||||
"ev_get_idd_opinfo" : {"ignore" : True},
|
||||
"ev_loader_elf_machine" : {"ignore" : True},
|
||||
"ev_get_regfinder" : {"ignore" : True},
|
||||
"ev_broadcast" : {"ignore" : True},
|
||||
"ev_obsolete1" : {"ignore" : True},
|
||||
"ev_obsolete2" : {"ignore" : True},
|
||||
|
||||
@@ -113,7 +113,7 @@ wrap_regex = re.compile(r"SWIGINTERN PyObject \*_wrap_([a-zA-Z0-9_]*)\(.*")
|
||||
director_method_regex = re.compile(r".*((SwigDirector_([a-zA-Z0-9_]*))::~?([a-zA-Z0-9_]*))\(.*")
|
||||
swig_clink_var_get_regex = re.compile(r"SWIGINTERN PyObject \*(Swig_var_[a-zA-Z0-9_]*_get).*")
|
||||
swig_clink_var_set_regex = re.compile(r"SWIGINTERN int (Swig_var_[a-zA-Z0-9_]*_set).*")
|
||||
SWIG_Python_TypeError_regex = re.compile(".*(SWIG_Python_TypeError)\(const char \*type, PyObject \*obj\).*")
|
||||
SWIG_Python_TypeError_regex = re.compile(r".*(SWIG_Python_TypeError)\(const char \*type, PyObject \*obj\).*")
|
||||
SwigPyObject_dealloc_regex = re.compile(r"^(SwigPyObject_dealloc)\(PyObject \*v\)$")
|
||||
|
||||
all_lines = [
|
||||
@@ -322,7 +322,7 @@ with open(args.input) as f:
|
||||
elif line.find("result = PyObject_CallMethodObjArgs") > -1:
|
||||
call_args = args_cmoa
|
||||
if call_args:
|
||||
subst = re.sub("\(.*\);", call_args + ";", line)
|
||||
subst = re.sub(r"\(.*\);", call_args + ";", line)
|
||||
if add_error:
|
||||
subst = ["#error CHECK_THAT_THIS_WORKS", subst]
|
||||
elif patch_kind == "nullptr_result_on_py_error":
|
||||
|
||||
@@ -92,4 +92,13 @@ if ( __argcnt == 2 )
|
||||
"(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0,(__argcnt < 3 ? nullptr : (PyObject *)obj1), nullptr)")
|
||||
),
|
||||
],
|
||||
|
||||
"SwigDirector_IDB_Hooks::local_types_changed" : [
|
||||
("director_method_call_arity_cap", (
|
||||
False, # add GIL lock
|
||||
"local_types_changed",
|
||||
"(method ,(__argcnt < 2 ? nullptr : (PyObject *)obj0), (__argcnt < 2 ? nullptr : (PyObject *)obj1), (__argcnt < 2 ? nullptr : (PyObject *)obj2), nullptr)",
|
||||
"(swig_get_self(), (PyObject *) swig_method_name ,(__argcnt < 2 ? nullptr : (PyObject *)obj0), (__argcnt < 2 ? nullptr : (PyObject *)obj1), (__argcnt < 2 ? nullptr : (PyObject *)obj2), nullptr)")
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,531 @@
|
||||
|
||||
import sys
|
||||
import ast
|
||||
import inspect
|
||||
import argparse
|
||||
import os
|
||||
|
||||
p = argparse.ArgumentParser()
|
||||
p.add_argument("-p", "--paths", type=str, required=True, help="Path(s) to the file(s) to parse")
|
||||
p.add_argument("-c", "--dump-doc", default=False, action="store_true", help="Dump python docstrings")
|
||||
p.add_argument("-k", "--dump-kind", default=False, action="store_true", help="Dump scopes kinds (class, method, ...)")
|
||||
args = p.parse_args()
|
||||
|
||||
class scope_t(object):
|
||||
def __init__(self, node, scope):
|
||||
self.node = node
|
||||
self.parent = None
|
||||
self.children = []
|
||||
self.doc = None
|
||||
|
||||
def _new_scope(self, _type, node):
|
||||
scope = _type(node, self)
|
||||
self.children.append(scope)
|
||||
scope.parent = self
|
||||
return scope
|
||||
|
||||
def kind(self):
|
||||
return self.__class__.__name__.replace("_t", "")
|
||||
|
||||
def new_class(self, node):
|
||||
return self._new_scope(class_t, node)
|
||||
|
||||
def new_method(self, node):
|
||||
return self._new_scope(method_t, node)
|
||||
|
||||
def new_function(self, node):
|
||||
return self._new_scope(function_t, node)
|
||||
|
||||
def new_variable(self, node, variable_name):
|
||||
s = self._new_scope(variable_t, node)
|
||||
s.variable_name = variable_name
|
||||
return s
|
||||
|
||||
def get_name(self):
|
||||
return self.node.name
|
||||
|
||||
def get_full_name_parts(self):
|
||||
parts = []
|
||||
s = self
|
||||
while s is not None:
|
||||
parts.append(s.get_name())
|
||||
s = s.parent
|
||||
return reversed(parts)
|
||||
|
||||
def get_full_name(self):
|
||||
return ".".join(self.get_full_name_parts())
|
||||
|
||||
def set_doc(self, doc):
|
||||
self.doc = doc
|
||||
|
||||
class module_t(scope_t):
|
||||
pass
|
||||
|
||||
class class_t(scope_t):
|
||||
pass
|
||||
|
||||
class method_t(scope_t):
|
||||
pass
|
||||
|
||||
class function_t(scope_t):
|
||||
pass
|
||||
|
||||
class variable_t(scope_t):
|
||||
def get_name(self):
|
||||
return self.variable_name
|
||||
|
||||
|
||||
DF_DOC = 0x1
|
||||
DF_KIND = 0x2
|
||||
|
||||
def dump(scope, flags=0, sort=True):
|
||||
lines = []
|
||||
def dump1(s):
|
||||
name = s.get_full_name()
|
||||
line = [name]
|
||||
if (flags & DF_KIND) != 0:
|
||||
line.append("(%s)" % s.kind())
|
||||
lines.append(" ".join(line))
|
||||
if (flags & DF_DOC) != 0:
|
||||
if s.doc is not None:
|
||||
lines.extend(s.doc.split("\n"))
|
||||
lines.append("")
|
||||
children = s.children[:]
|
||||
if sort:
|
||||
children = sorted(children, key=lambda n: n.get_name())
|
||||
for c in children:
|
||||
dump1(c)
|
||||
dump1(scope)
|
||||
return "\n".join(lines)
|
||||
|
||||
class collector_t(ast.NodeVisitor):
|
||||
|
||||
class temp_scope_t(object):
|
||||
def __init__(self, collector, scope):
|
||||
self.collector = collector
|
||||
self.scope = scope
|
||||
|
||||
def __enter__(self):
|
||||
old_scope = self.collector.scope
|
||||
self.collector.scope = self.scope
|
||||
self.scope = old_scope # swoop in the old context
|
||||
|
||||
def __exit__(self, tp, value, traceback):
|
||||
self.collector.scope = self.scope
|
||||
if value:
|
||||
raise
|
||||
|
||||
def __init__(self, module_name):
|
||||
class module_node_t(object):
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
self.scope = module_t(module_node_t(module_name), None)
|
||||
self.assign_last_line = -1
|
||||
|
||||
super(collector_t, self).__init__()
|
||||
|
||||
def in_function(self):
|
||||
return isinstance(self.scope, function_t)
|
||||
|
||||
def in_class(self):
|
||||
return isinstance(self.scope, class_t)
|
||||
|
||||
def accept(self, node):
|
||||
return True
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
if self.accept(node):
|
||||
if self.in_class():
|
||||
s = self.scope.new_method(node)
|
||||
else:
|
||||
s = self.scope.new_function(node)
|
||||
with self.temp_scope_t(self, s):
|
||||
self.generic_visit(node)
|
||||
|
||||
def visit_ClassDef(self, node):
|
||||
if self.in_function():
|
||||
return
|
||||
if self.accept(node):
|
||||
with self.temp_scope_t(self, self.scope.new_class(node)):
|
||||
self.generic_visit(node)
|
||||
|
||||
def visit_Assign(self, node):
|
||||
if self.in_function():
|
||||
return
|
||||
if len(node.targets) == 1:
|
||||
target = node.targets[0]
|
||||
if isinstance(target, ast.Name):
|
||||
self.assign_variable = target.id
|
||||
self.assign_last_line = self._highest_lineno(node)
|
||||
|
||||
def _highest_lineno(self, node):
|
||||
if hasattr(node, "end_lineno"):
|
||||
return node.end_lineno
|
||||
|
||||
highest = node.lineno
|
||||
for child in ast.walk(node):
|
||||
if hasattr(child, "lineno") and child.lineno > highest:
|
||||
highest = child.lineno
|
||||
return highest
|
||||
|
||||
def visit_Expr(self, node):
|
||||
# print("%d: %s" % (node.lineno, ast.dump(node.value)))
|
||||
if not isinstance(node.value, ast.Str):
|
||||
return
|
||||
|
||||
if hasattr(node, "end_lineno"):
|
||||
line_before = node.lineno - 1 # in this case, lineno = start
|
||||
else:
|
||||
# hack until Python 3.8; if <3.8, lineno = end
|
||||
line_before = node.lineno - len(node.value.s.split("\n"))
|
||||
|
||||
clean_doc = self._cleandoc(node.value.s)
|
||||
if line_before == self.assign_last_line:
|
||||
self.scope.new_variable(node, self.assign_variable).set_doc(clean_doc)
|
||||
else:
|
||||
self.scope.set_doc(clean_doc)
|
||||
# self.variables.append(
|
||||
# "\nDocumentation on variable %s in module %s:\n\n%s\n" \
|
||||
# % (self.assign_variable,
|
||||
# self.module_name,
|
||||
# self._cleandoc(node.value.s)))
|
||||
|
||||
def _cleandoc(self, docstring):
|
||||
if docstring:
|
||||
docstring = inspect.cleandoc(docstring)
|
||||
|
||||
# 4-blanks indent
|
||||
docstring = "\n".join(" " + line for line in docstring.split("\n"))
|
||||
|
||||
return docstring
|
||||
|
||||
|
||||
class docfixing_collector_t(collector_t):
|
||||
|
||||
IGNORE = [
|
||||
"ida_kernwin.__ask_form_callable",
|
||||
"ida_kernwin.__call_form_callable",
|
||||
"ida_kernwin.__open_form_callable",
|
||||
"*._SwigNonDynamicMeta",
|
||||
"*._swig_add_metaclass",
|
||||
"*._swig_add_metaclass.wrapper",
|
||||
"*._swig_repr",
|
||||
"*._swig_setattr_nondynamic_class_variable",
|
||||
"*._swig_setattr_nondynamic_class_variable.set_class_attr",
|
||||
"*._swig_setattr_nondynamic_instance_variable",
|
||||
"*._swig_setattr_nondynamic_instance_variable.set_instance_attr",
|
||||
"*.*.dump_state",
|
||||
]
|
||||
|
||||
def accept(self, node):
|
||||
full_name_parts = list(self.scope.get_full_name_parts()) + [node.name]
|
||||
for ign in self.IGNORE:
|
||||
ign_parts = ign.split(".")
|
||||
if len(full_name_parts) == len(ign_parts):
|
||||
match = True
|
||||
for got, against in zip(full_name_parts, ign_parts):
|
||||
if against != "*" and got != against:
|
||||
match = False
|
||||
break
|
||||
if match:
|
||||
return False
|
||||
return True
|
||||
|
||||
TRANSLATIONS = {
|
||||
"ida_hexrays.casm_t" : [
|
||||
((
|
||||
"uintvec_t",
|
||||
"uint64vec_t"
|
||||
), "eavec_t", True),
|
||||
((
|
||||
"unsigned int *",
|
||||
"unsigned long long *"
|
||||
), "unsigned-ea-like-numeric-type *", True),
|
||||
((
|
||||
"unsigned int &",
|
||||
"unsigned long long &"
|
||||
), "unsigned-ea-like-numeric-type &", True),
|
||||
((
|
||||
"unsigned int const &",
|
||||
"unsigned long long const &"
|
||||
), "unsigned-ea-like-numeric-type const &", True),
|
||||
((
|
||||
"qvector< unsigned int >::",
|
||||
"qvector< unsigned long long >::"
|
||||
), "qvector< unsigned-ea-like-numeric-type >::", True),
|
||||
((
|
||||
"qvector< unsigned int > &",
|
||||
"qvector< unsigned long long > &"
|
||||
), "qvector< unsigned-ea-like-numeric-type > &", True),
|
||||
],
|
||||
"ida_hexrays.ivl_t" : [
|
||||
((
|
||||
") -> 'unsigned int'",
|
||||
") -> 'unsigned long long'", # py3
|
||||
), ") -> 'unsigned-ea-like-numeric-type'", True),
|
||||
((
|
||||
") -> unsigned int",
|
||||
") -> unsigned long long", # py3
|
||||
), ") -> unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.uval_ivl_t" : [
|
||||
((
|
||||
") -> 'unsigned int'",
|
||||
") -> 'unsigned long long'", # py3
|
||||
), ") -> 'unsigned-ea-like-numeric-type'", True),
|
||||
((
|
||||
") -> unsigned int",
|
||||
") -> unsigned long long", # py3
|
||||
), ") -> unsigned-ea-like-numeric-type", True),
|
||||
((
|
||||
"_off: unsigned int",
|
||||
"_off: unsigned long long", # py3
|
||||
), "_off: unsigned-ea-like-numeric-type", True),
|
||||
((
|
||||
"_size: unsigned int",
|
||||
"_size: unsigned long long", # py3
|
||||
), "_size: unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.ivlset_t" : [
|
||||
((
|
||||
"ivlset_tpl< ivl_t,unsigned int >::",
|
||||
"ivlset_tpl< ivl_t,unsigned long long >::", # py3
|
||||
), "ivlset_tpl< ivl_t,unsigned-ea-like-numeric-type >::", True),
|
||||
((
|
||||
"v: unsigned int",
|
||||
"v: unsigned long long"
|
||||
), "v: unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.uval_ivl_ivlset_t" : [
|
||||
((
|
||||
"ivlset_tpl< ivl_t,unsigned int >::",
|
||||
"ivlset_tpl< ivl_t,unsigned long long >::",
|
||||
), "ivlset_tpl< ivl_t,unsigned-ea-like-numeric-type >::", True),
|
||||
((
|
||||
"v: unsigned int",
|
||||
"v: unsigned long long"
|
||||
), "v: unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_segment.segment_defsr_array" : [
|
||||
((
|
||||
"unsigned int const &",
|
||||
"unsigned long long const &",
|
||||
), "unsigned-ea-like-numeric-type const &", True),
|
||||
((
|
||||
"data: unsigned int (&)",
|
||||
"data: unsigned long long (&)",
|
||||
), "data: unsigned-ea-like-numeric-type (&)", True),
|
||||
],
|
||||
"ida_nalt.strpath_ids_array" : [
|
||||
# py3
|
||||
((
|
||||
"unsigned int const &",
|
||||
"unsigned long long const &",
|
||||
), "unsigned-ea-like-numeric-type const &", True),
|
||||
# py3
|
||||
((
|
||||
"data: unsigned int (&)",
|
||||
"data: unsigned long long (&)",
|
||||
), "data: unsigned-ea-like-numeric-type (&)", True),
|
||||
],
|
||||
"idc.add_func" : [
|
||||
(("add_func(start, end=4294967295)",
|
||||
"add_func(start, end=4294967295L)",
|
||||
"add_func(start, end=18446744073709551615)", # py3
|
||||
"add_func(start, end=18446744073709551615L)",
|
||||
), "add_func(start, end=BADADDR)", True),
|
||||
],
|
||||
"idc.next_head" : [
|
||||
(("next_head(ea, maxea=4294967295)",
|
||||
"next_head(ea, maxea=4294967295L)",
|
||||
"next_head(ea, maxea=18446744073709551615)", # py3
|
||||
"next_head(ea, maxea=18446744073709551615L)",
|
||||
), "next_head(ea, maxea=BADADDR)", True),
|
||||
],
|
||||
"ida_xref.casevec_t" : [
|
||||
((
|
||||
"qvector< int >",
|
||||
"qvector< long long >",
|
||||
), "qvector< signed-ea-like-numeric-type >", True),
|
||||
],
|
||||
|
||||
# all that follows is for py3
|
||||
"ida_dbg.dbg_bin_search" : [
|
||||
((
|
||||
"'uint32 *, qstring *'",
|
||||
"'uint64 *, qstring *'",
|
||||
), "'unsigned-ea-like-numeric-type *, qstring *'", True),
|
||||
],
|
||||
"ida_dbg.get_ip_val" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_dbg.get_sp_val" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_funcs.dyn_ea_array" : [
|
||||
((
|
||||
"-> unsigned int const &",
|
||||
"-> unsigned long long const &",
|
||||
), "-> unsigned-ea-like-numeric-type const &", True),
|
||||
((
|
||||
"-> unsigned int *",
|
||||
"-> unsigned long long *",
|
||||
), "-> unsigned-ea-like-numeric-type *", True),
|
||||
((
|
||||
"_data: unsigned int *",
|
||||
"_data: unsigned long long *",
|
||||
), "_data: unsigned-ea-like-numeric-type *", True),
|
||||
((
|
||||
"v: unsigned int const &",
|
||||
"v: unsigned long long const &",
|
||||
), "v: unsigned-ea-like-numeric-type const &", True),
|
||||
# Python3
|
||||
((
|
||||
"-> 'unsigned int const &'",
|
||||
"-> 'unsigned long long const &'",
|
||||
), "-> 'unsigned-ea-like-numeric-type const &'", True),
|
||||
],
|
||||
"ida_idp.ph_find_op_value" : [
|
||||
((
|
||||
"uint32",
|
||||
"uint64",
|
||||
), "unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_idp.ph_find_reg_value" : [
|
||||
((
|
||||
"uint32",
|
||||
"uint64",
|
||||
), "unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_regfinder.find_reg_value" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "unsigned-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_regfinder.find_sp_value" : [
|
||||
((
|
||||
"'int32 *'",
|
||||
"'int64 *'",
|
||||
), "signed-ea-like-numeric-type", True),
|
||||
],
|
||||
"ida_hexrays.user_iflags_t" : [
|
||||
((
|
||||
"int([x]) -> integer",
|
||||
), "int(x=0) -> integer", False),
|
||||
],
|
||||
"ida_hexrays.eamap_t" : [
|
||||
((
|
||||
"int([x]) -> integer",
|
||||
), "int(x=0) -> integer", False),
|
||||
((
|
||||
"_Keyval: unsigned int const &",
|
||||
"_Keyval: unsigned long long const &"
|
||||
), "_Keyval: unsigned-ea-like-numeric-type const &", True),
|
||||
],
|
||||
"ida_hexrays.user_unions_t" : [
|
||||
((
|
||||
"_Keyval: unsigned int const &",
|
||||
"_Keyval: unsigned long long const &"
|
||||
), "_Keyval: unsigned-ea-like-numeric-type const &", True),
|
||||
],
|
||||
"ida_hexrays.DecompilationFailure" : [
|
||||
((
|
||||
"Helper for pickle.",
|
||||
), "helper for pickle", False),
|
||||
],
|
||||
"idc.DeprecatedIDCError" : [
|
||||
((
|
||||
"Helper for pickle.",
|
||||
), "helper for pickle", False),
|
||||
],
|
||||
"ida_idp._processor_t" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_idp._processor_t_find_op_value" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'uint64 *'",
|
||||
), "'unsigned-ea-like-numeric-type *'", True),
|
||||
],
|
||||
"ida_idp._processor_t_find_reg_value" : [
|
||||
((
|
||||
"'uint32 *'",
|
||||
"'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),
|
||||
],
|
||||
}
|
||||
|
||||
def _cleandoc(self, docstring):
|
||||
docstring = super(docfixing_collector_t, self)._cleandoc(docstring)
|
||||
name = self.scope.get_full_name()
|
||||
translations = None
|
||||
while name:
|
||||
translations = self.TRANSLATIONS.get(name, None)
|
||||
if translations:
|
||||
break
|
||||
name_parts = name.split(".")
|
||||
name = ".".join(name_parts[:-1])
|
||||
if translations:
|
||||
out = []
|
||||
for l in docstring.split("\n"):
|
||||
for all_frm, dst, _ in translations:
|
||||
assert(isinstance(all_frm, tuple))
|
||||
for frm in all_frm:
|
||||
idx = l.find(frm)
|
||||
if idx > -1:
|
||||
# sys.stderr.write("SPOTTED '%s' in '%s', position %s\n" % (frm, l, idx))
|
||||
l = l[0:idx] + dst + l[idx+len(frm):]
|
||||
# sys.stderr.write("ADDING '%s'\n" % l)
|
||||
out.append(l)
|
||||
docstring = '\n'.join(out)
|
||||
return docstring
|
||||
|
||||
|
||||
toplevel_scopes = []
|
||||
for path in args.paths.split(","):
|
||||
with open(path, "r") as f:
|
||||
tree = ast.parse(f.read())
|
||||
_, fname = os.path.split(path)
|
||||
module_name = fname[:fname.index(".")]
|
||||
vc = docfixing_collector_t(module_name)
|
||||
vc.visit(tree)
|
||||
toplevel_scopes.append(vc.scope)
|
||||
|
||||
flags = (DF_DOC if args.dump_doc else 0) \
|
||||
| (DF_KIND if args.dump_kind else 0)
|
||||
for s in toplevel_scopes:
|
||||
print(dump(s, flags=flags))
|
||||
Reference in New Issue
Block a user