Repository navigation
Expand file tree
/
Copy pathfunctionUse.py
More file actions
executable file
·168 lines (150 loc) · 5.61 KB
/
Copy pathfunctionUse.py
File metadata and controls
executable file
·168 lines (150 loc) · 5.61 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/python
import blockDB
import sys
import re
import os
#import kazoo
import fnmatch
import socket
import logging
here = '/mnt/cgcsvn/cgc/users/mft/zk/py'
if here not in sys.path:
sys.path.append(here)
import szk
import configMgr
import utils
class functionUse():
functions = []
max_depth = 0
cur_depth = 0
previous = 'start'
current = None
previous = None
stack = []
biggest = []
block_db = None
class function():
def __init__(self, name, address, level):
self.name = name
self.address = address
self.level = level
self.calls = []
self.recurs_list = []
self.recurs = False
def __init__(self, operation_file, block_db_file):
self.block_db = blockDB.blockDB(block_db_file)
self.of = open(operation_file, 'r')
for line in self.of:
parts = line.split()
if parts[2] == 'start':
fun = self.function(parts[3], parts[4], 0)
self.functions.append(fun)
self.current = fun
elif parts[2] == 'call':
self.stack.append(self.current)
fun = self.getFunction(parts[3])
if fun is None:
fun = self.function(parts[3], parts[4], 0)
self.functions.append(fun)
if self.current is not None and fun.name not in self.current.calls:
self.current.calls.append(fun.name)
if fun in self.stack:
print 'recurs from %s to %s' % (self.current.name, fun.name)
#for fun in self.stack:
# print fun.name
self.current.recurs_list.append(fun)
self.current = fun
self.cur_depth += 1
if self.cur_depth > self.max_depth:
self.max_depth = self.cur_depth
self.biggest = list(self.stack)
self.previous = self.current
elif parts[2] == 'return':
if self.cur_depth > 0:
self.cur_depth -= 1
self.current = self.stack.pop()
def getFunction(self, name):
for fun in self.functions:
if fun.name == name:
return fun
return None
def numFunctions(self):
print len(self.functions)
print 'max depth %d' % self.max_depth
def listCalls(self):
for fun in self.functions:
print '%s:%d %s' % (fun.name, fun.level, ' '.join([str(item) for item in fun.calls]))
def dumpfile(self, fname):
f = open(fname, 'w')
for fun in self.functions:
bfun = self.block_db.getFunction(int(fun.address,16))
if bfun is not None:
print 'write function %s' % fun.name
f.write('%s %d %d %s\n' % (fun.name, fun.level, len(bfun.blocks), fun.address))
else:
print 'NO function found in db for %s (%s)' % (fun.address, fun.name)
exit(1)
f.close()
def assignLongest(self):
i = 1
for function in self.biggest:
print 'function %s gets level %d' % (function.name, i)
function.level = i
i += 1
def cycleAll(self):
self.assignLongest()
done = False
zeros = 99
while not done:
done = True
zeros = 0
for function in self.functions:
if function.level > 0:
for call in function.calls:
called = self.getFunction(call)
if called in function.recurs_list:
if called.level == 0:
called.level = function.level
else:
print '%s calls up to %s, do not adjust' % (function.name, called.name)
else:
print 'function %s of level %d calls %s of level %d' % (function.name,
function.level, called.name, called.level)
if called.level <= function.level:
called.level = function.level+1
print 'adjust %s to be %d' % (called.name,called.level)
done = False
else:
zeros += 1
print 'looped %d zeros' % zeros
self.functions = sorted(self.functions, key=lambda function: function.level)
viz_project = '/Volumes/disk2/cgc/cgc/users/mft/simics/visualization/datasets'
block_file = None
ops_file = None
fun_file = None
if len(sys.argv) == 3:
replay = sys.argv[1]
cb_bin = sys.argv[2]
hostname = socket.gethostname()
cfg = configMgr.configMgr()
zk = szk.szk(hostname, cfg, cb_dir='/mnt/vmLib/cgcArtifacts')
common = utils.getCommonName(cb_bin)
path, cb = zk.replayPathFromNameArtifacts(replay, common)
art_path = os.path.dirname(path)
cb_path = zk.pathFromName(common)
block_file = os.path.join(os.path.dirname(cb_path),'ida', cb_bin, 'blocks.txt')
ops_file = os.path.join(art_path, cb_bin,'operation.txt')
#viz_path = vizUtils.getVizPath(viz_project, replay, cb_bin)
fun_file = os.path.join(art_path, cb_bin,'functionList.txt')
elif len(sys.argv) >= 4:
block_file = sys.argv[1]
ops_file = sys.argv[2]
fun_file = sys.argv[3]
else:
print 'functionUse.py replay cb_bin'
exit(1)
fu = functionUse(ops_file, block_file)
fu.numFunctions()
fu.cycleAll()
#fu.listCalls()
fu.dumpfile(fun_file)