static uint8_t process_tsk_file(TSK_FS_FILE * fs_file, const char *path) { /* Use a flag to determine if a file is generically fit for plugins. */ bool can_run_plugin; /* Make sure that the SleuthKit structures are properly set */ if (fs_file->name == NULL) return 1; if (fs_file->meta == NULL && opt_debug) printf("File: %s %s has no meta\n", path, fs_file->name->name); /* SleuthKit meta types are defined in tsk_fs.h.*/ if (opt_debug) printf("Processing %s%s type=%s (0x%x) \n", path, fs_file->name->name, tsk_fs_name_type_str[fs_file->name->type],fs_file->name->type); /* Recover the filename from the fs_dent, if it is provided */ content ci(fs_file->fs_info->img_info); // where the content will go ci.evidence_dirname = path; ci.set_filename(fs_file->name->name); /* If we are filtering and we have a filename, see if we want this file. */ if (ci.name_filtered()) return 0; /* Looks like we are processing */ if(a) a->new_row(); // tell ARFF we are starting a new row if(x) x->push("fileobject"); // tell XML we are starting a new XML object if(opt_parent_tracking) { if(fs_file->name->par_addr) { if(x) { x->push("parent_object"); file_info("inode", fs_file->name->par_addr); if(x) x->pop(); } if((t||a) && !opt_body_file) { file_info("parent_inode", fs_file->name->par_addr); } } } if(fs_file->meta != NULL) { /* Get the content if needed */ if(ci.need_file_walk() && (opt_maxgig==0 || fs_file->meta->size/1000000000 < opt_maxgig)) { int myflags = TSK_FS_FILE_WALK_FLAG_NOID; if (opt_no_data) myflags |= TSK_FS_FILE_WALK_FLAG_AONLY; if (tsk_fs_file_walk (fs_file, (TSK_FS_FILE_WALK_FLAG_ENUM) myflags, file_act, (void *) &ci)) { // ignore errors from deleted files that were being recovered //if (tsk_errno != TSK_ERR_FS_RECOVER) { if (tsk_error_get_errno() != TSK_ERR_FS_RECOVER) { if(opt_debug) { fprintf(stderr,"Processing: %s/%s (%" PRIuINUM ")\n", path, fs_file->name->name, fs_file->meta->addr); tsk_error_print(stderr); } } tsk_error_reset(); } } } if(file_count_max && file_count>file_count_max) return TSK_WALK_STOP; file_count++; /* Send through to the plugin if we were doing that. * Currently results only go to ARFF file, not to the XML file. */ /* Finally output the informaton */ if(opt_body_file && (fs_file->meta != NULL)) { char ls[64]; tsk_fs_meta_make_ls(fs_file->meta,ls,sizeof(ls)); fprintf(t,"%s|%s|%" PRId64 "|%s|%d|%d|%" PRId64 "|%d|%d|%d|%d\n", ci.h_md5.final().hexdigest().c_str(),ci.filename().c_str(),fs_file->meta->addr, ls,fs_file->meta->uid,fs_file->meta->gid, fs_file->meta->size, (uint32_t)(fs_file->meta->atime), (uint32_t)fs_file->meta->mtime, (uint32_t)fs_file->meta->ctime, (uint32_t)fs_file->meta->crtime); return TSK_WALK_CONT; }
/** * \internal * ** Print output in the format that mactime reads. ** ** If the flags in the fs_file->meta structure are set to FS_FLAG_ALLOC ** then it is assumed that the inode has been reallocated and the ** contents are not displayed ** ** fs is not required (only used for block size). * @param hFile handle to print results to * @param fs_file File to print details about * @param a_path Parent directory of file (needs to end with "/") * @param fs_attr Attribute in file that is being called for (NULL for non-NTFS) * @param prefix Path of mounting point for image * @param time_skew number of seconds skew to adjust time */ void tsk_fs_name_print_mac(FILE * hFile, const TSK_FS_FILE * fs_file, const char *a_path, const TSK_FS_ATTR * fs_attr, const char *prefix, int32_t time_skew) { char ls[12]; size_t i; uint8_t isADS = 0; if ((!hFile) || (!fs_file)) return; /* see if we are going to be printing the name of the attribute * We don't do it for FNAME attributes, which we handle specially below. */ if ((fs_attr) && (fs_attr->name) && (fs_attr->type != TSK_FS_ATTR_TYPE_NTFS_FNAME) && ((fs_attr->type != TSK_FS_ATTR_TYPE_NTFS_IDXROOT) || (strcmp(fs_attr->name, "$I30") != 0))) { isADS = 1; } /* md5 */ tsk_fprintf(hFile, "0|"); /* file name */ tsk_fprintf(hFile, "%s", prefix); // remove any control chars as we print the names if (a_path != NULL) { for (i = 0; i < strlen(a_path); i++) { if (TSK_IS_CNTRL(a_path[i])) tsk_fprintf(hFile, "^"); else tsk_fprintf(hFile, "%c", a_path[i]); } } for (i = 0; i < strlen(fs_file->name->name); i++) { if (TSK_IS_CNTRL(fs_file->name->name[i])) tsk_fprintf(hFile, "^"); else tsk_fprintf(hFile, "%c", fs_file->name->name[i]); } /* print the data stream name if it exists and is not the default NTFS */ if (isADS) { tsk_fprintf(hFile, ":"); for (i = 0; i < strlen(fs_attr->name); i++) { if (TSK_IS_CNTRL(fs_attr->name[i])) tsk_fprintf(hFile, "^"); else tsk_fprintf(hFile, "%c", fs_attr->name[i]); } } // special label if FNAME if ((fs_attr) && (fs_attr->type == TSK_FS_ATTR_TYPE_NTFS_FNAME)) { tsk_fprintf(hFile, " ($FILE_NAME)"); } if ((fs_file->meta) && (fs_file->meta->type == TSK_FS_META_TYPE_LNK) && (fs_file->meta->link)) { tsk_fprintf(hFile, " -> %s", fs_file->meta->link); } /* if filename is deleted add a comment and if the inode is now * allocated, then add realloc comment */ if (fs_file->name->flags & TSK_FS_NAME_FLAG_UNALLOC) tsk_fprintf(hFile, " (deleted%s)", ((fs_file->meta) && (fs_file-> meta->flags & TSK_FS_META_FLAG_ALLOC)) ? "-realloc" : ""); /* inode */ tsk_fprintf(hFile, "|%" PRIuINUM, fs_file->name->meta_addr); if (fs_attr) tsk_fprintf(hFile, "-%" PRIu32 "-%" PRIu16 "", fs_attr->type, fs_attr->id); tsk_fprintf(hFile, "|"); /* TYPE as specified in the directory entry */ if (fs_file->name->type < TSK_FS_NAME_TYPE_STR_MAX) tsk_fprintf(hFile, "%s/", tsk_fs_name_type_str[fs_file->name->type]); else tsk_fprintf(hFile, "-/"); if (!fs_file->meta) { tsk_fprintf(hFile, "----------|0|0|0|"); } else { /* mode as string */ tsk_fs_meta_make_ls(fs_file->meta, ls, sizeof(ls)); tsk_fprintf(hFile, "%s|", ls); /* uid, gid */ tsk_fprintf(hFile, "%" PRIuUID "|%" PRIuGID "|", fs_file->meta->uid, fs_file->meta->gid); /* size - use data stream if we have it */ if (fs_attr) tsk_fprintf(hFile, "%" PRIuOFF "|", fs_attr->size); else tsk_fprintf(hFile, "%" PRIuOFF "|", fs_file->meta->size); } if (!fs_file->meta) { tsk_fprintf(hFile, "0|0|0|0\n"); } else { // special case for NTFS FILE_NAME attribute if ((fs_attr) && (fs_attr->type == TSK_FS_ATTR_TYPE_NTFS_FNAME)) { /* atime, mtime, ctime, crtime */ if (fs_file->meta->time2.ntfs.fn_atime) tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->time2.ntfs.fn_atime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->time2.ntfs.fn_atime); if (fs_file->meta->time2.ntfs.fn_mtime) tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->time2.ntfs.fn_mtime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->time2.ntfs.fn_mtime); if (fs_file->meta->time2.ntfs.fn_ctime) tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->time2.ntfs.fn_ctime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->time2.ntfs.fn_ctime); if (fs_file->meta->time2.ntfs.fn_crtime) tsk_fprintf(hFile, "%" PRIu32 "\n", fs_file->meta->time2.ntfs.fn_crtime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "\n", fs_file->meta->time2.ntfs.fn_crtime); } else { /* atime, mtime, ctime, crtime */ if (fs_file->meta->atime) tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->atime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->atime); if (fs_file->meta->mtime) tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->mtime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->mtime); if (fs_file->meta->ctime) tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->ctime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "|", fs_file->meta->ctime); if (fs_file->meta->crtime) tsk_fprintf(hFile, "%" PRIu32 "\n", fs_file->meta->crtime - time_skew); else tsk_fprintf(hFile, "%" PRIu32 "\n", fs_file->meta->crtime); } } }