/** * \ingroup baselib * Parse a TSK_TCHAR block address string. * Note that the cnt\@size format is no longer supported. * Set the device sector size in img_open to set the block size. * * @param [in] a_offset_str The string version of the offset * @return -1 on error or block offset on success */ TSK_OFF_T tsk_parse_offset(const TSK_TCHAR * a_offset_str) { TSK_TCHAR offset_lcl[64], *offset_lcl_p; TSK_DADDR_T num_blk; TSK_TCHAR *cp; if (a_offset_str == NULL) { return 0; } if (TSTRLEN(a_offset_str) > 63) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_OFFSET; snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_parse: offset string is too long: %" PRIttocTSK, a_offset_str); return -1; } /* Make a local copy */ TSTRNCPY(offset_lcl, a_offset_str, 64); offset_lcl_p = offset_lcl; /* Check for the old x@y setup */ if (TSTRCHR(offset_lcl_p, '@') != NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_OFFSET; snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_parse: offset string format no longer supported. Use -b to specify sector size: %" PRIttocTSK, a_offset_str); return -1; } offset_lcl_p = offset_lcl; /* remove leading 0s */ while ((offset_lcl_p[0] != '\0') && (offset_lcl_p[0] == '0')) offset_lcl_p++; num_blk = 0; if (offset_lcl_p[0] != '\0') { num_blk = TSTRTOULL(offset_lcl_p, &cp, 0); if (*cp || *cp == *offset_lcl_p) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_OFFSET; snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_parse: invalid image offset: %" PRIttocTSK, offset_lcl_p); return -1; } } return num_blk; }
/** * \ingroup hashdblib * \internal * Initializes TSK_HDB_INFO struct with "base class" method pointers and basic * setup of values. * @param hdb_info Allocated struct to initialize. * @param db_path * @return 0 on success, 1 on failure. */ uint8_t hdb_info_base_open(TSK_HDB_INFO *hdb_info, const TSK_TCHAR *db_path) { // copy the database path into the struct size_t path_len = TSTRLEN(db_path); hdb_info->db_fname = (TSK_TCHAR*)tsk_malloc((path_len + 1) * sizeof(TSK_TCHAR)); if (!hdb_info->db_fname) { return 1; } TSTRNCPY(hdb_info->db_fname, db_path, path_len); // set the name based on path hdb_base_db_name_from_path(hdb_info); hdb_info->db_type = TSK_HDB_DBTYPE_INVALID_ID; tsk_init_lock(&hdb_info->lock); hdb_info->transaction_in_progress = 0; hdb_info->get_db_path = hdb_base_get_db_path; hdb_info->get_display_name = hdb_base_get_display_name; hdb_info->uses_external_indexes = hdb_base_uses_external_indexes; hdb_info->get_index_path = hdb_base_get_index_path; hdb_info->has_index = hdb_base_has_index; hdb_info->make_index = hdb_base_make_index; hdb_info->open_index = hdb_base_open_index; hdb_info->lookup_str = hdb_base_lookup_str; hdb_info->lookup_raw = hdb_base_lookup_bin; hdb_info->lookup_verbose_str = hdb_base_lookup_verbose_str; hdb_info->accepts_updates = hdb_base_accepts_updates; hdb_info->add_entry = hdb_base_add_entry; hdb_info->begin_transaction = hdb_base_begin_transaction; hdb_info->commit_transaction = hdb_base_commit_transaction; hdb_info->rollback_transaction = hdb_base_rollback_transaction; hdb_info->close_db = hdb_info_base_close; return 0; }
TSK_IMG_INFO * ewf_open(int a_num_img, const TSK_TCHAR * const a_images[], unsigned int a_ssize) { #if defined( HAVE_LIBEWF_V2_API ) char error_string[TSK_EWF_ERROR_STRING_SIZE]; libewf_error_t *ewf_error = NULL; int result = 0; #elif !defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) uint8_t md5_hash[16]; #endif IMG_EWF_INFO *ewf_info = NULL; TSK_IMG_INFO *img_info = NULL; #if !defined( HAVE_LIBEWF_V2_API) if (tsk_verbose) libewf_set_notify_values(stderr, 1); #endif if ((ewf_info = (IMG_EWF_INFO *) tsk_img_malloc(sizeof(IMG_EWF_INFO))) == NULL) { return NULL; } img_info = (TSK_IMG_INFO *) ewf_info; // See if they specified only the first of the set... ewf_info->used_ewf_glob = 0; if (a_num_img == 1) { #if defined( HAVE_LIBEWF_V2_API) #ifdef TSK_WIN32 if (libewf_glob_wide(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images, &ewf_info->num_imgs, &ewf_error) == -1) { #else if (libewf_glob(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images, &ewf_info->num_imgs, &ewf_error) == -1) { #endif tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open: Not an E01 glob name (%s)", error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); return NULL; } #else //use v1 #ifdef TSK_WIN32 ewf_info->num_imgs = libewf_glob_wide(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images); #else ewf_info->num_imgs = libewf_glob(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images); #endif if (ewf_info->num_imgs <= 0) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); tsk_error_set_errstr("ewf_open: Not an E01 glob name"); tsk_img_free(ewf_info); return NULL; } #endif // end v1 ewf_info->used_ewf_glob = 1; if (tsk_verbose) tsk_fprintf(stderr, "ewf_open: found %d segment files via libewf_glob\n", ewf_info->num_imgs); } else { int i; ewf_info->num_imgs = a_num_img; if ((ewf_info->images = (TSK_TCHAR **) tsk_malloc(a_num_img * sizeof(TSK_TCHAR *))) == NULL) { tsk_img_free(ewf_info); return NULL; } for (i = 0; i < a_num_img; i++) { if ((ewf_info->images[i] = (TSK_TCHAR *) tsk_malloc((TSTRLEN(a_images[i]) + 1) * sizeof(TSK_TCHAR))) == NULL) { tsk_img_free(ewf_info); return NULL; } TSTRNCPY(ewf_info->images[i], a_images[i], TSTRLEN(a_images[i]) + 1); } } #if defined( HAVE_LIBEWF_V2_API ) // Check the file signature before we call the library open #if defined( TSK_WIN32 ) if (libewf_check_file_signature_wide(a_images[0], &ewf_error) != 1) #else if (libewf_check_file_signature(a_images[0], &ewf_error) != 1) #endif { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open: Not an EWF file (%s)", error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Not an EWF file\n"); } return (NULL); } if (libewf_handle_initialize(&(ewf_info->handle), &ewf_error) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error initializing handle (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Unable to create EWF handle\n"); } return (NULL); } #if defined( TSK_WIN32 ) if (libewf_handle_open_wide(ewf_info->handle, (wchar_t * const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ, &ewf_error) != 1) #else if (libewf_handle_open(ewf_info->handle, (char *const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ, &ewf_error) != 1) #endif { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error opening (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error opening EWF file\n"); } return (NULL); } if (libewf_handle_get_media_size(ewf_info->handle, (size64_t *) & (img_info->size), &ewf_error) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error getting size of image (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error getting size of EWF file\n"); } return (NULL); } result = libewf_handle_get_utf8_hash_value_md5(ewf_info->handle, (uint8_t *) ewf_info->md5hash, 33, &ewf_error); if (result == -1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); getError(ewf_error, error_string); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error getting MD5 of image (%s)", a_images[0], error_string); libewf_error_free(&ewf_error); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error getting size of EWF file\n"); } return (NULL); } ewf_info->md5hash_isset = result; #else // V1 API // Check the file signature before we call the library open #if defined( TSK_WIN32 ) if (libewf_check_file_signature_wide(a_images[0]) != 1) #else if (libewf_check_file_signature(a_images[0]) != 1) #endif { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); tsk_error_set_errstr("ewf_open: Not an EWF file"); tsk_img_free(ewf_info); if (tsk_verbose) tsk_fprintf(stderr, "Not an EWF file\n"); return NULL; } #if defined( TSK_WIN32 ) ewf_info->handle = libewf_open_wide( (wchar_t * const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ); #else ewf_info->handle = libewf_open( (char *const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ); #endif if (ewf_info->handle == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error opening", ewf_info->images[0]); tsk_img_free(ewf_info); if (tsk_verbose != 0) { tsk_fprintf(stderr, "Error opening EWF file\n"); } return (NULL); } #if defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) // 2007 version img_info->size = libewf_get_media_size(ewf_info->handle); ewf_info->md5hash_isset = libewf_get_stored_md5_hash(ewf_info->handle, ewf_info->md5hash, LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5); #else // libewf-20080322 version if (libewf_get_media_size(ewf_info->handle, (size64_t *) & (img_info->size)) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error getting size of image", ewf_info->images[0]); tsk_img_free(ewf_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error getting size of EWF file\n"); } return (NULL); } if (libewf_get_md5_hash(ewf_info->handle, md5_hash, 16) == 1) { int md5_string_iterator = 0; int md5_hash_iterator = 0; for (md5_hash_iterator = 0; md5_hash_iterator < 16; md5_hash_iterator++) { int digit = md5_hash[md5_hash_iterator] / 16; if (digit <= 9) { ewf_info->md5hash[md5_string_iterator++] = '0' + (char) digit; } else { ewf_info->md5hash[md5_string_iterator++] = 'a' + (char) (digit - 10); } digit = md5_hash[md5_hash_iterator] % 16; if (digit <= 9) { ewf_info->md5hash[md5_string_iterator++] = '0' + (char) digit; } else { ewf_info->md5hash[md5_string_iterator++] = 'a' + (char) (digit - 10); } } ewf_info->md5hash_isset = 1; } #endif /* defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) */ #endif /* defined( HAVE_LIBEWF_V2_API ) */ if (a_ssize != 0) { img_info->sector_size = a_ssize; } else { img_info->sector_size = 512; } img_info->itype = TSK_IMG_TYPE_EWF_EWF; img_info->read = &ewf_image_read; img_info->close = &ewf_image_close; img_info->imgstat = &ewf_image_imgstat; // initialize the read lock tsk_init_lock(&(ewf_info->read_lock)); return (img_info); }
/** * Open one or more files as a disk image. This serves as a * wrapper around the specific types of disk image formats. You * can specify the type or autodetection can be used. * * @param type The text a user supplied for the type of format. * Examples include "raw", "split", "aff", etc. * @param num_img The number of images that are being considered. * @param images The path to the files (the number of files must * be equal to num_img) * * @return Pointer to the Image state structure or NULL on error */ TSK_IMG_INFO * tsk_img_open(const TSK_TCHAR * type, const int num_img, const TSK_TCHAR ** images) { TSK_IMG_INFO *img_info = NULL; TSK_TCHAR *tp, *next; TSK_TCHAR type_lcl[128], *type_lcl_p; const TSK_TCHAR **img_tmp; int num_img_tmp = num_img; // Get rid of any old error messages laying around tsk_error_reset(); if ((num_img == 0) || (images[0] == NULL)) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_NOFILE; snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_img_open"); tsk_errstr2[0] = '\0'; return NULL; } if (tsk_verbose) TFPRINTF(stderr, _TSK_T("tsk_img_open: Type: %s NumImg: %d Img1: %s\n"), (type ? type : _TSK_T("n/a")), num_img, images[0]); // only the first in list (lowest) layer gets the files img_tmp = images; /* If no type is given, then we use the autodetection methods * In case the image file matches the signatures of multiple formats, * we try all of the embedded formats */ if (type == NULL) { TSK_IMG_INFO *img_set = NULL; #if HAVE_LIBAFFLIB || HAVE_LIBEWF char *set = NULL; #endif struct STAT_STR stat_buf; /* First verify that the image file exists */ if (TSTAT(images[0], &stat_buf) < 0) { // special case to handle windows objects #if defined(TSK_WIN32) if ((images[0][0] == _TSK_T('\\')) && (images[0][1] == _TSK_T('\\')) && (images[0][2] == _TSK_T('.')) && (images[0][3] == _TSK_T('\\'))) { if (tsk_verbose) TFPRINTF(stderr, _TSK_T ("tsk_img_open: Ignoring stat error because of windows object: %s\n"), images[0]); } #endif /* AFFLIB supports s3 storage on Amazon, so skip those 'file' paths */ #if HAVE_LIBAFFLIB #if defined(TSK_WIN32) else #endif if (((images[0][0] == _TSK_T('s')) && (images[0][1] == _TSK_T('3')) && (images[0][2] == _TSK_T(':')) && (images[0][3] == _TSK_T('/')) && (images[0][4] == _TSK_T('/'))) || ((images[0][0] == _TSK_T('h')) && (images[0][1] == _TSK_T('t')) && (images[0][2] == _TSK_T('t')) && (images[0][3] == _TSK_T('p')) && (images[0][4] == _TSK_T(':')) && (images[0][5] == _TSK_T('/')) && (images[0][6] == _TSK_T('/')))) { if (tsk_verbose) TFPRINTF(stderr, _TSK_T ("tsk_img_open: Ignoring stat error because of s3/http object: %s\n"), images[0]); } #endif #if HAVE_LIBAFFLIB || defined(TSK_WIN32) else { #endif tsk_error_reset(); tsk_errno = TSK_ERR_IMG_STAT; snprintf(tsk_errstr, TSK_ERRSTR_L, "%" PRIttocTSK " : %s", images[0], strerror(errno)); return NULL; #if HAVE_LIBAFFLIB || defined(TSK_WIN32) } #endif } // we rely on tsk_errno, so make sure it is 0 tsk_error_reset(); /* Try the non-raw formats first */ #if HAVE_LIBAFFLIB if ((img_info = aff_open(images, NULL)) != NULL) { set = "AFF"; img_set = img_info; } else { tsk_error_reset(); } #endif #if HAVE_LIBEWF if ((img_info = ewf_open(num_img, images, NULL)) != NULL) { if (set == NULL) { set = "EWF"; img_set = img_info; } else { img_set->close(img_set); img_info->close(img_info); tsk_error_reset(); tsk_errno = TSK_ERR_IMG_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "EWF or %s", set); return NULL; } } else { tsk_error_reset(); } #endif if (img_set != NULL) return img_set; /* We'll use the raw format */ if (num_img == 1) { if ((img_info = raw_open(images, NULL)) != NULL) { return img_info; } else if (tsk_errno) { return NULL; } } else { if ((img_info = split_open(num_img, images, NULL)) != NULL) { return img_info; } else if (tsk_errno) { return NULL; } } tsk_errno = TSK_ERR_IMG_UNKTYPE; tsk_errstr[0] = '\0'; tsk_errstr2[0] = '\0'; return NULL; } /* * Type values * Make a local copy that we can modify the string as we parse it */ TSTRNCPY(type_lcl, type, 128); type_lcl_p = type_lcl; /* We parse this and go up in the layers */ tp = TSTRTOK(type_lcl, _TSK_T(",")); while (tp != NULL) { uint8_t imgtype; next = TSTRTOK(NULL, _TSK_T(",")); imgtype = tsk_img_parse_type(type); switch (imgtype) { case TSK_IMG_INFO_TYPE_RAW_SING: /* If we have more than one image name, and raw was the only * type given, then use split */ if ((num_img > 1) && (next == NULL) && (img_tmp != NULL)) { img_info = split_open(num_img_tmp, img_tmp, img_info); num_img_tmp = 0; } else { img_info = raw_open(img_tmp, img_info); } img_tmp = NULL; break; case TSK_IMG_INFO_TYPE_RAW_SPLIT: /* If only one image file is given, and only one type was * given then use raw */ if ((num_img == 1) && (next == NULL) && (img_tmp != NULL)) { img_info = raw_open(img_tmp, img_info); } else { img_info = split_open(num_img_tmp, img_tmp, img_info); num_img_tmp = 0; } img_tmp = NULL; break; #if HAVE_LIBAFFLIB case TSK_IMG_INFO_TYPE_AFF_AFF: case TSK_IMG_INFO_TYPE_AFF_AFD: case TSK_IMG_INFO_TYPE_AFF_AFM: img_info = aff_open(img_tmp, img_info); break; #endif #if HAVE_LIBEWF case TSK_IMG_INFO_TYPE_EWF_EWF: img_info = ewf_open(num_img_tmp, img_tmp, img_info); break; #endif default: tsk_error_reset(); tsk_errno = TSK_ERR_IMG_UNSUPTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "%" PRIttocTSK, tp); return NULL; } /* Advance the pointer */ tp = next; } /* Return the highest layer */ return img_info; }
/** Originally we used tsk_img_open_sing(), but that leads to calling ewf_open(), which in turn will fail if the L01 file has an incorrect filename extension. This function is a simpler version of ewf_open() which will not fail if the filename extension is wrong. */ TSK_IMG_INFO * TskL01Extract::openEwfSimple() { const int a_num_img = 1; unsigned int a_ssize = 512; int result = 0; TSK_IMG_INFO *img_info = NULL; ewf::libewf_error_t *ewfError = NULL; ewf::IMG_EWF_INFO *ewf_info = NULL; try { // Make an absolute path (if it's relative) so that libewf doesn't cause // an error when it tries to make it absolute. Poco::Path tempPath(TskUtilities::toUTF8(m_archivePath)); tempPath.makeAbsolute(); // We convert to unicode here because that is what the TSK_IMG_INFO structure requires. std::wstring ewfArchivePath = TskUtilities::toUTF16(tempPath.toString()); if ((ewf_info = (ewf::IMG_EWF_INFO *) tsk_img_malloc(sizeof(ewf::IMG_EWF_INFO))) == NULL) { throw TskException("tsk_img_malloc"); } img_info = (TSK_IMG_INFO *) ewf_info; if (ewf::libewf_handle_initialize(&(ewf_info->handle), &ewfError) != 1) { throw TskException("libewf_handle_initialize"); } //int i; ewf_info->num_imgs = a_num_img; if ((ewf_info->images = (TSK_TCHAR **) tsk_malloc(a_num_img * sizeof(TSK_TCHAR *))) == NULL) { throw TskException("tsk_malloc"); } if ((ewf_info->images[0] = (TSK_TCHAR *) tsk_malloc((TSTRLEN(ewfArchivePath.c_str()) + 1) * sizeof(TSK_TCHAR))) == NULL) { throw TskException("tsk_malloc 2"); } TSTRNCPY(ewf_info->images[0], ewfArchivePath.c_str(), TSTRLEN(ewfArchivePath.c_str()) + 1); ///NOTE: libewf_handle_open_wide() will not open the file if the filename length is < 4 chars long. ewfError = NULL; #if defined( TSK_WIN32 ) if (ewf::libewf_handle_open_wide(ewf_info->handle, (TSK_TCHAR * const *) ewf_info->images, ewf_info->num_imgs, ewf::LIBEWF_ACCESS_FLAG_READ, &ewfError) != 1) #else if (ewf::libewf_handle_open(ewf_info->handle, (char *const *) ewf_info->images, ewf_info->num_imgs, ewf::LIBEWF_OPEN_READ, &ewfError) != 1) #endif { throw TskException("libewf_handle_open_wide"); } ewfError = NULL; if (ewf::libewf_handle_get_media_size(ewf_info->handle, (ewf::size64_t *) & (img_info->size), &ewfError) != 1) { throw TskException("libewf_handle_get_media_size"); } ewfError = NULL; result = ewf::libewf_handle_get_utf8_hash_value_md5(ewf_info->handle, (uint8_t *) ewf_info->md5hash, 33, &ewfError); if (result == -1) { throw TskException("libewf_handle_get_utf8_hash_value_md5"); } ewf_info->md5hash_isset = result; if (a_ssize != 0) { img_info->sector_size = a_ssize; } else { img_info->sector_size = 512; } img_info->itype = TSK_IMG_TYPE_EWF_EWF; img_info->close = ewf_image_close; img_info->read = null_read; img_info->imgstat = null_imgstat; // initialize the read lock tsk_init_lock(&(ewf_info->read_lock)); return img_info; } catch (TskException &ex) { std::ostringstream msg; msg << "openEwfSimple: TskException: " << ex.message(); if (ewfError) { char errorString[512]; errorString[0] = '\0'; ewf::libewf_error_backtrace_sprint(ewfError, errorString, 512); msg << " - libewf error: " << errorString << std::endl; } LOGERROR(msg.str()); free(ewf_info); return NULL; } }
/** * \internal * Open the set of disk images as a set of split raw images * * @param a_num_img Number of images in set * @param a_images List of disk image paths (in sorted order) * @param a_ssize Size of device sector in bytes (or 0 for default) * * @return NULL on error */ TSK_IMG_INFO * raw_open(int a_num_img, const TSK_TCHAR * const a_images[], unsigned int a_ssize) { IMG_RAW_INFO *raw_info; TSK_IMG_INFO *img_info; int i; TSK_OFF_T first_seg_size; if ((raw_info = (IMG_RAW_INFO *) tsk_img_malloc(sizeof(IMG_RAW_INFO))) == NULL) return NULL; img_info = (TSK_IMG_INFO *) raw_info; img_info->itype = TSK_IMG_TYPE_RAW; img_info->read = raw_read; img_info->close = raw_close; img_info->imgstat = raw_imgstat; img_info->sector_size = 512; if (a_ssize) img_info->sector_size = a_ssize; raw_info->is_winobj = 0; #if defined(TSK_WIN32) || defined(__CYGWIN__) /* determine if this is the path to a Windows device object */ if ((a_images[0][0] == _TSK_T('\\')) && (a_images[0][1] == _TSK_T('\\')) && ((a_images[0][2] == _TSK_T('.')) || (a_images[0][2] == _TSK_T('?'))) && (a_images[0][3] == _TSK_T('\\'))) { raw_info->is_winobj = 1; } #endif /* Check that the first image file exists and is not a directory */ first_seg_size = get_size(a_images[0], raw_info->is_winobj); if (first_seg_size < -1) { tsk_img_free(raw_info); return NULL; } /* see if there are more of them... */ if ((a_num_img == 1) && (raw_info->is_winobj == 0)) { if ((raw_info->images = tsk_img_findFiles(a_images[0], &raw_info->num_img)) == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_STAT); tsk_error_set_errstr ("raw_open: could not find segment files starting at \"%" PRIttocTSK "\"", a_images[0]); tsk_img_free(raw_info); return NULL; } } else { raw_info->num_img = a_num_img; raw_info->images = (TSK_TCHAR **) tsk_malloc(sizeof(TSK_TCHAR *) * a_num_img); if (raw_info->images == NULL) { tsk_img_free(raw_info); return NULL; } for (i = 0; i < raw_info->num_img; i++) { size_t len = TSTRLEN(a_images[i]); raw_info->images[i] = (TSK_TCHAR *) tsk_malloc(sizeof(TSK_TCHAR) * (len + 1)); if (raw_info->images[i] == NULL) { int j; for (j = 0; j < i; j++) { free(raw_info->images[j]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } TSTRNCPY(raw_info->images[i], a_images[i], len + 1); } } /* sanity check: when we have multiple segments, the size of * each must be known */ if ((raw_info->num_img > 1) && (first_seg_size < 0)) { if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: file size is unknown in a segmented raw image\n"); } for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } /* initialize the split cache */ raw_info->cptr = (int *) tsk_malloc(raw_info->num_img * sizeof(int)); if (raw_info->cptr == NULL) { for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } memset((void *) &raw_info->cache, 0, SPLIT_CACHE * sizeof(IMG_SPLIT_CACHE)); raw_info->next_slot = 0; /* initialize the offset table and re-use the first segment * size gathered above */ raw_info->max_off = (TSK_OFF_T *) tsk_malloc(raw_info->num_img * sizeof(TSK_OFF_T)); if (raw_info->max_off == NULL) { free(raw_info->cptr); for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } img_info->size = first_seg_size; raw_info->max_off[0] = img_info->size; raw_info->cptr[0] = -1; if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: segment: 0 size: %" PRIuOFF " max offset: %" PRIuOFF " path: %" PRIttocTSK "\n", first_seg_size, raw_info->max_off[0], raw_info->images[0]); } /* get size info for each file - we do not open each one because that * could cause us to run out of file decsriptors when we only need a few. * The descriptors are opened as needed */ for (i = 1; i < raw_info->num_img; i++) { TSK_OFF_T size; raw_info->cptr[i] = -1; size = get_size(raw_info->images[i], raw_info->is_winobj); if (size < 0) { if (size == -1) { if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: file size is unknown in a segmented raw image\n"); } } free(raw_info->cptr); for (i = 0; i < raw_info->num_img; i++) { free(raw_info->images[i]); } free(raw_info->images); tsk_img_free(raw_info); return NULL; } /* add the size of this image to the total and save the current max */ img_info->size += size; raw_info->max_off[i] = img_info->size; if (tsk_verbose) { tsk_fprintf(stderr, "raw_open: segment: %d size: %" PRIuOFF " max offset: %" PRIuOFF " path: %" PRIttocTSK "\n", i, size, raw_info->max_off[i], raw_info->images[i]); } } return img_info; }
/** * \ingroup hashdblib * * Opens an existing hash database. * @param file_path Path to database or database index file. * @param flags Flags for opening the database. * @return Pointer to a struct representing the hash database or NULL on error. */ TSK_HDB_INFO * tsk_hdb_open(TSK_TCHAR *file_path, TSK_HDB_OPEN_ENUM flags) { const char *func_name = "tsk_hdb_open"; uint8_t file_path_is_idx_path = 0; TSK_TCHAR *db_path = NULL; TSK_TCHAR *ext = NULL; FILE *hDb = NULL; FILE *hIdx = NULL; TSK_HDB_DBTYPE_ENUM db_type = TSK_HDB_DBTYPE_INVALID_ID; TSK_HDB_INFO *hdb_info = NULL; if (NULL == file_path) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("%s: NULL file path", func_name); return NULL; } // Determine the hash database path using the given file path. Note that // direct use of an external index file for a text-format hash database for // simple yes/no lookups is both explicitly and implicitly supported. For // such "index only" databases, the path to where the hash database is // normally required to be is still needed because of the way the code for // text-format hash databases has been written. db_path = (TSK_TCHAR*)tsk_malloc((TSTRLEN(file_path) + 1) * sizeof(TSK_TCHAR)); if (NULL == db_path) { return NULL; } ext = TSTRRCHR(file_path, _TSK_T('-')); if ((NULL != ext) && (TSTRLEN(ext) == 8 || TSTRLEN(ext) == 9) && ((TSTRCMP(ext, _TSK_T("-md5.idx")) == 0) || TSTRCMP(ext, _TSK_T("-sha1.idx")) == 0)) { // The file path extension suggests the path is for an external index // file generated by TSK for a text-format hash database. In this case, // the database path should be the given file path sans the extension // because the hash database, if it is available for lookups, is // required to be be in the same directory as the external index file. file_path_is_idx_path = 1; TSTRNCPY(db_path, file_path, (ext - file_path)); } else { TSTRNCPY(db_path, file_path, TSTRLEN(file_path)); } // Determine the database type. if ((flags & TSK_HDB_OPEN_IDXONLY) == 0) { hDb = hdb_open_file(db_path); if (NULL != hDb) { db_type = hdb_determine_db_type(hDb, db_path); if (TSK_HDB_DBTYPE_INVALID_ID == db_type) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_UNKTYPE); tsk_error_set_errstr("%s: error determining hash database type of %"PRIttocTSK, func_name, db_path); free(db_path); return NULL; } } else { if (file_path_is_idx_path) { db_type = TSK_HDB_DBTYPE_IDXONLY_ID; } else { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_OPEN); tsk_error_set_errstr("%s: failed to open %"PRIttocTSK, func_name, db_path); free(db_path); return NULL; } } } else { db_type = TSK_HDB_DBTYPE_IDXONLY_ID; } switch (db_type) { case TSK_HDB_DBTYPE_NSRL_ID: hdb_info = nsrl_open(hDb, db_path); break; case TSK_HDB_DBTYPE_MD5SUM_ID: hdb_info = md5sum_open(hDb, db_path); break; case TSK_HDB_DBTYPE_ENCASE_ID: hdb_info = encase_open(hDb, db_path); break; case TSK_HDB_DBTYPE_HK_ID: hdb_info = hk_open(hDb, db_path); break; case TSK_HDB_DBTYPE_IDXONLY_ID: hIdx = hdb_open_file(file_path); if (NULL == hIdx) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_OPEN); tsk_error_set_errstr("%s: database is index only, failed to open index %"PRIttocTSK, func_name, db_path); free(db_path); return NULL; } else { fclose(hIdx); } hdb_info = idxonly_open(db_path); break; case TSK_HDB_DBTYPE_SQLITE_ID: if (NULL != hDb) { fclose(hDb); } hdb_info = sqlite_hdb_open(db_path); break; // included to prevent compiler warnings that it is not used case TSK_HDB_DBTYPE_INVALID_ID: break; } if (NULL != db_path) { free(db_path); } return hdb_info; }
/** * Open a hash database and index for lookup. * * @param db_file Path to database. * @param flags Flags for opening the database. * * @return Poiner to hash database state structure or NULL on error */ TSK_HDB_INFO * tsk_hdb_open(TSK_TCHAR * db_file, TSK_HDB_OPEN_ENUM flags) { TSK_HDB_INFO *hdb_info; size_t flen; FILE *hDb; uint8_t dbtype = 0; if ((flags & TSK_HDB_OPEN_IDXONLY) == 0) { /* Open the database file */ #ifdef TSK_WIN32 { HANDLE hWin; if ((hWin = CreateFile(db_file, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_open: Error opening database file: %s", db_file); return NULL; } hDb = _fdopen(_open_osfhandle((intptr_t) hWin, _O_RDONLY), "r"); if (hDb == NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_open: Error converting Windows handle to C handle"); return NULL; } } #else if (NULL == (hDb = fopen(db_file, "r"))) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_open: Error opening database file: %s", db_file); return NULL; } #endif /* Try to figure out what type of DB it is */ if (nsrl_test(hDb)) { dbtype = TSK_HDB_DBTYPE_NSRL_ID; } if (md5sum_test(hDb)) { if (dbtype != 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_open: Error determining DB type (MD5sum)"); return NULL; } dbtype = TSK_HDB_DBTYPE_MD5SUM_ID; } if (hk_test(hDb)) { if (dbtype != 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_open: Error determining DB type (HK)"); return NULL; } dbtype = TSK_HDB_DBTYPE_HK_ID; } if (dbtype == 0) { tsk_error_reset(); tsk_errno = TSK_ERR_HDB_UNKTYPE; snprintf(tsk_errstr, TSK_ERRSTR_L, "hdb_open: Error determining DB type"); return NULL; } fseeko(hDb, 0, SEEK_SET); } else { dbtype = TSK_HDB_DBTYPE_IDXONLY_ID; hDb = NULL; } if ((hdb_info = talloc(NULL, TSK_HDB_INFO)) == NULL) return NULL; hdb_info->hDb = hDb; /* Get database specific information */ hdb_info->db_type = dbtype; switch (dbtype) { case TSK_HDB_DBTYPE_NSRL_ID: hdb_info->getentry = nsrl_getentry; hdb_info->makeindex = nsrl_makeindex; break; case TSK_HDB_DBTYPE_MD5SUM_ID: hdb_info->getentry = md5sum_getentry; hdb_info->makeindex = md5sum_makeindex; break; case TSK_HDB_DBTYPE_HK_ID: hdb_info->getentry = hk_getentry; hdb_info->makeindex = hk_makeindex; break; case TSK_HDB_DBTYPE_IDXONLY_ID: hdb_info->getentry = idxonly_getentry; hdb_info->makeindex = idxonly_makeindex; break; default: return NULL; } hdb_info->hash_type = 0; hdb_info->hash_len = 0; hdb_info->idx_fname = NULL; hdb_info->uns_fname = NULL; hdb_info->hIdxTmp = NULL; hdb_info->hIdx = NULL; hdb_info->idx_size = 0; hdb_info->idx_off = 0; hdb_info->idx_lbuf = NULL; /* Copy the database name into the structure */ flen = TSTRLEN(db_file) + 8; // + 32; hdb_info->db_fname = (TSK_TCHAR *) talloc_size(hdb_info, flen * sizeof(TSK_TCHAR)); if (hdb_info->db_fname == NULL) { talloc_free(hdb_info); return NULL; } TSTRNCPY(hdb_info->db_fname, db_file, flen); return hdb_info; }
int MAIN(int argc, TSK_TCHAR ** argv) { TSK_TCHAR *imgtype = NULL; TSK_TCHAR *fstype = NULL; TSK_FS_INFO *fs; TSK_IMG_INFO *img; int ch; TSK_TCHAR *cp; extern int optind; DADDR_T block = 0; /* the block to find */ INUM_T parinode = 0; TSK_TCHAR *path = NULL; SSIZE_T imgoff = 0; progname = argv[0]; setlocale(LC_ALL, ""); localflags = 0; while ((ch = getopt(argc, argv, _TSK_T("ad:f:i:ln:o:p:vVz:"))) > 0) { switch (ch) { case _TSK_T('a'): localflags |= TSK_FS_IFIND_ALL; break; case _TSK_T('d'): if (localflags & (TSK_FS_IFIND_PAR | TSK_FS_IFIND_PATH)) { tsk_fprintf(stderr, "error: only one address type can be given\n"); usage(); } localflags |= TSK_FS_IFIND_DATA; block = TSTRTOULL(optarg, &cp, 0); if (*cp || *cp == *optarg) { TFPRINTF(stderr, _TSK_T("Invalid block address: %s\n"), optarg); usage(); } break; case _TSK_T('f'): fstype = optarg; if (TSTRCMP(fstype, _TSK_T("list")) == 0) { tsk_fs_print_types(stderr); exit(1); } break; case _TSK_T('i'): imgtype = optarg; if (TSTRCMP(imgtype, _TSK_T("list")) == 0) { tsk_img_print_types(stderr); exit(1); } break; case _TSK_T('l'): localflags |= TSK_FS_IFIND_PAR_LONG; break; case _TSK_T('n'): { size_t len; if (localflags & (TSK_FS_IFIND_PAR | TSK_FS_IFIND_DATA)) { tsk_fprintf(stderr, "error: only one address type can be given\n"); usage(); } localflags |= TSK_FS_IFIND_PATH; len = (TSTRLEN(optarg) + 1) * sizeof(TSK_TCHAR); if ((path = (TSK_TCHAR *) tsk_malloc(len)) == NULL) { tsk_error_print(stderr); exit(1); } TSTRNCPY(path, optarg, TSTRLEN(optarg) + 1); break; } case 'o': if ((imgoff = tsk_parse_offset(optarg)) == -1) { tsk_error_print(stderr); exit(1); } break; case 'p': if (localflags & (TSK_FS_IFIND_PATH | TSK_FS_IFIND_DATA)) { tsk_fprintf(stderr, "error: only one address type can be given\n"); usage(); } localflags |= TSK_FS_IFIND_PAR; if (tsk_parse_inum(optarg, &parinode, NULL, NULL, NULL)) { TFPRINTF(stderr, _TSK_T("Invalid inode address: %s\n"), optarg); usage(); } break; case 'v': tsk_verbose++; break; case 'V': tsk_print_version(stdout); exit(0); case 'z': { TSK_TCHAR envstr[32]; TSNPRINTF(envstr, 32, _TSK_T("TZ=%s"), optarg); if (0 != PUTENV(envstr)) { tsk_fprintf(stderr, "error setting environment"); exit(1); } /* we should be checking this somehow */ TZSET(); break; } case '?': default: tsk_fprintf(stderr, "Invalid argument: %s\n", argv[optind]); usage(); } } /* We need at least one more argument */ if (optind >= argc) { tsk_fprintf(stderr, "Missing image name\n"); if (path) free(path); usage(); } if (0 == (localflags & (TSK_FS_IFIND_PATH | TSK_FS_IFIND_DATA | TSK_FS_IFIND_PAR))) { tsk_fprintf(stderr, "-d, -n, or -p must be given\n"); usage(); } if ((img = tsk_img_open(imgtype, argc - optind, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); if (path) free(path); exit(1); } if ((fs = tsk_fs_open(img, imgoff, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_fs_print_types(stderr); img->close(img); if (path) free(path); exit(1); } if (localflags & TSK_FS_IFIND_DATA) { if (block > fs->last_block) { tsk_fprintf(stderr, "Block %" PRIuDADDR " is larger than last block in image (%" PRIuDADDR ")\n", block, fs->last_block); fs->close(fs); img->close(img); exit(1); } else if (block == 0) { tsk_printf("Inode not found\n"); fs->close(fs); img->close(img); exit(1); } if (tsk_fs_ifind_data(fs, localflags, block)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } } else if (localflags & TSK_FS_IFIND_PAR) { if ((fs->ftype & TSK_FS_INFO_TYPE_FS_MASK) != TSK_FS_INFO_TYPE_NTFS_TYPE) { tsk_fprintf(stderr, "-p works only with NTFS file systems\n"); fs->close(fs); img->close(img); exit(1); } else if (parinode > fs->last_inum) { tsk_fprintf(stderr, "Meta data %" PRIuINUM " is larger than last MFT entry in image (%" PRIuINUM ")\n", parinode, fs->last_inum); fs->close(fs); img->close(img); exit(1); } if (tsk_fs_ifind_par(fs, localflags, parinode)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } } else if (localflags & TSK_FS_IFIND_PATH) { int retval; INUM_T inum; if (-1 == (retval = tsk_fs_ifind_path(fs, localflags, path, &inum))) { tsk_error_print(stderr); fs->close(fs); img->close(img); free(path); exit(1); } free(path); if (retval == 1) tsk_printf("File not found\n"); else tsk_printf("%" PRIuINUM "\n", inum); } fs->close(fs); img->close(img); exit(0); }
TSK_IMG_INFO * ewf_open(int a_num_img, const TSK_TCHAR * const a_images[], unsigned int a_ssize) { IMG_EWF_INFO *ewf_info; TSK_IMG_INFO *img_info; #if !defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) uint8_t md5_hash[16]; #endif if ((ewf_info = (IMG_EWF_INFO *) tsk_img_malloc(sizeof(IMG_EWF_INFO))) == NULL) { return NULL; } img_info = (TSK_IMG_INFO *) ewf_info; // See if they specified only the first of the set... if (a_num_img == 1) { #ifdef TSK_WIN32 ewf_info->num_imgs = libewf_glob_wide(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images); #else ewf_info->num_imgs = libewf_glob(a_images[0], TSTRLEN(a_images[0]), LIBEWF_FORMAT_UNKNOWN, &ewf_info->images); #endif if (ewf_info->num_imgs <= 0) { free(ewf_info); return NULL; } if (tsk_verbose) tsk_fprintf(stderr, "ewf_open: found %d segment files via libewf_glob\n", ewf_info->num_imgs); } else { int i; ewf_info->num_imgs = a_num_img; if ((ewf_info->images = (TSK_TCHAR **) tsk_malloc(a_num_img * sizeof(TSK_TCHAR *))) == NULL) { free(ewf_info); return NULL; } for (i = 0; i < a_num_img; i++) { if ((ewf_info->images[i] = (TSK_TCHAR *) tsk_malloc((TSTRLEN(a_images[i]) + 1) * sizeof(TSK_TCHAR))) == NULL) { free(ewf_info); return NULL; } TSTRNCPY(ewf_info->images[i], a_images[i], TSTRLEN(a_images[i]) + 1); } } /* check the magic before we call the library open */ //if (img_file_header_signature_ncmp(images[0], // "\x45\x56\x46\x09\x0d\x0a\xff\x00", 8) != 1) { #if defined (TSK_WIN32) if (libewf_check_file_signature_wide(ewf_info->images[0]) == 0) { #else if (libewf_check_file_signature(ewf_info->images[0]) == 0) { #endif tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_MAGIC); tsk_error_set_errstr("ewf_open: Not an EWF file"); free(ewf_info); if (tsk_verbose) tsk_fprintf(stderr, "Not an EWF file\n"); return NULL; } #if defined (TSK_WIN32) ewf_info->handle = libewf_open_wide((wchar_t * const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ); #else ewf_info->handle = libewf_open((char *const *) ewf_info->images, ewf_info->num_imgs, LIBEWF_OPEN_READ); #endif if (ewf_info->handle == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error opening", ewf_info->images[0]); free(ewf_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error opening EWF file\n"); } return NULL; } // 2007 version #if defined( LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5 ) img_info->size = libewf_get_media_size(ewf_info->handle); ewf_info->md5hash_isset = libewf_get_stored_md5_hash(ewf_info->handle, ewf_info->md5hash, LIBEWF_STRING_DIGEST_HASH_LENGTH_MD5); // libewf-20080322 version #else if (libewf_get_media_size(ewf_info->handle, (size64_t *) & (img_info->size)) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("ewf_open file: %" PRIttocTSK ": Error getting size of image", ewf_info->images[0]); free(ewf_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error getting size of EWF file\n"); } return NULL; } if (libewf_get_md5_hash(ewf_info->handle, md5_hash, 16) == 1) { int md5_string_iterator = 0; int md5_hash_iterator; for (md5_hash_iterator = 0; md5_hash_iterator < 16; md5_hash_iterator++) { int digit = md5_hash[md5_hash_iterator] / 16; if (digit <= 9) ewf_info->md5hash[md5_string_iterator++] = (char) ('0' + digit); else ewf_info->md5hash[md5_string_iterator++] = (char) ('a' + (digit - 10)); digit = md5_hash[md5_hash_iterator] % 16; if (digit <= 9) ewf_info->md5hash[md5_string_iterator++] = (char) ('0' + digit); else ewf_info->md5hash[md5_string_iterator++] = (char) ('a' + (digit - 10)); } ewf_info->md5hash_isset = 1; } #endif img_info->sector_size = 512; if (a_ssize) img_info->sector_size = a_ssize; img_info->itype = TSK_IMG_TYPE_EWF_EWF; img_info->read = ewf_image_read; img_info->close = ewf_image_close; img_info->imgstat = ewf_image_imgstat; return img_info; }