Autopsy  4.21.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
PlatformUtil.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2012-2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.coreutils;
20 
21 import java.io.BufferedInputStream;
22 import java.io.BufferedOutputStream;
23 import java.io.BufferedReader;
24 import java.io.File;
25 import java.io.FileInputStream;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.io.OutputStream;
31 import java.lang.management.ManagementFactory;
32 import java.lang.management.MemoryMXBean;
33 import java.lang.management.MemoryUsage;
34 import java.nio.charset.Charset;
35 import java.nio.charset.StandardCharsets;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.HashMap;
41 import java.util.List;
42 import java.util.Map;
43 import java.util.regex.Pattern;
44 import java.util.stream.Stream;
45 import javax.swing.filechooser.FileSystemView;
46 import org.apache.commons.io.FilenameUtils;
47 import org.apache.commons.io.IOUtils;
48 import org.openide.modules.InstalledFileLocator;
49 import org.openide.modules.Places;
50 import org.openide.util.NbBundle;
51 import org.sleuthkit.datamodel.SleuthkitJNI;
52 import org.sleuthkit.datamodel.TskCoreException;
53 
58 public class PlatformUtil {
59 
60  private static final String PYTHON_MODULES_SUBDIRECTORY = "python_modules"; //NON-NLS
61  private static final String CLASSIFIERS_SUBDIRECTORY = "object_detection_classifiers"; //NON-NLS
62  private static final String OCR_LANGUAGE_SUBDIRECTORY = "ocr_language_packs"; //NON-NLS
63  private static final String OCR_LANGUAGE_PACK_EXT = "traineddata";
64  private static String javaPath = null;
65  public static final String OS_NAME_UNKNOWN = NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.nameUnknown");
66  public static final String OS_VERSION_UNKNOWN = NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.verUnknown");
67  public static final String OS_ARCH_UNKNOWN = NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.archUnknown");
68  private static volatile long pid = -1;
69  private static volatile MemoryMXBean memoryManager = null;
70 
76  public static String getInstallPath() {
77  File coreFolder = InstalledFileLocator.getDefault().locate("core", PlatformUtil.class.getPackage().getName(), false); //NON-NLS
78  File rootPath = coreFolder.getParentFile().getParentFile();
79  return rootPath.getAbsolutePath();
80  }
81 
88  public static String getInstallModulesPath() {
89  File coreFolder = InstalledFileLocator.getDefault().locate("core", PlatformUtil.class.getPackage().getName(), false); //NON-NLS
90 
91  File rootPath = coreFolder.getParentFile();
92  String modulesPath = rootPath.getAbsolutePath() + File.separator + "modules"; //NON-NLS
93  File modulesPathF = new File(modulesPath);
94  if (modulesPathF.exists() && modulesPathF.isDirectory()) {
95  return modulesPath;
96  } else {
97  rootPath = rootPath.getParentFile();
98  modulesPath = rootPath.getAbsolutePath() + File.separator + "modules"; //NON-NLS
99  modulesPathF = new File(modulesPath);
100  if (modulesPathF.exists() && modulesPathF.isDirectory()) {
101  return modulesPath;
102  } else {
103  return null;
104  }
105  }
106 
107  }
108 
115  public static String getUserModulesPath() {
116  return getUserDirectory().getAbsolutePath() + File.separator + "modules"; //NON-NLS
117  }
118 
124  public static String getUserPythonModulesPath() {
125  return getUserDirectory().getAbsolutePath() + File.separator + PYTHON_MODULES_SUBDIRECTORY;
126  }
127 
133  public static String getOcrLanguagePacksPath() {
134  return getUserDirectory().getAbsolutePath() + File.separator + OCR_LANGUAGE_SUBDIRECTORY;
135  }
136 
142  public static List<String> getOcrLanguagePacks() {
143  File languagePackRootDir = new File(getOcrLanguagePacksPath());
144 
145  List<String> languagePacks = new ArrayList<>();
146  for (File languagePack : languagePackRootDir.listFiles()) {
147  String fileExt = FilenameUtils.getExtension(languagePack.getName());
148  if (!languagePack.isDirectory() && OCR_LANGUAGE_PACK_EXT.equals(fileExt)) {
149  String packageName = FilenameUtils.getBaseName(languagePack.getName());
150  languagePacks.add(packageName);
151  }
152  }
153 
154  return languagePacks;
155  }
156 
162  public static String getObjectDetectionClassifierPath() {
163  return getUserDirectory().getAbsolutePath() + File.separator + CLASSIFIERS_SUBDIRECTORY;
164  }
165 
173  public synchronized static String getJavaPath() {
174  if (javaPath != null) {
175  return javaPath;
176  }
177 
178  // by default, use Java that came with Autopsy
179  File jrePath = new File(getInstallPath() + File.separator + "jre");
180  if (jrePath.exists() && jrePath.isDirectory()) {
181  System.out.println(
182  NbBundle.getMessage(PlatformUtil.class,
183  "PlatformUtil.jrePath.jreDir.msg",
184  jrePath.getAbsolutePath()));
185  javaPath = jrePath.getAbsolutePath() + File.separator + "bin" + File.separator + "java"; //NON-NLS
186  } else if (System.getProperty("java.home") != null && !(System.getProperty("java.home").isEmpty())) {
187  // if OS knows where Java is located
188  return System.getProperty("java.home") + File.separator + "bin" + File.separator + "java"; //NON-NLS
189  } else {
190  //else use system installed java in PATH env variable
191  javaPath = "java"; //NON-NLS
192  }
193 
194  System.out.println(NbBundle.getMessage(PlatformUtil.class, "PlatformUtil.jrePath.usingJavaPath.msg", javaPath));
195 
196  return javaPath;
197  }
198 
205  public static File getUserDirectory() {
206  return Places.getUserDirectory();
207  }
208 
214  public static List<String> getProjectsDirs() {
215  List<String> ret = new ArrayList<>();
216  String projectDir = System.getProperty("netbeans.dirs");
217  if (projectDir == null) {
218  return ret;
219  }
220  String[] split = projectDir.split(";");
221  if (split == null || split.length == 0) {
222  return ret;
223  }
224  ret.addAll(Arrays.asList(split));
225 
226  return ret;
227  }
228 
234  public static String getUserConfigDirectory() {
235  return Places.getUserDirectory() + File.separator + "config"; //NON-NLS
236  }
237 
243  public static String getModuleConfigDirectory() {
244  return Paths.get(getUserConfigDirectory(), "ModuleConfig").toString();
245  }
246 
252  public static String getLogDirectory() {
253  return Places.getUserDirectory().getAbsolutePath() + File.separator
254  + "var" + File.separator + "log" + File.separator; //NON-NLS
255  }
256 
257  public static String getDefaultPlatformFileEncoding() {
258  return System.getProperty("file.encoding");
259  }
260 
261  public static String getDefaultPlatformCharset() {
262  return Charset.defaultCharset().name();
263  }
264 
265  public static String getLogFileEncoding() {
266  return Charset.forName("UTF-8").name();
267  }
268 
283  public static <T> boolean extractResourceToUserConfigDir(final Class<T> resourceClass, final String resourceFileName, boolean overWrite) throws IOException {
284  Path resourceFilePath = Paths.get(getUserConfigDirectory(), resourceFileName);
285  final File resourceFile = resourceFilePath.toFile();
286  if (resourceFile.exists() && !overWrite) {
287  return false;
288  }
289 
290  InputStream inputStream = resourceClass.getResourceAsStream(resourceFileName);
291  if (null == inputStream) {
292  return false;
293  }
294 
295  resourceFile.getParentFile().mkdirs();
296  try (InputStream in = new BufferedInputStream(inputStream)) {
297  try (OutputStream out = new BufferedOutputStream(new FileOutputStream(resourceFile))) {
298  int readBytes;
299  while ((readBytes = in.read()) != -1) {
300  out.write(readBytes);
301  }
302  }
303  }
304  return true;
305  }
306 
312  public static String getOSName() {
313  return System.getProperty("os.name", OS_NAME_UNKNOWN); //NON-NLS
314  }
315 
321  public static String getOSVersion() {
322  return System.getProperty("os.version", OS_VERSION_UNKNOWN); //NON-NLS
323  }
324 
330  public static String getOSArch() {
331  return System.getProperty("os.arch", OS_ARCH_UNKNOWN); //NON-NLS
332  }
333 
339  public static boolean isWindowsOS() {
340  return PlatformUtil.getOSName().toLowerCase().contains("windows"); //NON-NLS
341  }
342 
350  public static String getOSFilePath(String origFilePath) {
351  if (isWindowsOS()) {
352  return "\"" + origFilePath + "\"";
353  } else {
354  return origFilePath;
355  }
356  }
357 
365  public static boolean is64BitOS() {
366  if (System.getProperty("os.name").contains("Windows")) { //NON-NLS
367  return (System.getenv("ProgramFiles(x86)") != null); //NON-NLS
368  } else {
369  return (System.getProperty("os.arch").contains("64")); //NON-NLS
370  }
371  }
372 
379  public static boolean is64BitJVM() {
380  return (System.getProperty("sun.arch.data.model").equals("64"));
381  }
382 
389  public static List<LocalDisk> getPhysicalDrives() {
390  List<LocalDisk> drives = new ArrayList<>();
391  // Windows drives
392  if (PlatformUtil.isWindowsOS()) {
393  int n = 0;
394  int breakCount = 0;
395  while (true) {
396  String path = "\\\\.\\PhysicalDrive" + n; //NON-NLS
397  if (canReadDrive(path)) {
398  try {
399  drives.add(new LocalDisk("Drive " + n, path, SleuthkitJNI.findDeviceSize(path))); //NON-NLS
400  } catch (TskCoreException ex) {
401  // Don't add the drive because we can't read the size
402  }
403  n++;
404  } else {
405  if (breakCount > 4) { // Give up after 4 non-existent drives
406  break;
407  }
408  breakCount++;
409  n++;
410  }
411  }
412  // Linux drives
413  } else {
414  File dev = new File("/dev/");
415  File[] files = dev.listFiles();
416  for (File f : files) {
417  String name = f.getName();
418  if ((name.contains("hd") || name.contains("sd") || name.contains("disk")) && f.canRead() && name.length() <= 5) { //NON-NLS
419  String path = "/dev/" + name; //NON-NLS
420  if (canReadDrive(path)) {
421  try {
422  drives.add(new LocalDisk(path, path, SleuthkitJNI.findDeviceSize(path)));
423  } catch (TskCoreException ex) {
424  // Don't add the drive because we can't read the size
425  }
426  }
427  }
428  }
429 
430  }
431  return drives;
432  }
433 
440  public static List<LocalDisk> getPartitions() {
441  List<LocalDisk> drives = new ArrayList<>();
442  FileSystemView fsv = FileSystemView.getFileSystemView();
443  if (PlatformUtil.isWindowsOS()) {
444  File[] f = File.listRoots();
445  for (File f1 : f) {
446  String name = fsv.getSystemDisplayName(f1);
447  // Check if it is a drive, readable, and not mapped to the network
448  if (f1.canRead() && !name.contains("\\\\") && (fsv.isDrive(f1) || fsv.isFloppyDrive(f1))) {
449  String path = f1.getPath();
450  String diskPath = "\\\\.\\" + path.substring(0, path.length() - 1);
451  if (canReadDrive(diskPath)) {
452  drives.add(new LocalDisk(fsv.getSystemDisplayName(f1), diskPath, f1.getTotalSpace()));
453  }
454  }
455  }
456  } else {
457  File dev = new File("/dev/");
458  File[] files = dev.listFiles();
459  for (File f : files) {
460  String name = f.getName();
461  if ((name.contains("hd") || name.contains("sd") || name.contains("disk")) && f.canRead() && name.length() <= 7) { //NON-NLS
462  String path = "/dev/" + name; //NON-NLS
463  if (canReadDrive(path)) {
464  drives.add(new LocalDisk(path, path, f.getTotalSpace()));
465  }
466  }
467  }
468  }
469  return drives;
470  }
471 
487  private static boolean canReadDrive(String diskPath) {
488  BufferedInputStream br = null;
489  try {
490  File tmp = new File(diskPath);
491  br = new BufferedInputStream(new FileInputStream(tmp));
492  int b = br.read();
493  return b != -1;
494  } catch (IOException ex) {
495  return false;
496  } finally {
497  try {
498  if (br != null) {
499  br.close();
500  }
501  } catch (IOException ex) {
502  }
503  }
504  }
505 
511  public static synchronized long getPID() {
512  // taken from https://stackoverflow.com/a/7303433/2375948
513  return ProcessHandle.current().pid();
514  }
515 
526  public static synchronized long getJavaPID(String sigarSubQuery) {
527  long[] pids = getJavaPIDs(sigarSubQuery);
528  return pids == null || pids.length < 1
529  ? -1
530  : pids[0];
531  }
532 
540  private static String convertSqlLikeToRegex(String originalLikeStatement) {
541  if (originalLikeStatement == null) {
542  return "";
543  }
544 
545  Map<Character, String> likeEscapeSequences = new HashMap<>() {
546  {
547  put('%', ".*");
548  put('_', ".");
549  }
550  };
551 
552  String regexQuoted = Pattern.quote(originalLikeStatement);
553  char[] charArr = regexQuoted.toCharArray();
554  StringBuilder sb = new StringBuilder();
555 
556  for (int i = 0; i < charArr.length; i++) {
557  char curChar = charArr[i];
558  String regexReplacement = likeEscapeSequences.get(curChar);
559  if (regexReplacement == null) {
560  sb.append(curChar);
561  } else {
562  Character nextChar = charArr.length > i + 1 ? charArr[i + 1] : null;
563  if (nextChar != null && curChar == nextChar) {
564  sb.append(curChar);
565  i++;
566  } else {
567  sb.append(regexReplacement);
568  }
569  }
570  }
571 
572  return sb.toString();
573  }
574 
583  public static synchronized long[] getJavaPIDs(String argsSubQuery) {
584  try {
585  if (isWindowsOS()) {
586 
587  ProcessBuilder pb = new ProcessBuilder("wmic process where \"name='java.exe' AND commandline LIKE '%" + argsSubQuery + "%'\" get ProcessID");
588  String output = IOUtils.toString(pb.start().getInputStream(), StandardCharsets.UTF_8);
589  String[] lines = output.split("\\r?\\n");
590 
591  return Stream.of(lines).skip(1).map(ln -> {
592  if (ln == null || ln.trim().isEmpty()) {
593  return null;
594  }
595 
596  try {
597  return Long.parseLong(ln.trim());
598  } catch (NumberFormatException ex) {
599  return null;
600  }
601  })
602  .filter(num -> num != null)
603  .mapToLong(l -> l)
604  .toArray();
605 
606  } else {
607  String sigarRegexQuery = convertSqlLikeToRegex(argsSubQuery);
608  ProcessBuilder pb = new ProcessBuilder("sh", "-c", "ps -ef | grep -E 'java.*" + sigarRegexQuery + ".*'");
609  String output = IOUtils.toString(pb.start().getInputStream(), StandardCharsets.UTF_8);
610  List<String> lines = Arrays.asList(output.split("\\r?\\n"));
611 
612  if (lines.size() > 0) {
613  // ignore last one as it will be the same as this command
614  lines.remove(lines.size() - 1);
615  }
616 
617  return lines.stream().skip(1).map(ln -> {
618  if (ln == null || ln.trim().isEmpty()) {
619  return null;
620  }
621 
622  ln = ln.trim();
623 
624  String[] pieces = ln.split("\\s*");
625  if (pieces.length < 2) {
626  return null;
627  }
628 
629  try {
630  return Long.parseLong(pieces[1]);
631  } catch (NumberFormatException ex) {
632  return null;
633  }
634  })
635  .filter(num -> num != null)
636  .mapToLong(l -> l)
637  .toArray();
638  }
639  } catch (IOException ex) {
640  System.out.println("An exception occurred while fetching java pids with query: " + argsSubQuery + " with IO Exception: " + ex.getMessage());
641  ex.printStackTrace();
642  return null;
643  }
644  }
645 
651  public static synchronized void killProcess(long pid) {
652  String cmd = isWindowsOS()
653  ? "taskkill /F /PID " + pid
654  : "kill " + pid;
655 
656  try {
657  Runtime.getRuntime().exec(cmd);
658  } catch (IOException ex) {
659  System.out.println("An exception occurred while killing process pid: " + pid);
660  ex.printStackTrace();
661  }
662  }
663 
669  public static synchronized long getProcessVirtualMemoryUsed() {
670  // taken from https://stackoverflow.com/a/17376879/2375948
671  return Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
672  }
673 
679  public static String getJvmMemInfo() {
680  synchronized (PlatformUtil.class) {
681  if (memoryManager == null) {
682  memoryManager = ManagementFactory.getMemoryMXBean();
683  }
684  }
685  final MemoryUsage heap = memoryManager.getHeapMemoryUsage();
686  final MemoryUsage nonHeap = memoryManager.getNonHeapMemoryUsage();
687 
688  return NbBundle.getMessage(PlatformUtil.class,
689  "PlatformUtil.getJvmMemInfo.usageText",
690  heap.toString(), nonHeap.toString());
691  }
692 
698  public static String getPhysicalMemInfo() {
699  final Runtime runTime = Runtime.getRuntime();
700  final long maxMemory = runTime.maxMemory();
701  final long totalMemory = runTime.totalMemory();
702  final long freeMemory = runTime.freeMemory();
703  return NbBundle.getMessage(PlatformUtil.class,
704  "PlatformUtil.getPhysicalMemInfo.usageText",
705  Long.toString(maxMemory), Long.toString(totalMemory), Long.toString(freeMemory));
706  }
707 
713  public static String getAllMemUsageInfo() {
714  return NbBundle.getMessage(PlatformUtil.class,
715  "PlatformUtil.getAllMemUsageInfo.usageText",
718  }
719 }
static synchronized long[] getJavaPIDs(String argsSubQuery)
static synchronized void killProcess(long pid)
static synchronized long getProcessVirtualMemoryUsed()
static String convertSqlLikeToRegex(String originalLikeStatement)
static boolean canReadDrive(String diskPath)
static List< LocalDisk > getPhysicalDrives()
static String getOSFilePath(String origFilePath)
static< T > boolean extractResourceToUserConfigDir(final Class< T > resourceClass, final String resourceFileName, boolean overWrite)
static synchronized long getJavaPID(String sigarSubQuery)
static volatile MemoryMXBean memoryManager
static synchronized String getJavaPath()

Copyright © 2012-2022 Basis Technology. Generated on: Tue Feb 6 2024
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.