⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntfs_dent.c

📁 linux下开发的针对所有磁盘的数据恢复的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
            tsk_getu16(fs->endian, (uintptr_t) idxrec + offset);        if (cur_seq != orig_seq) {            /* get the replacement value */            uint16_t cur_repl =                tsk_getu16(fs->endian, &upd->upd_seq + (i - 1) * 2);            tsk_error_reset();            tsk_errno = TSK_ERR_FS_INODE_COR;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "fix_idxrec: Incorrect update sequence value in index buffer\nUpdate Value: 0x%"                PRIx16 " Actual Value: 0x%" PRIx16                " Replacement Value: 0x%" PRIx16                "\nThis is typically because of a corrupted entry",                orig_seq, cur_seq, cur_repl);            return 1;        }        new_val = &upd->upd_seq + (i - 1) * 2;        old_val = (uint8_t *) ((uintptr_t) idxrec + offset);        if (tsk_verbose)            tsk_fprintf(stderr,                "ntfs_fix_idxrec: upd_seq %i   Replacing: %.4" PRIx16                "   With: %.4" PRIx16 "\n", i, tsk_getu16(fs->endian,                    old_val), tsk_getu16(fs->endian, new_val));        *old_val++ = *new_val++;        *old_val = *new_val;    }    return 0;}/** \internal* Process a directory and load up FS_DIR with the entries. If a pointer to* an already allocated FS_DIR struture is given, it will be cleared.  If no existing* FS_DIR structure is passed (i.e. NULL), then a new one will be created. If the return * value is error or corruption, then the FS_DIR structure could  * have entries (depending on when the error occured). ** @param a_fs File system to analyze* @param a_fs_dir Pointer to FS_DIR pointer. Can contain an already allocated* structure or a new structure. * @param a_addr Address of directory to process.* @returns error, corruption, ok etc. */TSK_RETVAL_ENUMntfs_dir_open_meta(TSK_FS_INFO * a_fs, TSK_FS_DIR ** a_fs_dir,    TSK_INUM_T a_addr){    NTFS_INFO *ntfs = (NTFS_INFO *) a_fs;    TSK_FS_DIR *fs_dir;    const TSK_FS_ATTR *fs_attr_root = NULL;    const TSK_FS_ATTR *fs_attr_idx;    char *idxalloc;    ntfs_idxentry *idxe;    ntfs_idxroot *idxroot;    ntfs_idxelist *idxelist;    ntfs_idxrec *idxrec_p, *idxrec;    int off;    TSK_OFF_T idxalloc_len;    TSK_FS_LOAD_FILE load_file;    NTFS_PAR_DATA data;    /* In this function, we will return immediately if we get an error.     * If we get corruption though, we will record that in 'retval_final'     * and continue processing.      */    TSK_RETVAL_ENUM retval_final = TSK_OK;    TSK_RETVAL_ENUM retval_tmp;    /* sanity check */    if (a_addr < a_fs->first_inum || a_addr > a_fs->last_inum) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_WALK_RNG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "ntfs_dir_open_meta: inode value: %" PRIuINUM "\n", a_addr);        return TSK_ERR;    }    else if (a_fs_dir == NULL) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_ARG;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "ntfs_dir_open_meta: NULL fs_attr argument given");        return TSK_ERR;    }    if (tsk_verbose)        tsk_fprintf(stderr,            "ntfs_open_dir: Processing directory %" PRIuINUM "\n", a_addr);    fs_dir = *a_fs_dir;    if (fs_dir) {        tsk_fs_dir_reset(fs_dir);    }    else {        if ((*a_fs_dir = fs_dir = tsk_fs_dir_alloc(a_fs, 128)) == NULL) {            return TSK_ERR;        }    }    //  handle the orphan directory if its contents were requested    if (a_addr == TSK_FS_ORPHANDIR_INUM(a_fs)) {        return tsk_fs_dir_find_orphans(a_fs, fs_dir);    }    /* Get the inode and verify it has attributes */    if ((fs_dir->fs_file =            tsk_fs_file_open_meta(a_fs, NULL, a_addr)) == NULL) {        strncat(tsk_errstr2, " - ntfs_dir_open_meta",            TSK_ERRSTR_L - strlen(tsk_errstr2));        tsk_fs_dir_close(fs_dir);        return TSK_COR;    }    if (!(fs_dir->fs_file->meta->attr)) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_INODE_COR;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "dent_walk: Error: Directory address %" PRIuINUM            " has no attributes", a_addr);        return TSK_COR;    }    /*      * Read the Index Root Attribute  -- we do some sanity checking here     * to report errors before we start to make up data for the "." and ".."     * entries     */    fs_attr_root =        tsk_fs_attrlist_get(fs_dir->fs_file->meta->attr,        NTFS_ATYPE_IDXROOT);    if (!fs_attr_root) {        strncat(tsk_errstr2, " - dent_walk: $IDX_ROOT not found",            TSK_ERRSTR_L - strlen(tsk_errstr2));        return TSK_COR;    }    if (fs_attr_root->flags & TSK_FS_ATTR_NONRES) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_INODE_COR;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "dent_walk: $IDX_ROOT is not resident - it should be");        return TSK_COR;    }    idxroot = (ntfs_idxroot *) fs_attr_root->rd.buf;    /* Verify that the attribute type is $FILE_NAME */    if (tsk_getu32(a_fs->endian, idxroot->type) == 0) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_INODE_COR;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "dent_walk: Attribute type in index root is 0");        return TSK_COR;    }    else if (tsk_getu32(a_fs->endian, idxroot->type) != NTFS_ATYPE_FNAME) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_INODE_COR;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "ERROR: Directory index is sorted by type: %" PRIu32            ".\nOnly $FNAME is currently supported",            tsk_getu32(a_fs->endian, idxroot->type));        return TSK_COR;    }    /* Get the header of the index entry list */    idxelist = &idxroot->list;    /* Get the offset to the start of the index entry list */    idxe = (ntfs_idxentry *) ((uintptr_t) idxelist +        tsk_getu32(a_fs->endian, idxelist->begin_off));    /*      * NTFS does not have "." and ".." entries in the index trees     * (except for a "." entry in the root directory)     *      * So, we'll make 'em up by making a TSK_FS_NAME structure for     * a '.' and '..' entry and call the action     */    if (a_addr != a_fs->root_inum) {    // && (flags & TSK_FS_NAME_FLAG_ALLOC)) {        TSK_FS_NAME *fs_name;        TSK_FS_META_NAME_LIST *fs_name_list;        if (tsk_verbose)            tsk_fprintf(stderr,                "ntfs_dir_open_meta: Creating . and .. entries\n");        if ((fs_name = tsk_fs_name_alloc(16, 0)) == NULL) {            return TSK_ERR;        }        /*          * "."          */        fs_name->meta_addr = a_addr;        fs_name->meta_seq = fs_dir->fs_file->meta->seq;        fs_name->type = TSK_FS_NAME_TYPE_DIR;        strcpy(fs_name->name, ".");        fs_name->flags = TSK_FS_NAME_FLAG_ALLOC;        if (tsk_fs_dir_add(fs_dir, fs_name)) {            tsk_fs_name_free(fs_name);            return TSK_ERR;        }        /*         * ".."         */        strcpy(fs_name->name, "..");        fs_name->type = TSK_FS_NAME_TYPE_DIR;        /* The fs_name structure holds the parent inode value, so we          * just cycle using those         */        for (fs_name_list = fs_dir->fs_file->meta->name2;            fs_name_list != NULL; fs_name_list = fs_name_list->next) {            fs_name->meta_addr = fs_name_list->par_inode;            fs_name->meta_seq = fs_name_list->par_seq;            if (tsk_fs_dir_add(fs_dir, fs_name)) {                tsk_fs_name_free(fs_name);                return TSK_ERR;            }        }        tsk_fs_name_free(fs_name);        fs_name = NULL;    }    /* Now we return to processing the Index Root Attribute */    if (tsk_verbose)        tsk_fprintf(stderr,            "ntfs_dir_open_meta: Processing $IDX_ROOT of inum %" PRIuINUM            "\n", a_addr);    /* Verify the offset pointers */    if ((tsk_getu32(a_fs->endian, idxelist->seqend_off) <            tsk_getu32(a_fs->endian, idxelist->begin_off)) ||        (tsk_getu32(a_fs->endian, idxelist->bufend_off) <            tsk_getu32(a_fs->endian, idxelist->seqend_off)) ||        (((uintptr_t) idxe + tsk_getu32(a_fs->endian,                    idxelist->bufend_off)) >            ((uintptr_t) fs_attr_root->rd.buf +                fs_attr_root->rd.buf_size))) {        tsk_error_reset();        tsk_errno = TSK_ERR_FS_INODE_COR;        snprintf(tsk_errstr, TSK_ERRSTR_L,            "Error: Index list offsets are invalid on entry: %" PRIuINUM,            fs_dir->fs_file->meta->addr);        return TSK_COR;    }    retval_tmp = ntfs_proc_idxentry(ntfs, fs_dir,        (fs_dir->fs_file->meta->flags & TSK_FS_META_FLAG_UNALLOC) ? 1 : 0,        idxe,        tsk_getu32(a_fs->endian, idxelist->bufend_off) -        tsk_getu32(a_fs->endian, idxelist->begin_off),        tsk_getu32(a_fs->endian, idxelist->seqend_off) -        tsk_getu32(a_fs->endian, idxelist->begin_off));    // stop if we get an error, continue if we got corruption    if (retval_tmp == TSK_ERR) {        return TSK_ERR;    }    else if (retval_tmp == TSK_COR) {        retval_final = TSK_COR;    }    /*      * get the index allocation attribute if it exists (it doesn't for      * small directories      */    fs_attr_idx =        tsk_fs_attrlist_get(fs_dir->fs_file->meta->attr,        NTFS_ATYPE_IDXALLOC);    /* if we don't have an index alloc then return, we have processed     * all of the entries      */    if (!fs_attr_idx) {        if (tsk_getu32(a_fs->endian,                idxelist->flags) & NTFS_IDXELIST_CHILD) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_INODE_COR;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "Error: $IDX_ROOT says there should be children, but there isn't");            return TSK_COR;        }    }    else {        if (fs_attr_idx->flags & TSK_FS_ATTR_RES) {            tsk_error_reset();            tsk_errno = TSK_ERR_FS_INODE_COR;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "$IDX_ALLOC is Resident - it shouldn't be");            return TSK_COR;        }        /*          * Copy the index allocation run into a big buffer         */        idxalloc_len = fs_attr_idx->nrd.allocsize;        if ((idxalloc = tsk_malloc((size_t) idxalloc_len)) == NULL) {            return TSK_ERR;        }        /* Fill in the loading data structure */        load_file.total = load_file.left = (size_t) idxalloc_len;        load_file.cur = load_file.base = idxalloc;        if (tsk_verbose)            tsk_fprintf(stderr,                "ntfs_dir_open_meta: Copying $IDX_ALLOC into buffer\n");        if (tsk_fs_attr_walk(fs_attr_idx,                TSK_FS_FILE_WALK_FLAG_SLACK, tsk_fs_load_file_action,                (void *) &load_file)) {            free(idxalloc);            strncat(tsk_errstr2, " - ntfs_dir_open_meta",                TSK_ERRSTR_L - strlen(tsk_errstr2));            return TSK_COR;     // this could be an error though        }        /* Not all of the directory was copied, so we exit */        if (load_file.left > 0) {            free(idxalloc);            tsk_error_reset();            tsk_errno = TSK_ERR_FS_FWALK;            snprintf(tsk_errstr, TSK_ERRSTR_L,                "Error reading directory contents: %" PRIuINUM "\n",                a_addr);            return TSK_COR;        }        /*         * The idxalloc is a big buffer that contains one or more         * idx buffer structures.  Each idxrec is a node in the B-Tree.           * We do not process the tree as a tree because then we could         * not find the deleted file names.         *         * Therefore, we scan the big buffer looking for the index record         * structures.  We save a pointer to the known beginning (idxrec_p).         * Then we scan for the beginning of the next one (idxrec) and process         * everything in the middle as an ntfs_idxrec.  We can't use the         * size given because then we wouldn't see the deleted names         */        /* Set the previous pointer to NULL */        idxrec_p = idxrec = NULL;        /* Loop by cluster size */        for (off = 0; off < idxalloc_len; off += ntfs->csize_b) {            uint32_t list_len, rec_len;            idxrec = (ntfs_idxrec *) & idxalloc[off];            if (tsk_verbose)                tsk_fprintf(stderr,                    "ntfs_dir_open_meta: Index Buffer Offset: %d  Magic: %"                    PRIx32 "\n", off, tsk_getu32(a_fs->endian,                        idxrec->magic));            /* Is this the begining of an index record? */            if (tsk_getu32(a_fs->endian,                    idxrec->magic) != NTFS_IDXREC_MAGIC)                continue;            /* idxrec_p is only NULL for the first time              * Set it and start again to find the next one */            if (idxrec_p == NULL) {                idxrec_p = idxrec;                continue;            }            /* Process the previous structure */            /* idxrec points to the next idxrec structure, idxrec_p             * points to the one we are going to process             */            rec_len =                (uint32_t) ((uintptr_t) idxrec - (uintptr_t) idxrec_p);            if (tsk_verbose)                tsk_fprintf(stderr,                    "ntfs_dir_open_meta: Processing previous index record (len: %"                    PRIu32 ")\n", rec_len);            /* remove the update sequence in the index record */            if (ntfs_fix_idxrec(ntfs, idxrec_p, rec_len)) {                free(idxalloc);                return TSK_COR;            }            /* Locate the start of the index entry list */            idxelist = &idxrec_p->list;            idxe = (ntfs_idxentry *) ((uintptr_t) idxelist +                tsk_getu32(a_fs->endian, idxelist->begin_off));            /* the length from the start of the next record to where our             * list starts.             * This should be the same as bufend_off in idxelist, but we don't             * trust it.             */            list_len = (uint32_t) ((uintptr_t) idxrec - (uintptr_t) idxe);            /* Verify the offset pointers */            if (((uintptr_t) idxe > (uintptr_t) idxrec) ||                ((uintptr_t) idxelist +                    tsk_getu32(a_fs->endian,                        idxelist->seqend_off) > (uintptr_t) idxrec)) {                tsk_error_reset();                tsk_errno = TSK_ERR_FS_INODE_COR;                snprintf(tsk_errstr, TSK_ERRSTR_L,                    "Error: Index list offsets are invalid on entry: %"                    PRIuINUM, fs_dir->fs_file->meta->addr);                free(idxalloc);                return TSK_COR;            }            /* process the list of index entries */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -