/* Inspect the device and initialises the img and fs structures. * Return 0 on success, -1 on error. */ static int open_filesystem (const char *device, TSK_IMG_INFO **img, TSK_FS_INFO **fs) { const char *images[] = { device }; *img = tsk_img_open (1, images, TSK_IMG_TYPE_DETECT, 0); if (*img == NULL) { reply_with_tsk_error ("tsk_image_open"); return -1; } *fs = tsk_fs_open_img (*img, 0, TSK_FS_TYPE_DETECT); if (*fs == NULL) { reply_with_tsk_error ("tsk_fs_open_img"); (*img)->close (*img); return -1; } return 0; }
/** * Analyze the volume starting at byte offset 'start' and look * for a file system. When found, the files will be analyzed. * * @param img Disk image to be analyzed. * @param start Byte offset of volume starting location. * * @return 1 on error and 0 on success */ static uint8_t proc_fs(TSK_IMG_INFO * img_info, TSK_OFF_T start) { TSK_FS_INFO *fs_info; TSK_STACK *stack; /* Try it as a file system */ if ((fs_info = tsk_fs_open_img(img_info, start, TSK_FS_TYPE_DETECT)) == NULL) { fprintf(stderr, "Error opening file system in partition at offset %" PRIuOFF "\n", start); tsk_error_print(stderr); /* We could do some carving on the volume data at this point */ return 1; } // create a stack to prevent infinite loops stack = tsk_stack_create(); // Process the directories if (proc_dir(fs_info, stack, fs_info->root_inum, "")) { fprintf(stderr, "Error processing file system in partition at offset %" PRIuOFF "\n", start); tsk_fs_close(fs_info); return 1; } tsk_stack_free(stack); /* We could do some analysis of unallocated blocks at this point... */ tsk_fs_close(fs_info); return 0; }
int test_fat12() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "fat12.dd"; char fname[512]; snprintf(fname, 512, "%s/fat12.dd", s_root); if ((img = tsk_img_open_sing((const TSK_TCHAR *)fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); return 1; } if ((fs = tsk_fs_open_img(img, 0, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); return 1; } // verify the APIs get teh same for file 47 if (test_get_apis(fs, 47, 1)) { fprintf(stderr, "%s failure\n", tname); return 1; } // verify the one attribte is the expected type if (test_get_type(fs, 47, TSK_FS_ATTR_TYPE_DEFAULT)) { fprintf(stderr, "%s failure\n", tname); return 1; } tsk_fs_close(fs); tsk_img_close(img); return 0; }
int test_fat12() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "fat12.dd"; char fname[512]; snprintf(fname, 512, "%s/fat12.dd", s_root); if ((img = tsk_img_open_sing(fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); return 1; } if ((fs = tsk_fs_open_img(img, 0, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); return 1; } if (test_dir_open_apis(fs, "/", 2)) { fprintf(stderr, "%s failure\n", tname); return 1; } if (test_walk_apis(fs, 2)) { fprintf(stderr, "%s failure\n", tname); return 1; } tsk_fs_close(fs); tsk_img_close(img); return 0; }
int test_ntfs_comp() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "ntfs-comp-1"; char fname[512]; snprintf(fname, 512, "%s/ntfs-comp-1.img", s_root); if ((img = tsk_img_open_sing(fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if ((fs = tsk_fs_open_img(img, 0, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (testfile(fs, 34)) { fprintf(stderr, "%s error (both)\n", tname); return 1; } if (testfile(fs, 32)) { fprintf(stderr, "%s error (sparse)\n", tname); return 1; } tsk_fs_close(fs); tsk_img_close(img); return 0; }
int test_ntfs_fe() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "fe_test_1-NTFS"; char fname[512]; snprintf(fname, 512, "%s/fe_test_1.img", s_root); if ((img = tsk_img_open_sing(fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if ((fs = tsk_fs_open_img(img, 32256, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (testfile(fs, 31)) { fprintf(stderr, "%s error (non-resident)\n", tname); return 1; } if (testfile(fs, 32)) { fprintf(stderr, "%s error (resident)\n", tname); return 1; } tsk_fs_close(fs); tsk_img_close(img); return 0; }
/** * \ingroup fslib * Tries to process data in a volume as a file system. * Returns a structure that can be used for analysis and reporting. * * @param a_part_info Open volume to read from and analyze * @param a_ftype Type of file system (or autodetect) * * @return NULL on error */ TSK_FS_INFO * tsk_fs_open_vol(const TSK_VS_PART_INFO * a_part_info, TSK_FS_TYPE_ENUM a_ftype) { TSK_OFF_T offset; if (a_part_info == NULL) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr("tsk_fs_open_vol: Null vpart handle"); return NULL; } else if ((a_part_info->vs == NULL) || (a_part_info->vs->tag != TSK_VS_INFO_TAG)) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr("tsk_fs_open_vol: Null vs handle"); return NULL; } offset = a_part_info->start * a_part_info->vs->block_size + a_part_info->vs->offset; return tsk_fs_open_img(a_part_info->vs->img_info, offset, a_ftype); }
// Find the filename of the specified harddisk byte offset // // \param imgname path of target image // \param haddr_img_offset the target harddisk byte address // // Return NULL if error, otherwise a UT_array of filename UT_array* tsk_get_filename_by_haddr(const char* imgname, uint64_t haddr_img_offset) { TSK_IMG_INFO *img; TSK_VS_INFO *vs; TSK_FS_INFO *fs; uint8_t id_used = 0, type_used = 0; TSK_DADDR_T partition_offset = 0; TSK_DADDR_T block_img_offset = 0; TSK_DADDR_T part_byte_offset = 0; TSK_DADDR_T part_block_offset = 0; MBA_IFIND_DATA_DATA* ifind_data; TSK_IMG_TYPE_ENUM imgtype; MBA_FFIND_DATA* ffind_data; UT_array* ret = NULL; //open image imgtype = tsk_img_type_toid(QCOW_IMG_TYPE); img = tsk_img_open_sing(imgname, imgtype, 0); if(img == NULL) { printf("Image Open Failed!!\n"); return NULL; } if(haddr_img_offset >= img->size) { printf("Request haddr is larger than image size\n"); tsk_img_close(img); return NULL; } //open volume vs = tsk_vs_open(img, 0 , TSK_VS_TYPE_DETECT); if(vs==NULL) { printf("Volume Open Failed!!\n"); tsk_img_close(img); return NULL; } //calculate block address block_img_offset = haddr_img_offset/img->sector_size; //search the partition contain the target block partition_offset = search_partition(vs, block_img_offset); if(partition_offset == 0) { tsk_img_close(img); tsk_vs_close(vs); return NULL; } //open the partition's file system fs = tsk_fs_open_img(img, partition_offset * img->sector_size, TSK_FS_TYPE_DETECT); if(fs==NULL) { printf("Cannot open file system\n"); tsk_img_close(img); tsk_vs_close(vs); return NULL; } //calculate offset to the current partition part_byte_offset = haddr_img_offset - (partition_offset * img->sector_size); part_block_offset = part_byte_offset/fs->block_size; //find the inode of this block ifind_data = fs_ifind_data(fs, (TSK_FS_IFIND_FLAG_ENUM) 0, part_block_offset); if(ifind_data == NULL) { tsk_img_close(img); tsk_vs_close(vs); return NULL; } if(ifind_data->found!=1) { tsk_img_close(img); tsk_vs_close(vs); return NULL; } //Find the inode's filename //Note: Do Not Know what to fill in variable type_used and id_used ffind_data = fs_ffind(fs, 0, ifind_data->curinode, ifind_data->curtype , type_used, ifind_data->curid , id_used, (TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC)); if(ffind_data==NULL){ printf("Cannot found fdata associate with inode\n"); tsk_img_close(img); tsk_vs_close(vs); return NULL; } //free data //reserve return data first ret = ffind_data->filenames; free(ifind_data); free(ffind_data); tsk_vs_close(vs); tsk_img_close(img); return ret; }
int main(int argc, char **argv1) { TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT; TSK_IMG_INFO *img; TSK_OFF_T imgaddr = 0; TSK_FS_TYPE_ENUM fstype = TSK_FS_TYPE_DETECT; TSK_FS_INFO *fs; int ch; TSK_TCHAR *cp; uint8_t type = 0; int set = 0; TSK_DADDR_T count = 0; TSK_TCHAR **argv; unsigned int ssize = 0; #ifdef TSK_WIN32 // On Windows, get the wide arguments (mingw doesn't support wmain) argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (argv == NULL) { fprintf(stderr, "Error getting wide arguments\n"); exit(1); } #else argv = (TSK_TCHAR **) argv1; #endif progname = argv[0]; setlocale(LC_ALL, ""); while ((ch = GETOPT(argc, argv, _TSK_T("b:d:f:i:o:s:u:vV"))) > 0) { switch (ch) { case _TSK_T('?'): default: TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"), argv[OPTIND]); usage(); case _TSK_T('b'): ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG || ssize < 1) { TFPRINTF(stderr, _TSK_T ("invalid argument: sector size must be positive: %s\n"), OPTARG); usage(); } break; case _TSK_T('d'): type |= TSK_FS_BLKCALC_DD; count = TSTRTOULL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG) { TFPRINTF(stderr, _TSK_T("Invalid address: %s\n"), OPTARG); usage(); } set = 1; break; case _TSK_T('f'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_fs_type_print(stderr); exit(1); } fstype = tsk_fs_type_toid(OPTARG); if (fstype == TSK_FS_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported file system type: %s\n"), OPTARG); usage(); } break; case _TSK_T('i'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_img_type_print(stderr); exit(1); } imgtype = tsk_img_type_toid(OPTARG); if (imgtype == TSK_IMG_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"), OPTARG); usage(); } break; case _TSK_T('o'): if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('s'): type |= TSK_FS_BLKCALC_SLACK; count = TSTRTOULL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG) { TFPRINTF(stderr, _TSK_T("Invalid address: %s\n"), OPTARG); usage(); } set = 1; break; case _TSK_T('u'): type |= TSK_FS_BLKCALC_BLKLS; count = TSTRTOULL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG) { TFPRINTF(stderr, _TSK_T("Invalid address: %s\n"), OPTARG); usage(); } set = 1; break; case _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_version_print(stdout); exit(0); } } /* We need at least one more argument */ if (OPTIND == argc) { tsk_fprintf(stderr, "Missing image name\n"); usage(); } if ((!type) || (set == 0)) { tsk_fprintf(stderr, "Calculation type not given (-u, -d, -s)\n"); usage(); } if ((type & TSK_FS_BLKCALC_DD) && (type & TSK_FS_BLKCALC_BLKLS) && (type & TSK_FS_BLKCALC_SLACK)) { tsk_fprintf(stderr, "Only one block type can be given\n"); usage(); } if ((img = tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } if ((fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_error_get_errno() == TSK_ERR_FS_UNSUPTYPE) tsk_fs_type_print(stderr); img->close(img); exit(1); } if (-1 == tsk_fs_blkcalc(fs, (TSK_FS_BLKCALC_FLAG_ENUM) type, count)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } fs->close(fs); img->close(img); exit(0); }
int TskImageFileTsk::openFile(const uint64_t fileId) { if (m_img_info == NULL) { if (open() != 0) return -1; } // Use ImgDb::getFileUniqueIdentifiers to get the four needed values. uint64_t fsByteOffset = 0; uint64_t fsFileId = 0; int attrType = 0; int attrId = 0; if (m_db.getFileUniqueIdentifiers(fileId, fsByteOffset, fsFileId, attrType, attrId) != 0) { LOGERROR(L"TskImageFileTsk::openFile - Error getting file identifiers.\n"); return -1; } // Check if the file system at the offset is already open (using m_openFs). If not, open it (tsk_fs_open) and add it to the map. TSK_FS_INFO * fsInfo = m_openFs[fsByteOffset]; if (fsInfo == NULL) { // Open the file system and add it to the map. fsInfo = tsk_fs_open_img(m_img_info, fsByteOffset, TSK_FS_TYPE_DETECT); if (fsInfo == NULL) { std::wstringstream errorMsg; errorMsg << L"TskImageFileTsk::openFile - Error opening file system : " << tsk_error_get(); LOGERROR(errorMsg.str()); return -1; } m_openFs[fsByteOffset] = fsInfo; } // Find a new entry in m_openFiles and use tsk_fs_file_open to open the file and save the handle in m_openFiles. TSK_FS_FILE * fsFile = tsk_fs_file_open_meta(fsInfo, NULL, fsFileId); if (fsFile == NULL) { std::wstringstream errorMsg; errorMsg << L"TskImageFileTsk::openFile - Error opening file : " << tsk_error_get(); LOGERROR(errorMsg.str()); return -1; } const TSK_FS_ATTR * fsAttr = tsk_fs_file_attr_get_id(fsFile, attrId); // @@@ TSK_ATTR_TYPE_ENUM should have a value added to it to represent an // empty (or null) attribute type and we should then compare attrType against // this enum value instead of 0. // It is possible to have a file with no attributes. We only report an // error if we are expecting a valid attribute. if (attrType != 0 && fsAttr == NULL) { std::wstringstream msg; msg << L"TskImageFileTsk::openFile - Error getting attribute : " << tsk_error_get(); LOGERROR(msg.str()); return -1; } TskImageFileTsk::OPEN_FILE * openFile = new TskImageFileTsk::OPEN_FILE(); openFile->fsFile = fsFile; openFile->fsAttr = fsAttr; m_openFiles.push_back(openFile); // Return the index into m_openFiles return m_openFiles.size() - 1; }
int main(int argc, char **argv1) { TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT; TSK_IMG_INFO *img; TSK_OFF_T imgaddr = 0; TSK_FS_TYPE_ENUM fstype = TSK_FS_TYPE_DETECT; TSK_FS_INFO *fs; TSK_INUM_T inum; int ch; TSK_TCHAR **argv; unsigned int ssize = 0; TSK_TCHAR *cp; #ifdef TSK_WIN32 // On Windows, get the wide arguments (mingw doesn't support wmain) argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (argv == NULL) { fprintf(stderr, "Error getting wide arguments\n"); exit(1); } #else argv = (TSK_TCHAR **) argv1; #endif progname = argv[0]; setlocale(LC_ALL, ""); while ((ch = GETOPT(argc, argv, _TSK_T("b:f:i:o:vV"))) > 0) { switch (ch) { case _TSK_T('?'): default: TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"), argv[OPTIND]); usage(); case _TSK_T('b'): ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG || ssize < 1) { TFPRINTF(stderr, _TSK_T ("invalid argument: sector size must be positive: %s\n"), OPTARG); usage(); } break; case _TSK_T('f'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_fs_type_print(stderr); exit(1); } fstype = tsk_fs_type_toid(OPTARG); if (fstype == TSK_FS_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported file system type: %s\n"), OPTARG); usage(); } break; case _TSK_T('i'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_img_type_print(stderr); exit(1); } imgtype = tsk_img_type_toid(OPTARG); if (imgtype == TSK_IMG_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"), OPTARG); usage(); } break; case _TSK_T('o'): if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_version_print(stdout); exit(0); } } /* We need at least one more argument */ if (OPTIND >= argc) { tsk_fprintf(stderr, "Missing image name and/or address\n"); usage(); } /* open image - there is an optional inode address at the end of args * * Check the final argument and see if it is a number */ if (tsk_fs_parse_inum(argv[argc - 1], &inum, NULL, NULL, NULL, NULL)) { /* Not an inode at the end */ if ((img = tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } if ((fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_error_get_errno() == TSK_ERR_FS_UNSUPTYPE) tsk_fs_type_print(stderr); img->close(img); exit(1); } inum = fs->journ_inum; } else { if ((img = tsk_img_open(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_error_get_errno() == TSK_ERR_FS_UNSUPTYPE) tsk_fs_type_print(stderr); img->close(img); exit(1); } } if (fs->jopen == NULL) { tsk_fprintf(stderr, "Journal support does not exist for this file system\n"); fs->close(fs); img->close(img); exit(1); } if (inum > fs->last_inum) { tsk_fprintf(stderr, "Inode value is too large for image (%" PRIuINUM ")\n", fs->last_inum); fs->close(fs); img->close(img); exit(1); } if (inum < fs->first_inum) { tsk_fprintf(stderr, "Inode value is too small for image (%" PRIuINUM ")\n", fs->first_inum); fs->close(fs); img->close(img); exit(1); } if (fs->jopen(fs, inum)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } if (fs->jentry_walk(fs, 0, 0, NULL)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } fs->close(fs); img->close(img); exit(0); }
int main(int argc, char **argv1) { TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT; TSK_IMG_INFO *img; TSK_OFF_T imgaddr = 0; TSK_FS_TYPE_ENUM fstype = TSK_FS_TYPE_DETECT; TSK_FS_INFO *fs; TSK_DADDR_T addr = 0; TSK_TCHAR *cp; TSK_DADDR_T read_num_units; /* Number of data units */ int usize = 0; /* Length of each data unit */ int ch; char format = 0; extern int OPTIND; TSK_TCHAR **argv; unsigned int ssize = 0; #ifdef TSK_WIN32 // On Windows, get the wide arguments (mingw doesn't support wmain) argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (argv == NULL) { fprintf(stderr, "Error getting wide arguments\n"); exit(1); } #else argv = (TSK_TCHAR **) argv1; #endif progname = argv[0]; setlocale(LC_ALL, ""); while ((ch = GETOPT(argc, argv, _TSK_T("ab:f:hi:o:su:vVw"))) > 0) { switch (ch) { case _TSK_T('a'): format |= TSK_FS_BLKCAT_ASCII; break; case _TSK_T('b'): ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG || ssize < 1) { TFPRINTF(stderr, _TSK_T ("invalid argument: sector size must be positive: %s\n"), OPTARG); usage(); } break; case _TSK_T('f'): if (TSTRCMP(OPTARG, BLKLS_TYPE) == 0) { fstype = TSK_FS_TYPE_RAW; } else if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_fprintf(stderr, "\t%" PRIttocTSK " (Unallocated Space)\n", BLKLS_TYPE); tsk_fs_type_print(stderr); exit(1); } else { fstype = tsk_fs_type_toid(OPTARG); } if (fstype == TSK_FS_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported file system type: %s\n"), OPTARG); usage(); } break; case _TSK_T('h'): format |= TSK_FS_BLKCAT_HEX; break; case _TSK_T('i'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_img_type_print(stderr); exit(1); } imgtype = tsk_img_type_toid(OPTARG); if (imgtype == TSK_IMG_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"), OPTARG); usage(); } break; case _TSK_T('o'): if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('s'): format |= TSK_FS_BLKCAT_STAT; break; case _TSK_T('u'): usize = TSTRTOUL(OPTARG, &cp, 0); if (*cp || cp == OPTARG) { TFPRINTF(stderr, _TSK_T("Invalid block size: %s\n"), OPTARG); usage(); } break; case _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_version_print(stdout); exit(0); break; case _TSK_T('w'): format |= TSK_FS_BLKCAT_HTML; break; case _TSK_T('?'): default: TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"), argv[OPTIND]); usage(); } } if (format & TSK_FS_BLKCAT_STAT) { if (OPTIND == argc) usage(); if (format & (TSK_FS_BLKCAT_HTML | TSK_FS_BLKCAT_ASCII | TSK_FS_BLKCAT_HEX)) { tsk_fprintf(stderr, "NOTE: Additional flags will be ignored\n"); } } /* We need at least two more arguments */ else if (OPTIND + 1 >= argc) { tsk_fprintf(stderr, "Missing image name and/or address\n"); usage(); } if ((format & TSK_FS_BLKCAT_ASCII) && (format & TSK_FS_BLKCAT_HEX)) { tsk_fprintf(stderr, "Ascii and Hex flags can not be used together\n"); usage(); } /* We need to figure out if there is a length argument... */ /* Check out the second argument from the end */ /* default number of units is 1 */ read_num_units = 1; /* Get the block address */ if (format & TSK_FS_BLKCAT_STAT) { if ((img = tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } else { addr = TSTRTOULL(argv[argc - 2], &cp, 0); if (*cp || *cp == *argv[argc - 2]) { /* Not a number, so it is the image name and we do not have a length */ addr = TSTRTOULL(argv[argc - 1], &cp, 0); if (*cp || *cp == *argv[argc - 1]) { TFPRINTF(stderr, _TSK_T("Invalid block address: %s\n"), argv[argc - 1]); usage(); } if ((img = tsk_img_open(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } else { /* We got a number, so take the length as well while we are at it */ read_num_units = TSTRTOULL(argv[argc - 1], &cp, 0); if (*cp || *cp == *argv[argc - 1]) { TFPRINTF(stderr, _TSK_T("Invalid size: %s\n"), argv[argc - 1]); usage(); } else if (read_num_units <= 0) { tsk_fprintf(stderr, "Invalid size: %" PRIuDADDR "\n", read_num_units); usage(); } if ((img = tsk_img_open(argc - OPTIND - 2, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } } /* open the file */ if ((fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_fs_type_print(stderr); img->close(img); exit(1); } /* Set the default size if given */ if ((usize != 0) && (TSK_FS_TYPE_ISRAW(fs->ftype) || TSK_FS_TYPE_ISSWAP(fs->ftype))) { TSK_DADDR_T sectors; int orig_dsize, new_dsize; if (usize % 512) { tsk_fprintf(stderr, "New data unit size not a multiple of 512 (%d)\n", usize); usage(); } /* We need to do some math to update the block_count value */ /* Get the original number of sectors */ orig_dsize = fs->block_size / 512; sectors = fs->block_count * orig_dsize; /* Convert that to the new size */ new_dsize = usize / 512; fs->block_count = sectors / new_dsize; if (sectors % new_dsize) fs->block_count++; fs->last_block = fs->block_count - 1; fs->block_size = usize; } if (addr > fs->last_block) { tsk_fprintf(stderr, "Data unit address too large for image (%" PRIuDADDR ")\n", fs->last_block); fs->close(fs); img->close(img); exit(1); } if (addr < fs->first_block) { tsk_fprintf(stderr, "Data unit address too small for image (%" PRIuDADDR ")\n", fs->first_block); fs->close(fs); img->close(img); exit(1); } if (tsk_fs_blkcat(fs, (TSK_FS_BLKCAT_FLAG_ENUM) format, addr, read_num_units)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } fs->close(fs); img->close(img); exit(0); }
static int test_ntfs_fe() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "fe_test_1-NTFS"; char fname[512]; snprintf(fname, 512, "%s/fe_test_1.img", s_root); if ((img = tsk_img_open_sing((const TSK_TCHAR *)fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); return 1; } if ((fs = tsk_fs_open_img(img, 32256, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); return 1; } // Verify the APIS get the same and that they are the expected type if (test_get_apis(fs, 35, 3)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 35, TSK_FS_ATTR_TYPE_NTFS_SI)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 35, TSK_FS_ATTR_TYPE_NTFS_FNAME)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 35, TSK_FS_ATTR_TYPE_NTFS_DATA)) { fprintf(stderr, "%s failure\n", tname); return 1; } if (test_get_apis(fs, 9, 7)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 9, TSK_FS_ATTR_TYPE_NTFS_SI)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 9, TSK_FS_ATTR_TYPE_NTFS_FNAME)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 9, TSK_FS_ATTR_TYPE_NTFS_DATA)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 9, TSK_FS_ATTR_TYPE_NTFS_IDXROOT)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 9, TSK_FS_ATTR_TYPE_NTFS_IDXALLOC)) { fprintf(stderr, "%s failure\n", tname); return 1; } else if (test_get_type(fs, 9, TSK_FS_ATTR_TYPE_NTFS_BITMAP)) { fprintf(stderr, "%s failure\n", tname); return 1; } tsk_fs_close(fs); tsk_img_close(img); return 0; }
/* This test checks the SLACK flags and verifies * that we read data from the slack space */ int test_fat_slack() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "fat-img-kw"; char fname[512]; TSK_FS_FILE *file1; char buf[512]; ssize_t retval; snprintf(fname, 512, "%s/fat-img-kw.dd", s_root); if ((img = tsk_img_open_sing(fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if ((fs = tsk_fs_open_img(img, 0, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } // file4.dat file1 = tsk_fs_file_open_meta(fs, NULL, 10); if (file1 == NULL) { fprintf(stderr, "Error opening file4.dat (%s)\n", tname); return 1; } // verify expected size if (file1->meta->size != 631) { fprintf(stderr, "Error: file4.dat not expected size (%" PRIuOFF ") (%s)\n", file1->meta->size, tname); return 1; } // try to read all of last sector with/out Slack set retval = tsk_fs_file_read(file1, 512, buf, 512, (TSK_FS_FILE_READ_FLAG_ENUM) 0); if (retval == -1) { fprintf(stderr, "Error reading file4.dat to end w/out slack flag\n"); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (retval != 119) { fprintf(stderr, "Unexpected return value from reading file4.dat to end w/out slack flag.\n"); fprintf(stderr, "Expected: 119. Got: %zd\n", retval); return 1; } retval = tsk_fs_file_read(file1, 512, buf, 512, TSK_FS_FILE_READ_FLAG_SLACK); if (retval == -1) { fprintf(stderr, "Error reading file4.dat to end w/slack flag\n"); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (retval != 512) { fprintf(stderr, "Unexpected return value from reading file4.dat w/slack flag.\n"); fprintf(stderr, "Expected: 512. Got: %zd\n", retval); return 1; } // verify the term in the slack space if (memcmp("3slack3", &buf[385], 7) != 0) { fprintf(stderr, "slack string not found in file4.dat slack space: %x %x %x %x %x %x %x\n", buf[385], buf[386], buf[387], buf[388], buf[389], buf[390], buf[391]); return 1; } tsk_fs_close(fs); tsk_img_close(img); return 0; }
int main(int argc, char** argv1) { TSK_TCHAR **argv; TSK_TCHAR *cp; #ifdef TSK_WIN32 // On Windows, get the wide arguments (mingw doesn't support wmain) argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (argv == NULL) { fprintf(stderr, "Error getting wide arguments\n"); exit(1); } #else argv = (TSK_TCHAR **) argv1; #endif progname = argv[0]; TSK_FS_TYPE_ENUM fstype = TSK_FS_TYPE_DETECT; TSK_OFF_T imgaddr = 0; int ch; while ((ch = GETOPT(argc, argv, _TSK_T("f:o:v"))) != -1) { switch (ch) { case _TSK_T('f'): fstype = tsk_fs_type_toid(OPTARG); if (fstype == TSK_FS_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported file system type: %s\n"), OPTARG); usage(); } break; case _TSK_T('o'): if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('v'): tsk_verbose = 1; break; default: usage(); break; } } if (argc - OPTIND != 3) { usage(); } const TSK_TCHAR* image = argv[OPTIND]; size_t nthreads = (size_t) TSTRTOUL(argv[OPTIND + 1], &cp, 0); if (nthreads == 0) { fprintf(stderr, "invalid nthreads\n"); exit(1); } size_t niters = (size_t) TSTRTOUL(argv[OPTIND + 2], &cp, 0); if (niters == 0) { fprintf(stderr, "invalid nthreads\n"); exit(1); } TSK_IMG_INFO* img = tsk_img_open_sing(image, TSK_IMG_TYPE_DETECT, 0); if (img == 0) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } TSK_FS_INFO* fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype); if (fs == 0) { tsk_img_close(img); tsk_error_print(stderr); exit(1); } TskThread** threads = new TskThread*[nthreads]; for (size_t i = 0; i < nthreads; ++i) { threads[i] = new MyThread(i, fs, niters); } TskThread::run(threads, nthreads); for (size_t i = 0; i < nthreads; ++i) { delete threads[i]; } delete[] threads; tsk_fs_close(fs); tsk_img_close(img); exit(0); }
int TskImageFileTsk::openFile(const uint64_t fileId) { if (m_img_info == NULL) { if (open() != 0) return -1; } // Use ImgDb::getFileUniqueIdentifiers to get the four needed values. uint64_t fsByteOffset = 0; uint64_t fsFileId = 0; int attrType = 0; int attrId = 0; if (m_db.getFileUniqueIdentifiers(fileId, fsByteOffset, fsFileId, attrType, attrId) != 0) { LOGERROR(L"TskImageFileTsk::openFile - Error getting file identifiers.\n"); return -1; } // Check if the file system at the offset is already open (using m_openFs). If not, open it (tsk_fs_open) and add it to the map. TSK_FS_INFO * fsInfo = m_openFs[fsByteOffset]; if (fsInfo == NULL) { // Open the file system and add it to the map. fsInfo = tsk_fs_open_img(m_img_info, fsByteOffset, TSK_FS_TYPE_DETECT); if (fsInfo == NULL) { std::wstringstream errorMsg; errorMsg << L"TskImageFileTsk::openFile - Error opening file system : " << tsk_error_get() << std::endl; LOGERROR(errorMsg.str()); return -1; } m_openFs[fsByteOffset] = fsInfo; } // Find a new entry in m_openFiles and use tsk_fs_file_open to open the file and save the handle in m_openFiles. TSK_FS_FILE * fsFile = tsk_fs_file_open_meta(fsInfo, NULL, fsFileId); if (fsFile == NULL) { std::wstringstream errorMsg; errorMsg << L"TskImageFileTsk::openFile - Error opening file : " << tsk_error_get() << std::endl; LOGERROR(errorMsg.str()); return -1; } TskImageFileTsk::OPEN_FILE * openFile = new TskImageFileTsk::OPEN_FILE(); openFile->attrId = attrId; openFile->attrType = attrType; openFile->fsFile = fsFile; m_openFiles.push_back(openFile); // Return the index into m_openFiles return m_openFiles.size() - 1; }
/** * Scan the image for file systems creating allocated volumes for file systems found * and unallocated volumes for areas in the image that do not contain file systems. * Will initially look for file system in first sect_count sectors. If a file system * is found then it will continue to process the remainder of the image for other * file systems. * * @param sect_start Start looking for file systems starting at this sector. * @param sect_count The initial number of sectors to scan for file systems. * @return 0 on success, 1 on failure */ uint8_t TSKAutoImpl::scanImgForFs(const uint64_t sect_start, const uint64_t sect_count) { if (m_img_info == NULL) { LOGERROR(L"TSKAutoImpl::scanImgForFs - Image not open."); return 1; } LOGINFO(L"TSKAutoImpl::scanImgForFs - Starting file system scan."); // Initialize current offset to our starting byte location. TSK_OFF_T current_offset = sect_start * m_img_info->sector_size; TSK_OFF_T end_offset = current_offset + (sect_count * m_img_info->sector_size); // Last offset keeps track of byte location where we last saw file system // data. It gets initialized to our starting location. TSK_OFF_T last_offset = current_offset; while (current_offset < end_offset) { TSK_FS_INFO * fs_info; if ((fs_info = tsk_fs_open_img(m_img_info, current_offset, TSK_FS_TYPE_DETECT)) == NULL) { // We didn't find a file system so we move on to the next sector. current_offset += m_img_info->sector_size; } else { // We found a file system so we will continue to search for file // systems beyond the initial sectors. end_offset = m_img_info->size; // If there is a gap between the location of this file system and // where we last saw file system data, an unallocated volume entry // needs to be created for the gap. if (fs_info->offset > last_offset) { createDummyVolume(last_offset / m_img_info->sector_size, (fs_info->offset - last_offset) / m_img_info->sector_size, "Dummy volume for carving purposes", TSK_VS_PART_FLAG_UNALLOC); } // The call to findFilesInFs will take care of creating a // dummy volume for the file system. if (findFilesInFs(fs_info) == TSK_ERR) { std::wstringstream msg; msg << L"TSKAutoImpl::scanImgForFs - Error finding files: " << tsk_error_get(); tsk_error_reset(); LOGERROR(msg.str()); } // Move the current offset past the file system we just found. current_offset += ((fs_info->block_count + 1) * fs_info->block_size); // Update the last location we saw file system data. last_offset = current_offset; tsk_fs_close(fs_info); } } // Finally, create a dummy unallocated volume for the area between the // last offset and the end of the image. if (last_offset < m_img_info->size) { createDummyVolume(last_offset / m_img_info->sector_size, (m_img_info->size - last_offset) / m_img_info->sector_size, "Dummy volume for carving purposes", TSK_VS_PART_FLAG_UNALLOC); } LOGINFO(L"TSKAutoImpl::scanImgForFs - File system scan complete."); return 0; }
/* This test checks the SLACK flags and verifies * that we read data from the slack space */ int test_ntfs_slack_ads() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "ntfs-img-kw"; char fname[512]; TSK_FS_FILE *file1; char buf[512]; ssize_t retval; snprintf(fname, 512, "%s/ntfs-img-kw-1.dd", s_root); if ((img = tsk_img_open_sing(fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if ((fs = tsk_fs_open_img(img, 0, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } // file-n-44.dat file1 = tsk_fs_file_open_meta(fs, NULL, 36); if (file1 == NULL) { fprintf(stderr, "Error opening file-n-4.dat (%s)\n", tname); return 1; } // verify expected size if (file1->meta->size != 2000) { fprintf(stderr, "Error: file-n-4.dat not expected size (%" PRIuOFF ") (%s)\n", file1->meta->size, tname); return 1; } // try to read all of last sector with/out Slack set retval = tsk_fs_file_read(file1, 1536, buf, 512, (TSK_FS_FILE_READ_FLAG_ENUM) 0); if (retval == -1) { fprintf(stderr, "Error reading file-n-4.dat to end w/out slack flag (%s)\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (retval != 464) { fprintf(stderr, "Unexpected return value from reading file-n-4.dat to end w/out slack flag (%s).\n", tname); fprintf(stderr, "Expected: 464. Got: %zd\n", retval); return 1; } retval = tsk_fs_file_read(file1, 1536, buf, 512, TSK_FS_FILE_READ_FLAG_SLACK); if (retval == -1) { fprintf(stderr, "Error reading file-n-4.dat to end w/slack flag (%s)\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (retval != 512) { fprintf(stderr, "Unexpected return value from reading file-n-4.dat w/slack flag. (%s)\n", tname); fprintf(stderr, "Expected: 512. Got: %zd\n", retval); return 1; } // verify the term in the slack space if (memcmp("n-slack", &buf[485], 7) != 0) { fprintf(stderr, "slack string not found in file-n-4.dat slack space: %c %c %c %c %c %c %c (%s)\n", buf[485], buf[486], buf[487], buf[488], buf[489], buf[490], buf[491], tname); return 1; } // try to read past end of file retval = tsk_fs_file_read(file1, 2001, buf, 32, (TSK_FS_FILE_READ_FLAG_ENUM) 0); if (retval != -1) { fprintf(stderr, "Unexpected return value from reading file-n-4.dat after end of file (%s).\n", tname); fprintf(stderr, "Expected: -1. Got: %zd\n", retval); return 1; } tsk_fs_file_close(file1); // file-n-5.dat file1 = tsk_fs_file_open_meta(fs, NULL, 37); if (file1 == NULL) { fprintf(stderr, "Error opening file-n-5.dat (%s)\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } // check the default size to make sure it is the default $Data if (file1->meta->size != 1300) { fprintf(stderr, "file-n-5.dat size is not 1300 (%" PRIuOFF ") (%s)", file1->meta->size, tname); return 1; } // test the getsize API for both attributes const TSK_FS_ATTR *fs_attr = tsk_fs_file_attr_get_type(file1, TSK_FS_ATTR_TYPE_NTFS_DATA, 3, 1); if (!fs_attr) { fprintf(stderr, "Error getting data attribute 3 in file-n-5.dat (%s)", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (fs_attr->size != 1300) { fprintf(stderr, "file-n-5.dat size (via getsize) is not 1300 (%" PRIuOFF ") (%s)", fs_attr->size, tname); return 1; } fs_attr = tsk_fs_file_attr_get_type(file1, TSK_FS_ATTR_TYPE_NTFS_DATA, 5, 1); if (!fs_attr) { fprintf(stderr, "Error getting size of attribute 5 in file-n-5.dat (%s)", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (fs_attr->size != 2000) { fprintf(stderr, "file-n-5.dat:here size (via getsize) is not 2000 (%" PRIuOFF ") (%s)", fs_attr->size, tname); return 1; } tsk_fs_file_close(file1); tsk_fs_close(fs); tsk_img_close(img); return 0; }
/* This test checks the RECOVER flags */ int test_fat_recover() { TSK_FS_INFO *fs; TSK_IMG_INFO *img; const char *tname = "fe_test_1.img-FAT"; char fname[512]; TSK_FS_FILE *file1; TSK_FS_FILE *file2; char buf[512]; ssize_t retval; snprintf(fname, 512, "%s/fe_test_1.img", s_root); if ((img = tsk_img_open_sing(fname, (TSK_IMG_TYPE_ENUM) 0, 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if ((fs = tsk_fs_open_img(img, 41126400, (TSK_FS_TYPE_ENUM) 0)) == NULL) { fprintf(stderr, "Error opening %s image\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } // fragmented.html const char *fname2 = "fragmented.html"; file1 = tsk_fs_file_open_meta(fs, NULL, 1162); if (file1 == NULL) { fprintf(stderr, "Error opening %s (%s)\n", fname2, tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } // verify expected size if (file1->meta->size != 5905) { fprintf(stderr, "Error: %s not expected size (%" PRIuOFF ") (%s)\n", fname2, file1->meta->size, tname); return 1; } // verify we can open it via name as well file2 = tsk_fs_file_open(fs, NULL, "/deleted/fragmented.html"); if (file2 == NULL) { fprintf(stderr, "Error opening /deleted/fragmented.html via path name (%s)\n", tname); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (file2->name == NULL) { fprintf(stderr, "Opening /deleted/fragmented.html via path name did not have name set(%s)\n", tname); return 1; } if (strcmp(file2->name->name, fname2) != 0) { fprintf(stderr, "Opening /deleted/fragmented.html via path had incorrect name set (%s) (%s)\n", file2->name->name, tname); return 1; } if ((file2->name->meta_addr != file2->meta->addr) || (file2->meta->addr != file1->meta->addr)) { fprintf(stderr, "Opening /deleted/fragmented.html via path had incorrect meta addresses (%" PRIuINUM " %" PRIuINUM " %" PRIuINUM " (%s)\n", file2->name->meta_addr, file2->meta->addr, file1->meta->addr, tname); return 1; } tsk_fs_file_close(file2); file2 = NULL; // try to read past end of first 2048-byte cluster retval = tsk_fs_file_read(file1, 2048, buf, 512, (TSK_FS_FILE_READ_FLAG_ENUM) 0); if (retval == -1) { fprintf(stderr, "Error reading %s past end w/out Recover flag\n", fname2); tsk_error_print(stderr); tsk_error_reset(); return 1; } // current behavior is to return 0s in "unitialized" space //if (retval != 0) { if (retval != 512) { fprintf(stderr, "Unexpected return value from reading %s past end w/out Recover flag.\n", fname2); fprintf(stderr, "Expected: 0. Got: %zd\n", retval); return 1; } retval = tsk_fs_file_read(file1, 2048, buf, 512, (TSK_FS_FILE_READ_FLAG_ENUM) 0); if (retval == -1) { fprintf(stderr, "Error reading %s past end w/Recover flag\n", fname2); tsk_error_print(stderr); tsk_error_reset(); return 1; } if (retval != 512) { fprintf(stderr, "Unexpected return value from %s past end w/Recover flag.\n", fname2); fprintf(stderr, "Expected: 512. Got: %zd\n", retval); return 1; } // verify the term in the slack space if (memcmp("appear", buf, 6) != 0) { fprintf(stderr, "expected string not found in %s recovery: %c %c %c %c %c %c\n", fname2, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); return 1; } tsk_fs_file_close(file1); tsk_fs_close(fs); tsk_img_close(img); return 0; }
/** * Parses the file and populates the structures used by this FUSE driver. * * \param filename The filename to parse * \param r The result structure to populate (or NULL if not needed) * \returns 0 if successful, -1 if not. */ static int process_file(const char *filename, result_t new_result) { img_info = tsk_img_open_sing(filename, TSK_IMG_TYPE_DETECT, 0); if (img_info == NULL) { info_log("Failed to open image: %s", filename); return -1; } fs_info = tsk_fs_open_img(img_info, 0, TSK_FS_TYPE_DETECT); if (fs_info == NULL) { info_log("Failed to open filesystem: %s", filename); return -1; } const char *fsname = tsk_fs_type_toname(fs_info->ftype); result_set_brief_data_description(new_result, fsname); mountpoint = g_strdup_printf("%s:mnt-%s", filename, fsname); char *description = g_strdup_printf("%" PRIdDADDR " bytes (%" PRIdDADDR " %ss of %u size)", fs_info->block_count * fs_info->block_size, fs_info->block_count, fs_info->duname, fs_info->block_size); result_set_data_description(new_result, description); g_free(description); result_set_confidence(new_result, 100); block_start(absolute_offset); TSK_FS_DIR_WALK_FLAG_ENUM name_flags = (TSK_FS_DIR_WALK_FLAG_ENUM) (TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE); if (tsk_fs_dir_walk(fs_info, fs_info->root_inum, name_flags, examine_dirent, new_result) != 0) { // Why does this occur? Is it because it's an invalid filesystem structure, or the // structure is damaged? I'm going to assume the structure is damaged, but partially available. warning_log("Warning, unable to fully walk fs! Probably truncated or not a real FS header."); } unsigned int size; block_range_t *ranges = block_end(&size); if (ranges != NULL) { result_set_block_ranges(new_result, ranges, size); for (int i = 0; i < size; i++) { block_range_close(ranges[i]); } g_free(ranges); } if (inode_lookup != NULL) { g_tree_destroy(inode_lookup); inode_lookup = NULL; } unsigned int num_contracts; result_get_new_contracts(new_result, &num_contracts); if (num_contracts > 0) { // Ready to mount! int ret = do_mount(mountpoint); if (ret != 0) { error_log("Failed to mount filesystem!"); } } remove_all_files(); return 0; }
void tsk_get_file(const char* imgname,uint64_t haddr_img_offset, const char* file_path, const char* destination, uint64_t start_offset, int read_file_len ) { TSK_IMG_INFO *img; TSK_VS_INFO *vs; TSK_FS_INFO *fs; uint8_t id_used = 0, type_used = 0; TSK_DADDR_T partition_offset = 0; TSK_DADDR_T block_img_offset = 0; TSK_DADDR_T part_byte_offset = 0; TSK_DADDR_T part_block_offset = 0; MBA_IFIND_DATA_DATA* ifind_data; TSK_IMG_TYPE_ENUM imgtype; MBA_FFIND_DATA* ffind_data; TSK_FS_FILE *file; FILE* writeHive; char *temp; //open image imgtype = tsk_img_type_toid(QCOW_IMG_TYPE); img = tsk_img_open_sing(imgname, imgtype, 0); if(img == NULL) { printf("Image Open Failed!!\n"); return; } if(haddr_img_offset >= img->size) { printf("Request haddr is larger than image size\n"); return; } //open volume vs = tsk_vs_open(img, 0 , TSK_VS_TYPE_DETECT); if(vs==NULL) { printf("Volume Open Failed!!\n"); return; } //calculate block address block_img_offset = haddr_img_offset/img->sector_size; //search the partition contain the target block partition_offset = search_partition(vs, block_img_offset); if(partition_offset == 0) { printf("Cannot found partition contains the target haddr\n"); return; } //open the partition's file system fs = tsk_fs_open_img(img, partition_offset * img->sector_size, TSK_FS_TYPE_DETECT); if(fs==NULL) { printf("Cannot open file system\n"); return; } //calculate offset to the current partition part_byte_offset = haddr_img_offset - (partition_offset * img->sector_size); part_block_offset = part_byte_offset/fs->block_size; file = tsk_fs_file_open( fs, NULL, file_path); if ( OPEN_FAIL(file) ) printf("open file fail\n\n"); temp = calloc( read_file_len, sizeof(char)); int size = tsk_fs_file_read( file, start_offset, temp, read_file_len, TSK_FS_FILE_READ_FLAG_NONE ); tsk_fs_file_close(file); writeHive = fopen( destination, "w" ); if ( writeHive == NULL ) printf("Open fail"); else { fwrite( temp, size, sizeof(char), writeHive ); fclose(writeHive); } // else free(temp); //find the inode of this block ifind_data = fs_ifind_data(fs, (TSK_FS_IFIND_FLAG_ENUM) 0, part_block_offset); if(ifind_data == NULL) { return; } if(ifind_data->found!=1) { printf("Inode not found\n"); return; } //Find the inode's filename //Note: Do Not Know what to fill in variable type_used and id_used ffind_data = fs_ffind(fs, 0, ifind_data->curinode, ifind_data->curtype , type_used, ifind_data->curid , id_used, (TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC)); if(ffind_data==NULL){ printf("Cannot found fdata associate with inode\n"); return; } free(ifind_data); return; }
/* main - open file system, list inode info */ int main(int argc, char **argv1) { TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT; TSK_IMG_INFO *img; TSK_OFF_T imgaddr = 0; TSK_FS_TYPE_ENUM fstype = TSK_FS_TYPE_DETECT; TSK_FS_INFO *fs; TSK_TCHAR *cp, *dash; TSK_INUM_T istart = 0, ilast = 0; int ch; int flags = TSK_FS_META_FLAG_UNALLOC | TSK_FS_META_FLAG_USED; int ils_flags = 0; int set_range = 1; TSK_TCHAR *image = NULL; int32_t sec_skew = 0; TSK_TCHAR **argv; unsigned int ssize = 0; #ifdef TSK_WIN32 // On Windows, get the wide arguments (mingw doesn't support wmain) argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (argv == NULL) { fprintf(stderr, "Error getting wide arguments\n"); exit(1); } #else argv = (TSK_TCHAR **) argv1; #endif progname = argv[0]; setlocale(LC_ALL, ""); /* * Provide convenience options for the most commonly selected feature * combinations. */ while ((ch = GETOPT(argc, argv, _TSK_T("aAb:ef:i:lLmo:Oprs:vVzZ"))) > 0) { switch (ch) { case _TSK_T('?'): default: TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"), argv[OPTIND]); usage(); case _TSK_T('b'): ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG || ssize < 1) { TFPRINTF(stderr, _TSK_T ("invalid argument: sector size must be positive: %s\n"), OPTARG); usage(); } break; case _TSK_T('f'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_fs_type_print(stderr); exit(1); } fstype = tsk_fs_type_toid(OPTARG); if (fstype == TSK_FS_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported file system type: %s\n"), OPTARG); usage(); } break; case _TSK_T('i'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_img_type_print(stderr); exit(1); } imgtype = tsk_img_type_toid(OPTARG); if (imgtype == TSK_IMG_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"), OPTARG); usage(); } break; case _TSK_T('e'): flags |= (TSK_FS_META_FLAG_ALLOC | TSK_FS_META_FLAG_UNALLOC); flags &= ~TSK_FS_META_FLAG_USED; break; case _TSK_T('m'): ils_flags |= TSK_FS_ILS_MAC; break; case _TSK_T('o'): if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('O'): flags |= TSK_FS_META_FLAG_UNALLOC; flags &= ~TSK_FS_META_FLAG_ALLOC; ils_flags |= TSK_FS_ILS_OPEN; break; case _TSK_T('p'): flags |= (TSK_FS_META_FLAG_ORPHAN | TSK_FS_META_FLAG_UNALLOC); flags &= ~TSK_FS_META_FLAG_ALLOC; break; case _TSK_T('r'): flags |= (TSK_FS_META_FLAG_UNALLOC | TSK_FS_META_FLAG_USED); flags &= ~TSK_FS_META_FLAG_ALLOC; break; case _TSK_T('s'): sec_skew = TATOI(OPTARG); break; case _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_version_print(stdout); exit(0); /* * Provide fine controls to tweak one feature at a time. */ case _TSK_T('a'): flags |= TSK_FS_META_FLAG_ALLOC; flags &= ~TSK_FS_META_FLAG_UNALLOC; break; case _TSK_T('A'): flags |= TSK_FS_META_FLAG_UNALLOC; break; case _TSK_T('l'): ils_flags |= TSK_FS_ILS_LINK; break; case _TSK_T('L'): ils_flags |= TSK_FS_ILS_UNLINK; break; case _TSK_T('z'): flags |= TSK_FS_META_FLAG_UNUSED; break; case _TSK_T('Z'): flags |= TSK_FS_META_FLAG_USED; break; } } if (OPTIND >= argc) { tsk_fprintf(stderr, "Missing image name\n"); usage(); } if ((ils_flags & TSK_FS_ILS_LINK) && (ils_flags & TSK_FS_ILS_UNLINK)) { tsk_fprintf(stderr, "ERROR: Only linked or unlinked should be used\n"); usage(); } /* We need to determine if an inode or inode range was given */ if ((dash = TSTRCHR(argv[argc - 1], _TSK_T('-'))) == NULL) { /* Check if is a single number */ istart = TSTRTOULL(argv[argc - 1], &cp, 0); if (*cp || *cp == *argv[argc - 1]) { /* Not a number - consider it a file name */ image = argv[OPTIND]; if ((img = tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } else { /* Single address set end addr to start */ ilast = istart; set_range = 0; image = argv[OPTIND]; if ((img = tsk_img_open(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } } else { /* We have a dash, but it could be part of the file name */ *dash = '\0'; istart = TSTRTOULL(argv[argc - 1], &cp, 0); if (*cp || *cp == *argv[argc - 1]) { /* Not a number - consider it a file name */ *dash = _TSK_T('-'); image = argv[OPTIND]; if ((img = tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } else { dash++; ilast = TSTRTOULL(dash, &cp, 0); if (*cp || *cp == *dash) { /* Not a number - consider it a file name */ dash--; *dash = '-'; image = argv[OPTIND]; if ((img = tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } else { set_range = 0; /* It was a block range, so do not include it in the open */ image = argv[OPTIND]; if ((img = tsk_img_open(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } } } } if ((fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_error_get_errno() == TSK_ERR_FS_UNSUPTYPE) tsk_fs_type_print(stderr); img->close(img); exit(1); } /* do we need to set the range or just check them? */ if (set_range) { istart = fs->first_inum; ilast = fs->last_inum; } else { if (istart < fs->first_inum) istart = fs->first_inum; if (ilast > fs->last_inum) ilast = fs->last_inum; } /* NTFS uses alloc and link different than UNIX so change * the default behavior * * The link value can be > 0 on deleted files (even when closed) */ /* NTFS and FAT have no notion of deleted but still open */ if ((ils_flags & TSK_FS_ILS_OPEN) && (TSK_FS_TYPE_ISNTFS(fs->ftype) || TSK_FS_TYPE_ISFAT(fs->ftype))) { fprintf(stderr, "Error: '-O' argument does not work with NTFS and FAT images\n"); exit(1); } if (tsk_fs_ils(fs, (TSK_FS_ILS_FLAG_ENUM) ils_flags, istart, ilast, (TSK_FS_META_FLAG_ENUM) flags, sec_skew, image)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } fs->close(fs); img->close(img); exit(0); }
int main(int argc, char **argv1) { TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT; TSK_IMG_INFO *img; TSK_OFF_T imgaddr = 0; TSK_FS_TYPE_ENUM fstype = TSK_FS_TYPE_DETECT; TSK_FS_INFO *fs; TSK_INUM_T inum; int ch; TSK_TCHAR *cp; int32_t sec_skew = 0; /* When > 0 this is the number of blocks to print, used for -B arg */ TSK_DADDR_T numblock = 0; TSK_TCHAR **argv; unsigned int ssize = 0; #ifdef TSK_WIN32 // On Windows, get the wide arguments (mingw doesn't support wmain) argv = CommandLineToArgvW(GetCommandLineW(), &argc); if (argv == NULL) { fprintf(stderr, "Error getting wide arguments\n"); exit(1); } #else argv = (TSK_TCHAR **) argv1; #endif progname = argv[0]; setlocale(LC_ALL, ""); while ((ch = GETOPT(argc, argv, _TSK_T("b:B:f:i:o:s:vVz:"))) > 0) { switch (ch) { case _TSK_T('?'): default: TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"), argv[OPTIND]); usage(); case _TSK_T('B'): numblock = TSTRTOULL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG || numblock < 1) { TFPRINTF(stderr, _TSK_T ("invalid argument: block count must be positive: %s\n"), OPTARG); usage(); } break; case _TSK_T('b'): ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0); if (*cp || *cp == *OPTARG || ssize < 1) { TFPRINTF(stderr, _TSK_T ("invalid argument: sector size must be positive: %s\n"), OPTARG); usage(); } break; case _TSK_T('f'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_fs_type_print(stderr); exit(1); } fstype = tsk_fs_type_toid(OPTARG); if (fstype == TSK_FS_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported file system type: %s\n"), OPTARG); usage(); } break; case _TSK_T('i'): if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) { tsk_img_type_print(stderr); exit(1); } imgtype = tsk_img_type_toid(OPTARG); if (imgtype == TSK_IMG_TYPE_UNSUPP) { TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"), OPTARG); usage(); } break; case _TSK_T('o'): if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('s'): sec_skew = TATOI(OPTARG); break; case _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_version_print(stdout); exit(0); case _TSK_T('z'): { TSK_TCHAR envstr[32]; TSNPRINTF(envstr, 32, _TSK_T("TZ=%s"), OPTARG); if (0 != TPUTENV(envstr)) { tsk_fprintf(stderr, "error setting environment"); exit(1); } TZSET(); } break; } } /* We need at least two more argument */ if (OPTIND + 1 >= argc) { tsk_fprintf(stderr, "Missing image name and/or address\n"); usage(); } /* if we are given the inode in the inode-type-id form, then ignore * the other stuff w/out giving an error * * This will make scripting easier */ if (tsk_fs_parse_inum(argv[argc - 1], &inum, NULL, NULL, NULL, NULL)) { TFPRINTF(stderr, _TSK_T("Invalid inode number: %s"), argv[argc - 1]); usage(); } /* * Open the file system. */ if ((img = tsk_img_open(argc - OPTIND - 1, &argv[OPTIND], imgtype, ssize)) == NULL) { tsk_error_print(stderr); exit(1); } if ((imgaddr * img->sector_size) >= img->size) { tsk_fprintf(stderr, "Sector offset supplied is larger than disk image (maximum: %" PRIu64 ")\n", img->size / img->sector_size); exit(1); } if ((fs = tsk_fs_open_img(img, imgaddr * img->sector_size, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_error_get_errno() == TSK_ERR_FS_UNSUPTYPE) tsk_fs_type_print(stderr); img->close(img); exit(1); } if (inum > fs->last_inum) { tsk_fprintf(stderr, "Metadata address is too large for image (%" PRIuINUM ")\n", fs->last_inum); fs->close(fs); img->close(img); exit(1); } if (inum < fs->first_inum) { tsk_fprintf(stderr, "Metadata address is too small for image (%" PRIuINUM ")\n", fs->first_inum); fs->close(fs); img->close(img); exit(1); } if (fs->istat(fs, stdout, inum, numblock, sec_skew)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } fs->close(fs); img->close(img); exit(0); }