libprefetch/lib.rs
1// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2// Version 2, December 2004
3//
4// Copyright (C) 2018 Thomas Bailleux <thomas@bailleux.me>
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10// DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11// TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13// 0. You just DO WHAT THE FUCK YOU WANT TO.
14//
15// Author: zadig <thomas chr(0x40) bailleux.me>
16
17//! A forensic library which parses and reads Microsoft Prefetch files.
18//!
19//! `libprefetch` fully supports the following versions of Windows:
20//! * Windows 2003
21//! * Windows XP
22//! * Windows Vista
23//! * Windows 7
24//! * Windows 8/8.1
25//!
26//! `libprefetch` **partially supports** Windows 10.
27//!
28//! Features:
29//! * Parser and validator
30//! * Auto detects version of Windows
31//! * Provides the last execution time and the execution counter
32//! * Provides metric information about loaded files (like dll etc) **if available**, such as :
33//! * filename
34//! * start time
35//! * duration
36//! * average duration
37//! * NTFS MFT entry
38//! * NTFS sequence numer
39//! * Provides the trace chains (**unavailable for Windows 10**)
40//! * Provides all pieces of information about the volumes:
41//! * device path
42//! * creation time
43//! * serial number
44//! * list of directories
45//!
46//! This library will be used in a global forensic computing library very soon.
47//!
48//! ## Example
49//!
50//! ```rust
51//! use libprefetch::Prefetch;
52//!
53//! let file = std::fs::File::open("assets/WUAUCLT.EXE-399A8E72.pf").unwrap();
54//!
55//! let prefetch = Prefetch::new(file).unwrap();
56//!
57//! // Prints some information
58//! println!("Executable {} launched {} times. The last time was: {}",
59//! prefetch.name(),
60//! prefetch.execution_counter(),
61//! prefetch.last_execution_time() // TODO: format the FILETIME here
62//! );
63//!
64//! // Iterates over all loaded DLL etc for the prefetch file
65//! println!(" ===== File metrics ===== ");
66//! for metric in prefetch.metrics().unwrap() {
67//! println!("#{}: {}", metric.id(), metric.filename());
68//! println!(" start time: {}", metric.start_time().unwrap());
69//! println!(" duration: {}", metric.duration().unwrap());
70//! println!(" ------------------------------- ");
71//! }
72//!
73//! // Iterates over the volumes
74//! println!(" ===== Volumes ===== ");
75//! for volume in prefetch.volumes().unwrap() {
76//! println!("Volume #{}:", volume.id());
77//! println!(" Path: {}", volume.device_path());
78//! println!(" Creation time: {}", volume.creation_time());
79//! println!(" Serial number: {}", volume.serial_number());
80//! println!(" Directories: ");
81//! for directory in volume.directories().unwrap() {
82//! println!(" {}", directory);
83//! }
84//! }
85//!
86//!
87//! ```
88//!
89//! ## Releases
90//!
91//! Release notes are available in [RELEASES.md](RELEASES.md).
92//!
93//! ## Compatibility
94//!
95//! `libprefetch` seems to work for rust 1.9 and greater.
96mod prefetch;
97mod parser;
98mod error;
99mod constants;
100mod header;
101mod util;
102pub mod iterator;
103pub mod metric;
104pub mod trace;
105pub mod volume;
106
107pub(crate) use error::Result;
108pub use prefetch::{FormatVersion, Prefetch};
109pub use error::Error;
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 fn prelude() -> prefetch::Prefetch {
116 let f =
117 std::fs::File::open("assets/WUAUCLT.EXE-399A8E72.pf").unwrap();
118 let p = prefetch::Prefetch::new(f).unwrap();
119
120 p
121 }
122
123 #[test]
124 fn header() {
125 let p = prelude();
126 assert_eq!(129453035816965472, p.last_execution_time());
127 assert_eq!(38, p.execution_counter());
128 }
129
130 #[test]
131 fn metrics() {
132 let p = prelude();
133 for metric in p.metrics().unwrap() {
134 println!("metric={:?}", metric);
135 }
136 }
137
138 #[test]
139 fn trace() {
140 let p = prelude();
141 for trace in p.trace().unwrap() {
142 println!("trace={:?}", trace);
143 }
144 }
145
146 #[test]
147 fn volumes() {
148 let p = prelude();
149 for volume in p.volumes().unwrap() {
150 println!("volume={:?}", volume);
151 }
152 }
153
154 #[test]
155 fn volumes_directories() {
156 let p = prelude();
157 for volume in p.volumes().unwrap() {
158 for d in volume.directories().unwrap() {
159 println!("directories={:?}", d);
160 }
161 }
162 }
163
164 #[test]
165 fn readme() {
166 let file = std::fs::File::open("assets/WUAUCLT.EXE-399A8E72.pf").unwrap();
167
168 let prefetch = Prefetch::new(file).unwrap();
169
170 // Prints some information
171 println!("Executable {} launched {} times. The last time was: {}",
172 prefetch.name(),
173 prefetch.execution_counter(),
174 prefetch.last_execution_time() // TODO: format the MSTIME here
175 );
176
177 // Iterates over all loaded DLL etc for the prefetch file
178 println!(" ===== File metrics ===== ");
179 for metric in prefetch.metrics().unwrap() {
180 println!("#{}: {}", metric.id(), metric.filename());
181 println!(" start time: {}", metric.start_time().unwrap());
182 println!(" duration: {}", metric.duration().unwrap());
183 println!(" ------------------------------- ");
184 }
185
186 // Iterates over the volumes
187 println!(" ===== Volumes ===== ");
188 for volume in prefetch.volumes().unwrap() {
189 println!("Volume #{}:", volume.id());
190 println!(" Path: {}", volume.device_path());
191 println!(" Creation time: {}", volume.creation_time());
192 println!(" Serial number: {}", volume.serial_number());
193 println!(" Directories: ");
194 for directory in volume.directories().unwrap() {
195 println!(" {}", directory);
196 }
197 }
198 }
199}