From d021306413869e6c96da1db1e93e745417c82908 Mon Sep 17 00:00:00 2001 From: Brian Carrier <carrier@sleuthkit.org> Date: Mon, 2 Aug 2010 22:15:30 +0000 Subject: [PATCH] updated docs for automated tools and doxygen comments. --- tools/autotools/tsk_comparedir.cpp | 2 +- tsk3/auto/auto.cpp | 453 ++++++++++++++++------------- tsk3/auto/auto_db.cpp | 36 ++- tsk3/auto/tsk_auto.h | 66 ++++- tsk3/docs/Doxyfile | 14 +- tsk3/docs/auto.dox | 44 +++ tsk3/docs/base.dox | 2 +- tsk3/docs/basics.dox | 46 +-- tsk3/docs/hashdb.dox | 2 + tsk3/docs/main.dox | 3 + tsk3/fs/tsk_fs.h | 7 + tsk3/fs/tsk_fs_i.h | 6 - tsk3/libtsk.h | 1 + 13 files changed, 420 insertions(+), 262 deletions(-) create mode 100644 tsk3/docs/auto.dox diff --git a/tools/autotools/tsk_comparedir.cpp b/tools/autotools/tsk_comparedir.cpp index 54b5befdf..f5e844fdb 100644 --- a/tools/autotools/tsk_comparedir.cpp +++ b/tools/autotools/tsk_comparedir.cpp @@ -1,5 +1,5 @@ /* - ** tsk_loaddb + ** tsk_comparedir ** The Sleuth Kit ** ** Brian Carrier [carrier <at> sleuthkit [dot] org] diff --git a/tsk3/auto/auto.cpp b/tsk3/auto/auto.cpp index 092975ec6..ae01647ad 100644 --- a/tsk3/auto/auto.cpp +++ b/tsk3/auto/auto.cpp @@ -7,10 +7,17 @@ ** This software is distributed under the Common Public License 1.0 ** */ + +/** + * \file auto.cpp + * Contains C++ code that creates the base file extraction automation class. + */ + #include "tsk_auto.h" #include "tsk3/fs/tsk_fatfs.h" + TskAuto::TskAuto() { m_img_info = NULL; @@ -27,10 +34,50 @@ TskAuto::~TskAuto() } +/** + * Opens the disk image to be analyzed. This must be called before any + * of the findFilesInXXX() methods. + * + * @param a_numImg The number of images to open (will be > 1 for split images). + * @param a_images The path to the image files (the number of files must + * be equal to num_img and they must be in a sorted order) + * @param a_imgType The disk image type (can be autodetection) + * @param a_sSize Size of device sector in bytes (or 0 for default) + * @returns 1 on error, 0 on success + */ +uint8_t + TskAuto::openImage(int a_numImg, const TSK_TCHAR * const a_images[], + TSK_IMG_TYPE_ENUM a_imgType, unsigned int a_sSize) +{ + if (m_img_info) + closeImage(); + + m_img_info = tsk_img_open(a_numImg, a_images, a_imgType, a_sSize); + if (m_img_info) + return 0; + else + return 1; +} + + +/** + * Closes the handles to the open disk image. Should be called after + * you have completed analysis of the image. + */ +void + TskAuto::closeImage() +{ + if (m_img_info) { + tsk_img_close(m_img_info); + m_img_info = NULL; + } +} + /** * Set the attributes for the volumes that should be processed. - * The default settings are for Allocated volumes only. + * The default settings are for Allocated Non-Meta volumes only. + * This must be called before the findFilesInXX() method. * @param vs_flags Flags to use for filtering */ void @@ -42,7 +89,8 @@ void /** * Set the attributes for the files that should be processed. - * The default settings are for all files. + * The default settings are for all files (allocated and deleted). + * This must be called before the findFilesInXX() method. * @param file_flags Flags to use for filtering */ void @@ -53,162 +101,174 @@ void /** - * File filter to ignore NTFS system files. - * - * @returns 1 if the file is an NTFS System file. + * Starts in sector 0 of the opened disk images and looks for a + * volume or file system. Will call processFile() on each file + * that is found. + * @return 1 on error, 0 on success */ -uint8_t - TskAuto::isNtfsSystemFiles(TSK_FS_FILE * a_fs_file, const char *a_path) +uint8_t TskAuto::findFilesInImg() { - if ((a_fs_file) && (a_fs_file->fs_info) - && (TSK_FS_TYPE_ISNTFS(a_fs_file->fs_info->ftype)) - && (a_fs_file->name) && (a_fs_file->name->name[0] == '$') - && (a_fs_file->name->meta_addr < 20)) + if (!m_img_info) { + // @@@ return 1; - else - return 0; -} - -/** - * File filter to ignore FAT system files. - * - * @returns 1 if the file is an FAT System file. - */ -uint8_t TskAuto::isFATSystemFiles(TSK_FS_FILE * a_fs_file) -{ - if ((a_fs_file) && (a_fs_file->fs_info) - && (TSK_FS_TYPE_ISFAT(a_fs_file->fs_info->ftype)) - && (a_fs_file->name->meta_addr == FATFS_MBRINO(a_fs_file->fs_info) - || a_fs_file->name->meta_addr == - FATFS_FAT1INO(a_fs_file->fs_info) - || a_fs_file->name->meta_addr == - FATFS_FAT2INO(a_fs_file->fs_info))) + } + if (findFilesInVs(0)) { + tsk_error_print(stderr); return 1; - else - return 0; + } + + return 0; } -/** - * File filter to ignore dot ("." and "..") directories. - * @returns 1 if the file is a dot directory +/** \internal + * Volume system walk callback function that will analyze + * each volume to find a file system. */ -uint8_t TskAuto::isDotDir(TSK_FS_FILE * a_fs_file, const char *a_path) +TSK_WALK_RET_ENUM + TskAuto::vsWalkCb(TSK_VS_INFO * a_vs_info, + const TSK_VS_PART_INFO * a_vs_part, void *a_ptr) { - if ((!a_fs_file) || (!a_fs_file->name) - || ((a_fs_file->name->flags & TSK_FS_NAME_TYPE_DIR) == 0)) - return 0; + TskAuto *tsk = (TskAuto *) a_ptr; + if (tsk->m_tag != TSK_AUTO_TAG) + return TSK_WALK_STOP; - if ((a_fs_file->name->name_size >= 2) - && (a_fs_file->name->name[0] == '.') - && ((a_fs_file->name->name[1] == '\0') - || ((a_fs_file->name->name_size > 2) - && (a_fs_file->name->name[1] == '.') - && (a_fs_file->name->name[2] == '\0')))) - return 1; - else - return 0; -} + TSK_FILTER_ENUM retval1 = tsk->filterVol(a_vs_part); + if (retval1 == TSK_FILTER_SKIP) + return TSK_WALK_CONT; + else if (retval1 == TSK_FILTER_STOP) + return TSK_WALK_STOP; -uint8_t TskAuto::isDir(TSK_FS_FILE * a_fs_file) -{ - if ((a_fs_file) && (a_fs_file->name) - && (a_fs_file->name->type == TSK_FS_NAME_TYPE_DIR)) - return 1; - else - return 0; -} + TSK_RETVAL_ENUM retval2 = + tsk->findFilesInFsRet(a_vs_part->start * + a_vs_part->vs->block_size); + if (retval2 == TSK_STOP) { + return TSK_WALK_STOP; + } + else if (retval2 != TSK_OK) { + // if we return ERROR here, then the walk will stop. But, the + // error could just be because we looked into an unallocated volume. + // do any special error handling / reporting here. + tsk_error_reset(); + } + return TSK_WALK_CONT; +} /** - * file name walk callback. Walk the contents of each file - * that is found. + * Starts in a specified sector of the opened disk images and looks for a + * volume or file system. Will call processFile() on each file + * that is found. + * @param a_start Byte offset to start analyzing from. + * @return 1 on error, 0 on success */ -TSK_WALK_RET_ENUM - TskAuto::dirWalkCb(TSK_FS_FILE * a_fs_file, const char *a_path, - void *a_ptr) +uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start) { - TskAuto *tsk = (TskAuto *) a_ptr; - if (tsk->m_tag != TSK_AUTO_TAG) - return TSK_WALK_STOP; + if (!m_img_info) { + // @@@ + return 1; + } - if (tsk->processFile(a_fs_file, a_path)) - return TSK_WALK_STOP; - else - return TSK_WALK_CONT; -} + TSK_VS_INFO * + vs_info; + // USE mm_walk to get the volumes + if ((vs_info = + tsk_vs_open(m_img_info, a_start, + TSK_VS_TYPE_DETECT)) == NULL) { + if (tsk_verbose) + fprintf(stderr, + "Error determining volume system -- trying file systems\n"); + /* There was no volume system, but there could be a file system */ + tsk_error_reset(); + if (findFilesInFs(a_start)) { + return 1; + } + } + else { + /* Walk the allocated volumes (skip metadata and unallocated volumes) */ + if (tsk_vs_part_walk(vs_info, 0, vs_info->part_count - 1, + m_volFilterFlags, vsWalkCb, this)) { + tsk_vs_close(vs_info); + return 1; + } + tsk_vs_close(vs_info); + } + return 0; +} -/** - * Analyze the volume starting at byte offset 'start' - * and walk each file that can be found. This will - * start at the root directory of the file system. - * - * @param a_start Byte offset of file system starting location. - * +/** + * Starts in a specified sector of the opened disk images and looks for a + * file system. Will call processFile() on each file + * that is found. + * @param a_start Byte offset to start analyzing from. * @returns values that allow the caller to differentiate stop from ok. */ - -TSK_RETVAL_ENUM -TskAuto::findFilesInFsRet(TSK_OFF_T a_start){ +TSK_RETVAL_ENUM TskAuto::findFilesInFsRet(TSK_OFF_T a_start) +{ if (!m_img_info) { // @@@ return TSK_ERR; } - - TSK_FS_INFO *fs_info; + + TSK_FS_INFO * + fs_info; /* Try it as a file system */ if ((fs_info = - tsk_fs_open_img(m_img_info, a_start, - TSK_FS_TYPE_DETECT)) == NULL) { - tsk_error_print(stderr); - - /* We could do some carving on the volume data at this point */ - - return TSK_ERR; + tsk_fs_open_img(m_img_info, a_start, + TSK_FS_TYPE_DETECT)) == NULL) { + tsk_error_print(stderr); + + /* We could do some carving on the volume data at this point */ + + return TSK_ERR; } - TSK_RETVAL_ENUM retval = findFilesInFsInt(fs_info, fs_info->root_inum); + TSK_RETVAL_ENUM + retval = findFilesInFsInt(fs_info, fs_info->root_inum); tsk_fs_close(fs_info); return retval; } /** - * Analyze the volume starting at byte offset 'start' - * and walk each file that can be found. This will - * start at the root directory of the file system. + * Starts in a specified sector of the opened disk images and looks for a + * file system. Will call processFile() on each file + * that is found. * * @param a_start Byte offset of file system starting location. * * @returns 1 on error and 0 on success */ -uint8_t -TskAuto::findFilesInFs(TSK_OFF_T a_start) { +uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start) +{ if (findFilesInFsRet(a_start) == TSK_ERR) return 1; - else + else return 0; } /** - * Analyze the volume starting at byte offset 'start' - * and walk each file that can be found. + * Starts in a specified sector of the opened disk images and looks for a + * file system. Will start processing the file system at a specified + * file system. Will call processFile() on each file + * that is found in that directory. * * @param a_start Byte offset of file system starting location. - * @param inum inum to start walking files system at - * @ returns 1 on error, 0 on success + * @param a_inum inum to start walking files system at + * + * @returns 1 on error and 0 on success */ -uint8_t -TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_INUM_T a_inum) +uint8_t TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_INUM_T a_inum) { if (!m_img_info) { // @@@ return 1; } - TSK_FS_INFO *fs_info; + TSK_FS_INFO * + fs_info; /* Try it as a file system */ if ((fs_info = tsk_fs_open_img(m_img_info, a_start, @@ -219,25 +279,46 @@ TskAuto::findFilesInFs(TSK_OFF_T a_start, TSK_INUM_T a_inum) return 1; } - TSK_RETVAL_ENUM retval = findFilesInFsInt(fs_info, a_inum); + TSK_RETVAL_ENUM + retval = findFilesInFsInt(fs_info, a_inum); tsk_fs_close(fs_info); if (retval == TSK_ERR) return 1; - else + else return 0; } + +/** \internal + * file name walk callback. Walk the contents of each file + * that is found. + */ +TSK_WALK_RET_ENUM + TskAuto::dirWalkCb(TSK_FS_FILE * a_fs_file, const char *a_path, + void *a_ptr) +{ + TskAuto *tsk = (TskAuto *) a_ptr; + if (tsk->m_tag != TSK_AUTO_TAG) + return TSK_WALK_STOP; + + if (tsk->processFile(a_fs_file, a_path)) + return TSK_WALK_STOP; + else + return TSK_WALK_CONT; +} + + /* Internal method that the other findFilesInFs can call after they * have opened FS_INFO. */ -TSK_RETVAL_ENUM -TskAuto::findFilesInFsInt(TSK_FS_INFO *a_fs_info, TSK_INUM_T a_inum) +TSK_RETVAL_ENUM + TskAuto::findFilesInFsInt(TSK_FS_INFO * a_fs_info, TSK_INUM_T a_inum) { TSK_FILTER_ENUM retval = filterFs(a_fs_info); if (retval == TSK_FILTER_STOP) return TSK_STOP; else if (retval == TSK_FILTER_SKIP) - return TSK_OK; + return TSK_OK; /* Walk the files, starting at the given inum */ if (tsk_fs_dir_walk(a_fs_info, a_inum, @@ -254,120 +335,88 @@ TskAuto::findFilesInFsInt(TSK_FS_INFO *a_fs_info, TSK_INUM_T a_inum) /** - * Volume system walk callback function that will analyze - * each volume to find a file system. + * Utility method to help determine if a file is an NTFS file system file (such as $MFT). + * + * @returns 1 if the file is an NTFS System file, 0 if not. */ - -TSK_WALK_RET_ENUM - TskAuto::vsWalkCb(TSK_VS_INFO * a_vs_info, - const TSK_VS_PART_INFO * a_vs_part, void *a_ptr) +uint8_t + TskAuto::isNtfsSystemFiles(TSK_FS_FILE * a_fs_file, const char *a_path) { - TskAuto *tsk = (TskAuto *) a_ptr; - if (tsk->m_tag != TSK_AUTO_TAG) - return TSK_WALK_STOP; - - TSK_FILTER_ENUM retval1 = tsk->filterVol(a_vs_part); - if (retval1 == TSK_FILTER_SKIP) - return TSK_WALK_CONT; - else if (retval1 == TSK_FILTER_STOP) - return TSK_WALK_STOP; - - TSK_RETVAL_ENUM retval2 = tsk->findFilesInFsRet(a_vs_part->start * a_vs_part->vs->block_size); - if (retval2 == TSK_STOP) { - return TSK_WALK_STOP; - } - else if (retval2 != TSK_OK) { - // if we return ERROR here, then the walk will stop. But, the - // error could just be because we looked into an unallocated volume. - // do any special error handling / reporting here. - tsk_error_reset(); - } - - return TSK_WALK_CONT; + if ((a_fs_file) && (a_fs_file->fs_info) + && (TSK_FS_TYPE_ISNTFS(a_fs_file->fs_info->ftype)) + && (a_fs_file->name) && (a_fs_file->name->name[0] == '$') + && (a_fs_file->name->meta_addr < 20)) + return 1; + else + return 0; } - /** - * Process the data as a volume system to find the partitions - * and volumes. - * File system analysis will be performed on each partition. + * Utility method to help determine if a file is a FAT file system file (such as $MBR). * - * @param a_start Byte offset to start analyzing from. - * - * @return 1 on error and 0 on success + * @returns 1 if the file is an FAT System file, 0 if not. */ -uint8_t -TskAuto::findFilesInVs(TSK_OFF_T a_start) +uint8_t TskAuto::isFATSystemFiles(TSK_FS_FILE * a_fs_file) { - if (!m_img_info) { - // @@@ + if ((a_fs_file) && (a_fs_file->fs_info) + && (TSK_FS_TYPE_ISFAT(a_fs_file->fs_info->ftype)) + && (a_fs_file->name->meta_addr == FATFS_MBRINO(a_fs_file->fs_info) + || a_fs_file->name->meta_addr == + FATFS_FAT1INO(a_fs_file->fs_info) + || a_fs_file->name->meta_addr == + FATFS_FAT2INO(a_fs_file->fs_info))) return 1; - } - - TSK_VS_INFO *vs_info; - // USE mm_walk to get the volumes - if ((vs_info = - tsk_vs_open(m_img_info, a_start, - TSK_VS_TYPE_DETECT)) == NULL) { - if (tsk_verbose) - fprintf(stderr, - "Error determining volume system -- trying file systems\n"); - - /* There was no volume system, but there could be a file system */ - tsk_error_reset(); - if (findFilesInFs(a_start)) { - return 1; - } - } - else { - /* Walk the allocated volumes (skip metadata and unallocated volumes) */ - if (tsk_vs_part_walk(vs_info, 0, vs_info->part_count - 1, - m_volFilterFlags, vsWalkCb, this)) { - tsk_vs_close(vs_info); - return 1; - } - tsk_vs_close(vs_info); - } - return 0; + else + return 0; } -uint8_t -TskAuto::findFilesInImg() +/** + * Utility method to help determine if a file is a . or .. directory. + * + * @returns 1 if the file is a dot directory, 0 if not. + */ +uint8_t TskAuto::isDotDir(TSK_FS_FILE * a_fs_file, const char *a_path) { - if (!m_img_info) { - // @@@ - return 1; - } - if (findFilesInVs(0)) { - tsk_error_print(stderr); - return 1; - } + if ((!a_fs_file) || (!a_fs_file->name) + || ((a_fs_file->name->flags & TSK_FS_NAME_TYPE_DIR) == 0)) + return 0; - return 0; + if ((a_fs_file->name->name_size >= 2) + && (a_fs_file->name->name[0] == '.') + && ((a_fs_file->name->name[1] == '\0') + || ((a_fs_file->name->name_size > 2) + && (a_fs_file->name->name[1] == '.') + && (a_fs_file->name->name[2] == '\0')))) + return 1; + else + return 0; } - - -uint8_t - TskAuto::openImage(int a_numImg, const TSK_TCHAR * const a_images[], - TSK_IMG_TYPE_ENUM a_imgType, unsigned int a_sSize) +/** + * Utility method to help determine if a file is a directory. + * + * @returns 1 if the file is a directory, 0 if not. + */ +uint8_t TskAuto::isDir(TSK_FS_FILE * a_fs_file) { - if (m_img_info) - closeImage(); - - m_img_info = tsk_img_open(a_numImg, a_images, a_imgType, a_sSize); - if (m_img_info) - return 0; - else + if ((a_fs_file) && (a_fs_file->name) + && (a_fs_file->name->type == TSK_FS_NAME_TYPE_DIR)) return 1; + else + return 0; } -void -TskAuto::closeImage() +/** + * Utility method to help determine if a file is a file (and not a directory). + * + * @returns 1 if the file is a file, 0 if not. + */ +uint8_t TskAuto::isFile(TSK_FS_FILE * a_fs_file) { - if (m_img_info) { - tsk_img_close(m_img_info); - m_img_info = NULL; - } + if ((a_fs_file) && (a_fs_file->name) + && (a_fs_file->name->type == TSK_FS_NAME_TYPE_REG)) + return 1; + else + return 0; } diff --git a/tsk3/auto/auto_db.cpp b/tsk3/auto/auto_db.cpp index fcab95dfd..ae1d8101a 100644 --- a/tsk3/auto/auto_db.cpp +++ b/tsk3/auto/auto_db.cpp @@ -7,6 +7,12 @@ ** This software is distributed under the Common Public License 1.0 ** */ + +/** + * \file auto_db.cpp + * Contains code to populate SQLite database with volume and file system information. + */ + #include "tsk_auto.h" #include "sqlite3.h" @@ -197,12 +203,12 @@ void } -TSK_FILTER_ENUM -TskAutoDb::filterVol(const TSK_VS_PART_INFO * vs_part) +TSK_FILTER_ENUM TskAutoDb::filterVol(const TSK_VS_PART_INFO * vs_part) { char foo[1024]; - char *errmsg; + char * + errmsg; snprintf(foo, 1024, "INSERT INTO tsk_vol_info (vol_id, start, length, desc, flags) VALUES (%d,%" @@ -222,12 +228,12 @@ TskAutoDb::filterVol(const TSK_VS_PART_INFO * vs_part) } -TSK_FILTER_ENUM -TskAutoDb::filterFs(TSK_FS_INFO * fs_info) +TSK_FILTER_ENUM TskAutoDb::filterFs(TSK_FS_INFO * fs_info) { char foo[1024]; - char *errmsg; + char * + errmsg; m_curFsId++; @@ -255,12 +261,12 @@ TskAutoDb::filterFs(TSK_FS_INFO * fs_info) } -uint8_t -TskAutoDb::processFile(TSK_FS_FILE * fs_file, const char *path) +uint8_t TskAutoDb::processFile(TSK_FS_FILE * fs_file, const char *path) { char foo[1024]; - char *errmsg; + char * + errmsg; int mtime = 0; int @@ -269,16 +275,20 @@ TskAutoDb::processFile(TSK_FS_FILE * fs_file, const char *path) ctime = 0; int atime = 0; - TSK_OFF_T size = 0; + TSK_OFF_T + size = 0; int meta_type = 0; int meta_flags = 0; int meta_mode = 0; - int gid = 0; - int uid = 0; - TSK_INUM_T par_inode; + int + gid = 0; + int + uid = 0; + TSK_INUM_T + par_inode; if (fs_file->name == NULL) return 0; diff --git a/tsk3/auto/tsk_auto.h b/tsk3/auto/tsk_auto.h index aad464a9f..0900e7d8f 100644 --- a/tsk3/auto/tsk_auto.h +++ b/tsk3/auto/tsk_auto.h @@ -1,5 +1,4 @@ /* - ** tsk_recover ** The Sleuth Kit ** ** Brian Carrier [carrier <at> sleuthkit [dot] org] @@ -9,16 +8,27 @@ ** */ +/** + * \file tsk_auto.h + * Contains the class definitions for the automated file extraction classes. + * Note that this file is not meant to be directly included. + * It is included by libtsk.h. + */ + +/** + * \defgroup autolib File Extraction Automation Functionality + */ + #ifndef _TSK_AUTO_H #define _TSK_AUTO_H #ifdef __cplusplus -// Include the other internal TSK header files -#include "tsk3/base/tsk_base_i.h" -#include "tsk3/img/tsk_img_i.h" -#include "tsk3/vs/tsk_vs_i.h" -#include "tsk3/fs/tsk_fs_i.h" +// Include the other TSK header files +#include "tsk3/base/tsk_base.h" +#include "tsk3/img/tsk_img.h" +#include "tsk3/vs/tsk_vs.h" +#include "tsk3/fs/tsk_fs.h" #include <map> #include <string> @@ -26,15 +36,28 @@ typedef enum { - TSK_FILTER_CONT = 0x00, ///< Framework should continue to process this object - TSK_FILTER_STOP = 0x01, ///< Framework should stop processing the image - TSK_FILTER_SKIP = 0x02, ///< Framework should skip this object and go on to the next + TSK_FILTER_CONT = 0x00, ///< Framework should continue to process this object + TSK_FILTER_STOP = 0x01, ///< Framework should stop processing the image + TSK_FILTER_SKIP = 0x02, ///< Framework should skip this object and go on to the next } TSK_FILTER_ENUM; +/** \ingroup autolib + * C++ class that automatically analyzes a disk image to extract files from it. This class + * hides many of the details that are required to use lower-level TSK APIs to analyze volume + * and file systems. + * + * The processFile() method must be implemented and it will be called for each file and + * directory that is found. + * + * An image file must be first opened using openImage(). It can then be analyzed using one + * of the findFilesInXXXX() methods. The filterXX() methods can be used to skip volumes + * and file systems. + */ class TskAuto { public: unsigned int m_tag; + TskAuto(); virtual ~ TskAuto(); @@ -52,7 +75,11 @@ class TskAuto { void setVolFilterFlags(TSK_VS_PART_FLAG_ENUM); /** - * Gets called for each partition that is found in a volume system. + * TskAuto calls this method before it processes each volume that is found in a + * volume system. You can use this to learn about each volume before it is processed + * and you can force TskAuto to skip this volume. The setvolFilterFlags() method can be + * used to configure if TskAuto should process unallocated space. + * * @param vs_part Parition details * @returns Value to show if volume should be processed, skipped, or process should stop. */ @@ -61,7 +88,9 @@ class TskAuto { }; /** - * Gets called for each file system that is found. + * TskAuto calls this method before it processes each file system that is found in a + * volume. You can use this to learn about each file system before it is processed + * and you can force TskAuto to skip this file system. * @param fs_info file system details * @returns Value to show if FS should be processed, skipped, or process should stop. */ @@ -70,8 +99,10 @@ class TskAuto { }; /** - * Gets called for each file that is found during search. This is where the subclass should - * process file content using other TSK methods. + * TskAuto calls this method for each file and directory that it finds in an image. + * The setFileFilterFlags() method can be used to set the criteria for what types of + * files this should be called for. There are several methods, such as isDir() that + * can be used by this method to help focus in on the files that you care about. * * @param fs_file file details * @param path full path of parent directory @@ -88,9 +119,8 @@ class TskAuto { const char *path, void *ptr); static TSK_WALK_RET_ENUM vsWalkCb(TSK_VS_INFO * vs_info, const TSK_VS_PART_INFO * vs_part, void *ptr); - + TSK_RETVAL_ENUM findFilesInFsInt(TSK_FS_INFO *, TSK_INUM_T inum); - protected: @@ -99,10 +129,15 @@ class TskAuto { uint8_t isFATSystemFiles(TSK_FS_FILE * fs_file); uint8_t isDotDir(TSK_FS_FILE * fs_file, const char *path); uint8_t isDir(TSK_FS_FILE * fs_file); + uint8_t isFile(TSK_FS_FILE * fs_file); }; + typedef struct sqlite3 sqlite3; +/** \internal + * C++ class that implements TskAuto to load file metadata into a SQLite database. + */ class TskAutoDb:public TskAuto { public: TskAutoDb(); @@ -114,6 +149,7 @@ class TskAutoDb:public TskAuto { virtual TSK_FILTER_ENUM filterVol(const TSK_VS_PART_INFO * vs_part); virtual TSK_FILTER_ENUM filterFs(TSK_FS_INFO * fs_info); virtual uint8_t processFile(TSK_FS_FILE * fs_file, const char *path); + private: sqlite3 * m_db; int m_curFsId; diff --git a/tsk3/docs/Doxyfile b/tsk3/docs/Doxyfile index 4e18c9047..e0655bc39 100644 --- a/tsk3/docs/Doxyfile +++ b/tsk3/docs/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = "The Sleuth Kit" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 3.0 +PROJECT_NUMBER = 3.2 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. @@ -186,7 +186,7 @@ ALIASES = # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. -OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for @@ -571,11 +571,13 @@ INPUT = tsk3/docs/main.dox \ tsk3/docs/vs.dox \ tsk3/docs/fs.dox \ tsk3/docs/hashdb.dox \ + tsk3/docs/auto.dox \ tsk3/base \ tsk3/fs \ tsk3/hashdb \ tsk3/img \ - tsk3/vs + tsk3/vs \ + tsk3/auto # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is @@ -592,7 +594,7 @@ INPUT_ENCODING = UTF-8 # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 -FILE_PATTERNS = *.c \ +FILE_PATTERNS = *.c *.cpp \ *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories @@ -619,7 +621,7 @@ EXCLUDE_SYMLINKS = NO # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */auto/sqlite3* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -1260,7 +1262,7 @@ INCLUDE_FILE_PATTERNS = # undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = __cplusplus # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. diff --git a/tsk3/docs/auto.dox b/tsk3/docs/auto.dox new file mode 100644 index 000000000..b9481cff3 --- /dev/null +++ b/tsk3/docs/auto.dox @@ -0,0 +1,44 @@ +/*! \page autopage File Extraction Automation + +This section describes the TskAuto C++ superclass that can be used to easily build automated applications that analyze a disk image and extract files from it. + +\section auto_over Overview + +The TSK API described in the previous sections of this User's Guide allows you to manually open a volume or file system and browse its contents to look at volumes and files. While this fine grained access is useful in some situations, there are others where you simply want to rip apart a disk image and see all of the files without worrying about how you get the files. + +The TskAuto class was designed to help in these situations. It is a C++ superclass that knows how to analyze a disk image. All you need to do is implement the TskAuto::processFile() method, which will get called for each file. Other methods in the class can also be implemented to get more details about the data being analyzed. + +\section auto_basics Basics + +To use TskAuto, you first need to create a C++ subclass of it and implement the TskAuto::processFile() method. The instructions in \ref basic_build will provide access to this class. + +To use your new TskAuto-based class, you must first open the disk images. This can be done with TskAuto::openImage(). Once you are done with the object, it should be closed with TskAuto::closeImage(). These methods have been defined as virtual so that you can override them if your class needs access to the list of image names (for a report, for example). + +To start the analysis after the image files have been opened, you must call either TskAuto::findFilesInImg(), TskAuto::findFilesInVs(), or TskAuto::findFilesInFs(). TskAuto::findFilesInImg() starts at sector 0 of the disk image and starts to analyze it. It looks for a volume system and, if it finds one, will examine the contents of each volume. If it doesn't find a volume system, it will assume that the image is of a volume and will analyze sector 0 as a file system. + +TskAuto::findFilesInVs() allows you to specify the sector offset where the volume system is located. It does the same analysis as TskAuto::findFilesInImg(), except that it doesn't always start in sector 0. In fact, TskAuto::findFilesInImg() simply calls TskAuto::findFilesInVs() with a starting offset of 0. + +TskAuto::findFilesInFs() allows you to specify the offset of a file system to process. This method will not look for a volume system, only a file system. Internally, this method is called from TskAuto::findFilesInVs() after a volume has been found. There is also a version that allows you to specify the directory start processing from. + +Regardless of the method that you use to start the processing, the TskAuto::processFile() method will be called for each file and directory that is found. You can specify if this method should be called for only allocated or unallocated files using the TskAuto::setFileFilterFlags() method. You can also specify what types of volumes to process by using the TskAuto::setVolFilterFlags() method. + +Inside of your TskAuto::processFile() method, you can read the contents of the file using either tsk_fs_file_read() or tsk_fs_file_walk(). + +\section auto_filter Filtering Results + +With the methods defined above, TskAuto::processFile() will get called for all files and directories in an image. This maybe more files than you want though. There are two methods that will alert you when TskAuto is about to process a new volume or file system and will allow you to not process the volume or file system. + +You can implement the TskAuto::filterVol() method to learn about each volume before it is processed. The return value of this method can cause TskAuto to skip the volume or stop processing the disk image entirely. + +You can implement the TskAuto::filterFs() method to learn about each file system before it is processed. The return value of this method can cause TskAuto to skip the file system or stop processing the disk image entirely. + +There are also a series of protected methods in TskAuto that will help you to skip files that may not be relevant to you. For example, TskAuto::isNtfsSystemFiles() will tell you if a file is one of the NTFS file system files (such as $MFT) that you may want to skip. You can use this method in TskAuto::processFile() to skip the big NTFS files. Refer to the protected methods in TskAuto for others that are defined for this purpose (they all begin with "is"). + + +\section auto_examples Examples + +Refer to the source code in the tools/autotools directory of the distribution for examples of TskAuto-based classes. Files in this directory all use TskAuto to do things like recover deleted files or load data into a SQLite database. + +Back to \ref users_guide "Table of Contents" + +*/ diff --git a/tsk3/docs/base.dox b/tsk3/docs/base.dox index e5e55475e..fb890935e 100644 --- a/tsk3/docs/base.dox +++ b/tsk3/docs/base.dox @@ -39,7 +39,7 @@ The TSK_STACK structure is used to prevent infinite loops when recursing into di The TSK library includes support to calculate MD5 and SHA-1 hashes. To calculate the MD5 hash, a context must be first initialized with TSK_MD5_Init(). Data is added to the context with TSK_MD5_Update() and the hash is calculated with a call to TSK_MD5_Final(). A similar process is used for SHA-1 hashes using TSK_SHA_Init(), TSK_SHA_Update(), and TSK_SHA_Final(). \section basic_version Version -To get the version number of the TSK library, you can all the tsk_version_get_str() function to get a string representation. Or, you can call tsk_version_print() to print the library name and version to a FILE handle. +To get the version number of the TSK library as a string, you can all the tsk_version_get_str() function to get a string representation. Or, you can call tsk_version_print() to print the library name and version to a FILE handle. There are also \#defines for the version as a string (in TSK_VERSION_STR) and as a number (in TSK_VERSION_NUM). Next to \ref imgpage diff --git a/tsk3/docs/basics.dox b/tsk3/docs/basics.dox index 1310b4ce4..e316879af 100644 --- a/tsk3/docs/basics.dox +++ b/tsk3/docs/basics.dox @@ -16,27 +16,37 @@ The next layer up is the <b>File System Layer</b>. This layer focuses on proces There is an independent <b>Hash Database Layer</b> that handles hash databases, such as NSRL and md5sum outputs. This API allows you to create an index of hashes and perform fast lookups of them. These functions do not depend on the Disk Image, Volume System, or File System Layers. +There is also an <b>Automation Layer</b> that integrates all of the previous layers in an automated fashion. It defines a C++ class named TskAuto that hides a lot of the details about analyzing file and volume systems. + A basic diagram of the relationship between these layers is shown here. Note that if a disk image file does not have a volume system, then we can use the File System Layer functions directly on it. <pre> - +================+ - | Base | - +================+ - / \ - / \ - +==============+ +==================+ - | Disk Image | | Hash Database | - +==============+ +==================+ - / | - / | - +===============+ | - | Volume System | | - +===============+ | - \ | - \ | - +===============+ - | File System | - +===============+ + + +==========================================================+ + | | + | +================+ | + | | Base | | + | +================+ | + | / \ | + | / \ | + | +==============+ +==================+ | + | | Disk Image | | Hash Database | | + | +==============+ +==================+ | + | / | | + | / | | + | +===============+ | | + | | Volume System | | | + | +===============+ | | + | \ | | + | \ | | + | +===============+ | + | | File System | | + | +===============+ | + | | + | | + | Automation | + +==========================================================+ + </pre> diff --git a/tsk3/docs/hashdb.dox b/tsk3/docs/hashdb.dox index 3ed32a28a..7af164978 100644 --- a/tsk3/docs/hashdb.dox +++ b/tsk3/docs/hashdb.dox @@ -23,5 +23,7 @@ An indexed database can be searched using either tsk_hdb_lookup_raw() or tsk_hdb Both functions can call a callback with details of entries that are found, or the QUICK flag can be given in which case the callback is not called and instead the return value of the function identifies if the hash is in the database or not. +Next to \ref autopage + Back to \ref users_guide "Table of Contents" */ diff --git a/tsk3/docs/main.dox b/tsk3/docs/main.dox index d19e0ff83..47872545c 100644 --- a/tsk3/docs/main.dox +++ b/tsk3/docs/main.dox @@ -16,6 +16,7 @@ The User's Guide describes the various components of TSK and how to use them. I - \subpage vspage - \subpage fspage - \subpage hashdbpage + - \subpage autopage <h3>API Reference</h3> The API Reference lists the public API functions and the arguments and return values. The Users's Guide should be read first so that the interaction and use of the functions are understood. These pages can also be found in the <a href="modules.html">Modules</a> section. @@ -24,5 +25,7 @@ The API Reference lists the public API functions and the arguments and return va - \ref vslib - \ref fslib - \ref hashdblib + - \ref autolib + */ diff --git a/tsk3/fs/tsk_fs.h b/tsk3/fs/tsk_fs.h index f13e59e97..d5c57ce08 100644 --- a/tsk3/fs/tsk_fs.h +++ b/tsk3/fs/tsk_fs.h @@ -463,6 +463,13 @@ extern "C" { * name is known, but the parent is not */ #define TSK_FS_ORPHAN_STR "-ORPHAN_FILE-" + /* we are using the last inode as the special inode for the orphan directory. Note that this + * macro is defined to abstract this convention, but there are many places in the code where + * there is implied logic about this convention. For example, inode_walks will stop before + * this value so that special handling can occur. */ +#define TSK_FS_ORPHANDIR_INUM(fs_info) \ +(fs_info->last_inum) + /** * inode walk callback function definition. This is called for every file diff --git a/tsk3/fs/tsk_fs_i.h b/tsk3/fs/tsk_fs_i.h index ce1010370..513fd4207 100644 --- a/tsk3/fs/tsk_fs_i.h +++ b/tsk3/fs/tsk_fs_i.h @@ -151,12 +151,6 @@ extern "C" { TSK_FS_NAME * a_fs_name); extern TSK_RETVAL_ENUM tsk_fs_dir_find_orphans(TSK_FS_INFO * a_fs, TSK_FS_DIR * a_fs_dir); - /* we are using the last inode as the special inode for the orphan directory. Note that this - * macro is defined to abstract this convention, but there are many places in the code where - * there is implied logic about this convention. For example, inode_walks will stop before - * this value so that special handling can occur. */ -#define TSK_FS_ORPHANDIR_INUM(fs_info) \ - (fs_info->last_inum) diff --git a/tsk3/libtsk.h b/tsk3/libtsk.h index 9dfdd091e..7e481924c 100644 --- a/tsk3/libtsk.h +++ b/tsk3/libtsk.h @@ -6,5 +6,6 @@ #include "tsk3/vs/tsk_vs.h" #include "tsk3/fs/tsk_fs.h" #include "tsk3/hashdb/tsk_hashdb.h" +#include "tsk3/auto/tsk_auto.h" #endif -- GitLab