コード例 #1
0
ファイル: fs_dir.c プロジェクト: bkerler/sleuthkit
/** \internal
 * Create a dummy META entry for the Orphan file virtual directory.
 * @param a_fs File system directory is for
 * @param a_fs_meta META structure to populate with data
* @returns 1 on error
*/
uint8_t
tsk_fs_dir_make_orphan_dir_meta(TSK_FS_INFO * a_fs,
    TSK_FS_META * a_fs_meta)
{
    a_fs_meta->type = TSK_FS_META_TYPE_DIR;
    a_fs_meta->mode = 0;
    a_fs_meta->nlink = 1;

    a_fs_meta->flags = (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_ALLOC);
    a_fs_meta->uid = a_fs_meta->gid = 0;
    a_fs_meta->mtime = a_fs_meta->atime = a_fs_meta->ctime =
        a_fs_meta->crtime = 0;
    a_fs_meta->mtime_nano = a_fs_meta->atime_nano = a_fs_meta->ctime_nano =
        a_fs_meta->crtime_nano = 0;

    if (a_fs_meta->name2 == NULL) {
        if ((a_fs_meta->name2 = (TSK_FS_META_NAME_LIST *)
                tsk_malloc(sizeof(TSK_FS_META_NAME_LIST))) == NULL)
            return 1;
        a_fs_meta->name2->next = NULL;
    }

    a_fs_meta->attr_state = TSK_FS_META_ATTR_EMPTY;
    if (a_fs_meta->attr) {
        tsk_fs_attrlist_markunused(a_fs_meta->attr);
    }

    a_fs_meta->addr = TSK_FS_ORPHANDIR_INUM(a_fs);
    strncpy(a_fs_meta->name2->name, "$OrphanFiles",
        TSK_FS_META_NAME_LIST_NSIZE);
    if (a_fs_meta->content_len) {
        TSK_DADDR_T *addr_ptr = (TSK_DADDR_T *) a_fs_meta->content_ptr;
        addr_ptr[0] = 0;
    }
    a_fs_meta->size = 0;
    return 0;
}
コード例 #2
0
ファイル: unix_misc.c プロジェクト: eugene7646/sleuthkit
/** \internal
 *
 * @returns 1 on error and 0 on success
 */
uint8_t
tsk_fs_unix_make_data_run(TSK_FS_FILE * fs_file)
{
    TSK_OFF_T length = 0;
    TSK_OFF_T read_b = 0;
    TSK_FS_ATTR *fs_attr;
    TSK_FS_ATTR *fs_attr_indir;
    TSK_FS_META *fs_meta = fs_file->meta;
    TSK_FS_INFO *fs = fs_file->fs_info;

    // clean up any error messages that are lying around
    tsk_error_reset();

    if (tsk_verbose)
        tsk_fprintf(stderr,
            "unix_make_data_run: Processing file %" PRIuINUM "\n",
            fs_meta->addr);

    // see if we have already loaded the runs
    if ((fs_meta->attr != NULL)
        && (fs_meta->attr_state == TSK_FS_META_ATTR_STUDIED)) {
        return 0;
    }
    else if (fs_meta->attr_state == TSK_FS_META_ATTR_ERROR) {
        return 1;
    }
    // not sure why this would ever happen, but...
    else if (fs_meta->attr != NULL) {
        tsk_fs_attrlist_markunused(fs_meta->attr);
    }
    else if (fs_meta->attr == NULL) {
        fs_meta->attr = tsk_fs_attrlist_alloc();
    }

    if ((TSK_FS_TYPE_ISFFS(fs->ftype) == 0)
        && (TSK_FS_TYPE_ISEXT(fs->ftype) == 0)) {
        tsk_error_set_errno(TSK_ERR_FS_INODE_COR);
        tsk_error_set_errstr
            ("unix_make_run: Called with non-Unix file system: %x",
            fs->ftype);
        return 1;
    }

    length = roundup(fs_meta->size, fs->block_size);

    if ((fs_attr =
            tsk_fs_attrlist_getnew(fs_meta->attr,
                TSK_FS_ATTR_NONRES)) == NULL) {
        return 1;
    }

    // initialize the data run
    if (tsk_fs_attr_set_run(fs_file, fs_attr, NULL, NULL,
            TSK_FS_ATTR_TYPE_DEFAULT, TSK_FS_ATTR_ID_DEFAULT,
            fs_meta->size, fs_meta->size, roundup(fs_meta->size,
                fs->block_size), 0, 0)) {
        return 1;
    }

    read_b =
        unix_make_data_run_direct(fs, fs_attr,
        (TSK_DADDR_T *) fs_meta->content_ptr, 12, length);
    if (read_b == -1) {
        fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;
        if (fs_meta->flags & TSK_FS_META_FLAG_UNALLOC)
            tsk_error_set_errno(TSK_ERR_FS_RECOVER);
        return 1;
    }
    length -= read_b;

    /* if there is still data left, read the indirect */
    if (length > 0) {
        int level;
        char *buf[4] = {NULL};
        size_t fs_bufsize0;
        size_t fs_bufsize1;
        size_t ptrsperblock;
        int numBlocks = 0;
        int numSingIndirect = 0;
        int numDblIndirect = 0;
        int numTripIndirect = 0;


        /* With FFS/UFS a full block contains the addresses, but block_size is
         * only a fragment.  Figure out the scratch buffer size and the buffers to 
         * store the cleaned addresses (endian converted) */
        if (TSK_FS_TYPE_ISFFS(fs->ftype)) {
            FFS_INFO *ffs = (FFS_INFO *) fs;

            fs_bufsize0 = ffs->ffsbsize_b;
            if ((fs->ftype == TSK_FS_TYPE_FFS1)
                || (fs->ftype == TSK_FS_TYPE_FFS1B)) {
                ptrsperblock = fs_bufsize0 / 4;
            }
            else {
                ptrsperblock = fs_bufsize0 / 8;
            }
        }
        else {
            fs_bufsize0 = fs->block_size;
            ptrsperblock = fs_bufsize0 / 4;
        }
        fs_bufsize1 = sizeof(TSK_DADDR_T) * ptrsperblock;

        /*
         * Initialize a buffer for the 3 levels of indirection that are supported by
         * this inode.  Each level of indirection will have a buffer to store
         * addresses in.  buf[0] is a special scratch buffer that is used to store
         * raw data from the image (before endian conversions are applied).  It is
         * equal to one block size.  The others will store TSK_DADDR_T structures
         * and will have a size depending on the FS type. 
         */
        if ((fs_attr_indir =
                tsk_fs_attrlist_getnew(fs_meta->attr,
                    TSK_FS_ATTR_NONRES)) == NULL) {
            return 1;
        }

        // determine number of indirect lbocks needed for file size...
        numBlocks =
            (int) (((fs_meta->size + fs_bufsize0 - 1) / fs_bufsize0) - 12);
        numSingIndirect =
            (int) ((numBlocks + ptrsperblock - 1) / ptrsperblock);
        numDblIndirect = 0;
        numTripIndirect = 0;

        // double block pointer?
        if (numSingIndirect > 1) {
            numDblIndirect = (int)
                ((numSingIndirect - 1 + ptrsperblock - 1) / ptrsperblock);
            if (numDblIndirect > 1) {
                numTripIndirect = (int)
                    ((numDblIndirect - 1 + ptrsperblock -
                        1) / ptrsperblock);
            }
        }

        // initialize the data run
        if (tsk_fs_attr_set_run(fs_file, fs_attr_indir, NULL, NULL,
                TSK_FS_ATTR_TYPE_UNIX_INDIR, TSK_FS_ATTR_ID_DEFAULT,
                fs_bufsize0 * (numSingIndirect + numDblIndirect +
                    numTripIndirect),
                fs_bufsize0 * (numSingIndirect + numDblIndirect +
                    numTripIndirect),
                fs_bufsize0 * (numSingIndirect + numDblIndirect +
                    numTripIndirect), 0, 0)) {
            return 1;
        }

        if ((buf[0] = (char *) tsk_malloc(fs_bufsize0)) == NULL) {
            return 1;
        }

        for (level = 1; length > 0 && level < 4; level++) {
            TSK_DADDR_T *addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr;

            if ((buf[level] = (char *) tsk_malloc(fs_bufsize1)) == NULL) {
                int f;
                for (f = 0; f < level; f++) {
                    free(buf[f]);
                }
                return 1;
            }

            /* the indirect addresses are stored in addr_ptr after the 12
             * direct addresses */
            read_b =
                unix_make_data_run_indirect(fs, fs_attr, fs_attr_indir,
                buf, level, addr_ptr[12 + level - 1], length);
            if (read_b == -1)
                break;
            length -= read_b;
        }

        /*
         * Cleanup.
         */
        for (level = 0; level < 4; ++level) {
            if (buf[level]) {
                free(buf[level]);
            }
        }
    }

    if (read_b == -1) {
        fs_meta->attr_state = TSK_FS_META_ATTR_ERROR;
        if (fs_meta->flags & TSK_FS_META_FLAG_UNALLOC)
            tsk_error_set_errno(TSK_ERR_FS_RECOVER);
        return 1;
    }

    fs_meta->attr_state = TSK_FS_META_ATTR_STUDIED;

    return 0;
}