📄 ext2fs.c
字号:
break; case EXT2_IN_LNK: fs_meta->type = TSK_FS_META_TYPE_LNK; break; case EXT2_IN_BLK: fs_meta->type = TSK_FS_META_TYPE_BLK; break; case EXT2_IN_CHR: fs_meta->type = TSK_FS_META_TYPE_CHR; break; case EXT2_IN_FIFO: fs_meta->type = TSK_FS_META_TYPE_FIFO; break; default: fs_meta->type = TSK_FS_META_TYPE_UNDEF; break; } // set the mode fs_meta->mode = 0; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_ISUID) fs_meta->mode |= TSK_FS_META_MODE_ISUID; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_ISGID) fs_meta->mode |= TSK_FS_META_MODE_ISGID; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_ISVTX) fs_meta->mode |= TSK_FS_META_MODE_ISVTX; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IRUSR) fs_meta->mode |= TSK_FS_META_MODE_IRUSR; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IWUSR) fs_meta->mode |= TSK_FS_META_MODE_IWUSR; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IXUSR) fs_meta->mode |= TSK_FS_META_MODE_IXUSR; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IRGRP) fs_meta->mode |= TSK_FS_META_MODE_IRGRP; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IWGRP) fs_meta->mode |= TSK_FS_META_MODE_IWGRP; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IXGRP) fs_meta->mode |= TSK_FS_META_MODE_IXGRP; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IROTH) fs_meta->mode |= TSK_FS_META_MODE_IROTH; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IWOTH) fs_meta->mode |= TSK_FS_META_MODE_IWOTH; if (tsk_getu16(fs->endian, in->i_mode) & EXT2_IN_IXOTH) fs_meta->mode |= TSK_FS_META_MODE_IXOTH; fs_meta->nlink = tsk_getu16(fs->endian, in->i_nlink); fs_meta->size = tsk_getu32(fs->endian, in->i_size); fs_meta->addr = ext2fs->dino_inum; /* the general size value in the inode is only 32-bits, * but the i_dir_acl value is used for regular files to * hold the upper 32-bits * * The RO_COMPAT_LARGE_FILE flag in the super block will identify * if there are any large files in the file system */ if ((fs_meta->type == TSK_FS_META_TYPE_REG) && (tsk_getu32(fs->endian, sb->s_feature_ro_compat) & EXT2FS_FEATURE_RO_COMPAT_LARGE_FILE)) { fs_meta->size += ((uint64_t) tsk_getu32(fs->endian, in->i_size_high) << 32); } fs_meta->uid = tsk_getu16(fs->endian, in->i_uid) + (tsk_getu16(fs->endian, in->i_uid_high) << 16); fs_meta->gid = tsk_getu16(fs->endian, in->i_gid) + (tsk_getu16(fs->endian, in->i_gid_high) << 16); fs_meta->mtime = tsk_getu32(fs->endian, in->i_mtime); fs_meta->atime = tsk_getu32(fs->endian, in->i_atime); fs_meta->ctime = tsk_getu32(fs->endian, in->i_ctime); fs_meta->crtime = 0; fs_meta->time2.ext2.dtime = tsk_getu32(fs->endian, in->i_dtime); fs_meta->seq = 0; if (fs_meta->link) { free(fs_meta->link); fs_meta->link = NULL; } if (fs_meta->content_len != EXT2FS_FILE_CONTENT_LEN) { if ((fs_meta = tsk_fs_meta_realloc(fs_meta, EXT2FS_FILE_CONTENT_LEN)) == NULL) { return 1; } } addr_ptr = (TSK_DADDR_T *) fs_meta->content_ptr; for (i = 0; i < EXT2FS_NDADDR + EXT2FS_NIADDR; i++) addr_ptr[i] = tsk_gets32(fs->endian, in->i_block[i]); /* set the link string * the size check prevents us from trying to allocate a huge amount of * memory for a bad inode value */ if ((fs_meta->type == TSK_FS_META_TYPE_LNK) && (fs_meta->size < EXT2FS_MAXPATHLEN) && (fs_meta->size >= 0)) { unsigned int count = 0; int i; if ((fs_meta->link = tsk_malloc((size_t) (fs_meta->size + 1))) == NULL) return 1; /* it is located directly in the pointers */ if (fs_meta->size < 4 * (EXT2FS_NDADDR + EXT2FS_NIADDR)) { unsigned int j; for (i = 0; i < (EXT2FS_NDADDR + EXT2FS_NIADDR) && count < fs_meta->size; i++) { char *a_ptr = (char *) &in->i_block[i]; for (j = 0; j < 4 && count < fs_meta->size; j++) { fs_meta->link[count++] = a_ptr[j]; } } fs_meta->link[count] = '\0'; /* clear the content pointer data to avoid the prog from reading them */ memset(fs_meta->content_ptr, 0, fs_meta->content_len); } /* it is in blocks */ else { TSK_FS_INFO *fs = (TSK_FS_INFO *) & ext2fs->fs_info; char *data_buf; char *a_ptr = fs_meta->link; TSK_DADDR_T *addr_ptr = fs_meta->content_ptr;; if ((data_buf = tsk_malloc(fs->block_size)) == NULL) return 1; /* we only need to do the direct blocks due to the limit * on path length */ for (i = 0; i < EXT2FS_NDADDR && count < fs_meta->size; i++) { ssize_t cnt; int read_count = (fs_meta->size - count < fs->block_size) ? (int) (fs_meta->size - count) : (int) (fs->block_size); cnt = tsk_fs_read_block(fs, addr_ptr[i], data_buf, fs->block_size); if (cnt != fs->block_size) { if (cnt >= 0) { tsk_error_reset(); tsk_errno = TSK_ERR_FS_READ; } snprintf(tsk_errstr2, TSK_ERRSTR_L, "ext2fs_dinode_copy: symlink destination from %" PRIuDADDR, addr_ptr[i]); free(data_buf); return 1; } memcpy(a_ptr, data_buf, read_count); count += read_count; a_ptr = (char *) ((uintptr_t) a_ptr + count); } /* terminate the string */ *a_ptr = '\0'; free(data_buf); } /* Clean up name */ i = 0; while (fs_meta->link[i] != '\0') { if (TSK_IS_CNTRL(fs_meta->link[i])) fs_meta->link[i] = '^'; i++; } } /* Fill in the flags value */ grp_num = (EXT2_GRPNUM_T) ((ext2fs->dino_inum - fs->first_inum) / tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group)); if (ext2fs->imap_grp_num != grp_num) { if (ext2fs_imap_load(ext2fs, grp_num)) { return 1; } } ibase = grp_num * tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group) + fs->first_inum; /* * Apply the allocated/unallocated restriction. */ fs_meta->flags = (isset(ext2fs->imap_buf, ext2fs->dino_inum - ibase) ? TSK_FS_META_FLAG_ALLOC : TSK_FS_META_FLAG_UNALLOC); /* * Apply the used/unused restriction. */ fs_meta->flags |= (fs_meta->ctime ? TSK_FS_META_FLAG_USED : TSK_FS_META_FLAG_UNUSED); return 0;}/* ext2fs_inode_lookup - lookup inode, external interface * * Returns 1 on error and 0 on success * */static uint8_text2fs_inode_lookup(TSK_FS_INFO * fs, TSK_FS_FILE * a_fs_file, TSK_INUM_T inum){ EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs; if (a_fs_file == NULL) { tsk_errno = TSK_ERR_FS_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "ext2fs_inode_lookup: fs_file is NULL"); return 1; } if (a_fs_file->meta == NULL) { if ((a_fs_file->meta = tsk_fs_meta_alloc(EXT2FS_FILE_CONTENT_LEN)) == NULL) return 1; } else { tsk_fs_meta_reset(a_fs_file->meta); } // see if they are looking for the special "orphans" directory if (inum == TSK_FS_ORPHANDIR_INUM(fs)) { if (tsk_fs_dir_make_orphan_dir_meta(fs, a_fs_file->meta)) return 1; else return 0; } if (ext2fs_dinode_load(ext2fs, inum)) { return 1; } if (ext2fs_dinode_copy(ext2fs, a_fs_file->meta)) { return 1; } return 0;}/* ext2fs_inode_walk - inode iterator * * flags used: TSK_FS_META_FLAG_USED, TSK_FS_META_FLAG_UNUSED, * TSK_FS_META_FLAG_ALLOC, TSK_FS_META_FLAG_UNALLOC, TSK_FS_META_FLAG_ORPHAN * * Return 1 on error and 0 on success*/uint8_text2fs_inode_walk(TSK_FS_INFO * fs, TSK_INUM_T start_inum, TSK_INUM_T end_inum, TSK_FS_META_FLAG_ENUM flags, TSK_FS_META_WALK_CB a_action, void *a_ptr){ char *myname = "extXfs_inode_walk"; EXT2FS_INFO *ext2fs = (EXT2FS_INFO *) fs; EXT2_GRPNUM_T grp_num; TSK_INUM_T inum; TSK_INUM_T end_inum_tmp; TSK_INUM_T ibase = 0; TSK_FS_FILE *fs_file; int myflags; // 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; } 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 ORPHAN is wanted, then make sure that the flags are correct */ if (flags & TSK_FS_META_FLAG_ORPHAN) { flags |= TSK_FS_META_FLAG_UNALLOC; flags &= ~TSK_FS_META_FLAG_ALLOC; flags |= TSK_FS_META_FLAG_USED; flags &= ~TSK_FS_META_FLAG_UNUSED; } else { if (((flags & TSK_FS_META_FLAG_ALLOC) == 0) && ((flags & TSK_FS_META_FLAG_UNALLOC) == 0)) { flags |= (TSK_FS_META_FLAG_ALLOC | TSK_FS_META_FLAG_UNALLOC); } /* If neither of the USED or UNUSED flags are set, then set them * both */ if (((flags & TSK_FS_META_FLAG_USED) == 0) && ((flags & TSK_FS_META_FLAG_UNUSED) == 0)) { 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 ((flags & TSK_FS_META_FLAG_ORPHAN) && (fs->list_inum_named == NULL)) { if (tsk_fs_dir_load_inum_named(fs) != TSK_OK) { strncat(tsk_errstr2, " - ext2fs_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(EXT2FS_FILE_CONTENT_LEN)) == NULL) return 1; // we need to handle fs->last_inum specially because it is for the // virtual ORPHANS directory. Handle it outside of the loop. if (end_inum == TSK_FS_ORPHANDIR_INUM(fs)) end_inum_tmp = end_inum - 1; else end_inum_tmp = end_inum; /* * Iterate. */ for (inum = start_inum; inum <= end_inum_tmp; inum++) { int retval; /* * Be sure to use the proper group descriptor data. XXX Linux inodes * start at 1, as in Fortran. */ grp_num = (EXT2_GRPNUM_T) ((inum - 1) / tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group)); if ((ext2fs->imap_buf == NULL) || (ext2fs->imap_grp_num != grp_num)) { if (ext2fs_imap_load(ext2fs, grp_num)) { return 1; } ibase = grp_num * tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group) + 1; } /* In case we didn't need to load it the bitmap */ else if (inum == start_inum) { ibase = grp_num * tsk_getu32(fs->endian, ext2fs->fs->s_inodes_per_group) + 1; } /* * Apply the allocated/unallocated restriction. */ myflags = (isset(ext2fs->imap_buf, inum - ibase) ? TSK_FS_META_FLAG_ALLOC : TSK_FS_META_FLAG_UNALLOC); if ((flags & myflags) != myflags) continue; if (ext2fs_dinode_load(ext2fs, inum)) { tsk_fs_file_close(fs_file); return 1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -