int do_internal_find_inode (const mountable_t *mountable, int64_t inode) { int ret = -1; TSK_FS_INFO *fs = NULL; TSK_IMG_INFO *img = NULL; /* Used internally by tsk_fs_dir_walk */ const int flags = TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_NOORPHAN; ret = open_filesystem (mountable->device, &img, &fs); if (ret < 0) return ret; reply (NULL, NULL); /* Reply message. */ ret = tsk_fs_dir_walk (fs, fs->root_inum, flags, findino_callback, (void *) &inode); if (ret == 0) ret = send_file_end (0); /* File transfer end. */ else send_file_end (1); /* Cancel file transfer. */ fs->close (fs); img->close (img); return ret; }
/** \internal * Check the arguments for the tsk_fs_file_attr_XXX functions * and load the attributes if needed. * @param a_fs_file File argument to check. * @param a_func Name of function that this is checking for (for error messages) * @returns 1 on error */ static int tsk_fs_file_attr_check(TSK_FS_FILE * a_fs_file, char *a_func) { TSK_FS_INFO *fs; // check the FS_INFO, FS_FILE structures if ((a_fs_file == NULL) || (a_fs_file->meta == NULL) || (a_fs_file->fs_info == NULL)) { tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr("%s: called with NULL pointers", a_func); return 1; } else if (a_fs_file->meta->tag != TSK_FS_META_TAG) { tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr("%s: called with unallocated structures", a_func); return 1; } fs = a_fs_file->fs_info; // If the attributes haven't been loaded, then load them. if (a_fs_file->meta->attr_state == TSK_FS_META_ATTR_ERROR) { tsk_error_set_errno(TSK_ERR_FS_INODE_COR); tsk_error_set_errstr("%s: called for file with corrupt data", a_func); return 1; } else if ((a_fs_file->meta->attr_state != TSK_FS_META_ATTR_STUDIED) || (a_fs_file->meta->attr == NULL)) { if (fs->load_attrs(a_fs_file)) { return 1; } } return 0; }
/** \ingroup fslib * Return the default attribute for the file * @param a_fs_file File to get data from * @returns NULL on error */ const TSK_FS_ATTR * tsk_fs_file_attr_get(TSK_FS_FILE * a_fs_file) { TSK_FS_ATTR_TYPE_ENUM type; TSK_FS_INFO *fs; if (tsk_fs_file_attr_check(a_fs_file, "tsk_fs_file_attr_get")) return NULL; // since they did not give us a type, get the default for the file fs = a_fs_file->fs_info; type = fs->get_default_attr_type(a_fs_file); return tsk_fs_attrlist_get(a_fs_file->meta->attr, type); }
/** \internal * Processes a non-resident TSK_FS_ATTR structure and calls the callback with the associated * data. * * @param fs_attr Resident data structure to be walked * @param a_flags Flags for walking * @param a_action Callback action * @param a_ptr Pointer to data that is passed to callback * @returns 1 on error or 0 on success */ static uint8_t tsk_fs_attr_walk_nonres(const TSK_FS_ATTR * fs_attr, TSK_FS_FILE_WALK_FLAG_ENUM a_flags, TSK_FS_FILE_WALK_CB a_action, void *a_ptr) { char *buf = NULL; TSK_OFF_T tot_size; TSK_OFF_T off = 0; TSK_FS_ATTR_RUN *fs_attr_run; int retval; uint32_t skip_remain; TSK_FS_INFO *fs = fs_attr->fs_file->fs_info; uint8_t stop_loop = 0; if ((fs_attr->flags & TSK_FS_ATTR_NONRES) == 0) { tsk_error_set_errno(TSK_ERR_FS_ARG); tsk_error_set_errstr ("tsk_fs_file_walk_nonres: called with non-non-resident data"); return 1; } /* if we want the slack space too, then use the allocsize */ if (a_flags & TSK_FS_FILE_WALK_FLAG_SLACK) tot_size = fs_attr->nrd.allocsize; else tot_size = fs_attr->size; skip_remain = fs_attr->nrd.skiplen; if ((a_flags & TSK_FS_FILE_WALK_FLAG_AONLY) == 0) { if ((buf = (char *) tsk_malloc(fs->block_size)) == NULL) { return 1; } } /* cycle through the number of runs we have */ retval = TSK_WALK_CONT; for (fs_attr_run = fs_attr->nrd.run; fs_attr_run; fs_attr_run = fs_attr_run->next) { TSK_DADDR_T addr, len_idx; addr = fs_attr_run->addr; /* cycle through each block in the run */ for (len_idx = 0; len_idx < fs_attr_run->len; len_idx++) { TSK_FS_BLOCK_FLAG_ENUM myflags; /* If the address is too large then give an error */ if (addr + len_idx > fs->last_block) { if (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 1; } // load the buffer if they want more than just the address if ((a_flags & TSK_FS_FILE_WALK_FLAG_AONLY) == 0) { /* sparse files just get 0s */ if (fs_attr_run->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE) { memset(buf, 0, fs->block_size); } /* FILLER entries exist when the source file system can store run * info out of order and we did not get all of the run info. We * return 0s if data is read from this type of run. */ else if (fs_attr_run->flags & TSK_FS_ATTR_RUN_FLAG_FILLER) { memset(buf, 0, fs->block_size); if (tsk_verbose) fprintf(stderr, "tsk_fs_attr_walk_nonres: File %" PRIuINUM " has FILLER entry, using 0s\n", fs_attr->fs_file->meta->addr); } // we return 0s for reads past the initsize else if ((off >= fs_attr->nrd.initsize) && ((a_flags & TSK_FS_FILE_READ_FLAG_SLACK) == 0)) { memset(buf, 0, fs->block_size); } else { ssize_t cnt; cnt = tsk_fs_read_block (fs, addr + len_idx, buf, fs->block_size); if (cnt != fs->block_size) { if (cnt >= 0) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_READ); } tsk_error_set_errstr2 ("tsk_fs_file_walk: Error reading block at %" PRIuDADDR, addr + len_idx); return 1; } if ((off + fs->block_size > fs_attr->nrd.initsize) && ((a_flags & TSK_FS_FILE_READ_FLAG_SLACK) == 0)) { memset(&buf[fs_attr->nrd.initsize - off], 0, fs->block_size - (size_t) (fs_attr->nrd.initsize - off)); } } } /* 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; } 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); /* Only do sparse or FILLER clusters if NOSPARSE is not set */ if ((fs_attr_run->flags & TSK_FS_ATTR_RUN_FLAG_SPARSE) || (fs_attr_run->flags & TSK_FS_ATTR_RUN_FLAG_FILLER) || (off > fs_attr->nrd.initsize)) { myflags = fs->block_getflags(fs, 0); myflags |= TSK_FS_BLOCK_FLAG_SPARSE; if ((a_flags & TSK_FS_FILE_WALK_FLAG_NOSPARSE) == 0) { retval = a_action(fs_attr->fs_file, off, 0, &buf[skip_remain], ret_len, myflags, a_ptr); } } else { myflags = fs->block_getflags(fs, addr + len_idx); myflags |= TSK_FS_BLOCK_FLAG_RAW; retval = a_action(fs_attr->fs_file, off, addr + len_idx, &buf[skip_remain], ret_len, myflags, a_ptr); } off += ret_len; skip_remain = 0; if (retval != TSK_WALK_CONT) { stop_loop = 1; break; } if (off >= tot_size) { stop_loop = 1; break; } } } if (stop_loop) break; } if (buf) free(buf); if (retval == TSK_WALK_ERROR) return 1; else return 0; }
/* * * NoTe that this does not set the flag value. * * return 1 on error and 0 on success */ static uint8_t ext2fs_dent_copy(EXT2FS_INFO * ext2fs, EXT2FS_DINFO * dinfo, char *ext2_dent, TSK_FS_DENT * fs_dent) { TSK_FS_INFO *fs = &(ext2fs->fs_info); int i; if (ext2fs->deentry_type == EXT2_DE_V1) { ext2fs_dentry1 *dir = (ext2fs_dentry1 *) ext2_dent; fs_dent->inode = tsk_getu32(fs->endian, dir->inode); /* ext2 does not null terminate */ if (tsk_getu16(fs->endian, dir->name_len) >= fs_dent->name_max) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2fs_dent_copy: Name Space too Small %d %lu", tsk_getu16(fs->endian, dir->name_len), fs_dent->name_max); return 1; } /* Copy and Null Terminate */ strncpy(fs_dent->name, dir->name, tsk_getu16(fs->endian, dir->name_len)); fs_dent->name[tsk_getu16(fs->endian, dir->name_len)] = '\0'; fs_dent->ent_type = TSK_FS_DENT_TYPE_UNDEF; } else { ext2fs_dentry2 *dir = (ext2fs_dentry2 *) ext2_dent; fs_dent->inode = tsk_getu32(fs->endian, dir->inode); /* ext2 does not null terminate */ if (dir->name_len >= fs_dent->name_max) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2_dent_copy: Name Space too Small %d %lu", dir->name_len, fs_dent->name_max); return 1; } /* Copy and Null Terminate */ strncpy(fs_dent->name, dir->name, dir->name_len); fs_dent->name[dir->name_len] = '\0'; switch (dir->type) { case EXT2_DE_REG_FILE: fs_dent->ent_type = TSK_FS_DENT_TYPE_REG; break; case EXT2_DE_DIR: fs_dent->ent_type = TSK_FS_DENT_TYPE_DIR; break; case EXT2_DE_CHRDEV: fs_dent->ent_type = TSK_FS_DENT_TYPE_CHR; break; case EXT2_DE_BLKDEV: fs_dent->ent_type = TSK_FS_DENT_TYPE_BLK; break; case EXT2_DE_FIFO: fs_dent->ent_type = TSK_FS_DENT_TYPE_FIFO; break; case EXT2_DE_SOCK: fs_dent->ent_type = TSK_FS_DENT_TYPE_SOCK; break; case EXT2_DE_SYMLINK: fs_dent->ent_type = TSK_FS_DENT_TYPE_LNK; break; case EXT2_DE_UNKNOWN: default: fs_dent->ent_type = TSK_FS_DENT_TYPE_UNDEF; break; } } /* Clean up name */ i = 0; while (fs_dent->name[i] != '\0') { if (TSK_IS_CNTRL(fs_dent->name[i])) fs_dent->name[i] = '^'; i++; } fs_dent->path = dinfo->dirs; fs_dent->pathdepth = dinfo->depth; if ((fs != NULL) && (fs_dent->inode) && (fs_dent->inode <= fs->last_inum)) { /* Get inode */ if (fs_dent->fsi) tsk_fs_inode_free(fs_dent->fsi); if ((fs_dent->fsi = fs->inode_lookup(fs, fs_dent->inode)) == NULL) { strncat(tsk_errstr2, " - ext2fs_dent_copy", TSK_ERRSTR_L - strlen(tsk_errstr2)); return 1; } } else { if (fs_dent->fsi) tsk_fs_inode_free(fs_dent->fsi); fs_dent->fsi = NULL; } fs_dent->flags = 0; return 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; 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 MAIN(int argc, TSK_TCHAR ** argv) { TSK_FS_INFO *fs; TSK_IMG_INFO *img; TSK_TCHAR *fstype = NULL; TSK_TCHAR *imgtype = NULL; int ch; uint8_t type = 0; SSIZE_T imgoff = 0; progname = argv[0]; setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, _TSK_T("f:i:o:tvV"))) > 0) { switch (ch) { case _TSK_T('?'): default: TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"), argv[optind]); usage(); case _TSK_T('f'): fstype = optarg; if (TSTRCMP(fstype, _TSK_T("list")) == 0) { tsk_fs_print_types(stderr); exit(1); } break; case _TSK_T('i'): imgtype = optarg; if (TSTRCMP(imgtype, _TSK_T("list")) == 0) { tsk_img_print_types(stderr); exit(1); } break; case _TSK_T('o'): if ((imgoff = tsk_parse_offset(optarg)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('t'): type = 1; break; case _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_print_version(stdout); exit(0); } } /* We need at least one more argument */ if (optind >= argc) { tsk_fprintf(stderr, "Missing image name\n"); usage(); } if ((img = tsk_img_open(imgtype, argc - optind, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); exit(1); } if ((fs = tsk_fs_open(img, imgoff, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_fs_print_types(stderr); img->close(img); exit(1); } if (type) { char *str = tsk_fs_get_type(fs->ftype); tsk_printf("%s\n", str); } else { if (fs->fsstat(fs, stdout)) { 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 **argv) { 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 **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]; while ((ch = GETOPT(argc, argv, "b:f:i:o:vV")) > 0) { switch (ch) { case '?': default: fprintf(stderr, "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 '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 '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 'o': if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case 'v': verbose++; break; case 'V': print_version(stdout); exit(0); } } /* We need at least one more argument */ if (OPTIND >= argc) { fprintf(stderr, "Missing image name\n"); usage(); } img = img_open(imgoff, argc - OPTIND, (const char **) &argv[OPTIND], imgtype, ssize); if (img == NULL) { tsk_error_print(stderr); exit(1); } if (fs = fs_open(img, fstype)) { if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_print_types(stderr); tsk_error_print(stderr); img->close(img); exit(1); } if (fs->fscheck(fs, stdout)) { 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 **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); }
int MAIN(int argc, TSK_TCHAR ** argv) { TSK_TCHAR *imgtype = NULL; TSK_TCHAR *fstype = NULL; TSK_FS_INFO *fs; TSK_IMG_INFO *img; int ch; TSK_TCHAR *cp; extern int optind; DADDR_T block = 0; /* the block to find */ INUM_T parinode = 0; TSK_TCHAR *path = NULL; SSIZE_T imgoff = 0; progname = argv[0]; setlocale(LC_ALL, ""); localflags = 0; while ((ch = getopt(argc, argv, _TSK_T("ad:f:i:ln:o:p:vVz:"))) > 0) { switch (ch) { case _TSK_T('a'): localflags |= TSK_FS_IFIND_ALL; break; case _TSK_T('d'): if (localflags & (TSK_FS_IFIND_PAR | TSK_FS_IFIND_PATH)) { tsk_fprintf(stderr, "error: only one address type can be given\n"); usage(); } localflags |= TSK_FS_IFIND_DATA; block = TSTRTOULL(optarg, &cp, 0); if (*cp || *cp == *optarg) { TFPRINTF(stderr, _TSK_T("Invalid block address: %s\n"), optarg); usage(); } break; case _TSK_T('f'): fstype = optarg; if (TSTRCMP(fstype, _TSK_T("list")) == 0) { tsk_fs_print_types(stderr); exit(1); } break; case _TSK_T('i'): imgtype = optarg; if (TSTRCMP(imgtype, _TSK_T("list")) == 0) { tsk_img_print_types(stderr); exit(1); } break; case _TSK_T('l'): localflags |= TSK_FS_IFIND_PAR_LONG; break; case _TSK_T('n'): { size_t len; if (localflags & (TSK_FS_IFIND_PAR | TSK_FS_IFIND_DATA)) { tsk_fprintf(stderr, "error: only one address type can be given\n"); usage(); } localflags |= TSK_FS_IFIND_PATH; len = (TSTRLEN(optarg) + 1) * sizeof(TSK_TCHAR); if ((path = (TSK_TCHAR *) tsk_malloc(len)) == NULL) { tsk_error_print(stderr); exit(1); } TSTRNCPY(path, optarg, TSTRLEN(optarg) + 1); break; } case 'o': if ((imgoff = tsk_parse_offset(optarg)) == -1) { tsk_error_print(stderr); exit(1); } break; case 'p': if (localflags & (TSK_FS_IFIND_PATH | TSK_FS_IFIND_DATA)) { tsk_fprintf(stderr, "error: only one address type can be given\n"); usage(); } localflags |= TSK_FS_IFIND_PAR; if (tsk_parse_inum(optarg, &parinode, NULL, NULL, NULL)) { TFPRINTF(stderr, _TSK_T("Invalid inode address: %s\n"), optarg); usage(); } break; case 'v': tsk_verbose++; break; case 'V': tsk_print_version(stdout); exit(0); case 'z': { TSK_TCHAR envstr[32]; TSNPRINTF(envstr, 32, _TSK_T("TZ=%s"), optarg); if (0 != PUTENV(envstr)) { tsk_fprintf(stderr, "error setting environment"); exit(1); } /* we should be checking this somehow */ TZSET(); break; } case '?': default: tsk_fprintf(stderr, "Invalid argument: %s\n", argv[optind]); usage(); } } /* We need at least one more argument */ if (optind >= argc) { tsk_fprintf(stderr, "Missing image name\n"); if (path) free(path); usage(); } if (0 == (localflags & (TSK_FS_IFIND_PATH | TSK_FS_IFIND_DATA | TSK_FS_IFIND_PAR))) { tsk_fprintf(stderr, "-d, -n, or -p must be given\n"); usage(); } if ((img = tsk_img_open(imgtype, argc - optind, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); if (path) free(path); exit(1); } if ((fs = tsk_fs_open(img, imgoff, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_fs_print_types(stderr); img->close(img); if (path) free(path); exit(1); } if (localflags & TSK_FS_IFIND_DATA) { if (block > fs->last_block) { tsk_fprintf(stderr, "Block %" PRIuDADDR " is larger than last block in image (%" PRIuDADDR ")\n", block, fs->last_block); fs->close(fs); img->close(img); exit(1); } else if (block == 0) { tsk_printf("Inode not found\n"); fs->close(fs); img->close(img); exit(1); } if (tsk_fs_ifind_data(fs, localflags, block)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } } else if (localflags & TSK_FS_IFIND_PAR) { if ((fs->ftype & TSK_FS_INFO_TYPE_FS_MASK) != TSK_FS_INFO_TYPE_NTFS_TYPE) { tsk_fprintf(stderr, "-p works only with NTFS file systems\n"); fs->close(fs); img->close(img); exit(1); } else if (parinode > fs->last_inum) { tsk_fprintf(stderr, "Meta data %" PRIuINUM " is larger than last MFT entry in image (%" PRIuINUM ")\n", parinode, fs->last_inum); fs->close(fs); img->close(img); exit(1); } if (tsk_fs_ifind_par(fs, localflags, parinode)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } } else if (localflags & TSK_FS_IFIND_PATH) { int retval; INUM_T inum; if (-1 == (retval = tsk_fs_ifind_path(fs, localflags, path, &inum))) { tsk_error_print(stderr); fs->close(fs); img->close(img); free(path); exit(1); } free(path); if (retval == 1) tsk_printf("File not found\n"); else tsk_printf("%" PRIuINUM "\n", inum); } fs->close(fs); img->close(img); exit(0); }
int MAIN(int argc, TSK_TCHAR ** argv) { TSK_TCHAR *imgtype = NULL; TSK_TCHAR *fstype = NULL; TSK_IMG_INFO *img; TSK_FS_INFO *fs; INUM_T inum; int ch; TSK_TCHAR *cp; int32_t sec_skew = 0; SSIZE_T imgoff = 0; /* When > 0 this is the number of blocks to print, used for -b arg */ DADDR_T numblock = 0; progname = argv[0]; setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, _TSK_T("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('f'): fstype = optarg; if (TSTRCMP(fstype, _TSK_T("list")) == 0) { tsk_fs_print_types(stderr); exit(1); } break; case _TSK_T('i'): imgtype = optarg; if (TSTRCMP(imgtype, _TSK_T("list")) == 0) { tsk_img_print_types(stderr); exit(1); } break; case _TSK_T('o'): if ((imgoff = 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_print_version(stdout); exit(0); case _TSK_T('z'): { TSK_TCHAR envstr[32]; TSNPRINTF(envstr, 32, _TSK_T("TZ=%s"), optarg); if (0 != PUTENV(envstr)) { tsk_fprintf(stderr, "error setting environment"); exit(1); } 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_parse_inum(argv[argc - 1], &inum, NULL, NULL, NULL)) { TFPRINTF(stderr, _TSK_T("Invalid inode number: %s"), argv[argc - 1]); usage(); } /* * Open the file system. */ if ((img = tsk_img_open(imgtype, argc - optind - 1, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); exit(1); } if ((fs = tsk_fs_open(img, imgoff, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_fs_print_types(stderr); img->close(img); 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); }
/* * copy the index (directory) entry into the generic structure * * uses the global variables 'dirs' and 'depth' * * Returns 1 on eror and 0 on success */ static uint8_t ntfs_dent_copy(NTFS_INFO * ntfs, NTFS_DINFO * dinfo, ntfs_idxentry * idxe, TSK_FS_DENT * fs_dent) { ntfs_attr_fname *fname = (ntfs_attr_fname *) & idxe->stream; TSK_FS_INFO *fs = (TSK_FS_INFO *) & ntfs->fs_info; UTF16 *name16; UTF8 *name8; int retVal; int i; fs_dent->inode = tsk_getu48(fs->endian, idxe->file_ref); name16 = (UTF16 *) & fname->name; name8 = (UTF8 *) fs_dent->name; retVal = tsk_UTF16toUTF8(fs->endian, (const UTF16 **) &name16, (UTF16 *) ((uintptr_t) name16 + fname->nlen * 2), &name8, (UTF8 *) ((uintptr_t) name8 + fs_dent->name_max), TSKlenientConversion); if (retVal != TSKconversionOK) { *name8 = '\0'; if (tsk_verbose) tsk_fprintf(stderr, "Error converting NTFS name to UTF8: %d %" PRIuINUM, retVal, fs_dent->inode); } /* Make sure it is NULL Terminated */ if ((uintptr_t) name8 > (uintptr_t) fs_dent->name + fs_dent->name_max) fs_dent->name[fs_dent->name_max] = '\0'; else *name8 = '\0'; /* Clean up name */ i = 0; while (fs_dent->name[i] != '\0') { if (TSK_IS_CNTRL(fs_dent->name[i])) fs_dent->name[i] = '^'; i++; } /* copy the path data */ fs_dent->path = dinfo->dirs; fs_dent->pathdepth = dinfo->depth; /* Get the actual inode */ if (fs_dent->fsi != NULL) tsk_fs_inode_free(fs_dent->fsi); if (NULL == (fs_dent->fsi = fs->inode_lookup(fs, fs_dent->inode))) { if (tsk_verbose) { tsk_fprintf(stderr, "ntfs_dent_copy: error looking up inode: %" PRIuINUM "\n", fs_dent->inode); tsk_error_print(stderr); tsk_error_reset(); } } if (tsk_getu64(fs->endian, fname->flags) & NTFS_FNAME_FLAGS_DIR) fs_dent->ent_type = TSK_FS_DENT_TYPE_DIR; else fs_dent->ent_type = TSK_FS_DENT_TYPE_REG; fs_dent->flags = 0; return 0; }
int MAIN(int argc, TSK_TCHAR ** argv) { TSK_FS_INFO *fs = NULL; TSK_IMG_INFO *img; DADDR_T addr = 0; TSK_TCHAR *fstype = NULL; TSK_TCHAR *cp, *imgtype = NULL; 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; SSIZE_T imgoff = 0; progname = argv[0]; setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, _TSK_T("af:hi:o:su:vVw"))) > 0) { switch (ch) { case _TSK_T('a'): format |= TSK_FS_DCAT_ASCII; break; case _TSK_T('f'): fstype = optarg; if (TSTRCMP(fstype, _TSK_T(DLS_TYPE)) == 0) fstype = _TSK_T(RAW_STR); if (TSTRCMP(fstype, _TSK_T("list")) == 0) { tsk_fprintf(stderr, "\t%s (Unallocated Space)\n", DLS_TYPE); tsk_fs_print_types(stderr); exit(1); } break; case _TSK_T('h'): format |= TSK_FS_DCAT_HEX; break; case _TSK_T('i'): imgtype = optarg; if (TSTRCMP(imgtype, _TSK_T("list")) == 0) { tsk_img_print_types(stderr); exit(1); } break; case _TSK_T('o'): if ((imgoff = tsk_parse_offset(optarg)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('s'): format |= TSK_FS_DCAT_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_print_version(stdout); exit(0); break; case _TSK_T('w'): format |= TSK_FS_DCAT_HTML; break; case _TSK_T('?'): default: TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"), argv[optind]); usage(); } } if (format & TSK_FS_DCAT_STAT) { if (optind == argc) usage(); if (format & (TSK_FS_DCAT_HTML | TSK_FS_DCAT_ASCII | TSK_FS_DCAT_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_DCAT_ASCII) && (format & TSK_FS_DCAT_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_DCAT_STAT) { if ((img = tsk_img_open(imgtype, argc - optind, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); 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(imgtype, argc - optind - 1, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); 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(imgtype, argc - optind - 2, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); exit(1); } } } /* open the file */ if ((fs = tsk_fs_open(img, imgoff, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_fs_print_types(stderr); img->close(img); exit(1); } /* Set the default size if given */ if ((usize != 0) && (((fs->ftype & TSK_FS_INFO_TYPE_FS_MASK) == TSK_FS_INFO_TYPE_RAW_TYPE) || ((fs->ftype & TSK_FS_INFO_TYPE_FS_MASK) == TSK_FS_INFO_TYPE_SWAP_TYPE))) { 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_dcat(fs, 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); }
/* main - open file system, list inode info */ int MAIN(int argc, TSK_TCHAR ** argv) { TSK_TCHAR *fstype = NULL; TSK_TCHAR *imgtype = NULL, *cp, *dash; TSK_IMG_INFO *img; TSK_FS_INFO *fs; INUM_T istart = 0, ilast = 0; int ch; int flags = TSK_FS_INODE_FLAG_UNALLOC | TSK_FS_INODE_FLAG_USED; int argflags = 0; SSIZE_T imgoff = 0; int set_range = 1; TSK_TCHAR *image = NULL; int32_t sec_skew = 0; progname = argv[0]; setlocale(LC_ALL, ""); /* * Provide convenience options for the most commonly selected feature * combinations. */ while ((ch = getopt(argc, argv, _TSK_T("aAef: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('f'): fstype = optarg; if (TSTRCMP(fstype, _TSK_T("list")) == 0) { tsk_fs_print_types(stderr); exit(1); } break; case _TSK_T('i'): imgtype = optarg; if (TSTRCMP(imgtype, _TSK_T("list")) == 0) { tsk_img_print_types(stderr); exit(1); } break; case _TSK_T('e'): flags |= (TSK_FS_INODE_FLAG_ALLOC | TSK_FS_INODE_FLAG_UNALLOC); flags &= ~TSK_FS_INODE_FLAG_USED; break; case _TSK_T('m'): argflags |= TSK_FS_ILS_MAC; break; case _TSK_T('o'): if ((imgoff = tsk_parse_offset(optarg)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('O'): flags |= TSK_FS_INODE_FLAG_UNALLOC; flags &= ~TSK_FS_INODE_FLAG_ALLOC; argflags |= TSK_FS_ILS_OPEN; break; case _TSK_T('p'): flags |= (TSK_FS_INODE_FLAG_ORPHAN | TSK_FS_INODE_FLAG_UNALLOC); flags &= ~TSK_FS_INODE_FLAG_ALLOC; break; case _TSK_T('r'): flags |= (TSK_FS_INODE_FLAG_UNALLOC | TSK_FS_INODE_FLAG_USED); flags &= ~TSK_FS_INODE_FLAG_ALLOC; break; case _TSK_T('s'): sec_skew = TATOI(optarg); break; case _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_print_version(stdout); exit(0); /* * Provide fine controls to tweak one feature at a time. */ case _TSK_T('a'): flags |= TSK_FS_INODE_FLAG_ALLOC; break; case _TSK_T('A'): flags |= TSK_FS_INODE_FLAG_UNALLOC; break; case _TSK_T('l'): argflags |= TSK_FS_ILS_LINK; break; case _TSK_T('L'): argflags |= TSK_FS_ILS_UNLINK; break; case _TSK_T('z'): flags |= TSK_FS_INODE_FLAG_UNUSED; break; case _TSK_T('Z'): flags |= TSK_FS_INODE_FLAG_USED; break; } } if (optind >= argc) { tsk_fprintf(stderr, "Missing image name\n"); usage(); } if ((argflags & TSK_FS_ILS_LINK) && (argflags & 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(imgtype, argc - optind, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); exit(1); } } else { /* Single address set end addr to start */ ilast = istart; set_range = 0; image = argv[optind]; if ((img = tsk_img_open(imgtype, argc - optind - 1, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); 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(imgtype, argc - optind, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); 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(imgtype, argc - optind, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); 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(imgtype, argc - optind - 1, (const TSK_TCHAR **) &argv[optind])) == NULL) { tsk_error_print(stderr); exit(1); } } } } if ((fs = tsk_fs_open(img, imgoff, fstype)) == NULL) { tsk_error_print(stderr); if (tsk_errno == TSK_ERR_FS_UNSUPTYPE) tsk_fs_print_types(stderr); img->close(img); 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 ((argflags & TSK_FS_ILS_OPEN) && (((fs->ftype & TSK_FS_INFO_TYPE_FS_MASK) == TSK_FS_INFO_TYPE_NTFS_TYPE) || ((fs->ftype & TSK_FS_INFO_TYPE_FS_MASK) == TSK_FS_INFO_TYPE_FAT_TYPE))) { fprintf(stderr, "Error: '-O' argument does not work with NTFS and FAT images\n"); exit(1); } if (tsk_fs_ils(fs, argflags, istart, ilast, flags, sec_skew, image)) { tsk_error_print(stderr); fs->close(fs); img->close(img); exit(1); } fs->close(fs); img->close(img); exit(0); }
/* 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); }