-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuboo_rec.py
executable file
·169 lines (118 loc) · 3.92 KB
/
uboo_rec.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
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
169
#!/usr/bin/env python
# (C) navid@navid.it
import os
import sys
from stat import *
import pdb
import re
import commands
from optparse import OptionParser, Option
from time import sleep
from tempfile import gettempdir
__cmdParser__ = OptionParser()
__cmdParser__.add_option("-o", "--output", metavar="FILE", \
dest="dst", type = "string", \
help="output file")
__cmdParser__.add_option("-c", "--command", metavar="COMMAND", \
dest="cmd", type = "string", \
help="command to run")
(__cmdLineOpts__, __cmdLineArgs__) = __cmdParser__.parse_args()
if not __cmdLineOpts__.cmd:
print
print """Please specify a command. For example, to analyse a simple dd just run:"""
print
print '''\tubuu_rec -c "dd if=/dev/zero of=/tmp/testing123.dat bs=1k count=4"'''
print
sys.exit()
if not __cmdLineOpts__.dst:
__cmdLineOpts__.dst = "appdump.txt"
print """no output file specified, using "%s".""" % __cmdLineOpts__.dst
fp = open(__cmdLineOpts__.dst, "w")
re_c = re.compile(r"""^(?P<pid>\S+) (?P<timestamp>\S+)\s+(?P<syscall>\S+)\((?P<args>.*)\)\s*=\s*(?P<ret>\S+).*<(?P<time_elapsed>\S+)\>$""")
print
tmppipe = "%s/uboo-%d.pipe" % (gettempdir(), os.getpid())
os.mkfifo(tmppipe)
pid = os.fork()
if not pid:
sleep(1)
os.system('''/usr/bin/strace -q -o %s -T -e open,dup,fcntl,dup2,lseek,read,write,close,unlink,unlinkat -ttt -vv -s 0 -f %s''' % (tmppipe, __cmdLineOpts__.cmd) )
sys.exit()
r = open(tmppipe, "r")
fp.write("%cmdline\n")
fp.write("%s\n" % __cmdLineOpts__.cmd)
fp.write("%dump\n# timestamp,pid,syscall(args),return_value,time_elapsed\n")
fsizes = {}
fdmap = {}
unfinished_by_pid = {}
lines = 0
try:
while True:
line = r.readline()
if len(line) == 0:
break
xpos = line.find("""<unfinished ...>""")
if xpos > 0:
pid, unfinished_by_pid[pid] = line[:xpos].split(" ", 1)
continue
if line.find("""<... """) > 0:
pid = line.split(" ", 1)[0]
xpos = line.find(""" resumed>""")
line = pid + " " + unfinished_by_pid[pid] + line[xpos + len(""" resumed>"""):]
# continue
if not re_c.match(line):
print "cannot parse line: %s\n" % line
fp.write( "# cannot parse line: %s\n" % line)
continue
ret = re_c.findall(line)[0]
if not ret[re_c.groupindex['syscall']-1] in [ "open", "dup", "fcntl", "dup2", "lseek", "read", "write", "close", "unlink", "unlinkat" ]:
continue
pid = int(ret[re_c.groupindex['pid']-1])
syscall = ret[re_c.groupindex['syscall']-1]
args = ret[re_c.groupindex['args']-1]
x = []
for arg in args.split(","):
x.append( arg.strip(''' "''') )
args = "|".join(x)
fp.write( "%s,%s,%s|%s,%s,%s\n" % (ret[re_c.groupindex['timestamp']-1], pid, syscall, args, ret[re_c.groupindex['ret']-1], ret[re_c.groupindex['time_elapsed']-1]) )
lines += 1
if syscall == "open":
fname = args.split("|")[0]
# if not os.path.isfile(fname):
# continue
fdmap[int(ret[re_c.groupindex['ret']-1])] = fname
try: fsizes[fname] = os.stat(fname)[ST_SIZE]
except: fsizes[fname] = -1
elif not syscall in "unlink":
# all other syscalls take "fd" as their first argument
fd = int(args.split("|")[0])
if syscall == "close":
if fdmap.has_key(fd):
del fdmap[fd]
else:
fp.write( "# couldn't resolve fd %s\n" % (fd))
else:
if fdmap.has_key(fd):
continue
try: fname = os.readlink("/proc/%d/fd/%d" % (pid, fd))
except OSError:
fp.write( "# couldn't resolve fd %d for pid %d\n" % (fd, pid))
pass
# if not os.path.isfile(fname):
# continue
fdmap[fd] = fname
try: fsizes[fname] = os.stat(fname)[ST_SIZE]
except: fsizes[fname] = -1
except KeyboardInterrupt:
print "Keyboard interrupt."
pass
r.close()
os.unlink(tmppipe)
fp.write("%files\n# filename,size\n")
for fname in fsizes.keys():
fp.write( "%s|%s\n" % (fname, fsizes[fname]) )
status, output = commands.getstatusoutput("/bin/mount")
fp.write("%mounts\n" + output + "\n")
fp.close()
print
print "%s files used, %d operations captured." % ( len(fsizes), lines )
sys.exit()