Skip to content

Commit

Permalink
Adds body file, timeline, l2t back. Closes Files not marked as delete…
Browse files Browse the repository at this point in the history
…d in bodyfile output #33 Data run calculations are wrong? #21 Investigate update sequence numbers #9 Datarun oddity #16 Additional rules #46
  • Loading branch information
rowingdude committed Sep 4, 2024
1 parent 2ee4d83 commit cef6594
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
10 changes: 8 additions & 2 deletions src/analyzeMFT/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import asyncio
from optparse import OptionParser
from optparse import OptionParser, OptionGroup
import sys
from .mft_analyzer import MftAnalyzer
from .constants import VERSION
Expand All @@ -21,6 +21,12 @@ async def main():
help="Export as XML")
export_group.add_option("--excel", action="store_const", const="excel", dest="export_format",
help="Export as Excel")
export_group.add_option("--body", action="store_const", const="body", dest="export_format",
help="Export as body file (for mactime)")
export_group.add_option("--timeline", action="store_const", const="timeline", dest="export_format",
help="Export as TSK timeline")
export_group.add_option("--l2t", action="store_const", const="l2t", dest="export_format",
help="Export as log2timeline CSV")
parser.add_option_group(export_group)

parser.add_option("-d", "--debug", action="store_true", dest="debug",
Expand All @@ -35,7 +41,7 @@ async def main():
sys.exit(1)

if not options.export_format:
options.export_format = "csv"
options.export_format = "csv" # Default to CSV if no format specified

analyzer = MftAnalyzer(options.filename, options.output_file, options.debug, options.compute_hashes, options.export_format)
await analyzer.analyze()
Expand Down
40 changes: 39 additions & 1 deletion src/analyzeMFT/file_writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,42 @@ async def write_excel(records: List[MftRecord], output_file: str) -> None:
for record in records:
ws.append(record.to_csv())
wb.save(output_file)
await asyncio.sleep(0)
await asyncio.sleep(0)

@staticmethod
async def write_body(records: List[MftRecord], output_file: str) -> None:
with open(output_file, 'w', encoding='utf-8') as bodyfile:
for record in records:
# Format: MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime
bodyfile.write(f"0|{record.filename}|{record.recordnum}|{record.flags:04o}|0|0|"
f"{record.filesize}|{record.fn_times['atime'].unixtime}|"
f"{record.fn_times['mtime'].unixtime}|{record.fn_times['ctime'].unixtime}|"
f"{record.fn_times['crtime'].unixtime}\n")
await asyncio.sleep(0)

@staticmethod
async def write_timeline(records: List[MftRecord], output_file: str) -> None:
with open(output_file, 'w', encoding='utf-8') as timeline:
for record in records:
# Format: Time|Source|Type|User|Host|Short|Desc|Version|Filename|Inode|Notes|Format|Extra
timeline.write(f"{record.fn_times['crtime'].unixtime}|MFT|CREATE|||||{record.filename}|{record.recordnum}||||\n")
timeline.write(f"{record.fn_times['mtime'].unixtime}|MFT|MODIFY|||||{record.filename}|{record.recordnum}||||\n")
timeline.write(f"{record.fn_times['atime'].unixtime}|MFT|ACCESS|||||{record.filename}|{record.recordnum}||||\n")
timeline.write(f"{record.fn_times['ctime'].unixtime}|MFT|CHANGE|||||{record.filename}|{record.recordnum}||||\n")
await asyncio.sleep(0)

@staticmethod
async def write_l2t(records: List[MftRecord], output_file: str) -> None:
with open(output_file, 'w', newline='', encoding='utf-8') as l2tfile:
writer = csv.writer(l2tfile)
writer.writerow(['date', 'time', 'timezone', 'MACB', 'source', 'sourcetype', 'type', 'user', 'host', 'short', 'desc', 'version', 'filename', 'inode', 'notes', 'format', 'extra'])
for record in records:
for time_type, time_obj in record.fn_times.items():
macb = 'M' if time_type == 'mtime' else 'A' if time_type == 'atime' else 'C' if time_type == 'ctime' else 'B'
date_str = time_obj.dt.strftime('%m/%d/%Y') if time_obj.dt else ''
time_str = time_obj.dt.strftime('%H:%M:%S') if time_obj.dt else ''
writer.writerow([
date_str, time_str, 'UTC', macb, 'MFT', 'FILESYSTEM', time_type, '', '', '',
f"{record.filename} {time_type}", '', record.filename, record.recordnum, '', '', ''
])
await asyncio.sleep(0)

0 comments on commit cef6594

Please sign in to comment.