@@ -47,4 +47,42 @@ async def write_excel(records: List[MftRecord], output_file: str) -> None:
4747 for record in records :
4848 ws .append (record .to_csv ())
4949 wb .save (output_file )
50- await asyncio .sleep (0 )
50+ await asyncio .sleep (0 )
51+
52+ @staticmethod
53+ async def write_body (records : List [MftRecord ], output_file : str ) -> None :
54+ with open (output_file , 'w' , encoding = 'utf-8' ) as bodyfile :
55+ for record in records :
56+ # Format: MD5|name|inode|mode_as_string|UID|GID|size|atime|mtime|ctime|crtime
57+ bodyfile .write (f"0|{ record .filename } |{ record .recordnum } |{ record .flags :04o} |0|0|"
58+ f"{ record .filesize } |{ record .fn_times ['atime' ].unixtime } |"
59+ f"{ record .fn_times ['mtime' ].unixtime } |{ record .fn_times ['ctime' ].unixtime } |"
60+ f"{ record .fn_times ['crtime' ].unixtime } \n " )
61+ await asyncio .sleep (0 )
62+
63+ @staticmethod
64+ async def write_timeline (records : List [MftRecord ], output_file : str ) -> None :
65+ with open (output_file , 'w' , encoding = 'utf-8' ) as timeline :
66+ for record in records :
67+ # Format: Time|Source|Type|User|Host|Short|Desc|Version|Filename|Inode|Notes|Format|Extra
68+ timeline .write (f"{ record .fn_times ['crtime' ].unixtime } |MFT|CREATE|||||{ record .filename } |{ record .recordnum } ||||\n " )
69+ timeline .write (f"{ record .fn_times ['mtime' ].unixtime } |MFT|MODIFY|||||{ record .filename } |{ record .recordnum } ||||\n " )
70+ timeline .write (f"{ record .fn_times ['atime' ].unixtime } |MFT|ACCESS|||||{ record .filename } |{ record .recordnum } ||||\n " )
71+ timeline .write (f"{ record .fn_times ['ctime' ].unixtime } |MFT|CHANGE|||||{ record .filename } |{ record .recordnum } ||||\n " )
72+ await asyncio .sleep (0 )
73+
74+ @staticmethod
75+ async def write_l2t (records : List [MftRecord ], output_file : str ) -> None :
76+ with open (output_file , 'w' , newline = '' , encoding = 'utf-8' ) as l2tfile :
77+ writer = csv .writer (l2tfile )
78+ writer .writerow (['date' , 'time' , 'timezone' , 'MACB' , 'source' , 'sourcetype' , 'type' , 'user' , 'host' , 'short' , 'desc' , 'version' , 'filename' , 'inode' , 'notes' , 'format' , 'extra' ])
79+ for record in records :
80+ for time_type , time_obj in record .fn_times .items ():
81+ macb = 'M' if time_type == 'mtime' else 'A' if time_type == 'atime' else 'C' if time_type == 'ctime' else 'B'
82+ date_str = time_obj .dt .strftime ('%m/%d/%Y' ) if time_obj .dt else ''
83+ time_str = time_obj .dt .strftime ('%H:%M:%S' ) if time_obj .dt else ''
84+ writer .writerow ([
85+ date_str , time_str , 'UTC' , macb , 'MFT' , 'FILESYSTEM' , time_type , '' , '' , '' ,
86+ f"{ record .filename } { time_type } " , '' , record .filename , record .recordnum , '' , '' , ''
87+ ])
88+ await asyncio .sleep (0 )
0 commit comments