Exemple #1
0
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;
}
Exemple #2
0
/** \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;
}
Exemple #3
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);
}
Exemple #4
0
/** \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;
}
Exemple #5
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;
}
Exemple #6
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);
}
Exemple #7
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);
}
Exemple #8
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);
}
Exemple #9
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);
}
Exemple #10
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);
}
Exemple #11
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);
}
Exemple #12
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);
}
Exemple #13
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;
}
Exemple #14
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);
}
Exemple #15
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);
}
Exemple #16
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);
}
Exemple #17
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);
}