Sleuth Kit Java Bindings (JNI)  4.10.2
Java bindings for using The Sleuth Kit
Image.java
Go to the documentation of this file.
1 /*
2  * Sleuth Kit Data Model
3  *
4  * Copyright 2011-2018 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.datamodel;
20 
21 import java.text.MessageFormat;
22 import java.util.ResourceBundle;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28 import java.io.File;
29 import java.sql.ResultSet;
30 import java.sql.SQLException;
31 import java.sql.Statement;
32 
39 public class Image extends AbstractContent implements DataSource {
40  //data about image
41 
42  private final long type, ssize;
43  private long size;
44  private final String[] paths;
45  private volatile long imageHandle = 0;
46  private volatile Host host = null;
47  private final String deviceId, timezone;
48  private String md5, sha1, sha256;
49  private static ResourceBundle bundle = ResourceBundle.getBundle("org.sleuthkit.datamodel.Bundle");
50 
51  private static final Logger LOGGER = Logger.getLogger(Image.class.getName());
52 
71  @Deprecated
72  protected Image(SleuthkitCase db, long obj_id, long type, long ssize, String name, String[] paths, String timezone, String md5) throws TskCoreException {
73  super(db, obj_id, name);
74  this.deviceId = "";
75  this.type = type;
76  this.ssize = ssize;
77  this.paths = paths;
78  this.timezone = timezone;
79  this.size = 0;
80  this.md5 = md5;
81  this.sha1 = "";
82  this.sha256 = "";
83  }
84 
101  Image(SleuthkitCase db, long obj_id, long type, String deviceId, long ssize, String name, String[] paths, String timezone,
102  String md5, String sha1, String sha256, long size) throws TskCoreException {
103  super(db, obj_id, name);
104  this.deviceId = deviceId;
105  this.type = type;
106  this.ssize = ssize;
107  this.paths = paths;
108  this.timezone = timezone;
109  this.size = size;
110  this.md5 = md5;
111  this.sha1 = sha1;
112  this.sha256 = sha256;
113  }
114 
122  public synchronized long getImageHandle() throws TskCoreException {
123  if (paths.length == 0) {
124  throw new TskCoreException("Image has no associated paths");
125  }
126 
127  if (imageHandle == 0) {
128  imageHandle = SleuthkitJNI.openImage(paths, (int)ssize, getSleuthkitCase());
129  }
130 
131  return imageHandle;
132  }
133 
134  synchronized void setImageHandle(long imageHandle) {
135  this.imageHandle = imageHandle;
136  }
137 
138  @Override
140  return this;
141  }
142 
143  @Override
144  public void close() {
145  //frees nothing, as we are caching image handles
146  }
147 
148  @Override
149  public void finalize() throws Throwable {
150  try {
151  if (imageHandle != 0) {
152  // SleuthkitJNI.closeImg(imageHandle); // closeImg is currently a no-op
153  imageHandle = 0;
154  }
155  } finally {
156  super.finalize();
157  }
158  }
159 
160  @Override
161  public int read(byte[] buf, long offset, long len) throws TskCoreException {
162  // If there are no paths, don't attempt to read the image
163  if (paths.length == 0) {
164  return 0;
165  }
166 
167  // read from the image
168  return SleuthkitJNI.readImg(getImageHandle(), buf, offset, len);
169  }
170 
171  @Override
172  public long getSize() {
173  if (size == 0) {
174  try {
175  if (paths.length > 0) {
176  //should always had at least one path
177  size = SleuthkitJNI.findDeviceSize(paths[0]);
178  }
179  } catch (TskCoreException ex) {
180  Logger.getLogger(Image.class.getName()).log(Level.SEVERE, "Could not find image size, image: " + this.getId(), ex); //NON-NLS
181  }
182  }
183  return size;
184  }
185 
186  //Methods for retrieval of meta-data attributes
193  return TskData.TSK_IMG_TYPE_ENUM.valueOf(type);
194  }
195 
201  public long getSsize() {
202  return ssize;
203  }
204 
205  @Override
206  public String getUniquePath() throws TskCoreException {
207  return "/img_" + getName(); //NON-NLS
208  }
209 
215  public String[] getPaths() {
216  return paths;
217  }
218 
224  public List<VolumeSystem> getVolumeSystems() throws TskCoreException {
225 
226  List<Content> children = getChildren();
227  List<VolumeSystem> vs = new ArrayList<VolumeSystem>();
228  for (Content child : children) {
229  if (child instanceof VolumeSystem) {
230  vs.add((VolumeSystem) child);
231  }
232  }
233 
234  return vs;
235  }
236 
242  public List<Volume> getVolumes() throws TskCoreException {
243 
244  List<Content> children = getChildren();
245  List<Volume> volumes = new ArrayList<Volume>();
246  for (Content child : children) {
247  if (child instanceof Volume) {
248  volumes.add((Volume) child);
249  }
250  }
251 
252  return volumes;
253  }
254 
262  public List<FileSystem> getFileSystems() throws TskCoreException {
263  List<FileSystem> fs = new ArrayList<>();
264  fs.addAll(getSleuthkitCase().getImageFileSystems(this));
265  return fs;
266  }
267 
273  @Override
274  public String getTimeZone() {
275  return timezone;
276  }
277 
278  @Override
279  public <T> T accept(SleuthkitItemVisitor<T> v) {
280  return v.visit(this);
281  }
282 
283  @Override
284  public <T> T accept(ContentVisitor<T> v) {
285  return v.visit(this);
286  }
287 
288  @Override
289  public List<Content> getChildren() throws TskCoreException {
290  return getSleuthkitCase().getImageChildren(this);
291  }
292 
293  @Override
294  public List<Long> getChildrenIds() throws TskCoreException {
295  return getSleuthkitCase().getImageChildrenIds(this);
296  }
297 
298  @Override
299  public String toString(boolean preserveState) {
300  return super.toString(preserveState) + "Image [\t" + "\t" + "paths " + Arrays.toString(paths) + "\t" + "size " + size + "\t" + "ssize " + ssize + "\t" + "timezone " + timezone + "\t" + "type " + type + "]\t"; //NON-NLS
301  }
302 
309  public Boolean imageFileExists() {
310  if (paths.length > 0) {
311  File imageFile = new File(paths[0]);
312  return imageFile.exists();
313  }
314 
315  return false;
316  }
317 
325  public String verifyImageSize() {
326  Logger logger1 = Logger.getLogger("verifyImageSizes"); //NON-NLS
327  String errorString = "";
328  try {
329  List<VolumeSystem> volumeSystems = getVolumeSystems();
330  for (VolumeSystem vs : volumeSystems) {
331  List<Volume> volumes = vs.getVolumes();
332  for (Volume v : volumes) {
333  byte[] buf = new byte[512];
334  long endOffset = (v.getStart() + v.getLength()) * 512 - 512;
335  try {
336  int readBytes = read(buf, endOffset, 512);
337  if (readBytes < 0) {
338  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}", endOffset); //NON-NLS
339  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr1.text"), endOffset);
340  }
341  } catch (TskCoreException ex) {
342  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
343  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr2.text"), endOffset);
344  }
345  }
346  }
347 
348  List<FileSystem> fileSystems = getFileSystems();
349  for (FileSystem fs : fileSystems) {
350  long block_size = fs.getBlock_size();
351  long endOffset = fs.getImageOffset() + fs.getSize() - block_size;
352  try {
353  byte[] buf = new byte[(int) block_size];
354  int readBytes = read(buf, endOffset, block_size);
355  if (readBytes < 0) {
356  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}", endOffset); //NON-NLS
357  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr3.text"), endOffset);
358  }
359  } catch (TskCoreException ex) {
360  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
361  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr4.text"), endOffset);
362  }
363  }
364  } catch (TskException ex) {
365  // do nothing if we got an exception from trying to get file systems and volume systems
366  }
367  return errorString;
368  }
369 
377  public String getMd5() throws TskCoreException {
378  if (md5 == null || md5.isEmpty()) {
379  md5 = getSleuthkitCase().getMd5ImageHash(this);
380  }
381  return md5;
382  }
383 
391  public String getSha1() throws TskCoreException {
392  if (sha1 == null || sha1.isEmpty()) {
393  sha1 = getSleuthkitCase().getSha1ImageHash(this);
394  }
395  return sha1;
396  }
397 
405  public String getSha256() throws TskCoreException {
406  if (sha256 == null || sha256.isEmpty()) {
407  sha256 = getSleuthkitCase().getSha256ImageHash(this);
408  }
409  return sha256;
410  }
411 
418  public void setMD5(String md5) throws TskCoreException, TskDataException {
419  if (getMd5().isEmpty() == false) {
420  throw new TskDataException("MD5 value has already been set");
421  }
422  getSleuthkitCase().setMd5ImageHash(this, md5);
423  this.md5 = md5;
424  }
425 
432  public void setSha1(String sha1) throws TskCoreException, TskDataException {
433  if (getSha1().isEmpty() == false) {
434  throw new TskDataException("SHA1 value has already been set");
435  }
436  getSleuthkitCase().setSha1ImageHash(this, sha1);
437  this.sha1 = sha1;
438  }
439 
446  public void setSha256(String sha256) throws TskCoreException, TskDataException {
447  if (getSha256().isEmpty() == false) {
448  throw new TskDataException("SHA256 value has already been set");
449  }
450  getSleuthkitCase().setSha256ImageHash(this, sha256);
451  this.sha256 = sha256;
452  }
453 
461  @Override
462  public String getDeviceId() {
463  return deviceId;
464  }
465 
473  @Override
474  public void setDisplayName(String newName) throws TskCoreException {
475  this.getSleuthkitCase().setImageName(newName, getId());
476  }
477 
493  @Override
494  public long getContentSize(SleuthkitCase sleuthkitCase) throws TskCoreException {
495  SleuthkitCase.CaseDbConnection connection;
496  Statement statement = null;
497  ResultSet resultSet = null;
498  long contentSize = 0;
499 
500  connection = sleuthkitCase.getConnection();
501 
502  try {
503  statement = connection.createStatement();
504  resultSet = connection.executeQuery(statement, "SELECT SUM (size) FROM tsk_image_info WHERE tsk_image_info.obj_id = " + getId());
505  if (resultSet.next()) {
506  contentSize = resultSet.getLong("sum");
507  }
508  } catch (SQLException ex) {
509  throw new TskCoreException(String.format("There was a problem while querying the database for size data for object ID %d.", getId()), ex);
510  } finally {
511  closeResultSet(resultSet);
512  closeStatement(statement);
513  connection.close();
514  }
515 
516  return contentSize;
517  }
518 
526  @Override
527  public void setAcquisitionDetails(String details) throws TskCoreException {
528  getSleuthkitCase().setAcquisitionDetails(this, details);
529  }
530 
541  @Override
542  public void setAcquisitionToolDetails(String name, String version, String settings) throws TskCoreException {
543  getSleuthkitCase().setAcquisitionToolDetails(this, name, version, settings);
544  }
545 
553  public String getAcquisitionToolSettings() throws TskCoreException {
554  return getSleuthkitCase().getDataSourceInfoString(this, "acquisition_tool_settings");
555  }
556 
564  public String getAcquisitionToolName() throws TskCoreException{
565  return getSleuthkitCase().getDataSourceInfoString(this, "acquisition_tool_name");
566  }
567 
575  public String getAcquisitionToolVersion() throws TskCoreException {
576  return getSleuthkitCase().getDataSourceInfoString(this, "acquisition_tool_version");
577  }
578 
586  public Long getDateAdded() throws TskCoreException {
587  return getSleuthkitCase().getDataSourceInfoLong(this, "added_date_time");
588  }
589 
597  @Override
598  public String getAcquisitionDetails() throws TskCoreException {
599  return getSleuthkitCase().getAcquisitionDetails(this);
600  }
601 
609  @Override
610  public Host getHost() throws TskCoreException {
611  // This is a check-then-act race condition that may occasionally result
612  // in additional processing but is safer than using locks.
613  if (host == null) {
615  }
616  return host;
617  }
618 
632  public void setSizes(long totalSize, long sectorSize) throws TskCoreException {
633  getSleuthkitCase().setImageSizes(this, totalSize, sectorSize);
634  }
635 
641  private static void closeResultSet(ResultSet resultSet) {
642  if (resultSet != null) {
643  try {
644  resultSet.close();
645  } catch (SQLException ex) {
646  LOGGER.log(Level.SEVERE, "Error closing ResultSet", ex); //NON-NLS
647  }
648  }
649  }
650 
656  private static void closeStatement(Statement statement) {
657  if (statement != null) {
658  try {
659  statement.close();
660  } catch (SQLException ex) {
661  LOGGER.log(Level.SEVERE, "Error closing Statement", ex); //NON-NLS
662  }
663  }
664  }
665 }
static int readImg(long imgHandle, byte[] readBuffer, long offset, long len)
Host getHostByDataSource(DataSource dataSource)
List< Volume > getVolumes()
Definition: Image.java:242
List< FileSystem > getFileSystems()
Definition: Image.java:262
void setAcquisitionToolDetails(String name, String version, String settings)
Definition: Image.java:542
void setAcquisitionDetails(String details)
Definition: Image.java:527
Image(SleuthkitCase db, long obj_id, long type, long ssize, String name, String[] paths, String timezone, String md5)
Definition: Image.java:72
void setSha1(String sha1)
Definition: Image.java:432
static long openImage(String[] imageFiles, SleuthkitCase skCase)
TskData.TSK_IMG_TYPE_ENUM getType()
Definition: Image.java:192
List< Long > getChildrenIds()
Definition: Image.java:294
int read(byte[] buf, long offset, long len)
Definition: Image.java:161
String getAcquisitionToolVersion()
Definition: Image.java:575
void setSizes(long totalSize, long sectorSize)
Definition: Image.java:632
static long findDeviceSize(String devPath)
void setDisplayName(String newName)
Definition: Image.java:474
List< Content > getChildren()
Definition: Image.java:289
void setMD5(String md5)
Definition: Image.java:418
List< VolumeSystem > getVolumeSystems()
Definition: Image.java:224
void setSha256(String sha256)
Definition: Image.java:446
static TSK_IMG_TYPE_ENUM valueOf(long imgType)
Definition: TskData.java:540
String getAcquisitionToolSettings()
Definition: Image.java:553
String toString(boolean preserveState)
Definition: Image.java:299
long getContentSize(SleuthkitCase sleuthkitCase)
Definition: Image.java:494
synchronized long getImageHandle()
Definition: Image.java:122

Copyright © 2011-2021 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.