/** \internal */ uint8_t tsk_fs_nofs_file_add_meta(TSK_FS_INFO * a_fs, TSK_FS_FILE * a_fs_file, TSK_INUM_T inum) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC); tsk_error_set_errstr("Illegal analysis method for %s data ", tsk_fs_type_toname(a_fs->ftype)); return 1; }
/** \internal */ uint8_t tsk_fs_nofs_istat(TSK_FS_INFO * a_fs, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC); tsk_error_set_errstr("Illegal analysis method for %s data ", tsk_fs_type_toname(a_fs->ftype)); return 1; }
uint8_t hdb_base_add_entry(TSK_HDB_INFO *hdb_info, const char *file_name, const char *md5, const char *sha1, const char *sha2_256, const char *comment) { // This function needs an "override" by "derived classes" unless there is an // "override" of the accepts_updates function that returns 0 (false). tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_UNSUPFUNC); tsk_error_set_errstr("hdb_base_add_entry: operation not supported for hdb_info->db_type=%u", hdb_info->db_type); return 1; }
/** * \ingroup vslib * Walk a range of partitions and pass the data to a callback function. * * @param a_vs Pointer to open volume system * @param a_start Address of first partition to walk from. * @param a_last Address of last partition to walk to. * @param a_flags Flags that are used to identify which of the partitions in the range should be returned (if 0, all partitions will be returned). * @param a_action Callback action to call for each partition. * @param a_ptr Pointer to data that will be passed to callback. * @returns 1 on error and 0 on success */ uint8_t tsk_vs_part_walk(TSK_VS_INFO * a_vs, TSK_PNUM_T a_start, TSK_PNUM_T a_last, TSK_VS_PART_FLAG_ENUM a_flags, TSK_VS_PART_WALK_CB a_action, void *a_ptr) { TSK_VS_PART_INFO *part; if (a_start >= a_vs->part_count) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_VS_WALK_RNG); tsk_error_set_errstr ("tsk_vs_part_walk: Start partition too large: %" PRIuPNUM "", a_start); return 1; } if (a_last >= a_vs->part_count) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_VS_WALK_RNG); tsk_error_set_errstr("tsk_vs_part_walk: End partition too large: %" PRIuPNUM "", a_last); return 1; } if (a_flags == 0) { a_flags |= (TSK_VS_PART_FLAG_ALLOC | TSK_VS_PART_FLAG_UNALLOC | TSK_VS_PART_FLAG_META); } for (part = a_vs->part_list; part != NULL; part = part->next) { if ((part->addr >= a_start) && ((part->flags & a_flags) != 0)) { switch (a_action(a_vs, part, a_ptr)) { case TSK_WALK_STOP: return 0; case TSK_WALK_ERROR: return 1; } } if (part->addr >= a_last) break; } return 0; }
/** * \ingroup hashdblib * Rolls back a transaction on a hash database. * @param hdb_info A hash database info object * @return 1 on error, 0 on success */ uint8_t tsk_hdb_rollback_transaction(TSK_HDB_INFO *hdb_info) { const char *func_name = "tsk_hdb_rollback_transaction"; if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("%s: NULL hdb_info", func_name); return 1; } if (!hdb_info->rollback_transaction) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("%s: NULL rollback_transaction function ptr", func_name); return 1; } if (hdb_info->accepts_updates()) { if (hdb_info->transaction_in_progress) { if (hdb_info->commit_transaction(hdb_info)) { return 1; } else { hdb_info->transaction_in_progress = 0; return 0; } } else { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_PROC); tsk_error_set_errstr("%s: transaction not begun", func_name); return 1; } } else { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_PROC); tsk_error_set_errstr("%s: operation not supported for this database type (=%u)", func_name, hdb_info->db_type); return 1; } }
/** \internal */ TSK_RETVAL_ENUM tsk_fs_nofs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir, TSK_INUM_T a_addr) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC); tsk_error_set_errstr("Illegal analysis method for %s data ", tsk_fs_type_toname(a_fs->ftype)); return TSK_ERR; }
static TSK_WALK_RET_ENUM slack_file_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, char *buf, size_t size, TSK_FS_BLOCK_FLAG_ENUM flags, void *ptr) { BLKLS_DATA *data = (BLKLS_DATA *) ptr; if (tsk_verbose) tsk_fprintf(stderr, "slack_file_act: File: %" PRIuINUM " Remaining File: %" PRIuOFF " Buffer: %u\n", fs_file->meta->addr, data->flen, size); /* This is not the last data unit */ if (data->flen >= size) { data->flen -= size; } /* We have passed the end of the allocated space */ else if (data->flen == 0) { if (fwrite(buf, size, 1, stdout) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_WRITE); tsk_error_set_errstr("blkls_lib: error writing to stdout: %s", strerror(errno)); return TSK_WALK_ERROR; } } /* This is the last data unit and there is unused space */ else if (data->flen < size) { /* Clear the used space and print it */ memset(buf, 0, (size_t) data->flen); if (fwrite(buf, size, 1, stdout) != 1) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_WRITE); tsk_error_set_errstr("blkls_lib: error writing to stdout: %s", strerror(errno)); return TSK_WALK_ERROR; } data->flen = 0; } return TSK_WALK_CONT; }
/** * Starts in a specified byte offset of the opened disk images and looks for a * volume system or file system. Will call processFile() on each file * that is found. * @param a_start Byte offset to start analyzing from. * @param a_vtype Volume system type to analyze * @return 1 if an error occured (messages will have been registered) and 0 on success */ uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype) { if (!m_img_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_AUTO_NOTOPEN); tsk_error_set_errstr("findFilesInVs -- img_info"); registerError(); return 1; } TSK_VS_INFO *vs_info; // USE mm_walk to get the volumes if ((vs_info = tsk_vs_open(m_img_info, a_start, a_vtype)) == NULL) { /* we're going to ignore this error to avoid confusion if the * fs_open passes. */ tsk_error_reset(); if(tsk_verbose) fprintf(stderr, "findFilesInVs: Error opening volume system, trying as a file system\n"); /* There was no volume system, but there could be a file system * Errors will have been registered */ findFilesInFs(a_start); } // process the volume system else { TSK_FILTER_ENUM retval = filterVs(vs_info); if ((retval == TSK_FILTER_STOP) || (retval == TSK_FILTER_SKIP)|| (m_stopAllProcessing)) return m_errors.empty() ? 0 : 1; /* Walk the allocated volumes (skip metadata and unallocated volumes) */ if (tsk_vs_part_walk(vs_info, 0, vs_info->part_count - 1, m_volFilterFlags, vsWalkCb, this)) { registerError(); tsk_vs_close(vs_info); return 1; } tsk_vs_close(vs_info); } return m_errors.empty() ? 0 : 1; }
/* * return 1 on error and 0 on success */ uint8_t rawfs_file_walk(TSK_FS_INFO * fs, TSK_FS_INODE * inode, uint32_t type, uint16_t id, TSK_FS_FILE_FLAG_ENUM flags, TSK_FS_FILE_WALK_CB action, void *ptr) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_FUNC; snprintf(tsk_errstr, TSK_ERRSTR_L, " Illegal analysis method for raw data "); return 1; }
/* * return 1 on error and 0 on success */ uint8_t rawfs_dent_walk(TSK_FS_INFO * fs, INUM_T inode, TSK_FS_DENT_FLAG_ENUM flags, TSK_FS_DENT_TYPE_WALK_CB action, void *ptr) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_FUNC; snprintf(tsk_errstr, TSK_ERRSTR_L, "Illegal analysis method for raw data"); return 1; }
uint8_t tsk_hdb_open_idx(TSK_HDB_INFO *hdb_info, TSK_HDB_HTYPE_ENUM htype) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_open_idx: NULL hdb_info"); return 0; } return hdb_info->open_index(hdb_info, htype); }
/** \internal */ uint8_t tsk_fs_nofs_inode_walk(TSK_FS_INFO * a_fs, TSK_INUM_T a_start_inum, TSK_INUM_T a_end_inum, TSK_FS_META_FLAG_ENUM a_flags, TSK_FS_META_WALK_CB a_action, void *a_ptr) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNSUPFUNC); tsk_error_set_errstr("Illegal analysis method for %s data ", tsk_fs_type_toname(a_fs->ftype)); return 1; }
/** * This function should find the corresponding name at a * given offset. In this case though, we do not have the original database, * so just make an error... * * @param hdb_info Hash database to get data from * @param hash MD5 hash value that was searched for * @param offset Byte offset where hash value should be located in db_file * @param flags (not used) * @param action Callback used for each entry found in lookup * @param cb_ptr Pointer to data passed to callback * * @return 1 on error and 0 on succuss */ uint8_t idxonly_getentry(TSK_HDB_INFO * hdb_info, const char *hash, TSK_OFF_T offset, TSK_HDB_FLAG_ENUM flags, TSK_HDB_LOOKUP_FN action, void *cb_ptr) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr( "idxonly_getentry: Not supported when INDEX ONLY option is used"); return 1; }
/* * Walk the partitions that have already been loaded during _open * * Return 1 on error and 0 on success */ uint8_t gpt_part_walk(TSK_MM_INFO * mm, PNUM_T start, PNUM_T last, int flags, TSK_MM_PART_WALK_CB action, void *ptr) { TSK_MM_PART *part; unsigned int cnt = 0; if (start < mm->first_part || start > mm->last_part) { tsk_error_reset(); tsk_errno = TSK_ERR_MM_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "Starting partition: %" PRIuPNUM "", start); return 1; } if (last < mm->first_part || last > mm->last_part) { tsk_error_reset(); tsk_errno = TSK_ERR_MM_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "Ending partition: %" PRIuPNUM "", last); return 1; } part = mm->part_list; while ((part != NULL) && (cnt <= last)) { if (cnt >= start) { int retval; retval = action(mm, cnt, part, 0, ptr); if (retval == TSK_WALK_STOP) return 0; else if (retval == TSK_WALK_ERROR) return 1; } part = part->next; cnt++; } return 0; }
/** * \ingroup hashdblib * Create an index for an open hash database. * @param hdb_info Open hash database to index * @param type Text of hash database type * @returns 1 on error */ uint8_t tsk_hdb_make_index(TSK_HDB_INFO *hdb_info, TSK_TCHAR *type) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_make_index: NULL hdb_info"); return 1; } return hdb_info->make_index(hdb_info, type); }
const TSK_TCHAR * tsk_hdb_get_db_path(TSK_HDB_INFO * hdb_info) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_get_db_path: NULL hdb_info"); return 0; } return hdb_info->get_db_path(hdb_info); }
/** * \ingroup hashdblib * Closes an open hash database. * @param hdb_info The hash database object */ void tsk_hdb_close(TSK_HDB_INFO *hdb_info) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_close: NULL hdb_info"); return; } hdb_info->close_db(hdb_info); }
/** \ingroup fslib * Return the number of attributes in the file. * * @param a_fs_file File to return attribute count for * @returns number of attributes in file */ int tsk_fs_file_attr_getsize(TSK_FS_FILE * a_fs_file) { if (tsk_fs_file_attr_check(a_fs_file, "tsk_fs_file_attr_getsize")) { // @@@ Not sure if we should be ignoring this error or not... // Just added the reset because we were returning 0 with error codes set tsk_error_reset(); return 0; } return tsk_fs_attrlist_get_len(a_fs_file->meta->attr); }
/** * \ingroup hashdblib * Indicates whether a hash database accepts updates. * @param hdb_info The hash database object * @return 1 if hash database accepts updates, 0 if it does not */ uint8_t tsk_hdb_accepts_updates(TSK_HDB_INFO *hdb_info) { const char *func_name = "tsk_hdb_accepts_updates"; if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("%s: NULL hdb_info", func_name); return 0; } if (!hdb_info->accepts_updates) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("%s: NULL add_entry function ptr", func_name); return 0; } return hdb_info->accepts_updates(); }
const char * tsk_hdb_get_display_name(TSK_HDB_INFO * hdb_info) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_get_display_name: NULL hdb_info"); return 0; } return hdb_info->get_display_name(hdb_info); }
/** * Starts in sector 0 of the opened disk images and looks for a * volume or file system. Will call processFile() on each file * that is found. * @return 1 on error, 0 on success */ uint8_t TskAuto::findFilesInImg() { if (!m_img_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_AUTO_NOTOPEN); tsk_error_set_errstr("findFilesInImg\n"); return 1; } return findFilesInVs(0); }
/** * \ingroup hashdblib * Test for index only (legacy) * Assumes that the db was opened using the TSK_HDB_OPEN_TRY option. * * @param hdb_info Hash database to consider * * @return 1 if there is only a legacy index AND no db, 0 otherwise */ uint8_t tsk_hdb_is_idx_only(TSK_HDB_INFO *hdb_info) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_is_idx_only: NULL hdb_info"); return 0; } return (hdb_info->db_type == TSK_HDB_DBTYPE_IDXONLY_ID); }
/** * \ingroup fslib * Process an attribute and call a callback function with its contents. The callback will be * called with chunks of data that are fs->block_size or less. The address given in the callback * will be correct only for raw files (when the raw file contents were stored in the block). For * compressed and sparse attributes, the address may be zero. * * @param a_fs_attr Attribute to process * @param a_flags Flags to use while processing attribute * @param a_action Callback action to call with content * @param a_ptr Pointer that will passed to callback * @returns 1 on error and 0 on success. */ uint8_t tsk_fs_attr_walk(const TSK_FS_ATTR * a_fs_attr, TSK_FS_FILE_WALK_FLAG_ENUM a_flags, TSK_FS_FILE_WALK_CB a_action, void *a_ptr) { TSK_FS_INFO *fs; // clean up any error messages that are lying around tsk_error_reset(); // check the FS_INFO, FS_FILE structures if ((a_fs_attr == NULL) || (a_fs_attr->fs_file == NULL) || (a_fs_attr->fs_file->meta == NULL) || (a_fs_attr->fs_file->fs_info == NULL)) { tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr ("tsk_fs_attr_walk: called with NULL pointers"); return 1; } fs = a_fs_attr->fs_file->fs_info; if (fs->tag != TSK_FS_INFO_TAG) { // || (a_fs_attr->id != TSK_FS_ATTR_ID)) { tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr ("tsk_fs_attr_walk: called with unallocated structures"); return 1; } if (a_fs_attr->flags & TSK_FS_ATTR_COMP) { if (a_fs_attr->w == NULL) { tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr ("tsk_fs_attr_walk: compressed attribute found, but special function not defined"); return 1; } return a_fs_attr->w(a_fs_attr, a_flags, a_action, a_ptr); } // resident data if (a_fs_attr->flags & TSK_FS_ATTR_RES) { return tsk_fs_attr_walk_res(a_fs_attr, a_flags, a_action, a_ptr); } // non-resident data else if (a_fs_attr->flags & TSK_FS_ATTR_NONRES) { return tsk_fs_attr_walk_nonres(a_fs_attr, a_flags, a_action, a_ptr); } tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr ("tsk_fs_attr_walk: called with unknown attribute type: %x", a_fs_attr->flags); return 1; }
const TSK_TCHAR * tsk_hdb_get_idx_path(TSK_HDB_INFO * hdb_info, TSK_HDB_HTYPE_ENUM htype) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_get_idx_path: NULL hdb_info"); return 0; } return hdb_info->get_index_path(hdb_info, htype); }
uint8_t tsk_hdb_uses_external_indexes(TSK_HDB_INFO *hdb_info) { if (!hdb_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_HDB_ARG); tsk_error_set_errstr("tsk_hdb_get_display_name: NULL hdb_info"); return 0; } return hdb_info->uses_external_indexes(); }
/** \internal * Add a new attribute to the list. * * @param a_fs_attrlist List structure to add to * @param a_fs_attr Data attribute to add * @returns 1 on error and 0 on success. Caller must free memory on error. */ uint8_t tsk_fs_attrlist_add(TSK_FS_ATTRLIST * a_fs_attrlist, TSK_FS_ATTR * a_fs_attr) { if (a_fs_attrlist == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr("Null list in tsk_fs_attrlist_add"); return 1; } // verify INUSE is set a_fs_attr->flags |= TSK_FS_ATTR_INUSE; if (a_fs_attrlist->head == NULL) { a_fs_attrlist->head = a_fs_attr; } else { TSK_FS_ATTR *fs_attr_cur; fs_attr_cur = a_fs_attrlist->head; while (fs_attr_cur) { // check if it already exists if ((fs_attr_cur->type == a_fs_attr->type) && (fs_attr_cur->id == a_fs_attr->id)) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr ("datalist_add: Type %d and Id %d already in list", a_fs_attr->type, a_fs_attr->id); return 1; } if (fs_attr_cur->next == NULL) { fs_attr_cur->next = a_fs_attr; break; } fs_attr_cur = fs_attr_cur->next; } } return 0; }
/* rawfs_open - open a file as raw * * Return NULL on error * */ TSK_FS_INFO * rawfs_open(TSK_IMG_INFO * img_info, SSIZE_T offset) { OFF_T len; TSK_FS_INFO *fs; // clean up any error messages that are lying around tsk_error_reset(); fs = (TSK_FS_INFO *) tsk_malloc(sizeof(TSK_FS_INFO)); if (fs == NULL) return NULL; /* All we need to set are the block sizes and max block size etc. */ fs->img_info = img_info; fs->offset = offset; fs->ftype = TSK_FS_INFO_TYPE_RAW; fs->duname = "Sector"; fs->flags = 0; fs->inum_count = 0; fs->root_inum = 0; fs->first_inum = 0; fs->last_inum = 0; len = img_info->get_size(img_info); fs->block_count = len / 512; if (len % 512) fs->block_count++; fs->first_block = 0; fs->last_block = fs->block_count - 1; fs->block_size = 512; fs->dev_bsize = 512; fs->inode_walk = rawfs_inode_walk; fs->block_walk = rawfs_block_walk; fs->inode_lookup = rawfs_inode_lookup; fs->dent_walk = rawfs_dent_walk; fs->file_walk = rawfs_file_walk; fs->fsstat = rawfs_fsstat; fs->istat = rawfs_istat; fs->close = rawfs_close; fs->jblk_walk = rawfs_jblk_walk; fs->jentry_walk = rawfs_jentry_walk; fs->jopen = rawfs_jopen; fs->journ_inum = 0; return (fs); }
/** * Volume system walk callback function that will analyze * each volume to find a file system. */ static TSK_WALK_RET_ENUM vsAct(TskVsInfo * vs_info, const TskVsPartInfo * vs_part, void *ptr) { if (procFs(const_cast<TskImgInfo *>(vs_info->getImgInfo()), const_cast<TskVsPartInfo *>(vs_part)->getStart() * vs_info->getBlockSize())) { // if we return ERROR here, then the walk will stop. But, the // error could just be because we looked into an unallocated volume. // do any special error handling / reporting here. tsk_error_reset(); return TSK_WALK_CONT; } return TSK_WALK_CONT; }
/** * Volume system walk callback function that will analyze * each volume to find a file system. */ static TSK_WALK_RET_ENUM vs_act(TSK_VS_INFO * vs_info, const TSK_VS_PART_INFO * vs_part, void *ptr) { if (proc_fs(vs_info->img_info, vs_part->start * vs_info->block_size)) { // if we return ERROR here, then the walk will stop. But, the // error could just be because we looked into an unallocated volume. // do any special error handling / reporting here. tsk_error_reset(); return TSK_WALK_CONT; } return TSK_WALK_CONT; }
/** * \internal * Set the fields of a FS_BLOCk structure. This is internally used to set the data from a * larger buffer so that larger disk reads can occur. * * @param a_fs File system * @param a_fs_block Block to load data into * @param a_addr Address where data is from * @param a_flags Flags for data * @param a_buf Buffer to copy data from and into a_fs_block (block_size will be copied) * @returns 1 on error, 0 on success */ int tsk_fs_block_set(TSK_FS_INFO * a_fs, TSK_FS_BLOCK * a_fs_block, TSK_DADDR_T a_addr, TSK_FS_BLOCK_FLAG_ENUM a_flags, char *a_buf) { if ((a_fs == NULL) || (a_fs->tag != TSK_FS_INFO_TAG)) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_READ); tsk_error_set_errstr("tsk_fs_block_set: fs_info unallocated"); return 1; } if ((a_fs_block->tag != TSK_FS_BLOCK_TAG) || (a_fs_block->buf == NULL)) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_READ); tsk_error_set_errstr("tsk_fs_block_set: fs_block unallocated"); return 1; } a_fs_block->fs_info = a_fs; memcpy(a_fs_block->buf, a_buf, a_fs->block_size); a_fs_block->addr = a_addr; a_fs_block->flags = a_flags; return 0; }