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

Commit 7eb6d04

Browse files
author
elias.bachaalany@gmail.com
committed
Contributed by EiNSTeiN_:
- Fixed compilation error on Linux - Minor bugfix in hexrays.i - Added two more samples: vds3.py and vds_xrefs.py
1 parent db58b31 commit 7eb6d04

4 files changed

Lines changed: 491 additions & 6 deletions

File tree

examples/vds3.py

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
""" Invert the then and else blocks of a cif_t.
2+
3+
Author: EiNSTeiN_ <einstein@g3nius.org>
4+
5+
This is a rewrite in Python of the vds3 example that comes with hexrays sdk.
6+
7+
8+
The main difference with the original C code is that when we create the inverted
9+
condition object, the newly created cexpr_t instance is given to the hexrays and
10+
must not be freed by swig. To achieve this, we have to change the 'thisown' flag
11+
when appropriate. See http://www.swig.org/Doc1.3/Python.html#Python_nn35
12+
13+
"""
14+
15+
import idautils
16+
import idaapi
17+
import idc
18+
19+
import traceback
20+
21+
NETNODE_NAME = '$ hexrays-inverted-if'
22+
23+
class hexrays_callback_info(object):
24+
25+
def __init__(self):
26+
self.vu = None
27+
28+
self.node = idaapi.netnode()
29+
if not self.node.create(NETNODE_NAME):
30+
# node exists
31+
self.load()
32+
else:
33+
self.stored = []
34+
35+
return
36+
37+
def load(self):
38+
39+
self.stored = []
40+
41+
try:
42+
data = self.node.getblob(0, 'I')
43+
if data:
44+
self.stored = eval(data)
45+
print 'Invert-if: Loaded %s' % (repr(self.stored), )
46+
except:
47+
print 'Failed to load invert-if locations'
48+
traceback.print_exc()
49+
return
50+
51+
return
52+
53+
def save(self):
54+
55+
try:
56+
self.node.setblob(repr(self.stored), 0, 'I')
57+
except:
58+
print 'Failed to save invert-if locations'
59+
traceback.print_exc()
60+
return
61+
62+
return
63+
64+
def invert_if(self, cfunc, insn):
65+
66+
if insn.opname != 'if':
67+
return False
68+
69+
cif = insn.details
70+
71+
if not cif.ithen or not cif.ielse:
72+
return False
73+
74+
idaapi.qswap(cif.ithen, cif.ielse)
75+
cond = idaapi.cexpr_t(cif.expr)
76+
notcond = idaapi.lnot(cond)
77+
cond.thisown = 0 # the new wrapper 'notcond' now holds the reference to the cexpr_t
78+
79+
cif.expr.swap(notcond)
80+
81+
return True
82+
83+
def add_location(self, ea):
84+
if ea in self.stored:
85+
self.stored.remove(ea)
86+
else:
87+
self.stored.append(ea)
88+
self.save()
89+
return
90+
91+
def invert_if_event(self, vu):
92+
93+
vu.get_current_item(idaapi.USE_KEYBOARD)
94+
item = vu.item
95+
96+
cfunc = vu.cfunc.__deref__()
97+
98+
if item.citype != idaapi.VDI_EXPR:
99+
return False
100+
101+
if self.invert_if(cfunc, item.it.to_specific_type):
102+
vu.refresh_ctext()
103+
104+
self.add_location(item.it.ea)
105+
106+
return True
107+
108+
def restore(self, cfunc):
109+
110+
#~ print 'restoring invert-if for %x' % (cfunc.entry_ea, )
111+
112+
str(cfunc) # generate treeitems.
113+
114+
restored = False
115+
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, )
124+
125+
return restored
126+
127+
def menu_callback(self):
128+
try:
129+
self.invert_if_event(self.vu)
130+
except:
131+
traceback.print_exc()
132+
return 0
133+
134+
def event_callback(self, event, *args):
135+
136+
try:
137+
if event == idaapi.hxe_keyboard:
138+
vu, keycode, shift = args
139+
140+
if idaapi.lookup_key_code(keycode, shift, True) == idaapi.get_key_code("I") and shift == 0:
141+
if self.invert_if_event(vu):
142+
return 1
143+
144+
elif event == idaapi.hxe_right_click:
145+
self.vu = args[0]
146+
idaapi.add_custom_viewer_popup_item(self.vu.ct, "Invert then/else", "I", self.menu_callback)
147+
148+
elif event == idaapi.hxe_maturity:
149+
cfunc, maturity = args
150+
151+
if maturity == idaapi.CMAT_FINAL:
152+
self.restore(cfunc)
153+
except:
154+
traceback.print_exc()
155+
156+
return 0
157+
158+
if idaapi.init_hexrays_plugin():
159+
i = hexrays_callback_info()
160+
idaapi.install_hexrays_callback(i.event_callback)
161+
else:
162+
print 'invert-if: hexrays is not available.'

0 commit comments

Comments
 (0)