Sleuth Kit Java Bindings (JNI)  4.12.1
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  @SuppressWarnings("deprecation")
149  @Override
150  public void finalize() throws Throwable {
151  try {
152  if (imageHandle != 0) {
153  // SleuthkitJNI.closeImg(imageHandle); // closeImg is currently a no-op
154  imageHandle = 0;
155  }
156  } finally {
157  super.finalize();
158  }
159  }
160 
161  @Override
162  public int read(byte[] buf, long offset, long len) throws TskCoreException {
163  // If there are no paths, don't attempt to read the image
164  if (paths.length == 0) {
165  return 0;
166  }
167 
168  // read from the image
169  return SleuthkitJNI.readImg(getImageHandle(), buf, offset, len);
170  }
171 
172  @Override
173  public long getSize() {
174  if (size == 0) {
175  try {
176  if (paths.length > 0) {
177  //should always had at least one path
178  size = SleuthkitJNI.findDeviceSize(paths[0]);
179  }
180  } catch (TskCoreException ex) {
181  Logger.getLogger(Image.class.getName()).log(Level.SEVERE, "Could not find image size, image: " + this.getId(), ex); //NON-NLS
182  }
183  }
184  return size;
185  }
186 
187  //Methods for retrieval of meta-data attributes
194  return TskData.TSK_IMG_TYPE_ENUM.valueOf(type);
195  }
196 
202  public long getSsize() {
203  return ssize;
204  }
205 
206  @Override
207  public String getUniquePath() throws TskCoreException {
208  return "/img_" + getName(); //NON-NLS
209  }
210 
216  public String[] getPaths() {
217  return paths;
218  }
219 
225  public List<VolumeSystem> getVolumeSystems() throws TskCoreException {
226 
227  List<Content> children = getChildren();
228  List<VolumeSystem> vs = new ArrayList<VolumeSystem>();
229  for (Content child : children) {
230  if (child instanceof VolumeSystem) {
231  vs.add((VolumeSystem) child);
232  }
233  }
234 
235  return vs;
236  }
237 
243  public List<Volume> getVolumes() throws TskCoreException {
244 
245  List<Content> children = getChildren();
246  List<Volume> volumes = new ArrayList<Volume>();
247  for (Content child : children) {
248  if (child instanceof Volume) {
249  volumes.add((Volume) child);
250  }
251  }
252 
253  return volumes;
254  }
255 
263  public List<FileSystem> getFileSystems() throws TskCoreException {
264  List<FileSystem> fs = new ArrayList<>();
265  fs.addAll(getSleuthkitCase().getImageFileSystems(this));
266  return fs;
267  }
268 
274  @Override
275  public String getTimeZone() {
276  return timezone;
277  }
278 
279  @Override
280  public <T> T accept(SleuthkitItemVisitor<T> v) {
281  return v.visit(this);
282  }
283 
284  @Override
285  public <T> T accept(ContentVisitor<T> v) {
286  return v.visit(this);
287  }
288 
289  @Override
290  public List<Content> getChildren() throws TskCoreException {
291  return getSleuthkitCase().getImageChildren(this);
292  }
293 
294  @Override
295  public List<Long> getChildrenIds() throws TskCoreException {
296  return getSleuthkitCase().getImageChildrenIds(this);
297  }
298 
299  @Override
300  public String toString(boolean preserveState) {
301  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
302  }
303 
310  public Boolean imageFileExists() {
311  if (paths.length > 0) {
312  File imageFile = new File(paths[0]);
313  return imageFile.exists();
314  }
315 
316  return false;
317  }
318 
326  public String verifyImageSize() {
327  Logger logger1 = Logger.getLogger("verifyImageSizes"); //NON-NLS
328  String errorString = "";
329  try {
330  List<VolumeSystem> volumeSystems = getVolumeSystems();
331  for (VolumeSystem vs : volumeSystems) {
332  List<Volume> volumes = vs.getVolumes();
333  for (Volume v : volumes) {
334  byte[] buf = new byte[512];
335  long endOffset = (v.getStart() + v.getLength()) * 512 - 512;
336  try {
337  int readBytes = read(buf, endOffset, 512);
338  if (readBytes < 0) {
339  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}", endOffset); //NON-NLS
340  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr1.text"), endOffset);
341  }
342  } catch (TskCoreException ex) {
343  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
344  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr2.text"), endOffset);
345  }
346  }
347  }
348 
349  List<FileSystem> fileSystems = getFileSystems();
350  for (FileSystem fs : fileSystems) {
351  long block_size = fs.getBlock_size();
352  long endOffset = fs.getImageOffset() + fs.getSize() - block_size;
353  try {
354  byte[] buf = new byte[(int) block_size];
355  int readBytes = read(buf, endOffset, block_size);
356  if (readBytes < 0) {
357  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}", endOffset); //NON-NLS
358  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr3.text"), endOffset);
359  }
360  } catch (TskCoreException ex) {
361  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
362  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr4.text"), endOffset);
363  }
364  }
365  } catch (TskException ex) {
366  // do nothing if we got an exception from trying to get file systems and volume systems
367  }
368  return errorString;
369  }
370 
378  public String getMd5() throws TskCoreException {
379  if (md5 == null || md5.isEmpty()) {
380  md5 = getSleuthkitCase().getMd5ImageHash(this);
381  }
382  return md5;
383  }
384 
392  public String getSha1() throws TskCoreException {
393  if (sha1 == null || sha1.isEmpty()) {
394  sha1 = getSleuthkitCase().getSha1ImageHash(this);
395  }
396  return sha1;
397  }
398 
406  public String getSha256() throws TskCoreException {
407  if (sha256 == null || sha256.isEmpty()) {
408  sha256 = getSleuthkitCase().getSha256ImageHash(this);
409  }
410  return sha256;
411  }
412 
419  public void setMD5(String md5) throws TskCoreException, TskDataException {
420  if (getMd5().isEmpty() == false) {
421  throw new TskDataException("MD5 value has already been set");
422  }
423  getSleuthkitCase().setMd5ImageHash(this, md5);
424  this.md5 = md5;
425  }
426 
433  public void setSha1(String sha1) throws TskCoreException, TskDataException {
434  if (getSha1().isEmpty() == false) {
435  throw new TskDataException("SHA1 value has already been set");
436  }
437  getSleuthkitCase().setSha1ImageHash(this, sha1);
438  this.sha1 = sha1;
439  }
440 
447  public void setSha256(String sha256) throws TskCoreException, TskDataException {
448  if (getSha256().isEmpty() == false) {
449  throw new TskDataException("SHA256 value has already been set");
450  }
451  getSleuthkitCase().setSha256ImageHash(this, sha256);
452  this.sha256 = sha256;
453  }
454 
462  @Override
463  public String getDeviceId() {
464  return deviceId;
465  }
466 
474  @Override
475  public void setDisplayName(String newName) throws TskCoreException {
476  this.getSleuthkitCase().setImageName(newName, getId());
477  }
478 
494  @Override
495  public long getContentSize(SleuthkitCase sleuthkitCase) throws TskCoreException {
496  SleuthkitCase.CaseDbConnection connection;
497  Statement statement = null;
498  ResultSet resultSet = null;
499  long contentSize = 0;
500 
501  connection = sleuthkitCase.getConnection();
502 
503  try {
504  statement = connection.createStatement();
505  resultSet = connection.executeQuery(statement, "SELECT SUM (size) FROM tsk_image_info WHERE tsk_image_info.obj_id = " + getId());
506  if (resultSet.next()) {
507  contentSize = resultSet.getLong("sum");
508  }
509  } catch (SQLException ex) {
510  throw new TskCoreException(String.format("There was a problem while querying the database for size data for object ID %d.", getId()), ex);
511  } finally {
512  closeResultSet(resultSet);
513  closeStatement(statement);
514  connection.close();
515  }
516 
517  return contentSize;
518  }
519 
527  @Override
528  public void setAcquisitionDetails(String details) throws TskCoreException {
529  getSleuthkitCase().setAcquisitionDetails(this, details);
530  }
531 
542  @Override
543  public void setAcquisitionToolDetails(String name, String version, String settings) throws TskCoreException {
544  getSleuthkitCase().setAcquisitionToolDetails(this, name, version, settings);
545  }
546 
554  public String getAcquisitionToolSettings() throws TskCoreException {
555  return getSleuthkitCase().getDataSourceInfoString(this, "acquisition_tool_settings");
556  }
557 
565  public String getAcquisitionToolName() throws TskCoreException{
566  return getSleuthkitCase().getDataSourceInfoString(this, "acquisition_tool_name");
567  }
568 
576  public String getAcquisitionToolVersion() throws TskCoreException {
577  return getSleuthkitCase().getDataSourceInfoString(this, "acquisition_tool_version");
578  }
579 
587  public Long getDateAdded() throws TskCoreException {
588  return getSleuthkitCase().getDataSourceInfoLong(this, "added_date_time");
589  }
590 
598  @Override
599  public String getAcquisitionDetails() throws TskCoreException {
600  return getSleuthkitCase().getAcquisitionDetails(this);
601  }
602 
610  @Override
611  public Host getHost() throws TskCoreException {
612  // This is a check-then-act race condition that may occasionally result
613  // in additional processing but is safer than using locks.
614  if (host == null) {
616  }
617  return host;
618  }
619 
633  public void setSizes(long totalSize, long sectorSize) throws TskCoreException {
634  getSleuthkitCase().setImageSizes(this, totalSize, sectorSize);
635  }
636 
642  private static void closeResultSet(ResultSet resultSet) {
643  if (resultSet != null) {
644  try {
645  resultSet.close();
646  } catch (SQLException ex) {
647  LOGGER.log(Level.SEVERE, "Error closing ResultSet", ex); //NON-NLS
648  }
649  }
650  }
651 
657  private static void closeStatement(Statement statement) {
658  if (statement != null) {
659  try {
660  statement.close();
661  } catch (SQLException ex) {
662  LOGGER.log(Level.SEVERE, "Error closing Statement", ex); //NON-NLS
663  }
664  }
665  }
666 }
static int readImg(long imgHandle, byte[] readBuffer, long offset, long len)
Host getHostByDataSource(DataSource dataSource)
List< Volume > getVolumes()
Definition: Image.java:243
List< FileSystem > getFileSystems()
Definition: Image.java:263
void setAcquisitionToolDetails(String name, String version, String settings)
Definition: Image.java:543
void setAcquisitionDetails(String details)
Definition: Image.java:528
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:433
static long openImage(String[] imageFiles, SleuthkitCase skCase)
TskData.TSK_IMG_TYPE_ENUM getType()
Definition: Image.java:193
List< Long > getChildrenIds()
Definition: Image.java:295
int read(byte[] buf, long offset, long len)
Definition: Image.java:162
String getAcquisitionToolVersion()
Definition: Image.java:576
void setSizes(long totalSize, long sectorSize)
Definition: Image.java:633
static long findDeviceSize(String devPath)
void setDisplayName(String newName)
Definition: Image.java:475
List< Content > getChildren()
Definition: Image.java:290
void setMD5(String md5)
Definition: Image.java:419
List< VolumeSystem > getVolumeSystems()
Definition: Image.java:225
void setSha256(String sha256)
Definition: Image.java:447
static TSK_IMG_TYPE_ENUM valueOf(long imgType)
Definition: TskData.java:549
String getAcquisitionToolSettings()
Definition: Image.java:554
String toString(boolean preserveState)
Definition: Image.java:300
long getContentSize(SleuthkitCase sleuthkitCase)
Definition: Image.java:495
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.