Exemple #1
0
static TSK_WALK_RET_ENUM
blkstat_act(const TSK_FS_BLOCK * fs_block, void *ptr)
{
    tsk_printf("%s: %" PRIuDADDR "\n", fs_block->fs_info->duname,
        fs_block->addr);
    tsk_printf("%sAllocated%s\n",
        (fs_block->flags & TSK_FS_BLOCK_FLAG_ALLOC) ? "" : "Not ",
        (fs_block->flags & TSK_FS_BLOCK_FLAG_META) ? " (Meta)" : "");

    if (TSK_FS_TYPE_ISFFS(fs_block->fs_info->ftype)) {
        FFS_INFO *ffs = (FFS_INFO *) fs_block->fs_info;
        tsk_printf("Group: %" PRI_FFSGRP "\n", ffs->grp_num);
    }
    else if (TSK_FS_TYPE_ISEXT(fs_block->fs_info->ftype)) {
        EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs_block->fs_info;
        if (fs_block->addr >= ext2fs->first_data_block)
            tsk_printf("Group: %" PRI_EXT2GRP "\n", ext2fs->grp_num);
    }
    else if (TSK_FS_TYPE_ISFAT(fs_block->fs_info->ftype)) {
        FATFS_INFO *fatfs = (FATFS_INFO *) fs_block->fs_info;
        /* Does this have a cluster address? */
        if (fs_block->addr >= fatfs->firstclustsect) {
            tsk_printf("Cluster: %" PRIuDADDR "\n",
                (2 + (fs_block->addr -
                        fatfs->firstclustsect) / fatfs->csize));
        }
    }

    return TSK_WALK_STOP;
}
Exemple #2
0
/* Used to process orphan directories and make sure that their contents
 * are now marked as reachable */
static TSK_WALK_RET_ENUM
load_orphan_dir_walk_cb(TSK_FS_FILE * a_fs_file, const char *a_path,
    void *a_ptr)
{
    FIND_ORPHAN_DATA *data = (FIND_ORPHAN_DATA *) a_ptr;

    // ignore DOT entries
    if ((a_fs_file->name) && (a_fs_file->name->name) &&
        (TSK_FS_ISDOT(a_fs_file->name->name)))
        return TSK_WALK_CONT;

    // add this entry to the orphan list
    if (a_fs_file->meta) {
        tsk_list_add(&data->orphan_subdir_list, a_fs_file->meta->addr);

        /* FAT file systems spend a lot of time hunting for parent
         * directory addresses, so we put this code in here to save
         * the info when we have it. */
        if ((a_fs_file->meta->type == TSK_FS_META_TYPE_DIR)
            && (TSK_FS_TYPE_ISFAT(a_fs_file->fs_info->ftype))) {
            if (fatfs_dir_buf_add((FATFS_INFO *) a_fs_file->fs_info,
                    a_fs_file->name->par_addr, a_fs_file->meta->addr))
                return TSK_WALK_ERROR;
        }
    }

    return TSK_WALK_CONT;
}
/* Process a temporal value */
void file_infot(const string name,time_t t0, TSK_FS_TYPE_ENUM ftype)
{
	const char * tm_format = NULL;
	
	if(TSK_FS_TYPE_ISFAT(ftype))
	{
#ifdef _MSC_VER
	    tm_format="%Y-%m-%dT%H:%M:%S";
#else
	    tm_format="%FT%T";	
#endif
	}
	else
	{
#ifdef _MSC_VER
	    tm_format="%Y-%m-%dT%H:%M:%SZ";
#else
	    tm_format="%FT%TZ";
#endif
	}

    if(a) a->add_valuet(name,t0); 
//	struct tm *temp_time = gmtime(&t0);
    if(x){
	char buf[32];
	strftime(buf,sizeof(buf),tm_format,gmtime(&t0));
	if(TSK_FS_TYPE_ISFAT(ftype))
	{
		if (!name.compare("atime"))
			x->xmlout(name,buf,"prec=\"86400\"", false);
		if (!name.compare("mtime"))
			x->xmlout(name,buf,"prec=\"2\"", false);
		if (!name.compare("crtime"))
			x->xmlout(name,buf,"prec=\"2\"", false);
	}
	else
		x->xmlout(name,buf);
    }
    if(t) {
	char buf[64];
	fprintf(t,"%s: %ld\n",name.c_str(),(long)t0);
	strftime(buf,sizeof(buf),tm_format,gmtime(&t0));
	fprintf(t,"%s_txt: %s\n",name.c_str(),buf);
    }
}
Exemple #4
0
/* Used to process orphan directories and make sure that their contents
 * are now marked as reachable */
static TSK_WALK_RET_ENUM
load_orphan_dir_walk_cb(TSK_FS_FILE * a_fs_file, const char *a_path,
    void *a_ptr)
{
    FIND_ORPHAN_DATA *data = (FIND_ORPHAN_DATA *) a_ptr;

    // ignore DOT entries
    if ((a_fs_file->name) && (a_fs_file->name->name) &&
        (TSK_FS_ISDOT(a_fs_file->name->name)))
        return TSK_WALK_CONT;

    // add this entry to the orphan list
    if (a_fs_file->meta) {
        /* Stop if we hit an allocated entry.  We shouldn't get these, but did
         * have some trouble images that went into allocated clusters on
         * a FAT file system. */
        if (a_fs_file->meta->flags & TSK_FS_META_FLAG_ALLOC) {
            if (tsk_verbose) {
                tsk_fprintf(stderr,
                    "load_orphan_dir_walk_cb: Skipping an allocated file (ID: %"
                    PRIuINUM ")\n", a_fs_file->meta->addr);
            }
            return TSK_WALK_STOP;
        }

        /* check if we have already added it as an orphan (in a subdirectory)
         * Not entirely sure how possible this is, but it was added while
         * debugging an infinite loop problem. */
        if (tsk_list_find(data->orphan_subdir_list, a_fs_file->meta->addr)) {
            if (tsk_verbose)
                fprintf(stderr,
                    "load_orphan_dir_walk_cb: Detected loop with address %"
                    PRIuINUM, a_fs_file->meta->addr);
            return TSK_WALK_STOP;
        }

        tsk_list_add(&data->orphan_subdir_list, a_fs_file->meta->addr);

        /* FAT file systems spend a lot of time hunting for parent
         * directory addresses, so we put this code in here to save
         * the info when we have it. */
        if ((a_fs_file->meta->type == TSK_FS_META_TYPE_DIR)
            && (TSK_FS_TYPE_ISFAT(a_fs_file->fs_info->ftype))) {
            if (fatfs_dir_buf_add((FATFS_INFO *) a_fs_file->fs_info,
                    a_fs_file->name->par_addr, a_fs_file->meta->addr))
                return TSK_WALK_ERROR;
        }
    }

    return TSK_WALK_CONT;
}
Exemple #5
0
/**
 * Utility method to help determine if a file is a FAT file system file (such as $MBR).
 *
 * @returns 1 if the file is an FAT System file, 0 if not.
 */
uint8_t
TskAuto::isFATSystemFiles(TSK_FS_FILE * a_fs_file)
{
    if ((a_fs_file) && (a_fs_file->fs_info)
        && (TSK_FS_TYPE_ISFAT(a_fs_file->fs_info->ftype))
        && (a_fs_file->name->meta_addr == FATFS_MBRINO(a_fs_file->fs_info)
            || a_fs_file->name->meta_addr ==
            FATFS_FAT1INO(a_fs_file->fs_info)
            || a_fs_file->name->meta_addr ==
            FATFS_FAT2INO(a_fs_file->fs_info)))
        return 1;
    else
        return 0;
}
Exemple #6
0
/* used to identify the unnamed metadata structures */
static TSK_WALK_RET_ENUM
find_orphan_meta_walk_cb(TSK_FS_FILE * a_fs_file, void *a_ptr)
{
    FIND_ORPHAN_DATA *data = (FIND_ORPHAN_DATA *) a_ptr;
    TSK_FS_INFO *fs = a_fs_file->fs_info;

    /* We want only orphans, then check if this
     * inode is in the seen list
     */
    tsk_take_lock(&fs->list_inum_named_lock);
    if ((fs->list_inum_named)
        && (tsk_list_find(fs->list_inum_named, a_fs_file->meta->addr))) {
        tsk_release_lock(&fs->list_inum_named_lock);
        return TSK_WALK_CONT;
    }
    tsk_release_lock(&fs->list_inum_named_lock);

    // check if we have already added it as an orphan (in a subdirectory)
    if (tsk_list_find(data->orphan_subdir_list, a_fs_file->meta->addr)) {
        return TSK_WALK_CONT;
    }

    // use their name if they have one
    if (a_fs_file->meta->name2) {
        strncpy(data->fs_name->name, a_fs_file->meta->name2->name,
            data->fs_name->name_size);
    }
    else {
        snprintf(data->fs_name->name, data->fs_name->name_size,
            "OrphanFile-%" PRIuINUM, a_fs_file->meta->addr);
    }
    data->fs_name->meta_addr = a_fs_file->meta->addr;
    data->fs_name->flags = TSK_FS_NAME_FLAG_UNALLOC;
    data->fs_name->type = TSK_FS_NAME_TYPE_UNDEF;

    if (tsk_fs_dir_add(data->fs_dir, data->fs_name))
        return TSK_WALK_ERROR;

    /* FAT file systems spend a lot of time hunting for parent
     * directory addresses, so we put this code in here to save
     * the info when we have it. */
    if (TSK_FS_TYPE_ISFAT(fs->ftype)) {
        if (fatfs_dir_buf_add((FATFS_INFO *) fs,
                TSK_FS_ORPHANDIR_INUM(fs), a_fs_file->meta->addr))
            return TSK_WALK_ERROR;
    }

    /* Go into directories to mark their contents as "seen" */
    if (a_fs_file->meta->type == TSK_FS_META_TYPE_DIR) {

        if (tsk_verbose)
            fprintf(stderr,
                "find_orphan_meta_walk_cb: Going into directory %" PRIuINUM
                " to mark contents as seen\n", a_fs_file->meta->addr);

        if (tsk_fs_dir_walk(fs, a_fs_file->meta->addr,
                TSK_FS_DIR_WALK_FLAG_UNALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE
                | TSK_FS_DIR_WALK_FLAG_NOORPHAN, load_orphan_dir_walk_cb,
                data)) {
            tsk_error_errstr2_concat
                (" - find_orphan_meta_walk_cb: identifying inodes allocated by file names");
            return TSK_WALK_ERROR;
        }
    }

    return TSK_WALK_CONT;
}
Exemple #7
0
/** \internal
 * Add a FS_DENT structure to a FS_DIR structure by copying its
 * contents into the internal buffer. Checks for
 * duplicates and expands buffer as needed.
 * @param a_fs_dir DIR to add to
 * @param a_fs_name DENT to add
 * @returns 1 on error (memory allocation problems) and 0 on success
 */
uint8_t
tsk_fs_dir_add(TSK_FS_DIR * a_fs_dir, const TSK_FS_NAME * a_fs_name)
{
    TSK_FS_NAME *fs_name_dest = NULL;
    size_t i;

    /* see if we already have it in the buffer / queue
     * We skip this check for FAT because it will always fail because two entries
     * never have the same meta address. */
    // @@@ We could do something more effecient here too with orphan files because we do not 
    // need to check the contents of that directory either and this takes a lot of time on those
    // large images.
	if (TSK_FS_TYPE_ISFAT(a_fs_dir->fs_info->ftype) == 0) {
		for (i = 0; i < a_fs_dir->names_used; i++) {
			if ((a_fs_name->meta_addr == a_fs_dir->names[i].meta_addr) &&
				(strcmp(a_fs_name->name, a_fs_dir->names[i].name) == 0)) {

				if (tsk_verbose)
					tsk_fprintf(stderr,
						"tsk_fs_dir_add: removing duplicate entry: %s (%"
						PRIuINUM ")\n", a_fs_name->name, a_fs_name->meta_addr);

				/* We do not check type because then we cannot detect NTFS orphan file
				 * duplicates that are added as "-/r" while a similar entry exists as "r/r"
				 (a_fs_name->type == a_fs_dir->names[i].type)) { */

				// if the one in the list is unalloc and we have an alloc, replace it
				if ((a_fs_dir->names[i].flags & TSK_FS_NAME_FLAG_UNALLOC) &&
					(a_fs_name->flags & TSK_FS_NAME_FLAG_ALLOC)) {
					fs_name_dest = &a_fs_dir->names[i];

					// free the memory - not the most effecient, but prevents
					// duplicate code.
					if (fs_name_dest->name) {
						free(fs_name_dest->name);
						fs_name_dest->name = NULL;
						fs_name_dest->name_size = 0;
					}
					if (fs_name_dest->shrt_name) {
						free(fs_name_dest->shrt_name);
						fs_name_dest->shrt_name = NULL;
						fs_name_dest->shrt_name_size = 0;
					}
					break;
				}
				else {
					return 0;
				}
			}
		}
	}

    if (fs_name_dest == NULL) {
        // make sure we got the room
        if (a_fs_dir->names_used >= a_fs_dir->names_alloc) {
            if (tsk_fs_dir_realloc(a_fs_dir, a_fs_dir->names_used + 512))
                return 1;
        }

        fs_name_dest = &a_fs_dir->names[a_fs_dir->names_used++];
    }

    if (tsk_fs_name_copy(fs_name_dest, a_fs_name))
        return 1;

    // add the parent address
    if (a_fs_dir->addr)
        fs_name_dest->par_addr = a_fs_dir->addr;

    return 0;
}
Exemple #8
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 #9
0
/**
 * \ingroup fslib
 * Tries to process data in a disk image at a given offset as a file system. 
 * Returns a structure that can be used for analysis and reporting. 
 *
 * @param a_img_info Disk image to analyze
 * @param a_offset Byte offset to start analyzing from
 * @param a_ftype Type of file system (or autodetect)
 *
 * @return NULL on error 
 */
TSK_FS_INFO *
tsk_fs_open_img(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_offset,
    TSK_FS_TYPE_ENUM a_ftype)
{
    if (a_img_info == NULL) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "tsk_fs_open_img: Null image handle");
        return NULL;
    }

    /* We will try different file systems ... 
     * We need to try all of them in case more than one matches
     */
    if (a_ftype == TSK_FS_TYPE_DETECT) {
        TSK_FS_INFO *fs_info, *fs_set = NULL;
        char *set = NULL;

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "fsopen: Auto detection mode at offset %" PRIuOFF "\n",
                a_offset);

        if ((fs_info =
                ntfs_open(a_img_info, a_offset, TSK_FS_TYPE_NTFS_DETECT,
                    1)) != NULL) {
            set = "NTFS";
            fs_set = fs_info;
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                fatfs_open(a_img_info, a_offset, TSK_FS_TYPE_FAT_DETECT,
                    1)) != NULL) {
            if (set == NULL) {
                set = "FAT";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "FAT or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                ext2fs_open(a_img_info, a_offset, TSK_FS_TYPE_EXT_DETECT,
                    1)) != NULL) {
            if (set == NULL) {
                set = "EXT2/3";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "EXT2/3 or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                ffs_open(a_img_info, a_offset,
                    TSK_FS_TYPE_FFS_DETECT)) != NULL) {
            if (set == NULL) {
                set = "UFS";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "UFS or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }


#if TSK_USE_HFS
        if ((fs_info =
                hfs_open(a_img_info, a_offset, TSK_FS_TYPE_HFS_DETECT,
                    1)) != NULL) {
            if (set == NULL) {
                set = "HFS";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "HFS or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }
#endif

        if ((fs_info =
                iso9660_open(a_img_info, a_offset,
                    TSK_FS_TYPE_ISO9660_DETECT, 1)) != NULL) {
            if (set != NULL) {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "ISO9660 or %s", set);
                return NULL;
            }
            fs_set = fs_info;
        }
        else {
            tsk_error_reset();
        }


        if (fs_set == NULL) {
            tsk_error_reset();
            tsk_errno = TSK_ERR_FS_UNKTYPE;
            tsk_errstr[0] = '\0';
            tsk_errstr2[0] = '\0';
            return NULL;
        }
        return fs_set;
    }
    else {
        if (TSK_FS_TYPE_ISNTFS(a_ftype))
            return ntfs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISFAT(a_ftype))
            return fatfs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISFFS(a_ftype))
            return ffs_open(a_img_info, a_offset, a_ftype);
        else if (TSK_FS_TYPE_ISEXT(a_ftype))
            return ext2fs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISHFS(a_ftype))
            return hfs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISISO9660(a_ftype))
            return iso9660_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISRAW(a_ftype))
            return rawfs_open(a_img_info, a_offset);
        else if (TSK_FS_TYPE_ISSWAP(a_ftype))
            return swapfs_open(a_img_info, a_offset);
        else {
            tsk_error_reset();
            tsk_errno = TSK_ERR_FS_UNSUPTYPE;
            snprintf(tsk_errstr, TSK_ERRSTR_L, "%X", (int) a_ftype);
            return NULL;
        }
    }
}
Exemple #10
0
// XXX([email protected]): had better fix the comment
// find file of the given inode
// 
// \param fs         filesystem info structure defined in sleuthkit
// \param lclflags   traverse options defined in sleuthkit
// \param a_inode    the inode of the file
// \param type       filesystem type number
// \param type_used  don't know what it is, just give a 0(XXX)
// \param id         the id of file attribute that the inode refers
// \param id_used    don't know what it is, just give a 0(XXX)
// \param flags      traverse options difned in sleuthkit
// 
// Return 0 if error, otherwise a pointer
static MBA_FFIND_DATA*
fs_ffind(TSK_FS_INFO * fs, TSK_FS_FFIND_FLAG_ENUM lclflags,
    TSK_INUM_T a_inode,
    TSK_FS_ATTR_TYPE_ENUM type, uint8_t type_used,
    uint16_t id, uint8_t id_used, TSK_FS_DIR_WALK_FLAG_ENUM flags)
{
    MBA_FFIND_DATA* data=(MBA_FFIND_DATA*)malloc(sizeof(MBA_FFIND_DATA));
    char* orphan =NULL;
    int size = 0;

    if(data == NULL)
    {
        printf("Cannot allocate memory\n");
        return NULL;
    }

    data->found = 0;
    data->flags = lclflags;
    data->inode = a_inode;
    utarray_new(data->filenames, &ut_str_icd);


    /* Since we start the walk on the root inode, then this will not show
     ** up in the above functions, so do it now
     */
    if (data->inode == fs->root_inum) {
        if (flags & TSK_FS_DIR_WALK_FLAG_ALLOC) {
            //tsk_printf("/\n");
            data->found = 1;

            if (!(lclflags & TSK_FS_FFIND_ALL))
                return data;
        }
    }

    if (TSK_FS_TYPE_ISNTFS(fs->ftype)) {
        if (ntfs_find_file(fs, data->inode, type, type_used, id, id_used,
                flags, find_file_act, data))
            return NULL;
    }
    else {
        if (tsk_fs_dir_walk(fs, fs->root_inum, flags, find_file_act,
                data))
            return NULL;
    }

    if (data->found == 0) {

        /* With FAT, we can at least give the name of the file and call
         * it orphan
         */
        if (TSK_FS_TYPE_ISFAT(fs->ftype)) {
            TSK_FS_FILE *fs_file =
                tsk_fs_file_open_meta(fs, NULL, data->inode);
            if ((fs_file != NULL) && (fs_file->meta != NULL)
                && (fs_file->meta->name2 != NULL)) {
                //if (fs_file->meta->flags & TSK_FS_META_FLAG_UNALLOC)
                //    tsk_printf("* ");
                //tsk_printf("%s/%s\n", TSK_FS_ORPHAN_STR,
                //    fs_file->meta->name2->name);

                //Added Ophan file into file list
                size = strlen(TSK_FS_ORPHAN_STR) + strlen(fs_file->meta->name2->name)+2;
                orphan = (char*)malloc(size);
                if(orphan == NULL)
                {
                    printf("Cannot allocate memory\n");
                }else
                {
                    snprintf(orphan, size, "%s/%s", TSK_FS_ORPHAN_STR,fs_file->meta->name2->name);
                    utarray_push_back(data->filenames, orphan );
                }
            }
            if (fs_file)
                tsk_fs_file_close(fs_file);
        }
        else {
            tsk_printf("File name not found for inode\n");
        }
    }
    return data;
}
Exemple #11
0
/**
 * \internal
 * Print contents of  fs_name entry format like ls -l
**
** All elements are tab delimited 
**
** If path is NULL, then skip else use. it has the full directory name
**  It needs to end with "/"
*/
void
tsk_fs_name_print_long(FILE * hFile, const TSK_FS_FILE * fs_file,
    const char *a_path, TSK_FS_INFO * fs, const TSK_FS_ATTR * fs_attr,
    uint8_t print_path, int32_t sec_skew)
{
    tsk_fs_name_print(hFile, fs_file, a_path, fs, fs_attr, print_path);

    if ((fs == NULL) || (fs_file->meta == NULL)) {

        tsk_fprintf(hFile, "\t");
        tsk_fs_print_time(hFile, 0);    // mtime
        tsk_fprintf(hFile, "\t");
        tsk_fs_print_time(hFile, 0);    // atime
        tsk_fprintf(hFile, "\t");
        tsk_fs_print_time(hFile, 0);    // ctime
        tsk_fprintf(hFile, "\t");
        tsk_fs_print_time(hFile, 0);    // crtime

        // size, uid, gid
        tsk_fprintf(hFile, "\t0\t0\t0\n");
    }
    else {

        /* MAC times */
        tsk_fprintf(hFile, "\t");
        if (fs_file->meta->mtime)
            tsk_fs_print_time(hFile, fs_file->meta->mtime - sec_skew);
        else
            tsk_fs_print_time(hFile, fs_file->meta->mtime);

        tsk_fprintf(hFile, "\t");
        /* FAT only gives the day of last access */
        if ((TSK_FS_TYPE_ISFAT(fs->ftype)) || (fs_file->meta->atime == 0))
            tsk_fs_print_day(hFile, fs_file->meta->atime);
        else
            tsk_fs_print_time(hFile, fs_file->meta->atime - sec_skew);

        tsk_fprintf(hFile, "\t");
        if (fs_file->meta->ctime)
            tsk_fs_print_time(hFile, fs_file->meta->ctime - sec_skew);
        else
            tsk_fs_print_time(hFile, fs_file->meta->ctime);

        tsk_fprintf(hFile, "\t");
        if (fs_file->meta->crtime)
            tsk_fs_print_time(hFile, fs_file->meta->crtime - sec_skew);
        else
            tsk_fs_print_time(hFile, fs_file->meta->crtime);

        /* use the stream size if one was given */
        if (fs_attr)
            tsk_fprintf(hFile, "\t%" PRIuOFF, fs_attr->size);
        else
            tsk_fprintf(hFile, "\t%" PRIuOFF, fs_file->meta->size);

        tsk_fprintf(hFile, "\t%" PRIuGID "\t%" PRIuUID "\n",
            fs_file->meta->gid, fs_file->meta->uid);
    }

    return;
}
/**
 * \ingroup fslib
 * 
 * Find the meta data address for a given file name (UTF-8).
 * The basic idea of the function is to break the given name into its
 * subdirectories and start looking for each (starting in the root
 * directory). 
 *
 * @param a_fs FS to analyze
 * @param a_path UTF-8 path of file to search for
 * @param [out] a_result Meta data address of file
 * @param [out] a_fs_name Copy of name details (or NULL if details not wanted)
 * @returns -1 on (system) error, 0 if found, and 1 if not found
 */
int8_t
tsk_fs_path2inum(TSK_FS_INFO * a_fs, const char *a_path,
    TSK_INUM_T * a_result, TSK_FS_NAME * a_fs_name)
{
    char *cpath;
    size_t clen;
    char *cur_dir;              // The "current" directory or file we are looking for
    char *cur_attr;             // The "current" attribute of the dir we are looking for
    TSK_INUM_T next_meta;
    uint8_t is_done;
    char *strtok_last; 
    *a_result = 0;

    // copy path to a buffer that we can modify
    clen = strlen(a_path) + 1;
    if ((cpath = (char *) tsk_malloc(clen)) == NULL) {
        return -1;
    }
    strncpy(cpath, a_path, clen);

    // Get the first part of the directory path. 
    cur_dir = (char *) strtok_r(cpath, "/", &strtok_last);
    cur_attr = NULL;

    /* If there is no token, then only a '/' was given */
    if (cur_dir == NULL) {
        free(cpath);
        *a_result = a_fs->root_inum;

        // create the dummy entry if needed
        if (a_fs_name) {
            a_fs_name->meta_addr = a_fs->root_inum;
            // Note that we are not filling in meta_seq -- we could, we just aren't

            a_fs_name->type = TSK_FS_NAME_TYPE_DIR;
            a_fs_name->flags = TSK_FS_NAME_FLAG_ALLOC;
            if (a_fs_name->name)
                a_fs_name->name[0] = '\0';
            if (a_fs_name->shrt_name)
                a_fs_name->shrt_name[0] = '\0';
        }
        return 0;
    }

    /* If this is NTFS, seperate out the attribute of the current directory */
    if (TSK_FS_TYPE_ISNTFS(a_fs->ftype)
        && ((cur_attr = strchr(cur_dir, ':')) != NULL)) {
        *(cur_attr) = '\0';
        cur_attr++;
    }

    if (tsk_verbose)
        tsk_fprintf(stderr, "Looking for %s\n", cur_dir);

    // initialize the first place to look, the root dir
    next_meta = a_fs->root_inum;

    // we loop until we know the outcome and then exit. 
    // everything should return from inside the loop.
    is_done = 0;
    while (is_done == 0) {
        size_t i;
        TSK_FS_FILE *fs_file_alloc = NULL;      // set to the allocated file that is our target
        TSK_FS_FILE *fs_file_del = NULL;        // set to an unallocated file that matches our criteria

        TSK_FS_DIR *fs_dir = NULL;

        // open the next directory in the recursion
        if ((fs_dir = tsk_fs_dir_open_meta(a_fs, next_meta)) == NULL) {
            free(cpath);
            return -1;
        }

        /* Verify this is indeed a directory.  We had one reported
         * problem where a file was a disk image and opening it as
         * a directory found the directory entries inside of the file
         * and this caused problems... */
        if (fs_dir->fs_file->meta->type != TSK_FS_META_TYPE_DIR) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_FS_GENFS);
            tsk_error_set_errstr("Address %" PRIuINUM
                " is not for a directory\n", next_meta);
            free(cpath);
            return -1;
        }

        // cycle through each entry
        for (i = 0; i < tsk_fs_dir_getsize(fs_dir); i++) {

            TSK_FS_FILE *fs_file;
            uint8_t found_name = 0;

            if ((fs_file = tsk_fs_dir_get(fs_dir, i)) == NULL) {
                tsk_fs_dir_close(fs_dir);
                free(cpath);
                return -1;
            }

            /* 
             * Check if this is the name that we are currently looking for,
             * as identified in 'cur_dir'
             */
            /* FAT is a special case because we check the short name */
            if (TSK_FS_TYPE_ISFAT(a_fs->ftype)) {
                if ((fs_file->name->name)
                    && (a_fs->name_cmp(a_fs, fs_file->name->name,
                            cur_dir) == 0)) {
                    found_name = 1;
                }
                else if ((fs_file->name->shrt_name)
                    && (a_fs->name_cmp(a_fs, fs_file->name->shrt_name,
                            cur_dir) == 0)) {
                    found_name = 1;
                }
            }

            /* NTFS gets a case insensitive comparison */
            else if (TSK_FS_TYPE_ISNTFS(a_fs->ftype)) {
                if ((fs_file->name->name)
                    && (a_fs->name_cmp(a_fs, fs_file->name->name,
                            cur_dir) == 0)) {
                    /*  ensure we have the right attribute name */
                    if (cur_attr == NULL) {
                        found_name = 1;
                    }
                    else {
                        if (fs_file->meta) {
                            int cnt, i;

                            // cycle through the attributes
                            cnt = tsk_fs_file_attr_getsize(fs_file);
                            for (i = 0; i < cnt; i++) {
                                const TSK_FS_ATTR *fs_attr =
                                    tsk_fs_file_attr_get_idx(fs_file, i);
                                if (!fs_attr)
                                    continue;

                                if ((fs_attr->name)
                                    && (a_fs->name_cmp(a_fs, fs_attr->name,
                                            cur_attr) == 0)) {
                                    found_name = 1;
                                }
                            }
                        }
                    }
                }
            }
            else {
                if ((fs_file->name->name)
                    && (a_fs->name_cmp(a_fs, fs_file->name->name,
                            cur_dir) == 0)) {
                    found_name = 1;
                }
            }

            if (found_name) {
                /* If we found our file and it is allocated, then stop. If
                 * it is unallocated, keep on going to see if we can get
                 * an allocated hit */
                if (fs_file->name->flags & TSK_FS_NAME_FLAG_ALLOC) {
                    fs_file_alloc = fs_file;
                    break;
                }
                else {
                    // if we already have an unalloc and its addr is 0, then use the new one
                    if ((fs_file_del)
                        && (fs_file_del->name->meta_addr == 0)) {
                        tsk_fs_file_close(fs_file_del);
                    }
                    fs_file_del = fs_file;
                }
            }
            // close the file if we did not save it for future analysis.
            else {
                tsk_fs_file_close(fs_file);
                fs_file = NULL;
            }
        }

        // we found a directory, go into it 
        if ((fs_file_alloc) || (fs_file_del)) {

            const char *pname;
            TSK_FS_FILE *fs_file_tmp;

            // choose the alloc one first (if they both exist)
            if (fs_file_alloc)
                fs_file_tmp = fs_file_alloc;
            else
                fs_file_tmp = fs_file_del;

            pname = cur_dir;    // save a copy of the current name pointer

            // advance to the next name
            cur_dir = (char *) strtok_r(NULL, "/", &(strtok_last));
            cur_attr = NULL;

            if (tsk_verbose)
                tsk_fprintf(stderr,
                    "Found it (%s), now looking for %s\n", pname, cur_dir);

            /* That was the last name in the path -- we found the file! */
            if (cur_dir == NULL) {
                *a_result = fs_file_tmp->name->meta_addr;

                // make a copy if one was requested
                if (a_fs_name) {
                    tsk_fs_name_copy(a_fs_name, fs_file_tmp->name);
                }

                tsk_fs_dir_close(fs_dir);
                free(cpath);
                return 0;
            }

            // update the attribute field, if needed
            if (TSK_FS_TYPE_ISNTFS(a_fs->ftype)
                && ((cur_attr = strchr(cur_dir, ':')) != NULL)) {
                *(cur_attr) = '\0';
                cur_attr++;
            }

            // update the value for the next directory to open
            next_meta = fs_file_tmp->name->meta_addr;

            if (fs_file_alloc) {
                tsk_fs_file_close(fs_file_alloc);
                fs_file_alloc = NULL;
            }
            if (fs_file_del) {
                tsk_fs_file_close(fs_file_del);
                fs_file_del = NULL;
            }
        }

        // no hit in directory
        else {
            is_done = 1;
        }

        tsk_fs_dir_close(fs_dir);
        fs_dir = NULL;
    }

    free(cpath);
    return 1;
}
Exemple #13
0
/**
 * \ingroup fslib
 * Tries to process data in a disk image at a given offset as a file system.
 * Returns a structure that can be used for analysis and reporting.
 *
 * @param a_img_info Disk image to analyze
 * @param a_offset Byte offset to start analyzing from
 * @param a_ftype Type of file system (or autodetect)
 *
 * @return NULL on error
 */
TSK_FS_INFO *
tsk_fs_open_img(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_offset,
    TSK_FS_TYPE_ENUM a_ftype)
{
    TSK_FS_INFO *fs_info;

    const struct {
        char* name;
        TSK_FS_INFO* (*open)(TSK_IMG_INFO*, TSK_OFF_T,
                                 TSK_FS_TYPE_ENUM, uint8_t);
        TSK_FS_TYPE_ENUM type;
    } FS_OPENERS[] = {
        { "NTFS",     ntfs_open,    TSK_FS_TYPE_NTFS_DETECT    },
        { "FAT",      fatfs_open,   TSK_FS_TYPE_FAT_DETECT     },
        { "EXT2/3/4", ext2fs_open,  TSK_FS_TYPE_EXT_DETECT     },
        { "UFS",      ffs_open,     TSK_FS_TYPE_FFS_DETECT     },
        { "YAFFS2",   yaffs2_open,  TSK_FS_TYPE_YAFFS2_DETECT  },
#if TSK_USE_HFS
        { "HFS",      hfs_open,     TSK_FS_TYPE_HFS_DETECT     },
#endif
        { "ISO9660",  iso9660_open, TSK_FS_TYPE_ISO9660_DETECT }
    };

    if (a_img_info == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr("tsk_fs_open_img: Null image handle");
        return NULL;
    }

    /* We will try different file systems ...
     * We need to try all of them in case more than one matches
     */
    if (a_ftype == TSK_FS_TYPE_DETECT) {
        unsigned long i;
        const char *name_first = "";
        TSK_FS_INFO *fs_first = NULL;

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "fsopen: Auto detection mode at offset %" PRIuOFF "\n",
                a_offset);

        for (i = 0; i < sizeof(FS_OPENERS)/sizeof(FS_OPENERS[0]); ++i) {
            if ((fs_info = FS_OPENERS[i].open(
                    a_img_info, a_offset, FS_OPENERS[i].type, 1)) != NULL) {
                // fs opens as type i
                if (fs_first == NULL) {
                    // first success opening fs
                    name_first = FS_OPENERS[i].name;
                    fs_first = fs_info;
                }
                else {
                    // second success opening fs, which means we
                    // cannot autodetect the fs type and must give up
                    fs_first->close(fs_first);
                    fs_info->close(fs_info);
                    tsk_error_reset();
                    tsk_error_set_errno(TSK_ERR_FS_UNKTYPE);
                    tsk_error_set_errstr(
                        "%s or %s", FS_OPENERS[i].name, name_first);
                    return NULL;
                }
            }
            else {
                // fs does not open as type i
                tsk_error_reset();
            }
        }

        if (fs_first == NULL) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_FS_UNKTYPE);
        }

        return fs_first;
    }
    else if (TSK_FS_TYPE_ISNTFS(a_ftype)) {
        return ntfs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISFAT(a_ftype)) {
        return fatfs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISFFS(a_ftype)) {
        return ffs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISEXT(a_ftype)) {
        return ext2fs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISHFS(a_ftype)) {
        return hfs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISISO9660(a_ftype)) {
        return iso9660_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISRAW(a_ftype)) {
        return rawfs_open(a_img_info, a_offset);
    }
    else if (TSK_FS_TYPE_ISSWAP(a_ftype)) {
        return swapfs_open(a_img_info, a_offset);
    }
    else if (TSK_FS_TYPE_ISYAFFS2(a_ftype)) {
        return yaffs2_open(a_img_info, a_offset, a_ftype, 0);
    }
    tsk_error_reset();
    tsk_error_set_errno(TSK_ERR_FS_UNSUPTYPE);
    tsk_error_set_errstr("%X", (int) a_ftype);
    return NULL;
}