22 package org.sleuthkit.autopsy.recentactivity;
24 import java.io.BufferedReader;
26 import java.io.FileInputStream;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.io.InputStreamReader;
30 import java.nio.charset.StandardCharsets;
31 import java.text.ParseException;
32 import java.text.SimpleDateFormat;
33 import java.util.ArrayList;
34 import java.util.List;
35 import java.util.Locale;
36 import java.util.logging.Level;
42 class ShellBagParser {
43 private static final Logger logger = Logger.
getLogger(ShellBagParser.class.getName());
45 private static final SimpleDateFormat DATE_TIME_FORMATTER =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault());
47 private static final SimpleDateFormat DATE_TIME_FORMATTER2 =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyyy", Locale.getDefault());
49 private ShellBagParser() {
62 static List<ShellBag> parseShellbagOutput(String regFilePath)
throws FileNotFoundException, IOException {
63 List<ShellBag> shellbags =
new ArrayList<>();
64 File regfile =
new File(regFilePath);
66 ShellBagParser sbparser =
new ShellBagParser();
68 try (BufferedReader reader =
new BufferedReader(
new InputStreamReader(
new FileInputStream(regfile), StandardCharsets.UTF_8))) {
69 String line = reader.readLine();
70 while (line != null) {
73 if (line.matches(
"^shellbags_xp v.*")) {
74 shellbags.addAll(sbparser.parseShellBagsXP(reader));
75 }
else if (line.matches(
"^shellbags v.*")) {
76 shellbags.addAll(sbparser.parseShellBags(reader));
77 }
else if (line.matches(
"^itempos.*")) {
78 shellbags.addAll(sbparser.parseItempos(reader));
81 line = reader.readLine();
97 List<ShellBag> parseShellBagsXP(BufferedReader reader)
throws IOException {
98 List<ShellBag> shellbags =
new ArrayList<>();
99 String line = reader.readLine();
101 while (line != null && !isSectionSeparator(line)) {
103 if (isShellbagXPDataLine(line)) {
104 String[] tokens = line.split(
"\\|");
105 if (tokens.length >= 6) {
106 shellbags.add(
new ShellBag(tokens[5].trim(),
"Software\\Microsoft\\Windows\\ShellNoRoam\\BagMRU", tokens[0].trim(), tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
110 line = reader.readLine();
124 List<ShellBag> parseShellBags(BufferedReader reader)
throws IOException {
125 List<ShellBag> shellbags =
new ArrayList<>();
126 String line = reader.readLine();
127 String regPath =
"Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU";
129 while (line != null && !isSectionSeparator(line)) {
131 if (isShellbagDataLine(line)) {
132 String[] tokens = line.split(
"\\|");
133 String path = tokens[6].replaceAll(
"\\[.*?\\]",
"").trim();
134 int index = line.lastIndexOf(
'[');
135 String endstuff =
"";
137 endstuff = line.substring(index, line.length() - 1).replace(
"[Desktop",
"");
139 if (tokens.length >= 7) {
140 shellbags.add(
new ShellBag(path, regPath + endstuff, tokens[0].trim(), tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
144 line = reader.readLine();
159 List<ShellBag> parseItempos(BufferedReader reader)
throws IOException {
160 List<ShellBag> shellbags =
new ArrayList<>();
162 String lastWrite =
"";
163 String line = reader.readLine();
165 while (line != null && !isSectionSeparator(line)) {
167 if (isItemposDataLine(line)) {
168 String[] tokens = line.split(
"\\|");
169 if (tokens.length >= 5) {
170 shellbags.add(
new ShellBag(tokens[4].trim(), bagpath, lastWrite, tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
172 }
else if (line.contains(
"Software\\")) {
173 bagpath = line.trim();
175 }
else if (line.contains(
"LastWrite:")) {
176 lastWrite = line.replace(
"LastWrite:",
"").trim();
179 line = reader.readLine();
197 boolean isSectionSeparator(String line) {
198 if (line == null || line.isEmpty()) {
202 return line.trim().matches(
"^-+");
214 boolean isItemposDataLine(String line) {
215 return line.matches(
"^\\d*?\\s*?\\|.*?\\|.*?\\|.*?\\|.*?");
229 boolean isShellbagXPDataLine(String line) {
230 return line.matches(
"^(\\d+?.*?\\s*? | \\s*?)\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?");
244 boolean isShellbagDataLine(String line) {
245 return line.matches(
"^(\\d+?.*?\\s*? | \\s*?)\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?");
254 private final String resource;
255 private final String key;
256 private final String lastWrite;
257 private final String modified;
258 private final String accessed;
259 private final String created;
273 ShellBag(String resource, String key, String lastWrite, String modified, String accessed, String created) {
274 this.resource = resource;
276 this.lastWrite = lastWrite;
277 this.accessed = accessed;
278 this.modified = modified;
279 this.created = created;
287 String getResource() {
288 return resource == null ?
"" : resource;
297 return key == null ?
"" : key;
306 long getLastWrite() {
307 return parseDateTime(lastWrite);
317 return parseDateTime(modified);
327 return parseDateTime(accessed);
337 return parseDateTime(created);
348 long parseDateTime(String dateTimeString) {
349 if (!dateTimeString.isEmpty()) {
351 return DATE_TIME_FORMATTER.parse(dateTimeString).getTime() / 1000;
352 }
catch (ParseException ex) {
357 return DATE_TIME_FORMATTER2.parse(dateTimeString).getTime() / 1000;
358 }
catch (ParseException ex) {
359 logger.log(Level.WARNING, String.format(
"ShellBag parse failure. %s is not formated as expected.", dateTimeString), ex);
synchronized static Logger getLogger(String name)