22 package org.sleuthkit.autopsy.recentactivity;
24 import java.io.BufferedReader;
25 import java.io.FileReader;
27 import java.io.FileNotFoundException;
28 import java.io.IOException;
29 import java.text.ParseException;
30 import java.text.SimpleDateFormat;
31 import java.util.ArrayList;
32 import java.util.List;
33 import java.util.Locale;
34 import java.util.logging.Level;
40 class ShellBagParser {
41 private static final Logger logger = Logger.
getLogger(ShellBagParser.class.getName());
43 private static final SimpleDateFormat DATE_TIME_FORMATTER =
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss", Locale.getDefault());
45 private static final SimpleDateFormat DATE_TIME_FORMATTER2 =
new SimpleDateFormat(
"EEE MMM dd HH:mm:ss yyyyy", Locale.getDefault());
47 private ShellBagParser() {
60 static List<ShellBag> parseShellbagOutput(String regFilePath)
throws FileNotFoundException, IOException {
61 List<ShellBag> shellbags =
new ArrayList<>();
62 File regfile =
new File(regFilePath);
64 ShellBagParser sbparser =
new ShellBagParser();
66 try (BufferedReader reader =
new BufferedReader(
new FileReader(regfile))) {
67 String line = reader.readLine();
68 while (line != null) {
71 if (line.matches(
"^shellbags_xp v.*")) {
72 shellbags.addAll(sbparser.parseShellBagsXP(reader));
73 }
else if (line.matches(
"^shellbags v.*")) {
74 shellbags.addAll(sbparser.parseShellBags(reader));
75 }
else if (line.matches(
"^itempos.*")) {
76 shellbags.addAll(sbparser.parseItempos(reader));
79 line = reader.readLine();
95 List<ShellBag> parseShellBagsXP(BufferedReader reader)
throws IOException {
96 List<ShellBag> shellbags =
new ArrayList<>();
97 String line = reader.readLine();
99 while (line != null && !isSectionSeparator(line)) {
101 if (isShellbagXPDataLine(line)) {
102 String[] tokens = line.split(
"\\|");
103 if (tokens.length >= 6) {
104 shellbags.add(
new ShellBag(tokens[5].trim(),
"Software\\Microsoft\\Windows\\ShellNoRoam\\BagMRU", tokens[0].trim(), tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
108 line = reader.readLine();
122 List<ShellBag> parseShellBags(BufferedReader reader)
throws IOException {
123 List<ShellBag> shellbags =
new ArrayList<>();
124 String line = reader.readLine();
125 String regPath =
"Local Settings\\Software\\Microsoft\\Windows\\Shell\\BagMRU";
127 while (line != null && !isSectionSeparator(line)) {
129 if (isShellbagDataLine(line)) {
130 String[] tokens = line.split(
"\\|");
131 String path = tokens[6].replaceAll(
"\\[.*?\\]",
"").trim();
132 int index = line.lastIndexOf(
'[');
133 String endstuff =
"";
135 endstuff = line.substring(index, line.length() - 1).replace(
"[Desktop",
"");
137 if (tokens.length >= 7) {
138 shellbags.add(
new ShellBag(path, regPath + endstuff, tokens[0].trim(), tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
142 line = reader.readLine();
157 List<ShellBag> parseItempos(BufferedReader reader)
throws IOException {
158 List<ShellBag> shellbags =
new ArrayList<>();
160 String lastWrite =
"";
161 String line = reader.readLine();
163 while (line != null && !isSectionSeparator(line)) {
165 if (isItemposDataLine(line)) {
166 String[] tokens = line.split(
"\\|");
167 if (tokens.length >= 5) {
168 shellbags.add(
new ShellBag(tokens[4].trim(), bagpath, lastWrite, tokens[1].trim(), tokens[2].trim(), tokens[3].trim()));
170 }
else if (line.contains(
"Software\\")) {
171 bagpath = line.trim();
173 }
else if (line.contains(
"LastWrite:")) {
174 lastWrite = line.replace(
"LastWrite:",
"").trim();
177 line = reader.readLine();
195 boolean isSectionSeparator(String line) {
196 if (line == null || line.isEmpty()) {
200 return line.trim().matches(
"^-+");
212 boolean isItemposDataLine(String line) {
213 return line.matches(
"^\\d*?\\s*?\\|.*?\\|.*?\\|.*?\\|.*?");
227 boolean isShellbagXPDataLine(String line) {
228 return line.matches(
"^(\\d+?.*?\\s*? | \\s*?)\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?");
242 boolean isShellbagDataLine(String line) {
243 return line.matches(
"^(\\d+?.*?\\s*? | \\s*?)\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?\\|.*?");
252 private final String resource;
253 private final String key;
254 private final String lastWrite;
255 private final String modified;
256 private final String accessed;
257 private final String created;
271 ShellBag(String resource, String key, String lastWrite, String modified, String accessed, String created) {
272 this.resource = resource;
274 this.lastWrite = lastWrite;
275 this.accessed = accessed;
276 this.modified = modified;
277 this.created = created;
285 String getResource() {
286 return resource == null ?
"" : resource;
295 return key == null ?
"" : key;
304 long getLastWrite() {
305 return parseDateTime(lastWrite);
315 return parseDateTime(modified);
325 return parseDateTime(accessed);
335 return parseDateTime(created);
346 long parseDateTime(String dateTimeString) {
347 if (!dateTimeString.isEmpty()) {
349 return DATE_TIME_FORMATTER.parse(dateTimeString).getTime() / 1000;
350 }
catch (ParseException ex) {
355 return DATE_TIME_FORMATTER2.parse(dateTimeString).getTime() / 1000;
356 }
catch (ParseException ex) {
357 logger.log(Level.WARNING, String.format(
"ShellBag parse failure. %s is not formated as expected.", dateTimeString), ex);
synchronized static Logger getLogger(String name)