/
stack_strings_helper.py
125 lines (91 loc) · 3.2 KB
/
stack_strings_helper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#
# Stack strings helper
# IDA's decompiler view shows stack strings in numerical form, a format highly unreadable.
# This script adds a popup menu entry to display them as characters, to quickly skim through them
#
# Tested with IDA 7+
#
import ida_hexrays
import ida_kernwin
import idaapi
import string
ACTION_NAME = "Stack strings"
# --------------------------------------------------------------------------
class char_converter_visitor_t(idaapi.ctree_visitor_t):
def __init__(self):
idaapi.ctree_visitor_t.__init__(self, idaapi.CV_FAST)
def visit_expr(self, expr):
"""
Search for simple assignents to stack vars
"""
if expr.op != ida_hexrays.cot_asg:
return 0
_x = expr.x
_y = expr.y
if _x.op == ida_hexrays.cot_var and _y.op == ida_hexrays.cot_num:
# Something like "v1 = 65"
num_value = _y.n.value(_y.type)
# Bail out soon
if num_value < 1 or num_value > 255:
return 0
if chr(num_value) not in string.printable:
return 0
# Create a new expr object to replace _y
# This will be of type cot_str
z = idaapi.cexpr_t()
# In order to modify an existing cexpr
# you have to swap it with a newly created one
z.swap(_y)
_y.op = ida_hexrays.cot_str
_y.string = chr(num_value)
return 0
# --------------------------------------------------------------------------
class stack_strings_ah_t(ida_kernwin.action_handler_t):
def __init__(self):
ida_kernwin.action_handler_t.__init__(self)
def activate(self, ctx):
vu = ida_hexrays.get_widget_vdui(ctx.widget)
# ----------------------------------------------
# Do something with the vdui (vu)
print "Analyzing decompiled code..."
cv = char_converter_visitor_t()
cv.apply_to(vu.cfunc.body, None)
vu.refresh_ctext()
return 1
def update(self, ctx):
return ida_kernwin.AST_ENABLE_FOR_WIDGET if \
ctx.widget_type == ida_kernwin.BWN_PSEUDOCODE else \
ida_kernwin.AST_DISABLE_FOR_WIDGET
def cb(event, *args):
if event == ida_hexrays.hxe_populating_popup:
widget, phandle, vu = args
res = idaapi.attach_action_to_popup(vu.ct, None, ACTION_NAME)
return 0
def show_banner():
print "-" * 60
print "CHAR CONVERTER"
print "Converts stack string assignments to char representation"
print
print "Example:"
print "v1 = 65 -> v1 = 'A'"
print "v2 = 66 -> v1 = 'B'"
print "..."
print "-" * 60
def main():
show_banner()
print "Unregistering old action..."
ida_kernwin.unregister_action(ACTION_NAME)
if ida_hexrays.init_hexrays_plugin():
ida_kernwin.register_action(
ida_kernwin.action_desc_t(
ACTION_NAME,
"Keep sanity (stack strings)",
stack_strings_ah_t(),
None))
print "Registered new action"
idaapi.install_hexrays_callback(cb)
else:
print "[x] No decompiler found!"
return
if __name__ == '__main__':
main()