Sleuth Kit Java Bindings (JNI)  4.6
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  @Override
135  return this;
136  }
137 
138  @Override
139  public void close() {
140  //frees nothing, as we are caching image handles
141  }
142 
143  @Override
144  public void finalize() throws Throwable {
145  try {
146  if (imageHandle != 0) {
147  // SleuthkitJNI.closeImg(imageHandle); // closeImg is currently a no-op
148  imageHandle = 0;
149  }
150  } finally {
151  super.finalize();
152  }
153  }
154 
155  @Override
156  public int read(byte[] buf, long offset, long len) throws TskCoreException {
157  // If there are no paths, don't attempt to read the image
158  if (paths.length == 0) {
159  return 0;
160  }
161 
162  // read from the image
163  return SleuthkitJNI.readImg(getImageHandle(), buf, offset, len);
164  }
165 
166  @Override
167  public long getSize() {
168  if (size == 0) {
169  try {
170  if (paths.length > 0) {
171  //should always had at least one path
172  size = SleuthkitJNI.findDeviceSize(paths[0]);
173  }
174  } catch (TskCoreException ex) {
175  Logger.getLogger(Image.class.getName()).log(Level.SEVERE, "Could not find image size, image: " + this.getId(), ex); //NON-NLS
176  }
177  }
178  return size;
179  }
180 
181  //Methods for retrieval of meta-data attributes
188  return TskData.TSK_IMG_TYPE_ENUM.valueOf(type);
189  }
190 
196  public long getSsize() {
197  return ssize;
198  }
199 
200  @Override
201  public String getUniquePath() throws TskCoreException {
202  return "/img_" + getName(); //NON-NLS
203  }
204 
210  public String[] getPaths() {
211  return paths;
212  }
213 
219  public List<VolumeSystem> getVolumeSystems() throws TskCoreException {
220 
221  List<Content> children = getChildren();
222  List<VolumeSystem> vs = new ArrayList<VolumeSystem>();
223  for (Content child : children) {
224  if (child instanceof VolumeSystem) {
225  vs.add((VolumeSystem) child);
226  }
227  }
228 
229  return vs;
230  }
231 
237  public List<Volume> getVolumes() throws TskCoreException {
238 
239  List<Content> children = getChildren();
240  List<Volume> volumes = new ArrayList<Volume>();
241  for (Content child : children) {
242  if (child instanceof Volume) {
243  volumes.add((Volume) child);
244  }
245  }
246 
247  return volumes;
248  }
249 
257  public List<FileSystem> getFileSystems() throws TskCoreException {
258  List<FileSystem> fs = new ArrayList<FileSystem>();
259  fs.addAll(getSleuthkitCase().getFileSystems(this));
260  return fs;
261  }
262 
268  @Override
269  public String getTimeZone() {
270  return timezone;
271  }
272 
273  @Override
274  public <T> T accept(SleuthkitItemVisitor<T> v) {
275  return v.visit(this);
276  }
277 
278  @Override
279  public <T> T accept(ContentVisitor<T> v) {
280  return v.visit(this);
281  }
282 
283  @Override
284  public List<Content> getChildren() throws TskCoreException {
285  return getSleuthkitCase().getImageChildren(this);
286  }
287 
288  @Override
289  public List<Long> getChildrenIds() throws TskCoreException {
290  return getSleuthkitCase().getImageChildrenIds(this);
291  }
292 
293  @Override
294  public String toString(boolean preserveState) {
295  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
296  }
297 
304  public Boolean imageFileExists() {
305  if (paths.length > 0) {
306  File imageFile = new File(paths[0]);
307  return imageFile.exists();
308  }
309 
310  return false;
311  }
312 
320  public String verifyImageSize() {
321  Logger logger1 = Logger.getLogger("verifyImageSizes"); //NON-NLS
322  String errorString = "";
323  try {
324  List<VolumeSystem> volumeSystems = getVolumeSystems();
325  for (VolumeSystem vs : volumeSystems) {
326  List<Volume> volumes = vs.getVolumes();
327  for (Volume v : volumes) {
328  byte[] buf = new byte[512];
329  long endOffset = (v.getStart() + v.getLength()) * 512 - 512;
330  try {
331  int readBytes = read(buf, endOffset, 512);
332  if (readBytes < 0) {
333  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}", endOffset); //NON-NLS
334  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr1.text"), endOffset);
335  }
336  } catch (TskCoreException ex) {
337  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading volume at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
338  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr2.text"), endOffset);
339  }
340  }
341  }
342 
343  List<FileSystem> fileSystems = getFileSystems();
344  for (FileSystem fs : fileSystems) {
345  long block_size = fs.getBlock_size();
346  long endOffset = fs.getImageOffset() + fs.getSize() - block_size;
347  try {
348  byte[] buf = new byte[(int) block_size];
349  int readBytes = read(buf, endOffset, block_size);
350  if (readBytes < 0) {
351  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}", endOffset); //NON-NLS
352  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr3.text"), endOffset);
353  }
354  } catch (TskCoreException ex) {
355  logger1.log(Level.WARNING, "Possible Incomplete Image: Error reading file system at offset {0}: {1}", new Object[]{endOffset, ex.getLocalizedMessage()}); //NON-NLS
356  errorString = MessageFormat.format(bundle.getString("Image.verifyImageSize.errStr4.text"), endOffset);
357  }
358  }
359  } catch (TskException ex) {
360  // do nothing if we got an exception from trying to get file systems and volume systems
361  }
362  return errorString;
363  }
364 
372  public String getMd5() throws TskCoreException {
373  if (md5 == null || md5.isEmpty()) {
374  md5 = getSleuthkitCase().getMd5ImageHash(this);
375  }
376  return md5;
377  }
378 
386  public String getSha1() throws TskCoreException {
387  if (sha1 == null || sha1.isEmpty()) {
388  sha1 = getSleuthkitCase().getSha1ImageHash(this);
389  }
390  return sha1;
391  }
392 
400  public String getSha256() throws TskCoreException {
401  if (sha256 == null || sha256.isEmpty()) {
402  sha256 = getSleuthkitCase().getSha256ImageHash(this);
403  }
404  return sha256;
405  }
406 
413  public void setMD5(String md5) throws TskCoreException, TskDataException {
414  if (getMd5().isEmpty() == false) {
415  throw new TskDataException("MD5 value has already been set");
416  }
417  getSleuthkitCase().setMd5ImageHash(this, md5);
418  this.md5 = md5;
419  }
420 
427  public void setSha1(String sha1) throws TskCoreException, TskDataException {
428  if (getSha1().isEmpty() == false) {
429  throw new TskDataException("SHA1 value has already been set");
430  }
431  getSleuthkitCase().setSha1ImageHash(this, sha1);
432  this.sha1 = sha1;
433  }
434 
441  public void setSha256(String sha256) throws TskCoreException, TskDataException {
442  if (getSha256().isEmpty() == false) {
443  throw new TskDataException("SHA256 value has already been set");
444  }
445  getSleuthkitCase().setSha256ImageHash(this, sha256);
446  this.sha256 = sha256;
447  }
448 
456  @Override
457  public String getDeviceId() {
458  return deviceId;
459  }
460 
468  @Override
469  public void setDisplayName(String newName) throws TskCoreException {
470  this.getSleuthkitCase().setImageName(newName, getId());
471  }
472 
488  @Override
489  public long getContentSize(SleuthkitCase sleuthkitCase) throws TskCoreException {
490  SleuthkitCase.CaseDbConnection connection;
491  Statement statement = null;
492  ResultSet resultSet = null;
493  long contentSize = 0;
494 
495  connection = sleuthkitCase.getConnection();
496 
497  try {
498  statement = connection.createStatement();
499  resultSet = connection.executeQuery(statement, "SELECT SUM (size) FROM tsk_image_info WHERE tsk_image_info.obj_id = " + getId());
500  if (resultSet.next()) {
501  contentSize = resultSet.getLong("sum");
502  }
503  } catch (SQLException ex) {
504  throw new TskCoreException(String.format("There was a problem while querying the database for size data for object ID %d.", getId()), ex);
505  } finally {
506  closeResultSet(resultSet);
507  closeStatement(statement);
508  connection.close();
509  }
510 
511  return contentSize;
512  }
513 
521  @Override
522  public void setAcquisitionDetails(String details) throws TskCoreException {
523  getSleuthkitCase().setAcquisitionDetails(this, details);
524  }
525 
533  @Override
534  public String getAcquisitionDetails() throws TskCoreException {
535  return getSleuthkitCase().getAcquisitionDetails(this);
536  }
537 
543  private static void closeResultSet(ResultSet resultSet) {
544  if (resultSet != null) {
545  try {
546  resultSet.close();
547  } catch (SQLException ex) {
548  LOGGER.log(Level.SEVERE, "Error closing ResultSet", ex); //NON-NLS
549  }
550  }
551  }
552 
558  private static void closeStatement(Statement statement) {
559  if (statement != null) {
560  try {
561  statement.close();
562  } catch (SQLException ex) {
563  LOGGER.log(Level.SEVERE, "Error closing Statement", ex); //NON-NLS
564  }
565  }
566  }
567 }
static int readImg(long imgHandle, byte[] readBuffer, long offset, long len)
List< Volume > getVolumes()
Definition: Image.java:237
List< FileSystem > getFileSystems()
Definition: Image.java:257
void setAcquisitionDetails(String details)
Definition: Image.java:522
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:427
static long openImage(String[] imageFiles, SleuthkitCase skCase)
TskData.TSK_IMG_TYPE_ENUM getType()
Definition: Image.java:187
List< Long > getChildrenIds()
Definition: Image.java:289
int read(byte[] buf, long offset, long len)
Definition: Image.java:156
static long findDeviceSize(String devPath)
void setDisplayName(String newName)
Definition: Image.java:469
List< Content > getChildren()
Definition: Image.java:284
void setMD5(String md5)
Definition: Image.java:413
List< VolumeSystem > getVolumeSystems()
Definition: Image.java:219
void setSha256(String sha256)
Definition: Image.java:441
static TSK_IMG_TYPE_ENUM valueOf(long imgType)
Definition: TskData.java:540
String toString(boolean preserveState)
Definition: Image.java:294
long getContentSize(SleuthkitCase sleuthkitCase)
Definition: Image.java:489
synchronized long getImageHandle()
Definition: Image.java:121

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