Skip to content
This repository was archived by the owner on Dec 24, 2025. It is now read-only.

Commit c88a77e

Browse files
author
elias.bachaalany@gmail.com
committed
Contributed by EiNSTeiN_:
- added support for 'long' addresses - updated copyright notice in hexrays.i - added methods to remove or insert elements in the qlist<cinsn_t> list - added support for ctree_visitor_t / ctree_parentee_t / cfunc_parentee_t / user_lvar_visitor_t - updated vds3 sample - added vds4 and vds7 python samples (ported from their C++ counter parts)
1 parent 7eb6d04 commit c88a77e

4 files changed

Lines changed: 298 additions & 140 deletions

File tree

examples/vds3.py

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -88,41 +88,74 @@ def add_location(self, ea):
8888
self.save()
8989
return
9090

91-
def invert_if_event(self, vu):
91+
def find_if_statement(self, vu):
9292

9393
vu.get_current_item(idaapi.USE_KEYBOARD)
9494
item = vu.item
9595

96+
if item.is_citem() and item.it.op == idaapi.cit_if and item.it.to_specific_type.cif.ielse is not None:
97+
return item.it.to_specific_type
98+
99+
if vu.tail.citype == idaapi.VDI_TAIL and vu.tail.loc.itp == idaapi.ITP_ELSE:
100+
# for tail marks, we know only the corresponding ea,
101+
# not the pointer to if-statement
102+
# find it by walking the whole ctree
103+
class if_finder_t(idaapi.ctree_visitor_t):
104+
def __init__(self, ea):
105+
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST | idaapi.CV_INSNS)
106+
107+
self.ea = ea
108+
self.found = None
109+
return
110+
111+
def visit_insn(self, i):
112+
if i.op == idaapi.cit_if and i.ea == self.ea:
113+
self.found = i
114+
return 1 # stop enumeration
115+
return 0
116+
117+
iff = if_finder_t(vu.tail.loc.ea)
118+
if iff.apply_to(vu.cfunc.body, None):
119+
return iff.found
120+
121+
return
122+
123+
def invert_if_event(self, vu):
124+
96125
cfunc = vu.cfunc.__deref__()
97126

98-
if item.citype != idaapi.VDI_EXPR:
127+
i = self.find_if_statement(vu)
128+
if not i:
99129
return False
100130

101-
if self.invert_if(cfunc, item.it.to_specific_type):
131+
if self.invert_if(cfunc, i):
102132
vu.refresh_ctext()
103133

104-
self.add_location(item.it.ea)
134+
self.add_location(i.ea)
105135

106136
return True
107137

108138
def restore(self, cfunc):
109139

110-
#~ print 'restoring invert-if for %x' % (cfunc.entry_ea, )
111-
112-
str(cfunc) # generate treeitems.
113-
114-
restored = False
140+
class visitor(idaapi.ctree_visitor_t):
141+
142+
def __init__(self, inverter, cfunc):
143+
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST | idaapi.CV_INSNS)
144+
self.inverter = inverter
145+
self.cfunc = cfunc
146+
return
147+
148+
def visit_insn(self, i):
149+
try:
150+
if i.op == idaapi.cit_if and i.ea in self.inverter.stored:
151+
self.inverter.invert_if(self.cfunc, i)
152+
except:
153+
traceback.print_exc()
154+
return 0 # continue enumeration
115155

116-
for item in cfunc.treeitems:
117-
item = item.to_specific_type
118-
if item.opname == 'if' and item.ea in self.stored:
119-
if self.invert_if(cfunc, item):
120-
restored = True
121-
#~ print 'restore invert-if location %x' % (item.ea, )
122-
else:
123-
print 'invert-if location %x: NOT RESTORED' % (item.ea, )
156+
visitor(self, cfunc).apply_to(cfunc.body, None)
124157

125-
return restored
158+
return
126159

127160
def menu_callback(self):
128161
try:
@@ -142,7 +175,7 @@ def event_callback(self, event, *args):
142175
return 1
143176

144177
elif event == idaapi.hxe_right_click:
145-
self.vu = args[0]
178+
self.vu, = args
146179
idaapi.add_custom_viewer_popup_item(self.vu.ct, "Invert then/else", "I", self.menu_callback)
147180

148181
elif event == idaapi.hxe_maturity:

examples/vds4.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
""" Print user-defined details to the output window.
2+
3+
Author: EiNSTeiN_ <einstein@g3nius.org>
4+
5+
This is a rewrite in Python of the vds4 example that comes with hexrays sdk.
6+
"""
7+
8+
import idautils
9+
import idaapi
10+
import idc
11+
12+
import traceback
13+
14+
def run():
15+
16+
cfunc = idaapi.decompile(idaapi.get_screen_ea())
17+
if not cfunc:
18+
print 'Please move the cursor into a function.'
19+
return
20+
21+
entry_ea = cfunc.entry_ea
22+
print "Dump of user-defined information for function at %x" % (entry_ea, )
23+
24+
# Display user defined labels.
25+
labels = idaapi.restore_user_labels(entry_ea);
26+
if labels is not None:
27+
print "------- %u user defined labels" % (len(labels), )
28+
for org_label, name in labels.iteritems():
29+
print "Label %d: %s" % (org_label, str(name))
30+
idaapi.user_labels_free(labels)
31+
32+
# Display user defined comments
33+
cmts = idaapi.restore_user_cmts(entry_ea);
34+
if cmts is not None:
35+
print "------- %u user defined comments" % (len(cmts), )
36+
for tl, cmt in cmts.iteritems():
37+
print "Comment at %x, preciser %x:\n%s\n" % (tl.ea, tl.itp, str(cmt))
38+
idaapi.user_cmts_free(cmts)
39+
40+
# Display user defined citem iflags
41+
iflags = idaapi.restore_user_iflags(entry_ea)
42+
if iflags is not None:
43+
print "------- %u user defined citem iflags" % (len(iflags), )
44+
for cl, t in iflags.iteritems():
45+
print "%a(%d): %08X%s" % (cl.ea, cl.op, f, " CIT_COLLAPSED" if f & CIT_COLLAPSED else "")
46+
idaapi.user_iflags_free(iflags)
47+
48+
# Display user defined number formats
49+
numforms = idaapi.restore_user_numforms(entry_ea)
50+
if numforms is not None:
51+
print "------- %u user defined number formats" % (len(numforms), )
52+
for ol, nf in numforms.iteritems():
53+
54+
print "Number format at %a, operand %d: %s" % (ol.ea, ol.opnum, "negated " if (nf.props & NF_NEGATE) != 0 else "")
55+
56+
if nf.isEnum():
57+
print "enum %s (serial %d)" % (str(nf.type_name), nf.serial)
58+
59+
elif nf.isChar():
60+
print "char"
61+
62+
elif nf.isStroff():
63+
print "struct offset %s" % (str(nf.type_name), )
64+
65+
else:
66+
print "number base=%d" % (idaapi.getRadix(nf.flags, ol.opnum), )
67+
68+
idaapi.user_numforms_free(numforms)
69+
70+
# Display user-defined local variable information
71+
# First defined the visitor class
72+
class dump_lvar_info_t(idaapi.user_lvar_visitor_t):
73+
74+
def __init__(self):
75+
idaapi.user_lvar_visitor_t.__init__(self)
76+
self.displayed_header = False
77+
return
78+
79+
def get_info_qty_for_saving(self):
80+
return 0
81+
82+
def get_info_for_saving(self, lv):
83+
return False
84+
85+
def handle_retrieved_info(self, lv):
86+
87+
try:
88+
if not self.displayed_header:
89+
self.displayed_header = True;
90+
print "------- User defined local variable information"
91+
92+
print "Lvar defined at %x" % (lv.ll.defea, )
93+
94+
if len(str(lv.name)):
95+
print " Name: %s" % (str(lv.name), )
96+
97+
if len(str(lv.type)):
98+
#~ print_type_to_one_line(buf, sizeof(buf), idati, .c_str());
99+
print " Type: %s" % (str(lv.type), )
100+
101+
if len(str(lv.cmt)):
102+
print " Comment: %s" % (str(lv.cmt), )
103+
except:
104+
traceback.print_exc()
105+
return 0
106+
107+
def handle_retrieved_mapping(self, lm):
108+
return 0
109+
110+
def get_info_mapping_for_saving(self):
111+
return None
112+
113+
# Now iterate over all user definitions
114+
dli = dump_lvar_info_t();
115+
idaapi.restore_user_lvar_settings(entry_ea, dli)
116+
117+
return
118+
119+
120+
if idaapi.init_hexrays_plugin():
121+
run()
122+
else:
123+
print 'dump user info: hexrays is not available.'

examples/vds7.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
""" It demonstrates how to iterate a cblock_t object.
2+
3+
Author: EiNSTeiN_ <einstein@g3nius.org>
4+
5+
This is a rewrite in Python of the vds7 example that comes with hexrays sdk.
6+
"""
7+
8+
import idautils
9+
import idaapi
10+
import idc
11+
12+
import traceback
13+
14+
class cblock_visitor_t(idaapi.ctree_visitor_t):
15+
16+
def __init__(self):
17+
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST)
18+
return
19+
20+
def visit_insn(self, ins):
21+
22+
try:
23+
if ins.op == idaapi.cit_block:
24+
self.dump_block(ins.ea, ins.cblock)
25+
except:
26+
traceback.print_exc()
27+
28+
return 0
29+
30+
def dump_block(self, ea, b):
31+
# iterate over all block instructions
32+
print "dumping block %x" % (ea, )
33+
for ins in b:
34+
print " %x: insn %s" % (ins.ea, ins.opname)
35+
36+
return
37+
38+
class hexrays_callback_info(object):
39+
40+
def __init__(self):
41+
return
42+
43+
def event_callback(self, event, *args):
44+
45+
try:
46+
if event == idaapi.hxe_maturity:
47+
cfunc, maturity = args
48+
49+
if maturity == idaapi.CMAT_BUILT:
50+
cbv = cblock_visitor_t()
51+
cbv.apply_to(cfunc.body, None)
52+
53+
except:
54+
traceback.print_exc()
55+
56+
return 0
57+
58+
if idaapi.init_hexrays_plugin():
59+
i = hexrays_callback_info()
60+
idaapi.install_hexrays_callback(i.event_callback)
61+
else:
62+
print 'cblock visitor: hexrays is not available.'

0 commit comments

Comments
 (0)