From 0c17063163fb8ea15a1b221be19f1fd27f51074b Mon Sep 17 00:00:00 2001 From: apriestman <apriestman@basistech.com> Date: Fri, 6 Mar 2020 12:41:47 -0500 Subject: [PATCH] Added unallocated pool blocks --- bindings/java/jni/auto_db_java.cpp | 161 +++++++++++++++++- bindings/java/jni/auto_db_java.h | 8 + .../org/sleuthkit/datamodel/JniDbHelper.java | 1 - .../sleuthkit/datamodel/SleuthkitCase.java | 2 +- 4 files changed, 162 insertions(+), 10 deletions(-) diff --git a/bindings/java/jni/auto_db_java.cpp b/bindings/java/jni/auto_db_java.cpp index 92da611ea..d58f323ab 100644 --- a/bindings/java/jni/auto_db_java.cpp +++ b/bindings/java/jni/auto_db_java.cpp @@ -1097,8 +1097,6 @@ TskAutoDbJava::findParObjId(const TSK_FS_FILE* fs_file, const char* parentPath, return -1; } - int64_t parObjId; - if (m_getParentIdMethodID == NULL) { printf("#### Yikes m_addFileSystemMethodID is null...\n"); return TSK_ERR; @@ -1117,7 +1115,64 @@ TskAutoDbJava::findParObjId(const TSK_FS_FILE* fs_file, const char* parentPath, return -1; } - return parObjId; + return objId; +} + +/** +* Adds a fake volume that will hold the unallocated blocks for the pool. +* +* @param vol_index The index for the new volume (should be one higher than the number of pool volumes) +* @param parObjId The object ID of the parent volume system +* @param objId Will be set to the object ID of the new volume +* +* @returns TSK_ERR on error, TSK_OK on success +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addUnallocatedPoolVolume(int vol_index, int64_t parObjId, int64_t& objId) +{ + + printf("addUnallocatedPoolVolume\n"); + fflush(stdout); + + if (m_addVolumeMethodID == NULL) { + printf("#### Yikes m_addVolumeMethodID is null...\n"); + return TSK_ERR; + } + + char *desc = "Unallocated Blocks"; + jstring descj = m_jniEnv->NewStringUTF(desc); // TODO free? + + jlong objIdj = m_jniEnv->CallLongMethod(m_javaDbObj, m_addVolumeMethodID, + parObjId, vol_index, 0, 0, + descj, 0); + objId = (int64_t)objIdj; + printf("New unalloc pool volume object ID: %lld\n", objId); + fflush(stdout); + + if (objId < 0) { + return TSK_ERR; + } + /* + char stmt[1024]; + + if (addObject(TSK_DB_OBJECT_TYPE_VOL, parObjId, objId)) + return 1; + + char *desc = "Unallocated Blocks"; + char *desc_sql = PQescapeLiteral(conn, desc, strlen(desc)); + + snprintf(stmt, 1024, + "INSERT INTO tsk_vs_parts (obj_id, addr, start, length, descr, flags)" + "VALUES (%lld, %" PRIuPNUM ",%d, %d, %s, %d)", + objId, vol_index, 0, 0, desc_sql, 0); + + if (attempt_exec(stmt, "Error adding data to tsk_vs_parts table: %s\n")) { + PQfreemem(desc_sql); + return TSK_ERR; + } + + PQfreemem(desc_sql);*/ + return TSK_OK; } @@ -1347,6 +1402,8 @@ TskAutoDbJava::filterPool(const TSK_POOL_INFO * pool_info) registerError(); return TSK_FILTER_STOP; } + // Save the parent obj ID for the pool + m_poolOffsetToParentId[pool_info->img_offset] = m_curVolId; } else { // pool doesn't live in a volume, use image as parent @@ -1354,13 +1411,86 @@ TskAutoDbJava::filterPool(const TSK_POOL_INFO * pool_info) registerError(); return TSK_FILTER_STOP; } + // Save the parent obj ID for the pool + m_poolOffsetToParentId[pool_info->img_offset] = m_curImgId; } - + // Store the volume system object ID for later use + m_poolOffsetToVsId[pool_info->img_offset] = m_curPoolVs; return TSK_FILTER_CONT; } +/** +* Adds unallocated pool blocks to a new volume. +* +* @param numPool Will be updated with the number of pools processed +* +* @return Returns 0 for success, 1 for failure +*/ +TSK_RETVAL_ENUM +TskAutoDbJava::addUnallocatedPoolBlocksToDb(size_t & numPool) { + + for (int i = 0; i < m_poolInfos.size(); i++) { + const TSK_POOL_INFO * pool_info = m_poolInfos[i]; + if (m_poolOffsetToVsId.find(pool_info->img_offset) == m_poolOffsetToVsId.end()) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - could not find volume system object ID for pool at offset %lld", pool_info->img_offset); + return TSK_ERR; + } + int64_t curPoolVs = m_poolOffsetToVsId[pool_info->img_offset]; + + /* Make sure the pool_info is still allocated */ + if (pool_info->tag != TSK_POOL_INFO_TAG) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - pool_info is not allocated"); + return TSK_ERR; + } + + /* Only APFS pools are currently supported */ + if (pool_info->ctype != TSK_POOL_TYPE_APFS) { + continue; + } + + /* Increment the count of pools found */ + numPool++; + + /* Create the volume */ + int64_t unallocVolObjId; + if (TSK_ERR == addUnallocatedPoolVolume(pool_info->num_vols, curPoolVs, unallocVolObjId)) { + tsk_error_reset(); + tsk_error_set_errno(TSK_ERR_AUTO_DB); + tsk_error_set_errstr("Error addUnallocatedPoolBlocksToDb() - error createing unallocated space pool volume"); + return TSK_ERR; + } + + /* Create the unallocated space files */ + TSK_FS_ATTR_RUN * unalloc_runs = tsk_pool_unallocated_runs(pool_info); + TSK_FS_ATTR_RUN * current_run = unalloc_runs; + vector<TSK_DB_FILE_LAYOUT_RANGE> ranges; + while (current_run != NULL) { + + TSK_DB_FILE_LAYOUT_RANGE tempRange(current_run->addr * pool_info->block_size, current_run->len * pool_info->block_size, 0); + + ranges.push_back(tempRange); + int64_t fileObjId = 0; + if (TSK_ERR == addUnallocBlockFile(unallocVolObjId, NULL, current_run->len * pool_info->block_size, ranges, fileObjId, m_curImgId)) { + registerError(); + tsk_fs_attr_run_free(unalloc_runs); + return TSK_ERR; + } + + current_run = current_run->next; + ranges.clear(); + } + tsk_fs_attr_run_free(unalloc_runs); + } + + return TSK_OK; +} + TSK_FILTER_ENUM TskAutoDbJava::filterPoolVol(const TSK_POOL_VOLUME_INFO * pool_vol) { @@ -1819,7 +1949,7 @@ TSK_WALK_RET_ENUM TskAutoDbJava::fsWalkUnallocBlocksCb(const TSK_FS_BLOCK *a_blo */ TSK_RETVAL_ENUM TskAutoDbJava::addFsInfoUnalloc(const TSK_DB_FS_INFO & dbFsInfo) { - // Unalloc space is not yet implemented for APFS + // Unalloc space is handled separately for APFS if (dbFsInfo.fType == TSK_FS_TYPE_APFS) { return TSK_OK; } @@ -1890,18 +2020,20 @@ TSK_RETVAL_ENUM TskAutoDbJava::addUnallocSpaceToDb() { size_t numVsP = 0; size_t numFs = 0; + size_t numPool = 0; TSK_RETVAL_ENUM retFsSpace = addUnallocFsSpaceToDb(numFs); TSK_RETVAL_ENUM retVsSpace = addUnallocVsSpaceToDb(numVsP); + TSK_RETVAL_ENUM retPoolSpace = addUnallocatedPoolBlocksToDb(numPool); - //handle case when no fs and no vs partitions + //handle case when no fs and no vs partitions and no pools TSK_RETVAL_ENUM retImgFile = TSK_OK; - if (numVsP == 0 && numFs == 0) { + if (numVsP == 0 && numFs == 0 && numPool == 0) { retImgFile = addUnallocImageSpaceToDb(); } - if (retFsSpace == TSK_ERR || retVsSpace == TSK_ERR || retImgFile == TSK_ERR) + if (retFsSpace == TSK_ERR || retVsSpace == TSK_ERR || retPoolSpace == TSK_ERR || retImgFile == TSK_ERR) return TSK_ERR; else return TSK_OK; @@ -1986,6 +2118,19 @@ TSK_RETVAL_ENUM TskAutoDbJava::addUnallocVsSpaceToDb(size_t & numVsP) { //skip processing this vspart continue; } + + // Check if the volume contains a pool + bool hasPool = false; + for (std::map<int64_t, int64_t>::iterator iter = m_poolOffsetToParentId.begin(); iter != m_poolOffsetToParentId.end(); ++iter) { + if (iter->second == vsPart.objId) { + hasPool = true; + } + } + if (hasPool) { + // Skip processing this vspart + continue; + } + } //end checking vspart flags //get sector size and image offset from parent vs info diff --git a/bindings/java/jni/auto_db_java.h b/bindings/java/jni/auto_db_java.h index 7657219e1..d981e88cc 100644 --- a/bindings/java/jni/auto_db_java.h +++ b/bindings/java/jni/auto_db_java.h @@ -140,6 +140,12 @@ class TskAutoDbJava :public TskAuto { bool m_foundStructure; ///< Set to true when we find either a volume or file system bool m_attributeAdded; ///< Set to true when an attribute was added by processAttributes + // These are used to write unallocated blocks for pools at the end of the add image + // process. We can't load the pool_info objects directly from the database so we will + // store info about them here. + std::map<int64_t, int64_t> m_poolOffsetToParentId; + std::map<int64_t, int64_t> m_poolOffsetToVsId; + // Used to look up object IDs for files #define MAX_PATH_LENGTH_JAVA_DB_LOOKUP 2048 char parent_name[MAX_PATH_LENGTH_JAVA_DB_LOOKUP]; @@ -200,6 +206,7 @@ class TskAutoDbJava :public TskAuto { virtual TSK_RETVAL_ENUM processAttribute(TSK_FS_FILE *, const TSK_FS_ATTR * fs_attr, const char *path); + TSK_RETVAL_ENUM addUnallocatedPoolBlocksToDb(size_t & numPool); static TSK_WALK_RET_ENUM fsWalkUnallocBlocksCb(const TSK_FS_BLOCK *a_block, void *a_ptr); TSK_RETVAL_ENUM addFsInfoUnalloc(const TSK_DB_FS_INFO & dbFsInfo); TSK_RETVAL_ENUM addUnallocFsSpaceToDb(size_t & numFs); @@ -236,6 +243,7 @@ class TskAutoDbJava :public TskAuto { vector<TSK_DB_FILE_LAYOUT_RANGE>& ranges, int64_t& objId, int64_t dataSourceObjId); TSK_RETVAL_ENUM addUnallocFsBlockFilesParent(const int64_t fsObjId, int64_t& objId, int64_t dataSourceObjId); + TSK_RETVAL_ENUM addUnallocatedPoolVolume(int vol_index, int64_t parObjId, int64_t& objId); }; diff --git a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java index 29913c361..65719eaea 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java +++ b/bindings/java/src/org/sleuthkit/datamodel/JniDbHelper.java @@ -219,5 +219,4 @@ long addUnallocFsBlockFilesParent(long fsObjId, String name) { return -1; } } - } diff --git a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java index a8e66aa4b..ef8488d71 100644 --- a/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java +++ b/bindings/java/src/org/sleuthkit/datamodel/SleuthkitCase.java @@ -6000,7 +6000,7 @@ public FileSystem addFileSystem(long parentObjId, long imgOffset, TskData.TSK_FS preparedStatement.clearParameters(); preparedStatement.setLong(1, newObjId); preparedStatement.setLong(2, imgOffset); - preparedStatement.setShort(3, (short) type.getValue()); + preparedStatement.setInt(3, type.getValue()); preparedStatement.setLong(4, blockSize); preparedStatement.setLong(5, blockCount); preparedStatement.setLong(6, rootInum); -- GitLab