Skip to content

Commit 59770f8

Browse files
committed
Optimised AFF4 handler dispatch. FileBackedObject is now able to search for
file under a specified PATH variable. Moved and updated the partition scanner.
1 parent c692de6 commit 59770f8

File tree

8 files changed

+182
-88
lines changed

8 files changed

+182
-88
lines changed

docs/benchmark.txt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
## This is a little note for me to keep track of performance.
2+
## All tests were made using --workers=3 on a dual core laptop. Tests
3+
## ran several times until the disk cache was primed.
4+
5+
rm *tdb; python utilities/Tester.py --uploaddir /var/tmp/uploads/testimages/ -f Live
6+
Ran 1 test in 26.99s
7+
Serializing 1.206 sec
8+
9+
Ran 1 test in 14.428s
10+
Volume closed in 1.27537703514
11+
12+
rm *tdb; python utilities/Tester.py --uploaddir /var/tmp/uploads/testimages/ -f YahooMail
13+
Ran 1 test in 14.179s
14+
15+
16+

src/plugins/AFF4/AFF4.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@
3535
PYFLAG_NS = "urn:pyflag:"
3636
PYFLAG_CASE = PYFLAG_NS + "case"
3737

38+
## Make sure the aff4 subsystem can only load files from the upload
39+
## dir:
40+
os.environ['AFF4_FILEPATH'] = "%s:%s" % (config.RESULTDIR, config.UPLOADDIR)
41+
3842
## Ensure that it does not get exported.
3943

4044
## These are the supported streams
@@ -73,10 +77,10 @@ def display(self, query, result):
7377

7478
loaded_volumes = []
7579

76-
for f in filenames:
80+
for filename in filenames:
7781
## Filenames are always specified relative to the upload
7882
## directory
79-
filename = "file://%s/%s" % (config.UPLOADDIR, f)
83+
#filename = "file://%s/%s" % (config.UPLOADDIR, f)
8084
volumes = aff4.load_volume(filename)
8185
result.row("%s" % volumes)
8286
loaded_volumes.extend(volumes)
@@ -144,8 +148,9 @@ class AFF4ResolverTable(FlagFramework.EventHandler):
144148
def create(self, dbh, case):
145149
""" Create a new case AFF4 Result file """
146150
volume = aff4.ZipVolume(None, 'w')
147-
filename = "file://%s/%s.aff4" % (config.RESULTDIR, case)
151+
filename = CacheManager.AFF4_MANAGER.make_volume_filename(case)
148152
aff4.oracle.set(volume.urn, aff4.AFF4_STORED, filename)
153+
aff4.oracle.set(filename, aff4.AFF4_CONTAINS, volume.urn)
149154
volume.finish()
150155
aff4.oracle.cache_return(volume)
151156

src/plugins/AFF4/Loader.py

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
""" This module presents lots of GUIs to build AFF4 objects.
2+
3+
This is not really necessary since aff4 tools can be used on the
4+
command line to do the same thing.
5+
6+
The basic result is that a new AFF4 object is created in the case
7+
volume
8+
"""
9+
import pyflag.Reports as Reports
10+
import pyflag.CacheManager as CacheManager
11+
import pyflag.aff4.aff4 as aff4
12+
import pyflag.FlagFramework as FlagFramework
13+
import pdb
14+
15+
class LoadVolume(Reports.report):
16+
""" Creates a new AFF4 object in the VFS. """
17+
name = 'Load Volume'
18+
family = 'Load Data'
19+
20+
def display(self, query, result):
21+
result.start_form(query)
22+
result.heading("Load Volume")
23+
self.render_form(query, result)
24+
result.end_form('Submit')
25+
26+
def render_form(self, query,result):
27+
try:
28+
if query["__submit__"]:
29+
new_fd = CacheManager.AFF4_MANAGER.create_cache_map(
30+
query['case'], FlagFramework.normpath(query['name']))
31+
32+
for f in query.getarray('files'):
33+
fd = aff4.oracle.open(f)
34+
new_fd.write_from(fd.urn, 0, fd.size)
35+
36+
new_fd.close()
37+
38+
except KeyError:
39+
result.fileselector("Select files to load", 'files')
40+
result.text("Files will be logically concatenated in the order selected")
41+
result.textfield("Name of object in VFS",'name')

src/plugins_old/DiskForensics/FileHandlers/Partitions.py src/plugins/DiskForensics/FileHandlers/Partitions.py

+14-10
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
class PartitionScanner(Scanner.GenScanFactory):
1515
""" Detects partitions in the image and creates VFS nodes for them.
1616
"""
17-
18-
def scan(self, fd, factories, type, mime):
17+
default = True
18+
group = "Disk Forensics"
19+
20+
def scan(self, fd, scanners, type, mime, cookie, scores=None, **args):
1921
if 'x86 boot sector' in type:
2022
try:
2123
parts = sk.mmls(fd)
@@ -34,7 +36,7 @@ def scan(self, fd, factories, type, mime):
3436
names.add(name)
3537
## Add new maps for each partition
3638
map = CacheManager.AFF4_MANAGER.create_cache_map(
37-
self.case,
39+
fd.case,
3840
"%s/%s" % (fd.urn, name))
3941

4042
map.write_from(fd.urn, SECTOR_SIZE * part[0],
@@ -43,24 +45,26 @@ def scan(self, fd, factories, type, mime):
4345
map.close()
4446

4547
## Now we recursively scan each object
46-
new_fd = self.fsfd.open(inode_id = map.inode_id)
48+
fsfd = FileSystem.DBFS(fd.case)
49+
new_fd = fsfd.open(inode_id = map.inode_id)
4750
try:
4851
fs = sk.skfs(new_fd)
4952
fs.close()
50-
dbh = DB.DBO(self.case)
53+
dbh = DB.DBO(fd.case)
5154
dbh.insert("type",
5255
inode_id = map.inode_id,
5356
mime = "application/filesystem",
5457
type = "Filesystem")
5558
except: pass
5659

57-
Scanner.scan_inode(self.case, map.inode_id,
58-
factories)
60+
Scanner.scan_inode_distributed(fd.case, map.inode_id,
61+
scanners, cookie)
5962

6063

6164
class FilesystemLoader(Scanner.GenScanFactory):
6265
""" A Scanner to automatically load filesystem """
63-
def scan(self, fd, factories, type, mime):
66+
def scan(self, fd, scanners, type, mime, cookie, scores=None, **args):
67+
pdb.set_trace()
6468
if 'Filesystem' in type:
6569
print "Will load %s" % fd.urn
6670

@@ -80,7 +84,7 @@ def create_map(skfs_inode, path):
8084
skfd.seek(0,2)
8185
size = skfd.tell()
8286
map = CacheManager.AFF4_MANAGER.create_cache_map(
83-
self.case,
87+
fd.case,
8488
"%s/__inodes__/%s" % (fd.urn, skfs_inode),
8589
size = size,
8690
status=status)
@@ -89,7 +93,7 @@ def create_map(skfs_inode, path):
8993
map.write_from(fd.urn, block * block_size, block_size)
9094

9195
CacheManager.AFF4_MANAGER.create_link(
92-
self.case,
96+
fd.case,
9397
map.urn, DB.expand("%s/%s",(fd.urn, path)))
9498
map.close()
9599

src/plugins/Flash/BasicCommands.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,8 @@ def execute(self):
618618

619619
m = Magic.MagicResolver()
620620
for inode_id in self.args:
621-
type, mime = m.find_inode_magic(case = self.environment._CASE, inode_id=inode_id)
621+
type, mime, scores = m.find_inode_magic(
622+
case = self.environment._CASE, inode_id=inode_id)
622623

623624
yield dict(type=type, mime = mime)
624625

src/pyflag/CacheManager.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,29 @@ def close(self):
154154
class AFF4Manager:
155155
""" A Special Cache manager which maintains the main AFF4 Cache
156156
"""
157+
def make_volume_filename(self, case):
158+
return "%s.aff4" % (case)
159+
160+
def create_volume(self, case):
161+
""" Create a new case AFF4 Result file """
162+
volume = aff4.ZipVolume(None, 'w')
163+
filename = self.make_volume_filename(case)
164+
aff4.oracle.set(volume.urn, aff4.AFF4_STORED, filename)
165+
aff4.oracle.set(filename, aff4.AFF4_CONTAINS, volume.urn)
166+
volume.finish()
167+
aff4.oracle.cache_return(volume)
168+
169+
return volume.urn
170+
157171
def make_volume_urn(self, case):
158-
volume_path = "file://%s/%s.aff4" % (config.RESULTDIR, case)
172+
volume_path = self.make_volume_filename(case)
159173
volume_urn = aff4.oracle.resolve(volume_path, aff4.AFF4_CONTAINS)
160174

175+
if not volume_urn:
176+
## Volume does not exist - we need to make a new one for
177+
## this case:
178+
return self.create_volume(case)
179+
161180
return volume_urn
162181

163182
def close(self, case):

src/pyflag/Scanner.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class GenScanFactory:
7676
## Relative order of scanners - Higher numbers come later in the order
7777
order=10
7878

79-
def scan(self, fd, scanners, type, mime, cookie):
79+
def scan(self, fd, scanners, type, mime, cookie, scores=None):
8080
""" This is the new scan method - scanners just implement this
8181
method and go from there.
8282

0 commit comments

Comments
 (0)