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..f2d6bed78a2fbcd81c0ec99763147db50d4a9404 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,27 @@ 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)) { + tsk_fs_attr_print(fs_attr_default, hFile); + } } - 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 +3067,23 @@ 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) { + tsk_fs_attr_print(fs_attr_extent, hFile); + } + 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 +3092,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 baffa89bf46ccc5f1317253ea754ee2041d6dc40..0a1ad4857dce057ea9be5c297899c3be5080af5a 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,24 +983,42 @@ 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)) { + tsk_fs_attr_print(fs_attr_default, a_hFile); + } + /* + fatfs_make_data_runs(fs_file); + if (fs_file->meta->attr) { + + tsk_fs_attr_print(fs_file->meta->attr->head, a_hFile); + }*/ } - 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); return 0; } diff --git a/tsk/fs/ffs.c b/tsk/fs/ffs.c index 5b7116c512bf11611f550370b07c2b3546b8d1fc..86b092a87a6663b41b7ccb01340850e3bed1325d 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; @@ -1880,6 +1880,31 @@ ffs_istat(TSK_FS_INFO * fs, FILE * hFile, TSK_INUM_T inum, if (numblock > 0) fs_meta->size = numblock * ffs->ffsbsize_b; + if (istat_flags & TSK_FS_ISTAT_RUNLIST) { + fs_file->fs_info->load_attrs(fs_file); + if (fs_file->meta->attr == NULL) { + printf(" meta->attr is null\n"); + } + else if (fs_file->meta->attr->head == NULL) { + printf(" meta->attr->head is null\n"); + } + else { + TSK_FS_ATTR * attr = fs_file->meta->attr->head; + while (attr) { + printf(" attr : 0x%02x\n", attr->type); + if (attr->flags & TSK_FS_ATTR_NONRES) { + printf(" non-resident\n"); + tsk_fs_attr_print(attr, hFile); + } + else { + printf(" resident\n"); + } + + attr = attr->next; + } + } + } + tsk_fprintf(hFile, "\nDirect Blocks:\n"); print.idx = 0; diff --git a/tsk/fs/fs_attr.c b/tsk/fs/fs_attr.c index 58a066ff9bc3aeb39764395ae212f14f05a5b5e0..50338f3d1811da8d63ebf2c069140d033d0361a7 100644 --- a/tsk/fs/fs_attr.c +++ b/tsk/fs/fs_attr.c @@ -355,6 +355,7 @@ tsk_fs_attr_set_run(TSK_FS_FILE * a_fs_file, TSK_FS_ATTR * a_fs_attr, return 0; } + static void dump_attr(TSK_FS_ATTR * a_fs_attr) { @@ -369,6 +370,23 @@ dump_attr(TSK_FS_ATTR * a_fs_attr) } } +void +tsk_fs_attr_print(const TSK_FS_ATTR * a_fs_attr, FILE* hFile) { + TSK_FS_ATTR_RUN *cur_run; + cur_run = a_fs_attr->nrd.run; + + for (cur_run = a_fs_attr->nrd.run; cur_run; cur_run = cur_run->next) { + tsk_fprintf(hFile, "Staring address: %lld, length: %lld", cur_run->addr, cur_run->len); + if (cur_run->flags & TSK_FS_ATTR_RUN_FLAG_FILLER) { + tsk_fprintf(hFile, " FILLER"); + } + if (cur_run->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE) { + tsk_fprintf(hFile, " SPARSE"); + } + tsk_fprintf(hFile, "\n"); + } +} + /** * \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 5d71187c08956991c3785db1cee74530fbadead6..a7b3591404951c60ac219895cf01ad5cc105e538 100644 --- a/tsk/fs/hfs.c +++ b/tsk/fs/hfs.c @@ -5468,7 +5468,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; diff --git a/tsk/fs/ntfs.c b/tsk/fs/ntfs.c index 5d249b90b30c361be25a68c58b3f0234444a0c01..4779809b1cafbf9eef84507fd2713bb1a3ba9785 100755 --- a/tsk/fs/ntfs.c +++ b/tsk/fs/ntfs.c @@ -4241,7 +4241,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; @@ -4671,17 +4671,21 @@ 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) { + tsk_fs_attr_print(fs_attr, hFile); + } + 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"); diff --git a/tsk/fs/tsk_fs.h b/tsk/fs/tsk_fs.h index e12d4d97d1682902d25c006d4cc6149b99aea25a..89c9b4c08093f2b56b1f0c55db678333d342786c 100644 --- a/tsk/fs/tsk_fs.h +++ b/tsk/fs/tsk_fs.h @@ -870,6 +870,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 @@ -956,7 +962,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 ee15e2734e60ab63bf4695f1cf4ddee4e972fc70..67b7a33b73b55615872f7d64d0bc7f8475ef9656 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 void tsk_fs_attr_print(const TSK_FS_ATTR * a_fs_attr, FILE * hFile); /* FS_DATALIST */ extern TSK_FS_ATTRLIST *tsk_fs_attrlist_alloc(); diff --git a/tsk/fs/yaffs.cpp b/tsk/fs/yaffs.cpp index 35c173965fdd92165ca167e46964bca5a6af413b..ed6c6a12530ae2787dfe214f0d5826509976e40c 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,28 @@ 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)) { + tsk_fs_attr_print(fs_attr_default, hFile); + } + } + 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);