📄 fatfs_meta.c
字号:
return 0; else if ((tsk_getu16(fs->endian, de->adate) != 0) && (FATFS_ISDATE(tsk_getu16(fs->endian, de->adate)) == 0)) return 0; else if (FATFS_ISDATE(tsk_getu16(fs->endian, de->wdate)) == 0) return 0; /* verify the starting cluster is small enough */ else if ((FATFS_DENTRY_CLUST(fs, de) > (fatfs->lastclust)) && (FATFS_ISEOF(FATFS_DENTRY_CLUST(fs, de), fatfs->mask) == 0)) return 0; /* Verify the file size is smaller than the data area */ else if (tsk_getu32(fs->endian, de->size) > ((fatfs->clustcnt * fatfs->csize) << fatfs->ssize_sh)) return 0; return is_83_name(de); //return 1; }}/************************************************************************** * * INODE WALKING * *************************************************************************//* Mark the sector used in the bitmap */static TSK_WALK_RET_ENUMinode_walk_file_act(TSK_FS_FILE * fs_file, TSK_OFF_T a_off, TSK_DADDR_T addr, char *buf, size_t size, TSK_FS_BLOCK_FLAG_ENUM a_flags, void *a_ptr){ setbit((uint8_t *) a_ptr, addr); return TSK_WALK_CONT;}/* The inode_walk call back for each file. we want only the directories */static TSK_WALK_RET_ENUMinode_walk_dent_act(TSK_FS_FILE * fs_file, const char *a_path, void *a_ptr){ if ((fs_file->meta == NULL) || (fs_file->meta->type != TSK_FS_META_TYPE_DIR)) return TSK_WALK_CONT; /* Get the sector addresses & ignore any errors */ if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_SLACK | TSK_FS_FILE_WALK_FLAG_AONLY, inode_walk_file_act, a_ptr)) { tsk_error_reset(); } return TSK_WALK_CONT;}/* * walk the inodes * * Flags that are used: TSK_FS_META_FLAG_ALLOC, TSK_FS_META_FLAG_UNALLOC, * TSK_FS_META_FLAG_USED, TSK_FS_META_FLAG_UNUSED, TSK_FS_META_FLAG_ORPHAN * */uint8_tfatfs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum, TSK_INUM_T end_inum, TSK_FS_META_FLAG_ENUM a_flags, TSK_FS_META_WALK_CB a_action, void *a_ptr){ char *myname = "fatfs_inode_walk"; FATFS_INFO *fatfs = (FATFS_INFO *) fs; TSK_INUM_T end_inum_tmp; TSK_FS_FILE *fs_file; TSK_DADDR_T sect, ssect, lsect; fatfs_dentry *dep; unsigned int myflags, didx; uint8_t *sect_alloc; ssize_t cnt; uint8_t done = 0; // clean up any error messages that are lying around tsk_error_reset(); /* * Sanity checks. */ if (start_inum < fs->first_inum || start_inum > fs->last_inum) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s: Start inode: %" PRIuINUM "", myname, start_inum); return 1; } else if (end_inum < fs->first_inum || end_inum > fs->last_inum || end_inum < start_inum) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "%s: End inode: %" PRIuINUM "", myname, end_inum); return 1; } if (tsk_verbose) tsk_fprintf(stderr, "fatfs_inode_walk: Inode Walking %" PRIuINUM " to %" PRIuINUM "\n", start_inum, end_inum); /* If ORPHAN is wanted, then make sure that the a_flags are correct */ if (a_flags & TSK_FS_META_FLAG_ORPHAN) { a_flags |= TSK_FS_META_FLAG_UNALLOC; a_flags &= ~TSK_FS_META_FLAG_ALLOC; a_flags |= TSK_FS_META_FLAG_USED; a_flags &= ~TSK_FS_META_FLAG_UNUSED; } else { if (((a_flags & TSK_FS_META_FLAG_ALLOC) == 0) && ((a_flags & TSK_FS_META_FLAG_UNALLOC) == 0)) { a_flags |= (TSK_FS_META_FLAG_ALLOC | TSK_FS_META_FLAG_UNALLOC); } /* If neither of the USED or UNUSED a_flags are set, then set them * both */ if (((a_flags & TSK_FS_META_FLAG_USED) == 0) && ((a_flags & TSK_FS_META_FLAG_UNUSED) == 0)) { a_flags |= (TSK_FS_META_FLAG_USED | TSK_FS_META_FLAG_UNUSED); } } /* If we are looking for orphan files and have not yet filled * in the list of unalloc inodes that are pointed to, then fill * in the list */ if ((a_flags & TSK_FS_META_FLAG_ORPHAN) && (fs->list_inum_named == NULL)) { if (tsk_fs_dir_load_inum_named(fs) != TSK_OK) { strncat(tsk_errstr2, " - fatfs_inode_walk: identifying inodes allocated by file names", TSK_ERRSTR_L); return 1; } } if ((fs_file = tsk_fs_file_alloc(fs)) == NULL) return 1; if ((fs_file->meta = tsk_fs_meta_alloc(FATFS_FILE_CONTENT_LEN)) == NULL) return 1; // handle the root directory if (start_inum == FATFS_ROOTINO) { if (((TSK_FS_META_FLAG_ALLOC & a_flags) == TSK_FS_META_FLAG_ALLOC) && ((TSK_FS_META_FLAG_USED & a_flags) == TSK_FS_META_FLAG_USED) && ((TSK_FS_META_FLAG_ORPHAN & a_flags) == 0)) { int retval; if (fatfs_make_root(fatfs, fs_file->meta)) { tsk_fs_file_close(fs_file); return 1; } retval = a_action(fs_file, a_ptr); if (retval == TSK_WALK_STOP) { tsk_fs_file_close(fs_file); return 0; } else if (retval == TSK_WALK_ERROR) { tsk_fs_file_close(fs_file); return 1; } } /* advance it so that it is a valid starting point */ start_inum++; // exit if that is all that was requested if (start_inum == end_inum) { tsk_fs_file_close(fs_file); return 0; } } /* We will be looking at each sector to see if it contains directory * entries. We can make mistakes and ignore sectors that have valid * entries in them. To make sure we at least get all sectors that * are allocated by directories in the directory tree, we will * run name_walk and then a file walk on each dir. * We'll be make sure to print those. We skip this for ORPHAN hunting * because it doesn't help and can introduce infinite loop situations * inode_walk was called by the function that determines which inodes * are orphans. */ if (tsk_verbose) tsk_fprintf(stderr, "fatfs_inode_walk: Walking directories to collect sector info\n"); if ((sect_alloc = (uint8_t *) tsk_malloc((size_t) ((fs->block_count + 7) / 8))) == NULL) { tsk_fs_file_close(fs_file); return 1; } if ((a_flags & TSK_FS_META_FLAG_ORPHAN) == 0) { // Do a file_walk on the root directory to get its layout if (fatfs_make_root(fatfs, fs_file->meta)) { tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } if (tsk_fs_file_walk(fs_file, TSK_FS_FILE_WALK_FLAG_SLACK | TSK_FS_FILE_WALK_FLAG_AONLY, inode_walk_file_act, (void *) sect_alloc)) { tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } // now get the rest of the directories. if (tsk_fs_dir_walk(fs, fs->root_inum, TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_NOORPHAN, inode_walk_dent_act, (void *) sect_alloc)) { strncat(tsk_errstr2, " - fatfs_inode_walk: mapping directories", TSK_ERRSTR_L); tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } } /* start analyzing each sector * * Perform a test on the first 32 bytes of each sector to identify if * the sector contains directory entries. If it does, then continue * to analyze it. If not, then read the next sector */ /* identify the starting and ending inodes sector addrs */ /* we need to handle end_inum specially if it is for the * virtual ORPHANS directory or virtual FAT files. * Handle these outside of the loop. */ if (end_inum > fs->last_inum - FATFS_NUM_SPECFILE) end_inum_tmp = fs->last_inum - FATFS_NUM_SPECFILE; else end_inum_tmp = end_inum; ssect = FATFS_INODE_2_SECT(fatfs, start_inum); lsect = FATFS_INODE_2_SECT(fatfs, end_inum_tmp); if (ssect > fs->last_block) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "fatfs_inode_walk: Starting inode in sector too big for image: %" PRIuDADDR, ssect); tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } else if (lsect > fs->last_block) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_WALK_RNG; snprintf(tsk_errstr, TSK_ERRSTR_L, "fatfs_inode_walk: Ending inode in sector too big for image: %" PRIuDADDR, lsect); tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } sect = ssect; while (sect <= lsect) { int clustalloc; // 1 if current sector / cluster is allocated size_t sect_proc; // number of sectors read for this loop size_t sidx; // sector index for loop /* This occurs for the root directory of TSK_FS_TYPE_FAT12/16 * * We are going to process the image in clusters, so take care of the root * directory seperately. */ if (sect < fatfs->firstclustsect) { // there are no orphans in the root directory if ((a_flags & TSK_FS_META_FLAG_ORPHAN) != 0) { sect = fatfs->firstclustsect; continue; } clustalloc = 1; /* read the sector */ cnt = tsk_fs_read_block(fs, sect, fatfs->dinodes, fatfs->ssize); if (cnt != fatfs->ssize) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "fatfs_inode_walk (root dir): sector: %" PRIuDADDR, sect); tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } sect_proc = 1; } /* For the data area, we will read in cluster-sized chunks */ else { /* get the base sector for the cluster in which the first inode exists */ sect = FATFS_CLUST_2_SECT(fatfs, (FATFS_SECT_2_CLUST(fatfs, sect))); /* if the cluster is not allocated, then do not go into it if we * only want allocated/link entries * If it is allocated, then go into it no matter what */ clustalloc = fatfs_is_sectalloc(fatfs, sect); if (clustalloc == -1) { tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } else if ((clustalloc == 0) && ((a_flags & TSK_FS_META_FLAG_UNALLOC) == 0)) { sect += fatfs->csize; continue; } /* If it is allocated, but we know it is not allocated to a * directory then skip it. NOTE: This will miss unallocated * entries in slack space of the file... */ if ((clustalloc == 1) && (isset(sect_alloc, sect) == 0)) { sect += fatfs->csize; continue; } /* The final cluster may not be full */ if (lsect - sect + 1 < fatfs->csize) sect_proc = (size_t) (lsect - sect + 1); else sect_proc = fatfs->csize; /* read the full cluster */ cnt = tsk_fs_read_block (fs, sect, fatfs->dinodes, sect_proc << fatfs->ssize_sh); if (cnt != (sect_proc << fatfs->ssize_sh)) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "fatfs_inode_walk: sector: %" PRIuDADDR, sect); tsk_fs_file_close(fs_file); free(sect_alloc); return 1; } } // cycle through the sectors read for (sidx = 0; sidx < sect_proc; sidx++) { TSK_INUM_T inum;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -