On Monday, 19 September 2016 23:26:57 CEST Matteo Cafasso wrote:
The internal_find_block command searches all entries referring to
the
given filesystem data block and returns a tsk_dirent structure
for each of them.
For filesystems such as NTFS which do not delete the block mapping
when removing files, it is possible to get multiple non-allocated
entries for the same block.
The gathered list of tsk_dirent structs is serialised into XDR format
and written to a file by the appliance.
Signed-off-by: Matteo Cafasso <noxdafox(a)gmail.com>
---
The idea is fine, there are few notes below.
+int
+do_internal_find_block (const mountable_t *mountable, int64_t block)
+{
+ int ret = -1;
+ TSK_FS_INFO *fs = NULL;
+ TSK_IMG_INFO *img = NULL; /* Used internally by tsk_fs_dir_walk */
+ const int flags =
+ TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC |
+ TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_NOORPHAN;
+
+ ret = open_filesystem (mountable->device, &img, &fs);
+ if (ret < 0)
+ return ret;
+
+ reply (NULL, NULL); /* Reply message. */
+
+ ret = tsk_fs_dir_walk (fs, fs->root_inum, flags,
+ findblk_callback, (void *) &block);
+ if (ret == 0)
+ ret = send_file_end (0); /* File transfer end. */
+ else
+ send_file_end (1); /* Cancel file transfer. */
+
+ fs->close (fs);
+ img->close (img);
+
+ return ret;
+}
+
+
(One extra empty line.)
+static TSK_WALK_RET_ENUM
+findblk_callback (TSK_FS_FILE *fsfile, const char *path, void *data)
+{
+ findblk_data blkdata;
+ const TSK_FS_ATTR *fsattr = NULL;
+ int ret = 0, count = 0, index = 0;
+ uint64_t *block = (uint64_t *) data;
Just dereference the pointer directly, so it will not be needed later
on:
const uint64_t block = * (uint64_t *) data;
Or, even better, this can be done only when needed, ...
+ const int flags = TSK_FS_FILE_WALK_FLAG_AONLY |
TSK_FS_FILE_WALK_FLAG_SLACK;
+
+ if (entry_is_dot (fsfile))
+ return TSK_WALK_CONT;
+
+ blkdata.found = false;
+ blkdata.block = *block;
... here:
blkdata.block = * (uint64_t *) data;
+ /* Retrieve block list */
+ count = tsk_fs_file_attr_getsize (fsfile);
+
+ for (index = 0; index < count; index++) {
+ fsattr = tsk_fs_file_attr_get_idx (fsfile, index);
+
+ if (fsattr != NULL && fsattr->flags & TSK_FS_ATTR_NONRES)
+ tsk_fs_attr_walk (fsattr, flags, attrwalk_callback, (void*) &blkdata);
(Minor style nitpick: space missing between "void" and "*".)
Should the return value of tsk_fs_attr_walk be checked for failures,
and return TSK_WALK_ERROR in case of error?
+/* Attribute walk, searches the given block within the FS node
attributes. */
Even if within 80 columns, I'd split it at 70 for readability.
+static TSK_WALK_RET_ENUM
+attrwalk_callback (TSK_FS_FILE *fsfile, TSK_OFF_T offset,
+ TSK_DADDR_T blkaddr, char *buf, size_t size,
+ TSK_FS_BLOCK_FLAG_ENUM flags, void *data)
+{
+ findblk_data *blkdata = (findblk_data *) data;
+
+ if (blkaddr == blkdata->block) {
+ blkdata->found = true;
If I read the sleuthkit API docs, blkaddr will be meaningful only if
flags contains TSK_FS_BLOCK_FLAG_RAW. Should attrwalk_callback check
for it?
Thanks,
--
Pino Toscano