diff --git a/bindings/java/jni/dataModel_SleuthkitJNI.cpp b/bindings/java/jni/dataModel_SleuthkitJNI.cpp index 29ec6ab3cfbc47a2942167ab5489275a59b69c62..fc9ec672d9df2f3cb0201368fe83c73d50d420ed 100644 --- a/bindings/java/jni/dataModel_SleuthkitJNI.cpp +++ b/bindings/java/jni/dataModel_SleuthkitJNI.cpp @@ -1901,7 +1901,7 @@ JNIEXPORT jint JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_saveFileMetaDat } env->ReleaseStringUTFChars(a_tmp_path, str8); - if (fs_info->istat(fs_info, hFile, file_handle->fs_file->meta->addr, 0, 0) != 0) { + if (fs_info->istat(fs_info, TSK_FS_ISTAT_RUNLIST, hFile, file_handle->fs_file->meta->addr, 0, 0) != 0) { fclose(hFile); setThrowTskCoreError(env); return -1; diff --git a/tools/fstools/istat.cpp b/tools/fstools/istat.cpp index 9e80b7b604ab6c5f0beb850afb3517d795cb77fc..fb558d7b75e32d4f88352e9c5bad1ff835c32c3f 100644 --- a/tools/fstools/istat.cpp +++ b/tools/fstools/istat.cpp @@ -30,10 +30,11 @@ usage() { TFPRINTF(stderr, _TSK_T - ("usage: %s [-B num] [-f fstype] [-i imgtype] [-b dev_sector_size] [-o imgoffset] [-z zone] [-s seconds] [-vV] image inum\n"), + ("usage: %s [-B num] [-f fstype] [-i imgtype] [-b dev_sector_size] [-o imgoffset] [-z zone] [-s seconds] [-rvV] image inum\n"), progname); tsk_fprintf(stderr, "\t-B num: force the display of NUM address of block pointers\n"); + tsk_fprintf(stderr, "\t-r: display run list instead of list of block addresses\n"); tsk_fprintf(stderr, "\t-z zone: time zone of original machine (i.e. EST5EDT or GMT)\n"); tsk_fprintf(stderr, @@ -45,7 +46,7 @@ usage() tsk_fprintf(stderr, "\t-f fstype: File system type (use '-f list' for supported types)\n"); tsk_fprintf(stderr, - "\t-o imgoffset: The offset of the file system in the image (in sectors)\n"); + "\t-o imgoffset: The offset of the file system in the image (in sectors)\n"); tsk_fprintf(stderr, "\t-v: verbose output to stderr\n"); tsk_fprintf(stderr, "\t-V: print version\n"); exit(1); @@ -66,6 +67,7 @@ main(int argc, char **argv1) int ch; TSK_TCHAR *cp; int32_t sec_skew = 0; + int istat_flags = 0; /* When > 0 this is the number of blocks to print, used for -B arg */ TSK_DADDR_T numblock = 0; @@ -86,7 +88,7 @@ main(int argc, char **argv1) progname = argv[0]; setlocale(LC_ALL, ""); - while ((ch = GETOPT(argc, argv, _TSK_T("b:B:f:i:o:s:vVz:"))) > 0) { + while ((ch = GETOPT(argc, argv, _TSK_T("b:B:f:i:o:rs:vVz:"))) > 0) { switch (ch) { case _TSK_T('?'): default: @@ -146,6 +148,9 @@ main(int argc, char **argv1) case _TSK_T('s'): sec_skew = TATOI(OPTARG); break; + case _TSK_T('r'): + istat_flags |= TSK_FS_ISTAT_RUNLIST; + break; case _TSK_T('v'): tsk_verbose++; break; @@ -225,7 +230,7 @@ main(int argc, char **argv1) exit(1); } - if (fs->istat(fs, stdout, inum, numblock, sec_skew)) { + if (fs->istat(fs, (TSK_FS_ISTAT_FLAG_ENUM) istat_flags, stdout, inum, numblock, sec_skew)) { tsk_error_print(stderr); fs->close(fs); img->close(img); diff --git a/tsk/fs/ext2fs.c b/tsk/fs/ext2fs.c index 3e08a0fb20bd8232a58c65c38ade46f52277d86b..3a68220cf795b0487dc40adae8bc0c314c534995 100644 --- a/tsk/fs/ext2fs.c +++ b/tsk/fs/ext2fs.c @@ -2573,7 +2573,7 @@ print_addr_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, * @returns 1 on error and 0 on success */ static uint8_t -ext2fs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, +ext2fs_istat(TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs; @@ -3037,17 +3037,31 @@ ext2fs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, tsk_fprintf(hFile, "\nDirect Blocks:\n"); - print.idx = 0; - print.hFile = hFile; - - if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_AONLY, - print_addr_act, (void *) &print)) { - tsk_fprintf(hFile, "\nError reading file: "); - tsk_error_print(hFile); - tsk_error_reset(); + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + const TSK_FS_ATTR *fs_attr_default = + tsk_fs_file_attr_get_type(fs_file, + TSK_FS_ATTR_TYPE_DEFAULT, 0, 0); + if (fs_attr_default && (fs_attr_default->flags & TSK_FS_ATTR_NONRES)) { + if (tsk_fs_attr_print(fs_attr_default, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + } } - else if (print.idx != 0) { - tsk_fprintf(hFile, "\n"); + else { + print.idx = 0; + print.hFile = hFile; + + if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_AONLY, + print_addr_act, (void *)&print)) { + tsk_fprintf(hFile, "\nError reading file: "); + tsk_error_print(hFile); + tsk_error_reset(); + } + else if (print.idx != 0) { + tsk_fprintf(hFile, "\n"); + } } if (fs_meta->content_type == TSK_FS_META_CONTENT_TYPE_EXT4_EXTENTS) { @@ -3057,18 +3071,27 @@ ext2fs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, if (fs_attr_extent) { tsk_fprintf(hFile, "\nExtent Blocks:\n"); - print.idx = 0; + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + if (tsk_fs_attr_print(fs_attr_extent, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + } + else { + print.idx = 0; - if (tsk_fs_attr_walk(fs_attr_extent, + if (tsk_fs_attr_walk(fs_attr_extent, TSK_FS_FILE_WALK_FLAG_AONLY, print_addr_act, - (void *) &print)) { - tsk_fprintf(hFile, - "\nError reading indirect attribute: "); - tsk_error_print(hFile); - tsk_error_reset(); - } - else if (print.idx != 0) { - tsk_fprintf(hFile, "\n"); + (void *)&print)) { + tsk_fprintf(hFile, + "\nError reading indirect attribute: "); + tsk_error_print(hFile); + tsk_error_reset(); + } + else if (print.idx != 0) { + tsk_fprintf(hFile, "\n"); + } } } } @@ -3077,19 +3100,23 @@ ext2fs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, TSK_FS_ATTR_TYPE_UNIX_INDIR, 0, 0); if (fs_attr_indir) { tsk_fprintf(hFile, "\nIndirect Blocks:\n"); + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + tsk_fs_attr_print(fs_attr_indir, hFile); + } + else { + print.idx = 0; - print.idx = 0; - - if (tsk_fs_attr_walk(fs_attr_indir, + if (tsk_fs_attr_walk(fs_attr_indir, TSK_FS_FILE_WALK_FLAG_AONLY, print_addr_act, - (void *) &print)) { - tsk_fprintf(hFile, - "\nError reading indirect attribute: "); - tsk_error_print(hFile); - tsk_error_reset(); - } - else if (print.idx != 0) { - tsk_fprintf(hFile, "\n"); + (void *)&print)) { + tsk_fprintf(hFile, + "\nError reading indirect attribute: "); + tsk_error_print(hFile); + tsk_error_reset(); + } + else if (print.idx != 0) { + tsk_fprintf(hFile, "\n"); + } } } } diff --git a/tsk/fs/fatfs_meta.c b/tsk/fs/fatfs_meta.c index 591853d08372202da441ae1324e2603e37593c86..a002ac3f91dd01b5103dc56ff98ff22c44571663 100755 --- a/tsk/fs/fatfs_meta.c +++ b/tsk/fs/fatfs_meta.c @@ -885,17 +885,17 @@ print_addr_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, * @returns 1 on error and 0 on success. */ uint8_t -fatfs_istat(TSK_FS_INFO *a_fs, FILE *a_hFile, TSK_INUM_T a_inum, +fatfs_istat(TSK_FS_INFO *a_fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE *a_hFile, TSK_INUM_T a_inum, TSK_DADDR_T a_numblock, int32_t a_sec_skew) { const char* func_name = "fatfs_istat"; FATFS_INFO *fatfs = (FATFS_INFO*)a_fs; - TSK_FS_META *fs_meta = NULL; - TSK_FS_FILE *fs_file = NULL; + TSK_FS_META *fs_meta = NULL; + TSK_FS_FILE *fs_file = NULL; TSK_FS_META_NAME_LIST *fs_name_list = NULL; FATFS_PRINT_ADDR print; char timeBuf[128]; - + tsk_error_reset(); if (fatfs_ptr_arg_is_null(a_fs, "a_fs", func_name) || fatfs_ptr_arg_is_null(a_hFile, "a_hFile", func_name) || @@ -975,7 +975,7 @@ fatfs_istat(TSK_FS_INFO *a_fs, FILE *a_hFile, TSK_INUM_T a_inum, } tsk_fprintf(a_hFile, "Written:\t%s\n", tsk_fs_time_to_str(fs_meta->mtime, - timeBuf)); + timeBuf)); tsk_fprintf(a_hFile, "Accessed:\t%s\n", tsk_fs_time_to_str(fs_meta->atime, timeBuf)); tsk_fprintf(a_hFile, "Created:\t%s\n", @@ -983,22 +983,37 @@ fatfs_istat(TSK_FS_INFO *a_fs, FILE *a_hFile, TSK_INUM_T a_inum, /* Print the specified number of sector addresses. */ tsk_fprintf(a_hFile, "\nSectors:\n"); - if (a_numblock > 0) { - /* A bad hack to force a specified number of blocks */ - fs_meta->size = a_numblock * a_fs->block_size; + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + const TSK_FS_ATTR *fs_attr_default = + tsk_fs_file_attr_get_type(fs_file, + TSK_FS_ATTR_TYPE_DEFAULT, 0, 0); + if (fs_attr_default && (fs_attr_default->flags & TSK_FS_ATTR_NONRES)) { + if (tsk_fs_attr_print(fs_attr_default, a_hFile)) { + tsk_fprintf(a_hFile, "\nError creating run lists\n"); + tsk_error_print(a_hFile); + tsk_error_reset(); + } + } } - print.istat_seen = 0; - print.idx = 0; - print.hFile = a_hFile; - if (tsk_fs_file_walk(fs_file, + else { + + if (a_numblock > 0) { + /* A bad hack to force a specified number of blocks */ + fs_meta->size = a_numblock * a_fs->block_size; + } + print.istat_seen = 0; + print.idx = 0; + print.hFile = a_hFile; + if (tsk_fs_file_walk(fs_file, (TSK_FS_FILE_WALK_FLAG_ENUM)(TSK_FS_FILE_WALK_FLAG_AONLY | TSK_FS_FILE_WALK_FLAG_SLACK), - print_addr_act, (void *) &print)) { - tsk_fprintf(a_hFile, "\nError reading file\n"); - tsk_error_print(a_hFile); - tsk_error_reset(); - } - else if (print.idx != 0) { - tsk_fprintf(a_hFile, "\n"); + print_addr_act, (void *)&print)) { + tsk_fprintf(a_hFile, "\nError reading file\n"); + tsk_error_print(a_hFile); + tsk_error_reset(); + } + else if (print.idx != 0) { + tsk_fprintf(a_hFile, "\n"); + } } tsk_fs_file_close(fs_file); diff --git a/tsk/fs/ffs.c b/tsk/fs/ffs.c index df48ccb2ac3e7ba03b668d36762dfbd53f348cc8..c000a6f098e029052c2e824414a42dd9b0abf08e 100644 --- a/tsk/fs/ffs.c +++ b/tsk/fs/ffs.c @@ -1682,7 +1682,7 @@ print_addr_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, * @returns 1 on error and 0 on success */ static uint8_t -ffs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, +ffs_istat(TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { FFS_INFO *ffs = (FFS_INFO *) fs; @@ -1882,35 +1882,56 @@ ffs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, tsk_fprintf(hFile, "\nDirect Blocks:\n"); - print.idx = 0; - print.hFile = hFile; - - if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_AONLY, - print_addr_act, (void *) &print)) { - tsk_fprintf(hFile, "\nError reading blocks in file\n"); - tsk_error_print(hFile); - tsk_fs_file_close(fs_file); - return 1; + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + TSK_FS_ATTR * fs_attr_direct = tsk_fs_file_attr_get_type(fs_file, + TSK_FS_ATTR_TYPE_DEFAULT, 0, 0); + if (fs_attr_direct && (fs_attr_direct->flags & TSK_FS_ATTR_NONRES)) { + if (tsk_fs_attr_print(fs_attr_direct, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + } } + else { + print.idx = 0; + print.hFile = hFile; - if (print.idx != 0) - tsk_fprintf(hFile, "\n"); + if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_AONLY, + print_addr_act, (void *)&print)) { + tsk_fprintf(hFile, "\nError reading blocks in file\n"); + tsk_error_print(hFile); + tsk_fs_file_close(fs_file); + return 1; + } + + if (print.idx != 0) + tsk_fprintf(hFile, "\n"); + } fs_attr_indir = tsk_fs_file_attr_get_type(fs_file, TSK_FS_ATTR_TYPE_UNIX_INDIR, 0, 0); if (fs_attr_indir) { tsk_fprintf(hFile, "\nIndirect Blocks:\n"); - - print.idx = 0; - - if (tsk_fs_attr_walk(fs_attr_indir, TSK_FS_FILE_WALK_FLAG_AONLY, - print_addr_act, (void *) &print)) { - tsk_fprintf(hFile, "\nError reading indirect attribute: "); - tsk_error_print(hFile); - tsk_error_reset(); + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + if (tsk_fs_attr_print(fs_attr_indir, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } } - else if (print.idx != 0) { - tsk_fprintf(hFile, "\n"); + else { + print.idx = 0; + + if (tsk_fs_attr_walk(fs_attr_indir, TSK_FS_FILE_WALK_FLAG_AONLY, + print_addr_act, (void *)&print)) { + tsk_fprintf(hFile, "\nError reading indirect attribute: "); + tsk_error_print(hFile); + tsk_error_reset(); + } + else if (print.idx != 0) { + tsk_fprintf(hFile, "\n"); + } } } diff --git a/tsk/fs/fs_attr.c b/tsk/fs/fs_attr.c index 58a066ff9bc3aeb39764395ae212f14f05a5b5e0..8f1edea1e1f1ed27ed701b13045c40e37c27de4f 100644 --- a/tsk/fs/fs_attr.c +++ b/tsk/fs/fs_attr.c @@ -369,6 +369,102 @@ dump_attr(TSK_FS_ATTR * a_fs_attr) } } +/* + * Prints the data runs for a non-resident attribute + */ +uint8_t +tsk_fs_attr_print(const TSK_FS_ATTR * a_fs_attr, FILE* hFile) { + TSK_FS_ATTR_RUN *cur_run; + TSK_FS_ATTR_RUN *fs_attr_run; + uint32_t skip_remain; + TSK_OFF_T tot_size; + TSK_FS_INFO *fs = a_fs_attr->fs_file->fs_info; + TSK_OFF_T off = 0; + uint8_t stop_loop = 0; + + if ( ! (a_fs_attr->flags & TSK_FS_ATTR_NONRES)) { + tsk_error_set_errstr("tsk_fs_attr_print called on non-resident attribute"); + return TSK_ERR; + } + + cur_run = a_fs_attr->nrd.run; + tot_size = a_fs_attr->size; + skip_remain = a_fs_attr->nrd.skiplen; + + for (fs_attr_run = a_fs_attr->nrd.run; fs_attr_run; + fs_attr_run = fs_attr_run->next) { + TSK_DADDR_T addr, len_idx, run_len, run_start_addr; + + addr = fs_attr_run->addr; + run_len = 0; + run_start_addr = addr; + + /* cycle through each block in the run */ + for (len_idx = 0; len_idx < fs_attr_run->len; len_idx++) { + + + /* If the address is too large then give an error */ + if (addr + len_idx > fs->last_block) { + if (a_fs_attr->fs_file-> + meta->flags & TSK_FS_META_FLAG_UNALLOC) + tsk_error_set_errno(TSK_ERR_FS_RECOVER); + else + tsk_error_set_errno(TSK_ERR_FS_BLK_NUM); + tsk_error_set_errstr + ("Invalid address in run (too large): %" PRIuDADDR "", + addr + len_idx); + return TSK_ERR; + } + + + /* Need to account for the skip length, which is the number of bytes + * in the start of the attribute that are skipped and that are not + * included in the overall length. We will seek past those and not + * return those in the action. We just read a block size so check + * if there is data to be returned in this buffer. */ + + if (skip_remain >= fs->block_size) { + skip_remain -= fs->block_size; + run_start_addr++; + } + else { + size_t ret_len; + + /* Do we want to return a full block, or just the end? */ + if ((TSK_OFF_T)fs->block_size - skip_remain < + tot_size - off) + ret_len = fs->block_size - skip_remain; + else + ret_len = (size_t)(tot_size - off); + + off += ret_len; + run_len++; + skip_remain = 0; + + if (off >= tot_size) { + stop_loop = 1; + break; + } + } + } + + if (cur_run->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE) { + tsk_fprintf(hFile, " Staring address: X, length: %lld Sparse", run_len); + } + else if (cur_run->flags & TSK_FS_ATTR_RUN_FLAG_FILLER) { + tsk_fprintf(hFile, " Staring address: X, length: %lld Filler", run_len); + } + else { + tsk_fprintf(hFile, " Staring address: %lld, length: %lld", run_start_addr, run_len); + } + tsk_fprintf(hFile, "\n"); + if (stop_loop) { + break; + } + } + return TSK_OK; +} + /** * \internal * Add a set of consecutive runs to an attribute. This will add and remove FILLER entries diff --git a/tsk/fs/hfs.c b/tsk/fs/hfs.c index bfb101bd7c580754dea4caf38c8250c0e2794a45..d40d46e75c53b770af49b814536e671e3ee24769 100644 --- a/tsk/fs/hfs.c +++ b/tsk/fs/hfs.c @@ -5482,7 +5482,7 @@ print_addr_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, * @returns 1 on error and 0 on success */ static uint8_t -hfs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, +hfs_istat(TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { HFS_INFO *hfs = (HFS_INFO *) fs; @@ -5749,52 +5749,58 @@ hfs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, // N.B., a compressed file has no data fork, and tsk_fs_file_walk() will // do the wrong thing! if (!(entry.cat.std.perm.o_flags & HFS_PERM_OFLAG_COMPRESSED)) { - tsk_fprintf(hFile, "\nData Fork Blocks:\n"); - print.idx = 0; - print.hFile = hFile; - print.accumulating = FALSE; - print.startBlock = 0; - print.blockCount = 0; - - if (tsk_fs_file_walk_type(fs_file, + + if (!(istat_flags & TSK_FS_ISTAT_RUNLIST)) { + tsk_fprintf(hFile, "\nData Fork Blocks:\n"); + print.idx = 0; + print.hFile = hFile; + print.accumulating = FALSE; + print.startBlock = 0; + print.blockCount = 0; + + if (tsk_fs_file_walk_type(fs_file, TSK_FS_ATTR_TYPE_HFS_DATA, HFS_FS_ATTR_ID_DATA, (TSK_FS_FILE_WALK_FLAG_AONLY | TSK_FS_FILE_WALK_FLAG_SLACK), print_addr_act, - (void *) &print)) { - tsk_fprintf(hFile, "\nError reading file data fork\n"); - tsk_error_print(hFile); - tsk_error_reset(); - } - else { - output_print_addr(&print); - if (print.idx != 0) - tsk_fprintf(hFile, "\n"); + (void *)&print)) { + tsk_fprintf(hFile, "\nError reading file data fork\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + else { + output_print_addr(&print); + if (print.idx != 0) + tsk_fprintf(hFile, "\n"); + } } } // Only print out the blocks of the Resource fork if it has nonzero size if (tsk_getu64(fs->endian, entry.cat.resource.logic_sz) > 0) { - tsk_fprintf(hFile, "\nResource Fork Blocks:\n"); - print.idx = 0; - print.hFile = hFile; - print.accumulating = FALSE; - print.startBlock = 0; - print.blockCount = 0; + if (! (istat_flags & TSK_FS_ISTAT_RUNLIST)) { + tsk_fprintf(hFile, "\nResource Fork Blocks:\n"); + + print.idx = 0; + print.hFile = hFile; + print.accumulating = FALSE; + print.startBlock = 0; + print.blockCount = 0; - if (tsk_fs_file_walk_type(fs_file, + if (tsk_fs_file_walk_type(fs_file, TSK_FS_ATTR_TYPE_HFS_RSRC, HFS_FS_ATTR_ID_RSRC, (TSK_FS_FILE_WALK_FLAG_AONLY | TSK_FS_FILE_WALK_FLAG_SLACK), print_addr_act, - (void *) &print)) { - tsk_fprintf(hFile, "\nError reading file resource fork\n"); - tsk_error_print(hFile); - tsk_error_reset(); - } - else { - output_print_addr(&print); - if (print.idx != 0) - tsk_fprintf(hFile, "\n"); + (void *)&print)) { + tsk_fprintf(hFile, "\nError reading file resource fork\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + else { + output_print_addr(&print); + if (print.idx != 0) + tsk_fprintf(hFile, "\n"); + } } } @@ -5839,6 +5845,14 @@ hfs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, "", (fs_attr->flags & TSK_FS_ATTR_SPARSE) ? ", Sparse" : "", fs_attr->size, fs_attr->nrd.initsize); + + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + if (tsk_fs_attr_print(fs_attr, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + } } // END: non-resident attribute case else { tsk_fprintf(hFile, diff --git a/tsk/fs/iso9660.c b/tsk/fs/iso9660.c index 5a9f2c60f49f06a73e534cf471cbd0df7e359331..c7b9dc2c2a5680741830bba94eecc6f3279c0dad 100644 --- a/tsk/fs/iso9660.c +++ b/tsk/fs/iso9660.c @@ -2018,7 +2018,7 @@ iso9660_print_rockridge(FILE * hFile, rockridge_ext * rr) * @returns 1 on error and 0 on success */ static uint8_t -iso9660_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, +iso9660_istat(TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { ISO_INFO *iso = (ISO_INFO *) fs; @@ -2182,8 +2182,21 @@ iso9660_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, tsk_fs_time_to_str(fs_file->meta->atime, timeBuf)); tsk_fprintf(hFile, "\nSectors:\n"); - /* since blocks are all contiguous, print them here to simplify file_walk */ - { + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + const TSK_FS_ATTR *fs_attr_default = + tsk_fs_file_attr_get_type(fs_file, + TSK_FS_ATTR_TYPE_DEFAULT, 0, 0); + if (fs_attr_default && (fs_attr_default->flags & TSK_FS_ATTR_NONRES)) { + if (tsk_fs_attr_print(fs_attr_default, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + } + } + else { + /* since blocks are all contiguous, print them here to simplify file_walk */ + int block = tsk_getu32(fs->endian, dinode->dr.ext_loc_m); TSK_OFF_T size = fs_file->meta->size; int rowcount = 0; diff --git a/tsk/fs/nofs_misc.c b/tsk/fs/nofs_misc.c index ebd2e0a59064805780de6c26ebc9fc71fd5389d1..0829d1a7dd879e5a5ce0538892510fd3c4151f10 100644 --- a/tsk/fs/nofs_misc.c +++ b/tsk/fs/nofs_misc.c @@ -197,7 +197,7 @@ tsk_fs_nofs_file_add_meta(TSK_FS_INFO * a_fs, TSK_FS_FILE * a_fs_file, /** \internal */ uint8_t -tsk_fs_nofs_istat(TSK_FS_INFO * a_fs, FILE * hFile, TSK_INUM_T inum, +tsk_fs_nofs_istat(TSK_FS_INFO * a_fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { tsk_error_reset(); diff --git a/tsk/fs/ntfs.c b/tsk/fs/ntfs.c index c39d7e36a2d7f9b7617c16e2e15a836c0405e382..a3090f5ae4282acb58ec0b3afda1378708d99c76 100755 --- a/tsk/fs/ntfs.c +++ b/tsk/fs/ntfs.c @@ -4244,7 +4244,7 @@ print_addr_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, * @returns 1 on error and 0 on success */ static uint8_t -ntfs_istat(TSK_FS_INFO * fs, FILE * hFile, +ntfs_istat(TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { TSK_FS_FILE *fs_file; @@ -4673,20 +4673,29 @@ ntfs_istat(TSK_FS_INFO * fs, FILE * hFile, "", (fs_attr->flags & TSK_FS_ATTR_SPARSE) ? ", Sparse" : "", fs_attr->size, fs_attr->nrd.initsize); - - print_addr.idx = 0; - print_addr.hFile = hFile; - if (tsk_fs_file_walk_type(fs_file, fs_attr->type, + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + if (tsk_fs_attr_print(fs_attr, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + } + else { + print_addr.idx = 0; + print_addr.hFile = hFile; + if (tsk_fs_file_walk_type(fs_file, fs_attr->type, fs_attr->id, (TSK_FS_FILE_WALK_FLAG_AONLY | TSK_FS_FILE_WALK_FLAG_SLACK), - print_addr_act, (void *) &print_addr)) { - tsk_fprintf(hFile, "\nError walking file\n"); - tsk_error_print(hFile); - tsk_error_reset(); + print_addr_act, (void *)&print_addr)) { + tsk_fprintf(hFile, "\nError walking file\n"); + tsk_error_print(hFile); + tsk_error_reset(); + } + if (print_addr.idx != 0) + tsk_fprintf(hFile, "\n"); } - if (print_addr.idx != 0) - tsk_fprintf(hFile, "\n"); + } else { tsk_fprintf(hFile, diff --git a/tsk/fs/tsk_fatfs.h b/tsk/fs/tsk_fatfs.h index aa0a588013cb823d47c77ba60dbe523f1318ac24..ba60294c282bdd8ee67ccf72f5545d4af756a07b 100644 --- a/tsk/fs/tsk_fatfs.h +++ b/tsk/fs/tsk_fatfs.h @@ -331,7 +331,7 @@ extern "C" { fatfs_find_parent_act(TSK_FS_FILE * fs_file, const char *a_path, void *ptr); extern uint8_t - fatfs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, + fatfs_istat(TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew); extern uint8_t fatfs_inode_walk(TSK_FS_INFO * fs, diff --git a/tsk/fs/tsk_fs.h b/tsk/fs/tsk_fs.h index f991d7814d457980f1ea3b3f5a4f915cc019a4ba..6954495a998606c4f4cb4958990aca6c782a3c97 100644 --- a/tsk/fs/tsk_fs.h +++ b/tsk/fs/tsk_fs.h @@ -877,6 +877,12 @@ extern "C" { }; typedef enum TSK_FS_INFO_FLAG_ENUM TSK_FS_INFO_FLAG_ENUM; + enum TSK_FS_ISTAT_FLAG_ENUM { + TSK_FS_ISTAT_NONE = 0x00, + TSK_FS_ISTAT_RUNLIST = 0x01 + }; + typedef enum TSK_FS_ISTAT_FLAG_ENUM TSK_FS_ISTAT_FLAG_ENUM; + #define TSK_FS_INFO_TAG 0x10101010 #define TSK_FS_INFO_FS_ID_LEN 32 // set based on largest file system / volume ID supported @@ -963,7 +969,7 @@ extern "C" { * * @returns 1 on error and 0 on success */ - uint8_t(*istat) (TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, + uint8_t(*istat) (TSK_FS_INFO * fs, TSK_FS_ISTAT_FLAG_ENUM flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew); TSK_RETVAL_ENUM(*dir_open_meta) (TSK_FS_INFO * fs, TSK_FS_DIR ** a_fs_dir, TSK_INUM_T inode); ///< \internal Call tsk_fs_dir_open_meta() instead. diff --git a/tsk/fs/tsk_fs_i.h b/tsk/fs/tsk_fs_i.h index 8a8957ae4a7a97c204d3d6ecde7d3cf7d1f29215..fe2714927c3b120e327168785b08726bad470a6b 100644 --- a/tsk/fs/tsk_fs_i.h +++ b/tsk/fs/tsk_fs_i.h @@ -100,6 +100,7 @@ extern "C" { TSK_FS_ATTR * a_fs_attr, TSK_FS_ATTR_RUN * data_run_new); extern void tsk_fs_attr_append_run(TSK_FS_INFO * fs, TSK_FS_ATTR * a_fs_attr, TSK_FS_ATTR_RUN * a_data_run); + extern uint8_t tsk_fs_attr_print(const TSK_FS_ATTR * a_fs_attr, FILE * hFile); /* FS_DATALIST */ extern TSK_FS_ATTRLIST *tsk_fs_attrlist_alloc(); @@ -219,7 +220,7 @@ extern "C" { 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); - extern uint8_t tsk_fs_nofs_istat(TSK_FS_INFO * a_fs, FILE * hFile, + extern uint8_t tsk_fs_nofs_istat(TSK_FS_INFO * a_fs, TSK_FS_ISTAT_FLAG_ENUM istat_flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew); extern 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); diff --git a/tsk/fs/yaffs.cpp b/tsk/fs/yaffs.cpp index 35c173965fdd92165ca167e46964bca5a6af413b..6d118cb08951622db600496267e0d8e4046f98db 100644 --- a/tsk/fs/yaffs.cpp +++ b/tsk/fs/yaffs.cpp @@ -74,6 +74,8 @@ static const int TWELVE_BITS_MASK = 0xFFF; // Only keep 12 bits static uint8_t yaffsfs_read_header(YAFFSFS_INFO *yfs, YaffsHeader ** header, TSK_OFF_T offset); +static uint8_t + yaffsfs_load_attrs(TSK_FS_FILE *file); /** * Generate an inode number based on the file's object and version numbers @@ -2408,7 +2410,7 @@ static TSK_WALK_RET_ENUM * @returns 1 on error and 0 on success */ static uint8_t - yaffsfs_istat(TSK_FS_INFO *fs, FILE * hFile, TSK_INUM_T inum, + yaffsfs_istat(TSK_FS_INFO *fs, TSK_FS_ISTAT_FLAG_ENUM flags, FILE * hFile, TSK_INUM_T inum, TSK_DADDR_T numblock, int32_t sec_skew) { TSK_FS_META *fs_meta; @@ -2492,17 +2494,32 @@ static uint8_t } tsk_fprintf(hFile, "\nData Chunks:\n"); - print.idx = 0; - print.hFile = hFile; - if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_AONLY, - (TSK_FS_FILE_WALK_CB) print_addr_act, (void *) &print)) { + if (flags & TSK_FS_ISTAT_RUNLIST){ + const TSK_FS_ATTR *fs_attr_default = + tsk_fs_file_attr_get_type(fs_file, + TSK_FS_ATTR_TYPE_DEFAULT, 0, 0); + if (fs_attr_default && (fs_attr_default->flags & TSK_FS_ATTR_NONRES)) { + if (tsk_fs_attr_print(fs_attr_default, hFile)) { + tsk_fprintf(hFile, "\nError creating run lists "); + tsk_error_print(hFile); + tsk_error_reset(); + } + } + } + else { + print.idx = 0; + print.hFile = hFile; + + if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_AONLY, + (TSK_FS_FILE_WALK_CB)print_addr_act, (void *)&print)) { tsk_fprintf(hFile, "\nError reading file: "); tsk_error_print(hFile); tsk_error_reset(); - } - else if (print.idx != 0) { - tsk_fprintf(hFile, "\n"); + } + else if (print.idx != 0) { + tsk_fprintf(hFile, "\n"); + } } tsk_fs_file_close(fs_file);