Sleuth Kit Java Bindings (JNI)  4.10.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 final String deviceId, timezone;
47  private String md5, sha1, sha256;
48  private static ResourceBundle bundle = ResourceBundle.getBundle("org.sleuthkit.datamodel.Bundle");
49 
50  private static final Logger LOGGER = Logger.getLogger(Image.class.getName());
51 
70  @Deprecated
71  protected Image(SleuthkitCase db, long obj_id, long type, long ssize, String name, String[] paths, String timezone, String md5) throws TskCoreException {
72  super(db, obj_id, name);
73  this.deviceId = "";
74  this.type = type;
75  this.ssize = ssize;
76  this.paths = paths;
77  this.timezone = timezone;
78  this.size = 0;
79  this.md5 = md5;
80  this.sha1 = "";
81  this.sha256 = "";
82  }
83 
100  Image(SleuthkitCase db, long obj_id, long type, String deviceId, long ssize, String name, String[] paths, String timezone,
101  String md5, String sha1, String sha256, long size) throws TskCoreException {
102  super(db, obj_id, name);
103  this.deviceId = deviceId;
104  this.type = type;
105  this.ssize = ssize;
106  this.paths = paths;
107  this.timezone = timezone;
108  this.size = size;
109  this.md5 = md5;
110  this.sha1 = sha1;
111  this.sha256 = sha256;
112  }
113 
121  public synchronized long getImageHandle() throws TskCoreException {
122  if (paths.length == 0) {
123  throw new TskCoreException("Image has no associated paths");
124  }
125 
126  if (imageHandle == 0) {
127  imageHandle = SleuthkitJNI.openImage(paths, (int)ssize, getSleuthkitCase());
128  }
129 
130  return imageHandle;
131  }
132 
133  synchronized void setImageHandle(long imageHandle) {
134  this.imageHandle = imageHandle;
135  }
136 
137  @Override
139  return this;
140  }
141 
142  @Override
143  public void close() {
144  //frees nothing, as we are caching image handles
145  }
146 
147  @Override
148  public void finalize() throws Throwable {
149  try {
150  if (imageHandle != 0) {
151  // SleuthkitJNI.closeImg(imageHandle); // closeImg is currently a no-op
152  imageHandle = 0;
153  }
154  } finally {
155  super.finalize();
156  }
157  }
158 
159  @Override
160  public int read(byte[] buf, long offset, long len) throws TskCoreException {
161  // If there are no paths, don't attempt to read the image
162  if (paths.length == 0) {
163  return 0;
164  }
165 
166  // read from the image
167  return SleuthkitJNI.readImg(getImageHandle(), buf, offset, len);
168  }
169 
170  @Override
171  public long getSize() {
172  if (size == 0) {
173  try {
174  if (paths.length > 0) {
175  //should always had at least one path
176  size = SleuthkitJNI.findDeviceSize(paths[0]);
177  }
178  } catch (TskCoreException ex) {
179  Logger.getLogger(Image.class.getName()).log(Level.SEVERE, "Could not find image size, image: " + this.getId(), ex); //NON-NLS
180  }
181  }
182  return size;
183  }
184 
185  //Methods for retrieval of meta-data attributes
192  return TskData.TSK_IMG_TYPE_ENUM.valueOf(type);
193  }
194 
200  public long getSsize() {
201  return ssize;
202  }
203 
204  @Override
205  public String getUniquePath() throws TskCoreException {
206  return "/img_" + getName(); //NON-NLS
207  }
208 
214  public String[] getPaths() {
215  return paths;
216  }
217 
223  public List<VolumeSystem> getVolumeSystems() throws TskCoreException {
224 
225  List<Content> children = getChildren();
226  List<VolumeSystem> vs = new ArrayList<VolumeSystem>();
227  for (Content child : children) {
228  if (child instanceof VolumeSystem) {
229  vs.add((VolumeSystem) child);
230  }
231  }
232 
233  return vs;
234  }
235 
241  public List<Volume> getVolumes() throws TskCoreException {
242 
243  List<Content> children = getChildren();
244  List<Volume> volumes = new ArrayList<Volume>();
245  for (Content child : children) {
246  if (child instanceof Volume) {
247  volumes.add((Volume) child);
248  }
249  }
250 
251  return volumes;
252  }
253 
261  public List<FileSystem> getFileSystems() throws TskCoreException {
262  List<FileSystem> fs = new ArrayList<>();
263  fs.addAll(getSleuthkitCase().getImageFileSystems(this));
264  return fs;
265  }
266 
272  @Override
273  public String getTimeZone() {
274  return timezone;
275  }
276 
277  @Override
278  public <T> T accept(SleuthkitItemVisitor<T> v) {
279  return v.visit(this);
280  }
281 
282  @Override
283  public <T> T accept(ContentVisitor<T> v) {
284  return v.visit(this);
285  }
286 
287  @Override
288  public List<Content> getChildren() throws TskCoreException {
289  return getSleuthkitCase().getImageChildren(this);
290  }
291 
292  @Override
293  public List<Long> getChildrenIds() throws TskCoreException {
294  return getSleuthkitCase().getImageChildrenIds(this);
295  }
296 
297  @Override
298  public String toString(boolean preserveState) {
299  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
300  }
301 
308  public Boolean imageFileExists() {
309  if (paths.length > 0) {
310  File imageFile = new File(paths[0]);
311  return imageFile.exists();
312  }
313 
314  return false;
315  }
316 
324  public String verifyImageSize() {
325  Logger logger1 = Logger.getLogger("verifyImageSizes"); //NON-NLS
326  String errorString = "";
327  try {
328  List<VolumeSystem> volumeSystems = getVolumeSystems();
329  for (VolumeSystem vs : volumeSystems) {
330  List<Volume> volumes = vs.getVolumes();
331  for (Volume v : volumes) {
332  byte[] buf = new byte[512];
333  long endOffset = (v.getStart() + v.getLength()) * 512 - 512;
334  try {
335  int readBytes = read(buf, endOffset, 512);
336  if (readBytes < 0) {
337  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}", endOffset); //NON-NLS
338  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr1.text"), endOffset);
339  }
340  } catch (TskCoreException ex) {
341  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
342  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr2.text"), endOffset);
343  }
344  }
345  }
346 
347  List<FileSystem> fileSystems = getFileSystems();
348  for (FileSystem fs : fileSystems) {
349  long block_size = fs.getBlock_size();
350  long endOffset = fs.getImageOffset() + fs.getSize() - block_size;
351  try {
352  byte[] buf = new byte[(int) block_size];
353  int readBytes = read(buf, endOffset, block_size);
354  if (readBytes < 0) {
355  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}", endOffset); //NON-NLS
356  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr3.text"), endOffset);
357  }
358  } catch (TskCoreException ex) {
359  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
360  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr4.text"), endOffset);
361  }
362  }
363  } catch (TskException ex) {
364  // do nothing if we got an exception from trying to get file systems and volume systems
365  }
366  return errorString;
367  }
368 
376  public String getMd5() throws TskCoreException {
377  if (md5 == null || md5.isEmpty()) {
378  md5 = getSleuthkitCase().getMd5ImageHash(this);
379  }
380  return md5;
381  }
382 
390  public String getSha1() throws TskCoreException {
391  if (sha1 == null || sha1.isEmpty()) {
392  sha1 = getSleuthkitCase().getSha1ImageHash(this);
393  }
394  return sha1;
395  }
396 
404  public String getSha256() throws TskCoreException {
405  if (sha256 == null || sha256.isEmpty()) {
406  sha256 = getSleuthkitCase().getSha256ImageHash(this);
407  }
408  return sha256;
409  }
410 
417  public void setMD5(String md5) throws TskCoreException, TskDataException {
418  if (getMd5().isEmpty() == false) {
419  throw new TskDataException("MD5 value has already been set");
420  }
421  getSleuthkitCase().setMd5ImageHash(this, md5);
422  this.md5 = md5;
423  }
424 
431  public void setSha1(String sha1) throws TskCoreException, TskDataException {
432  if (getSha1().isEmpty() == false) {
433  throw new TskDataException("SHA1 value has already been set");
434  }
435  getSleuthkitCase().setSha1ImageHash(this, sha1);
436  this.sha1 = sha1;
437  }
438 
445  public void setSha256(String sha256) throws TskCoreException, TskDataException {
446  if (getSha256().isEmpty() == false) {
447  throw new TskDataException("SHA256 value has already been set");
448  }
449  getSleuthkitCase().setSha256ImageHash(this, sha256);
450  this.sha256 = sha256;
451  }
452 
460  @Override
461  public String getDeviceId() {
462  return deviceId;
463  }
464 
472  @Override
473  public void setDisplayName(String newName) throws TskCoreException {
474  this.getSleuthkitCase().setImageName(newName, getId());
475  }
476 
492  @Override
493  public long getContentSize(SleuthkitCase sleuthkitCase) throws TskCoreException {
494  SleuthkitCase.CaseDbConnection connection;
495  Statement statement = null;
496  ResultSet resultSet = null;
497  long contentSize = 0;
498 
499  connection = sleuthkitCase.getConnection();
500 
501  try {
502  statement = connection.createStatement();
503  resultSet = connection.executeQuery(statement, "SELECT SUM (size) FROM tsk_image_info WHERE tsk_image_info.obj_id = " + getId());
504  if (resultSet.next()) {
505  contentSize = resultSet.getLong("sum");
506  }
507  } catch (SQLException ex) {
508  throw new TskCoreException(String.format("There was a problem while querying the database for size data for object ID %d.", getId()), ex);
509  } finally {
510  closeResultSet(resultSet);
511  closeStatement(statement);
512  connection.close();
513  }
514 
515  return contentSize;
516  }
517 
525  @Override
526  public void setAcquisitionDetails(String details) throws TskCoreException {
527  getSleuthkitCase().setAcquisitionDetails(this, details);
528  }
529 
537  @Override
538  public String getAcquisitionDetails() throws TskCoreException {
539  return getSleuthkitCase().getAcquisitionDetails(this);
540  }
541 
547  private static void closeResultSet(ResultSet resultSet) {
548  if (resultSet != null) {
549  try {
550  resultSet.close();
551  } catch (SQLException ex) {
552  LOGGER.log(Level.SEVERE, "Error closing ResultSet", ex); //NON-NLS
553  }
554  }
555  }
556 
562  private static void closeStatement(Statement statement) {
563  if (statement != null) {
564  try {
565  statement.close();
566  } catch (SQLException ex) {
567  LOGGER.log(Level.SEVERE, "Error closing Statement", ex); //NON-NLS
568  }
569  }
570  }
571 }
static int readImg(long imgHandle, byte[] readBuffer, long offset, long len)
List< Volume > getVolumes()
Definition: Image.java:241
List< FileSystem > getFileSystems()
Definition: Image.java:261
void setAcquisitionDetails(String details)
Definition: Image.java:526
Image(SleuthkitCase db, long obj_id, long type, long ssize, String name, String[] paths, String timezone, String md5)
Definition: Image.java:71
void setSha1(String sha1)
Definition: Image.java:431
static long openImage(String[] imageFiles, SleuthkitCase skCase)
TskData.TSK_IMG_TYPE_ENUM getType()
Definition: Image.java:191
List< Long > getChildrenIds()
Definition: Image.java:293
int read(byte[] buf, long offset, long len)
Definition: Image.java:160
static long findDeviceSize(String devPath)
void setDisplayName(String newName)
Definition: Image.java:473
List< Content > getChildren()
Definition: Image.java:288
void setMD5(String md5)
Definition: Image.java:417
List< VolumeSystem > getVolumeSystems()
Definition: Image.java:223
void setSha256(String sha256)
Definition: Image.java:445
static TSK_IMG_TYPE_ENUM valueOf(long imgType)
Definition: TskData.java:540
String toString(boolean preserveState)
Definition: Image.java:298
long getContentSize(SleuthkitCase sleuthkitCase)
Definition: Image.java:493
synchronized long getImageHandle()
Definition: Image.java:121

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