From 8eb6547bb13b605b98a8f60cbfeec22e0fe08b56 Mon Sep 17 00:00:00 2001 From: Ann Priestman <apriestman@basistech.com> Date: Tue, 25 Oct 2016 09:36:51 -0400 Subject: [PATCH] Adding fs_file entries for slack --- tsk/auto/auto_db.cpp | 99 +++++++++++++++++++++++++++++++++++++- tsk/auto/db_postgresql.cpp | 49 ++++++++++++++++++- tsk/auto/db_sqlite.cpp | 57 +++++++++++++++++++++- tsk/auto/tsk_case_db.h | 4 ++ tsk/auto/tsk_db.h | 1 + 5 files changed, 207 insertions(+), 3 deletions(-) diff --git a/tsk/auto/auto_db.cpp b/tsk/auto/auto_db.cpp index 949be1345..e8cc374f1 100644 --- a/tsk/auto/auto_db.cpp +++ b/tsk/auto/auto_db.cpp @@ -348,6 +348,103 @@ TSK_RETVAL_ENUM return TSK_ERR; } + //return insertSlackFileData(fs_file, fs_attr, path, md5, known); + return TSK_OK; +} + +TSK_RETVAL_ENUM + TskAutoDb::insertSlackFileData(TSK_FS_FILE * fs_file, + const TSK_FS_ATTR * fs_attr, const char *path, + const unsigned char *const md5, + const TSK_DB_FILES_KNOWN_ENUM known) +{ + // Should do check that file name does not already end in "-slack". Or maybe can just test for type somehow later + int name_length; + TSK_FS_NAME* slack_name; + TSK_FS_NAME* orig_name; + + if((fs_file->name == NULL) || (fs_file->name->name == NULL) || + (fs_file->meta == NULL)){ + printf("Null name, name->name, or meta\n"); + } + else { + printf("fs_file: %s\n size: %d\n content len: %d\n", fs_file->name->name, fs_file->meta->size, + fs_file->meta->content_len); + } + + if(fs_file->meta == NULL){ + printf(" fs_file->meta is null, giving up\n"); + return TSK_OK; + } + printf(" type: %x\n", fs_file->meta->type); + if(fs_file->meta->type != TSK_FS_META_TYPE_REG){ + printf(" Not a file\n"); + return TSK_OK; + } + if(fs_file->name == NULL){ + printf(" fs_file->name is null! giving up\n"); + return TSK_OK; + } + + if(fs_file->name->name == NULL){ + printf(" fs_file->name->name is null! giving up\n"); + return TSK_OK; + } + + if(fs_file->meta->attr_state == TSK_FS_META_ATTR_STUDIED){ + printf(" attr_state is studied\n"); + TSK_FS_ATTR *fs_attr_cur; + for (fs_attr_cur = fs_file->meta->attr->head; fs_attr_cur;fs_attr_cur = fs_attr_cur->next) { + printf(" attr name: %s\n", fs_attr_cur->name); + printf(" flags: %x (non-resident: %x)", fs_attr_cur->flags, fs_attr_cur->flags & TSK_FS_ATTR_NONRES); + printf(" attr type: %x\n", fs_attr_cur->type); + printf(" alloc: 0x%llx\n", fs_attr_cur->nrd.allocsize); + printf(" size: 0x%llx\n", fs_attr_cur->size); + + } + + } + else { + printf(" attr_state is not studied\n"); + } + + // Ok we're good to go. + //TSK_FS_FILE * slack_file = tsk_fs_file_alloc(fs_file->fs_info); + + // Allocate the new name structure + name_length = strlen(fs_file->name->name) + 6; + if ((slack_name = tsk_fs_name_alloc(name_length, 32)) == NULL) { + return TSK_ERR; + } + + if(tsk_fs_name_copy(slack_name, fs_file->name)){ + tsk_fs_name_free(slack_name); + return TSK_ERR; + } + + // The name copy could end up resizing the array. It currently allocates an extra 16 bytes but we shouldn't count on that. + if(slack_name->name_size < name_length){ + tsk_fs_name_realloc(slack_name, name_length); + } + + // Add the "-slack" + strncat(slack_name->name, "-slack", 6); + + printf(" Trying to add fs_file %s with metadata addr %x\n", slack_name->name, fs_file->meta->addr); + + // Swap in the new name block and re-add the file + orig_name = fs_file->name; + fs_file->name = slack_name; + if (m_db->addFsFile(fs_file, fs_attr, path, md5, known, m_curFsId, m_curFileId, + m_curImgId)) { + fs_file->name = orig_name; + tsk_fs_name_free(slack_name); + registerError(); + return TSK_ERR; + } + fs_file->name = orig_name; + tsk_fs_name_free(slack_name); + return TSK_OK; } @@ -622,7 +719,7 @@ TskAutoDb::processFile(TSK_FS_FILE * fs_file, const char *path) return TSK_STOP; } - /* If no longe processing the same directroy as the last file, + /* If no longer processing the same directory as the last file, * then update the class-level setting. */ int64_t cur = fs_file->name->par_addr; if (m_curDirId != cur) { diff --git a/tsk/auto/db_postgresql.cpp b/tsk/auto/db_postgresql.cpp index a399ac41c..680bc17cc 100755 --- a/tsk/auto/db_postgresql.cpp +++ b/tsk/auto/db_postgresql.cpp @@ -964,7 +964,7 @@ int TskDbPostgreSQL::addFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr, // combine name and attribute name size_t len = strlen(fs_file->name->name); char *name; - size_t nlen = len + attr_nlen + 5; + size_t nlen = len + attr_nlen + 11; // Extra space for possible colon and '-slack' if ((name = (char *) tsk_malloc(nlen)) == NULL) { return 1; } @@ -1057,6 +1057,53 @@ int TskDbPostgreSQL::addFile(TSK_FS_FILE * fs_file, const TSK_FS_ATTR * fs_attr, return 1; } + // Add entry for the slack space if applicable + if((fs_attr != NULL) + && (fs_attr->flags & TSK_FS_ATTR_NONRES) + && (fs_attr->nrd.allocsize != fs_attr->size)){ + strncat(name, "-slack", 6); + name_sql = PQescapeLiteral(conn, name, strlen(name)); + TSK_OFF_T slackSize = fs_attr->nrd.allocsize - fs_attr->size; + + if (addObject(TSK_DB_OBJECT_TYPE_FILE, parObjId, objId)) { + free(name); + free(escaped_path); + return 1; + } + + snprintf(zSQL, 2048, "INSERT INTO tsk_files (fs_obj_id, obj_id, data_source_obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) " + "VALUES (" + "%" PRId64 ",%" PRId64 "," + "%" PRId64 "," + "%d," + "%d,%d,%s," + "%" PRIuINUM ",%d," + "%d,%d,%d,%d," + "%" PRIuOFF "," + "%llu,%llu,%llu,%llu," + "%d,%d,%d,%s,%d," + "%s)", + fsObjId, objId, + dataSourceObjId, + TSK_DB_FILES_TYPE_SLACK, + type, idx, name_sql, + fs_file->name->meta_addr, fs_file->name->meta_seq, + fs_file->name->type, meta_type, fs_file->name->flags, meta_flags, + size, + (unsigned long long)crtime, (unsigned long long)ctime,(unsigned long long) atime,(unsigned long long) mtime, + meta_mode, gid, uid, NULL, known, + escaped_path_sql); + + if (attempt_exec(zSQL, "TskDbPostgreSQL::addFile: Error adding data to tsk_files table: %s\n")) { + free(name); + free(escaped_path); + PQfreemem(name_sql); + PQfreemem(escaped_path_sql); + return 1; + } + + } + //if dir, update parent id cache if (meta_type == TSK_FS_META_TYPE_DIR) { std::string fullPath = std::string(path) + fs_file->name->name; diff --git a/tsk/auto/db_sqlite.cpp b/tsk/auto/db_sqlite.cpp index d19a6e591..61de45965 100755 --- a/tsk/auto/db_sqlite.cpp +++ b/tsk/auto/db_sqlite.cpp @@ -816,6 +816,7 @@ int64_t TskDbSqlite::findParObjId(const TSK_FS_FILE * fs_file, const char *paren // Find the parent file id in the database using the parent metadata address // @@@ This should use sequence number when the new database supports it + printf("Trying to look up parent %s %s with metadata addr %x\n", parent_path, parent_name, fs_file->name->par_addr); if (attempt(sqlite3_bind_int64(m_selectFilePreparedStmt, 1, fs_file->name->par_addr), "TskDbSqlite::findParObjId: Error binding meta_addr to statment: %s (result code %d)\n") || attempt(sqlite3_bind_int64(m_selectFilePreparedStmt, 2, fsObjId), @@ -914,7 +915,7 @@ int size_t len = strlen(fs_file->name->name); char * name; - size_t nlen = len + attr_nlen + 5; + size_t nlen = len + attr_nlen + 11; // Extra space for possible colon and '-slack' if ((name = (char *) tsk_malloc(nlen)) == NULL) { return 1; } @@ -983,12 +984,66 @@ int meta_mode, gid, uid, md5TextPtr, known, escaped_path); + printf("Adding file %s with objid %x\n", name, objId); if (attempt_exec(zSQL, "TskDbSqlite::addFile: Error adding data to tsk_files table: %s\n")) { free(name); free(escaped_path); sqlite3_free(zSQL); return 1; } + + // Add entry for the slack space if applicable + if((fs_attr != NULL) + && (fs_attr->flags & TSK_FS_ATTR_NONRES) + && (fs_attr->nrd.allocsize != fs_attr->size)){ + printf("Adding slack for %s\n", name); + printf(" Non-resident\n"); + printf(" Alloc: 0x%x\n", fs_attr->nrd.allocsize); + printf(" Size: 0x%x\n", fs_attr->size); + strncat(name, "-slack", 6); + printf(" Slack file: %s\n", name); + TSK_OFF_T slackSize = fs_attr->nrd.allocsize - fs_attr->size; + printf(" Slack file size: 0x%x\n", slackSize); + + if (addObject(TSK_DB_OBJECT_TYPE_FILE, parObjId, objId)) { + free(name); + free(escaped_path); + return 1; + } + + // Run the same insert with the new name, size, and type + zSQL = sqlite3_mprintf( + "INSERT INTO tsk_files (fs_obj_id, obj_id, data_source_obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path) " + "VALUES (" + "%" PRId64 ",%" PRId64 "," + "%" PRId64 "," + "%d," + "%d,%d,'%q'," + "%" PRIuINUM ",%d," + "%d,%d,%d,%d," + "%" PRIuOFF "," + "%llu,%llu,%llu,%llu," + "%d,%d,%d,%Q,%d," + "'%q')", + fsObjId, objId, + dataSourceObjId, + TSK_DB_FILES_TYPE_SLACK, + type, idx, name, + fs_file->name->meta_addr, fs_file->name->meta_seq, + fs_file->name->type, meta_type, fs_file->name->flags, meta_flags, + slackSize, + (unsigned long long)crtime, (unsigned long long)ctime,(unsigned long long) atime,(unsigned long long) mtime, + meta_mode, gid, uid, md5TextPtr, known, + escaped_path); + + if (attempt_exec(zSQL, "TskDbSqlite::addFile: Error adding data to tsk_files table: %s\n")) { + free(name); + free(escaped_path); + sqlite3_free(zSQL); + return 1; + } + } + sqlite3_free(zSQL); //if dir, update parent id cache diff --git a/tsk/auto/tsk_case_db.h b/tsk/auto/tsk_case_db.h index 5dcd5e39f..2132bbb0f 100644 --- a/tsk/auto/tsk_case_db.h +++ b/tsk/auto/tsk_case_db.h @@ -160,6 +160,10 @@ class TskAutoDb:public TskAuto { const TSK_FS_ATTR *, const char *path, const unsigned char *const md5, const TSK_DB_FILES_KNOWN_ENUM known); + TSK_RETVAL_ENUM insertSlackFileData(TSK_FS_FILE * fs_file, + const TSK_FS_ATTR *, const char *path, + const unsigned char *const md5, + const TSK_DB_FILES_KNOWN_ENUM known); virtual TSK_RETVAL_ENUM processAttribute(TSK_FS_FILE *, const TSK_FS_ATTR * fs_attr, const char *path); static TSK_WALK_RET_ENUM md5HashCallback(TSK_FS_FILE * file, diff --git a/tsk/auto/tsk_db.h b/tsk/auto/tsk_db.h index 9fbc6cf2c..54dec2399 100755 --- a/tsk/auto/tsk_db.h +++ b/tsk/auto/tsk_db.h @@ -52,6 +52,7 @@ typedef enum { TSK_DB_FILES_TYPE_UNALLOC_BLOCKS, ///< Set of blocks not allocated by file system. Parent should be image, volume, or file system. Many columns in tsk_files will be NULL. Set layout in tsk_file_layout. TSK_DB_FILES_TYPE_UNUSED_BLOCKS, ///< Set of blocks that are unallocated AND not used by a carved or other file type. Parent should be UNALLOC_BLOCKS, many columns in tsk_files will be NULL, set layout in tsk_file_layout. TSK_DB_FILES_TYPE_VIRTUAL_DIR, ///< Virtual directory (not on fs) with no meta-data entry that can be used to group files of types other than TSK_DB_FILES_TYPE_FS. Its parent is either another TSK_DB_FILES_TYPE_FS or a root directory or type TSK_DB_FILES_TYPE_FS. + TSK_DB_FILES_TYPE_SLACK ///< Slack space for a single file } TSK_DB_FILES_TYPE_ENUM; -- GitLab