示例#1
0
/* Deterine if a symlink should be hashed or not.
 * Returns TRUE if a symlink should be hashed.
 */
bool state::should_hash_symlink(const tstring &fn, file_types *link_type)
{
    /**
     * We must look at what this symlink points to before we process it.
     * The file_type() function uses lstat to examine the file.
     * Here we use the normal stat to examine what this symlink points to.
     */

    struct __stat64 sb;

    if (TSTAT(fn.c_str(),&sb))  {
	ocb.error_filename(fn,"%s",strerror(errno));
	return false;
    }

    file_types type = file_metadata_t::decode_file_type(sb);

    if (type == stat_directory)  {
	if (mode_recursive){
	    process_dir(fn);
	} else {
	    ocb.error_filename(fn,"Is a directory");
	}
	return false;
    }    

    if (link_type) *link_type = type;
    return true;    
}
示例#2
0
/**
* Opens a case from an existing database.
*
* @param path Full path to open database from.
*/
TskCaseDb *
TskCaseDb::openDb(const TSK_TCHAR * path)
{

    // Confirm that database already exsists
    struct STAT_STR stat_buf;
    if (TSTAT(path, &stat_buf) != 0) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_AUTO_DB);
        tsk_error_set_errstr("Database %" PRIttocTSK
            " does not exist.  Must be created first.", path);
        return NULL;
    }

    TskDbSqlite *db = new TskDbSqlite(path, true);

    // Open the database.
    if (db->open(false))
        return NULL;

    return new TskCaseDb(db);
}
示例#3
0
/**
* Creates a new case with a new database and initializes its tables.
* Fails if there's already a file at the given path. Returns a pointer
* to a new TskCaseDb if successful, else NULL.
*
* @param path Full path to create new database at.
*/
TskCaseDb *
TskCaseDb::newDb(const TSK_TCHAR * const path)
{

    // Check if the database already exsists
    struct STAT_STR stat_buf;
    if (TSTAT(path, &stat_buf) == 0) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_AUTO_DB);
        tsk_error_set_errstr("Database %" PRIttocTSK
            " already exists.  Must be deleted first.", path);
        return NULL;
    }

    TskDbSqlite *db = new TskDbSqlite(path, true);

    // Open the database.
    if (db->open(true))
        return NULL;

    return new TskCaseDb(db);
}
示例#4
0
/**
 * \ingroup imglib
 * Opens one or more disk image files so that they can be read.  If a file format
 * type is specified, this function will call the specific routine to open the file.
 * Otherwise, it will detect the type (it will default to raw if no specific type can
 * be detected).   This function must be called before a disk image can be read from. 
 * Note that the data type used to store the image paths is a TSK_TCHAR, which changes
 * depending on a Unix or Windows build.  If you will always have UTF8, then consider
 * using tsk_img_open_utf8(). 
 *
 * @param num_img The number of images to open (will be > 1 for split images).
 * @param 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 type The disk image type (can be autodetection)
 * @param a_ssize Size of device sector in bytes (or 0 for default)
 *
 * @return Pointer to TSK_IMG_INFO or NULL on error
 */
TSK_IMG_INFO *
tsk_img_open(int num_img,
    const TSK_TCHAR * const images[], TSK_IMG_TYPE_ENUM type,
    unsigned int a_ssize)
{
    TSK_IMG_INFO *img_info = NULL;

    // Get rid of any old error messages laying around
    tsk_error_reset();

    if ((num_img == 0) || (images[0] == NULL)) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_IMG_NOFILE;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_img_open");
        return NULL;
    }
    
    if ((a_ssize > 0) && (a_ssize < 512)) {
        tsk_error_reset(); 
        tsk_errno = TSK_ERR_IMG_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "sector size is less than 512 bytes (%d)", a_ssize);
        return NULL;
    }
    
    if ((a_ssize % 512) != 0) {
        tsk_error_reset(); 
        tsk_errno = TSK_ERR_IMG_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "sector size is not a multiple of 512 (%d)", a_ssize);
        return NULL;
    }
    

    if (tsk_verbose)
        TFPRINTF(stderr,
            _TSK_T("tsk_img_open: Type: %d   NumImg: %d  Img1: %s\n"),
            type, num_img, images[0]);

    /* If no type is given, then we use the autodetection methods 
     * In case the image file matches the signatures of multiple formats,
     * we try all of the embedded formats 
     */
    if (type == TSK_IMG_TYPE_DETECT) {
        TSK_IMG_INFO *img_set = NULL;
#if HAVE_LIBAFFLIB || HAVE_LIBEWF
        char *set = NULL;
#endif
        struct STAT_STR stat_buf;

        // we rely on tsk_errno, so make sure it is 0
        tsk_error_reset();

        /* Try the non-raw formats first */
#if HAVE_LIBAFFLIB
        if ((img_info = aff_open(images, a_ssize)) != NULL) {
            /* we don't allow the "ANY" when autodetect is used because
             * we only want to detect the tested formats. */
            if (img_info->itype == TSK_IMG_TYPE_AFF_ANY) {
                img_info->close(img_info);
            }
            else {
                set = "AFF";
                img_set = img_info;
            }
        }
        else {
            // If AFF is otherwise happy except for a password, stop trying to guess
            if (tsk_errno == TSK_ERR_IMG_PASSWD) {
                return NULL;
            }
            tsk_error_reset();
        }
#endif

#if HAVE_LIBEWF
        if ((img_info = ewf_open(num_img, images, a_ssize)) != NULL) {
            if (set == NULL) {
                set = "EWF";
                img_set = img_info;
            }
            else {
                img_set->close(img_set);
                img_info->close(img_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_IMG_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "EWF or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }
#endif
        // if any of the non-raw formats were detected, then use it. 
        if (img_set != NULL)
            return img_set;

        /* We'll use the raw format */
        if (num_img == 1) {
            if ((img_info = raw_open(images[0], a_ssize)) != NULL) {
                return img_info;
            }
            else if (tsk_errno) {
                return NULL;
            }
        }
        else {
            if ((img_info = split_open(num_img, images, a_ssize)) != NULL) {
                return img_info;
            }
            else if (tsk_errno) {
                return NULL;
            }
        }

        /* To improve the error message, verify the file can be read. */
        if (TSTAT(images[0], &stat_buf) < 0) {
            // special case to handle windows objects
#if defined(TSK_WIN32) || defined(__CYGWIN__)
            if (TSTRNCMP(_TSK_T("\\\\.\\"), images[0], 4) == 0) {
                if (tsk_verbose)
                    TFPRINTF(stderr,
                        _TSK_T
                        ("tsk_img_open: Ignoring stat error because of windows object: %s\n"),
                        images[0]);
            }
            else {
#endif
                tsk_error_reset();
                tsk_errno = TSK_ERR_IMG_STAT;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "%" PRIttocTSK " : %s",
                    images[0], strerror(errno));
                return NULL;
#if defined(TSK_WIN32) || defined(__CYGWIN__)
            }
#endif
        }

        tsk_errno = TSK_ERR_IMG_UNKTYPE;
        tsk_errstr[0] = '\0';
        tsk_errstr2[0] = '\0';
        return NULL;
    }

    /*
     * Type values
     * Make a local copy that we can modify the string as we parse it
     */

    switch (type) {
    case TSK_IMG_TYPE_RAW_SING:

        /* If we have more than one image name, and raw was the only
         * type given, then use split */
        if (num_img > 1)
            img_info = split_open(num_img, images, a_ssize);
        else
            img_info = raw_open(images[0], a_ssize);
        break;

    case TSK_IMG_TYPE_RAW_SPLIT:

        /* If only one image file is given, and only one type was
         * given then use raw */
        if (num_img == 1)
            img_info = raw_open(images[0], a_ssize);
        else
            img_info = split_open(num_img, images, a_ssize);
        break;

#if HAVE_LIBAFFLIB
    case TSK_IMG_TYPE_AFF_AFF:
    case TSK_IMG_TYPE_AFF_AFD:
    case TSK_IMG_TYPE_AFF_AFM:
    case TSK_IMG_TYPE_AFF_ANY:
        img_info = aff_open(images, a_ssize);
        break;
#endif

#if HAVE_LIBEWF
    case TSK_IMG_TYPE_EWF_EWF:
        img_info = ewf_open(num_img, images, a_ssize);
        break;
#endif
    case TSK_IMG_TYPE_QEMU:
        img_info = qemu_open(images[0], a_ssize);
        break;

    default:
        tsk_error_reset();
        tsk_errno = TSK_ERR_IMG_UNSUPTYPE;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "%d", type);
        return NULL;
    }

    return img_info;
}
示例#5
0
/**
 * Open one or more files as a disk image.  This serves as a
 * wrapper around the specific types of disk image formats. You 
 * can specify the type or autodetection can be used.
 *
 * @param type The text a user supplied for the type of format.
 * Examples include "raw", "split", "aff", etc.
 * @param num_img The number of images that are being considered.
 * @param images The path to the files (the number of files must
 * be equal to num_img)
 *
 * @return Pointer to the Image state structure or NULL on error
 */
TSK_IMG_INFO *
tsk_img_open(const TSK_TCHAR * type, const int num_img,
    const TSK_TCHAR ** images)
{
    TSK_IMG_INFO *img_info = NULL;
    TSK_TCHAR *tp, *next;
    TSK_TCHAR type_lcl[128], *type_lcl_p;
    const TSK_TCHAR **img_tmp;
    int num_img_tmp = num_img;

    // Get rid of any old error messages laying around
    tsk_error_reset();

    if ((num_img == 0) || (images[0] == NULL)) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_IMG_NOFILE;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_img_open");
        tsk_errstr2[0] = '\0';
        return NULL;
    }

    if (tsk_verbose)
        TFPRINTF(stderr,
            _TSK_T("tsk_img_open: Type: %s   NumImg: %d  Img1: %s\n"),
            (type ? type : _TSK_T("n/a")), num_img, images[0]);

    // only the first in list (lowest) layer gets the files
    img_tmp = images;

    /* If no type is given, then we use the autodetection methods 
     * In case the image file matches the signatures of multiple formats,
     * we try all of the embedded formats 
     */

    if (type == NULL) {
        TSK_IMG_INFO *img_set = NULL;
#if HAVE_LIBAFFLIB || HAVE_LIBEWF
        char *set = NULL;
#endif
        struct STAT_STR stat_buf;

        /* First verify that the image file exists */
        if (TSTAT(images[0], &stat_buf) < 0) {

            // special case to handle windows objects
#if defined(TSK_WIN32)
            if ((images[0][0] == _TSK_T('\\'))
                && (images[0][1] == _TSK_T('\\'))
                && (images[0][2] == _TSK_T('.'))
                && (images[0][3] == _TSK_T('\\'))) {
                if (tsk_verbose)
                    TFPRINTF(stderr,
                        _TSK_T
                        ("tsk_img_open: Ignoring stat error because of windows object: %s\n"),
                        images[0]);
            }
#endif

            /* AFFLIB supports s3 storage on Amazon, so skip those 'file' paths */
#if HAVE_LIBAFFLIB
#if defined(TSK_WIN32)
            else
#endif
                if (((images[0][0] == _TSK_T('s'))
                    && (images[0][1] == _TSK_T('3'))
                    && (images[0][2] == _TSK_T(':'))
                    && (images[0][3] == _TSK_T('/'))
                    && (images[0][4] == _TSK_T('/'))) ||
                ((images[0][0] == _TSK_T('h'))
                    && (images[0][1] == _TSK_T('t'))
                    && (images[0][2] == _TSK_T('t'))
                    && (images[0][3] == _TSK_T('p'))
                    && (images[0][4] == _TSK_T(':'))
                    && (images[0][5] == _TSK_T('/'))
                    && (images[0][6] == _TSK_T('/')))) {
                if (tsk_verbose)
                    TFPRINTF(stderr,
                        _TSK_T
                        ("tsk_img_open: Ignoring stat error because of s3/http object: %s\n"),
                        images[0]);

            }
#endif

#if HAVE_LIBAFFLIB || defined(TSK_WIN32)
            else {
#endif
                tsk_error_reset();
                tsk_errno = TSK_ERR_IMG_STAT;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "%" PRIttocTSK " : %s",
                    images[0], strerror(errno));
                return NULL;
#if HAVE_LIBAFFLIB || defined(TSK_WIN32)
            }
#endif
        }

        // we rely on tsk_errno, so make sure it is 0
        tsk_error_reset();

        /* Try the non-raw formats first */
#if HAVE_LIBAFFLIB
        if ((img_info = aff_open(images, NULL)) != NULL) {
            set = "AFF";
            img_set = img_info;
        }
        else {
            tsk_error_reset();
        }
#endif

#if HAVE_LIBEWF
        if ((img_info = ewf_open(num_img, images, NULL)) != NULL) {
            if (set == NULL) {
                set = "EWF";
                img_set = img_info;
            }
            else {
                img_set->close(img_set);
                img_info->close(img_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_IMG_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "EWF or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }
#endif
        if (img_set != NULL)
            return img_set;

        /* We'll use the raw format */
        if (num_img == 1) {
            if ((img_info = raw_open(images, NULL)) != NULL) {
                return img_info;
            }
            else if (tsk_errno) {
                return NULL;
            }
        }
        else {
            if ((img_info = split_open(num_img, images, NULL)) != NULL) {
                return img_info;
            }
            else if (tsk_errno) {
                return NULL;
            }
        }
        tsk_errno = TSK_ERR_IMG_UNKTYPE;
        tsk_errstr[0] = '\0';
        tsk_errstr2[0] = '\0';
        return NULL;
    }

    /*
     * Type values
     * Make a local copy that we can modify the string as we parse it
     */
    TSTRNCPY(type_lcl, type, 128);
    type_lcl_p = type_lcl;

    /* We parse this and go up in the layers */
    tp = TSTRTOK(type_lcl, _TSK_T(","));
    while (tp != NULL) {
        uint8_t imgtype;

        next = TSTRTOK(NULL, _TSK_T(","));

        imgtype = tsk_img_parse_type(type);
        switch (imgtype) {
        case TSK_IMG_INFO_TYPE_RAW_SING:

            /* If we have more than one image name, and raw was the only
             * type given, then use split */
            if ((num_img > 1) && (next == NULL) && (img_tmp != NULL)) {
                img_info = split_open(num_img_tmp, img_tmp, img_info);
                num_img_tmp = 0;
            }
            else {
                img_info = raw_open(img_tmp, img_info);
            }
            img_tmp = NULL;
            break;

        case TSK_IMG_INFO_TYPE_RAW_SPLIT:

            /* If only one image file is given, and only one type was
             * given then use raw */
            if ((num_img == 1) && (next == NULL) && (img_tmp != NULL)) {
                img_info = raw_open(img_tmp, img_info);
            }
            else {
                img_info = split_open(num_img_tmp, img_tmp, img_info);
                num_img_tmp = 0;
            }

            img_tmp = NULL;
            break;

#if HAVE_LIBAFFLIB
        case TSK_IMG_INFO_TYPE_AFF_AFF:
        case TSK_IMG_INFO_TYPE_AFF_AFD:
        case TSK_IMG_INFO_TYPE_AFF_AFM:
            img_info = aff_open(img_tmp, img_info);
            break;
#endif

#if HAVE_LIBEWF
        case TSK_IMG_INFO_TYPE_EWF_EWF:
            img_info = ewf_open(num_img_tmp, img_tmp, img_info);
            break;
#endif

        default:
            tsk_error_reset();
            tsk_errno = TSK_ERR_IMG_UNSUPTYPE;
            snprintf(tsk_errstr, TSK_ERRSTR_L, "%" PRIttocTSK, tp);
            return NULL;
        }

        /* Advance the pointer */
        tp = next;
    }

    /* Return the highest layer */
    return img_info;
}
示例#6
0
文件: raw.c 项目: Bletchley13/MBA
/**
 * Get the size in bytes of the given file.
 *
 * @param a_file The file to test
 * @param is_winobj 1 if the file is a windows object and not a real file
 *
 * @return the size in bytes, or -1 on error/unknown,
 *         -2 if unreadable, -3 if it's a directory.
 */
static TSK_OFF_T
get_size(const TSK_TCHAR * a_file, uint8_t a_is_winobj)
{
    TSK_OFF_T size = -1;
    struct STAT_STR sb;

    if (TSTAT(a_file, &sb) < 0) {
        if (a_is_winobj) {
            /* stat can fail for Windows objects; ignore that */
            if (tsk_verbose) {
                tsk_fprintf(stderr,
                    "raw_open: ignoring stat result on Windows device %"
                    PRIttocTSK "\n", a_file);
            }
        }
        else {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_IMG_STAT);
            tsk_error_set_errstr("raw_open: image \"%" PRIttocTSK
                "\" - %s", a_file, strerror(errno));
            return -2;
        }
    }
    else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
        tsk_error_set_errstr("raw_open: image \"%" PRIttocTSK
            "\" - is a directory", a_file);
        return -3;
    }

#ifdef TSK_WIN32
    {
        HANDLE fd;
        DWORD dwHi, dwLo;

        if ((fd = CreateFile(a_file, FILE_READ_DATA,
                    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 
                    OPEN_EXISTING, 0, NULL)) ==
            INVALID_HANDLE_VALUE) {
            int lastError = (int)GetLastError();
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_IMG_OPEN);
            // print string of commonly found errors
            if (lastError == ERROR_ACCESS_DENIED) {
                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
                    "\" - access denied", a_file);
            }
            else if (lastError == ERROR_SHARING_VIOLATION) {
                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
                    "\" - sharing violation", a_file);
            }
            else if (lastError == ERROR_FILE_NOT_FOUND) {
                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
                    "\" - file not found", a_file);
            }
            else {
                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
                    "\" - (error %d)", a_file, lastError);
            }
            return -2;
        }

        /* We need different techniques to determine the size of Windows physical
         * devices versus normal files */
        if (a_is_winobj == 0) {
            dwLo = GetFileSize(fd, &dwHi);
            if (dwLo == 0xffffffff) {
                int lastError = (int)GetLastError();
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_IMG_OPEN);
                tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
                    "\" - GetFileSize: %d", a_file, lastError);
                size = -1;
            }
            else {
                size = dwLo | ((TSK_OFF_T) dwHi << 32);
            }
        }
        else {
            
            //use GET_PARTITION_INFO_EX prior to IOCTL_DISK_GET_DRIVE_GEOMETRY
            // to determine the physical disk size because
            //calculating it with the help of GET_DRIVE_GEOMETRY gives only
            // approximate number
            DWORD junk;
            
            PARTITION_INFORMATION_EX partition;
            if (FALSE == DeviceIoControl(fd,
                IOCTL_DISK_GET_PARTITION_INFO_EX,
                NULL, 0, &partition, sizeof(partition), &junk,
                (LPOVERLAPPED)NULL) )  {
                DISK_GEOMETRY pdg;

                if (FALSE == DeviceIoControl(fd, IOCTL_DISK_GET_DRIVE_GEOMETRY,
                        NULL, 0, &pdg, sizeof(pdg), &junk, (LPOVERLAPPED) NULL)) {
                    int lastError = (int)GetLastError();
                    tsk_error_reset();
                    tsk_error_set_errno(TSK_ERR_IMG_OPEN);
                    tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK
                        "\" - DeviceIoControl: %d", a_file,
                        lastError);
                    size = -1;
                }
                else {
                    size = pdg.Cylinders.QuadPart *
                        (TSK_OFF_T) pdg.TracksPerCylinder *
                        (TSK_OFF_T) pdg.SectorsPerTrack *
                        (TSK_OFF_T) pdg.BytesPerSector;
                }
            }
            else {
                size = partition.PartitionLength.QuadPart;
            }
        }

        CloseHandle(fd);
    }
#else

    int fd;

    if ((fd = open(a_file, O_RDONLY | O_BINARY)) < 0) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_IMG_OPEN);
        tsk_error_set_errstr("raw_open: file \"%" PRIttocTSK "\" - %s",
            a_file, strerror(errno));
        return -2;
    }

#ifdef __APPLE__
    /* OS X doesn't support SEEK_END on char devices */
    if ((sb.st_mode & S_IFMT) != S_IFCHR) {
        size = lseek(fd, 0, SEEK_END);
    }

    if (size <= 0) {
        int blkSize;
        long long blkCnt;

        if (ioctl(fd, DKIOCGETBLOCKSIZE, &blkSize) >= 0) {
            if (ioctl(fd, DKIOCGETBLOCKCOUNT, &blkCnt) >= 0) {
                size = blkCnt * (long long) blkSize;
            }
        }
    }
#else
    /* We don't use the stat output because it doesn't work on raw
     * devices and such */
    size = lseek(fd, 0, SEEK_END);
#endif

    close(fd);

#endif

    return size;
}
示例#7
0
/**
 * \internal
 * Open the file as a raw image.
 * @param image Path to disk image to open.
 * @param a_ssize Size of device sector in bytes (or 0 for default)
 * @returns NULL on error.
 */
TSK_IMG_INFO *
raw_open(const TSK_TCHAR * image, unsigned int a_ssize)
{
    IMG_RAW_INFO *raw_info;
    TSK_IMG_INFO *img_info;
    struct STAT_STR stat_buf;
    int is_winobj = 0;

    if ((raw_info =
            (IMG_RAW_INFO *) tsk_img_malloc(sizeof(IMG_RAW_INFO))) == NULL)
        return NULL;

    img_info = (TSK_IMG_INFO *) raw_info;

    img_info->itype = TSK_IMG_TYPE_RAW_SING;
    img_info->read = raw_read;
    img_info->close = raw_close;
    img_info->imgstat = raw_imgstat;

    img_info->sector_size = 512;
    if (a_ssize)
        img_info->sector_size = a_ssize;


#if defined(TSK_WIN32) || defined(__CYGWIN__)
    if ((image[0] == _TSK_T('\\'))
        && (image[1] == _TSK_T('\\'))
        && (image[2] == _TSK_T('.'))
        && (image[3] == _TSK_T('\\'))) {
        is_winobj = 1;
    }
#endif
    if (is_winobj == 0) {
        /* Exit if we are given a directory */
        if (TSTAT(image, &stat_buf) < 0) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_IMG_STAT);
            tsk_error_set_errstr("raw_open: %s", strerror(errno));
            return NULL;
        }
        else if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) {
            if (tsk_verbose)
                TFPRINTF(stderr,
                    _TSK_T("raw_open: image %s is a directory\n"), image);

            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_IMG_MAGIC);
            tsk_error_set_errstr("raw_open: path is for a directory");
            return NULL;
        }
    }

#ifdef TSK_WIN32
    {
        DWORD dwHi, dwLo;

        if ((raw_info->fd = CreateFile(image, FILE_READ_DATA,
                    FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) ==
            INVALID_HANDLE_VALUE) {

            // if it is a device, try with SHARE_WRITE
            if ((image[0] == _TSK_T('\\')) && (image[1] == _TSK_T('\\')) &&
                (image[2] == _TSK_T('.')) && (image[3] == _TSK_T('\\'))) {
                if (tsk_verbose)
                    tsk_fprintf(stderr,
                        "raw_open: Trying Windows device with share_write mode\n");

                raw_info->fd = CreateFile(image, FILE_READ_DATA,
                    FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                    OPEN_EXISTING, 0, NULL);
            }

            if (raw_info->fd == INVALID_HANDLE_VALUE) {
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_IMG_OPEN);
                // print string of commonly found errors
                if (GetLastError() == ERROR_ACCESS_DENIED) {
                    tsk_error_set_errstr("raw_open file: %" PRIttocTSK
                        " (Access Denied)", image);
                }
                else if (GetLastError() == ERROR_SHARING_VIOLATION) {
                    tsk_error_set_errstr("raw_open file: %" PRIttocTSK
                        " (Sharing Violation)", image);
                }
                else if (GetLastError() == ERROR_FILE_NOT_FOUND) {
                    tsk_error_set_errstr("raw_open file: %" PRIttocTSK
                        " (File not found)", image);
                }
                else {
                    tsk_error_set_errstr("raw_open file: %" PRIttocTSK
                        " (%d)", image, (int) GetLastError());
                }
                return NULL;
            }
        }

        /* We need different techniques to determine the size of physical
         * devices versus normal files
         */
        if (is_winobj == 0) {
            dwLo = GetFileSize(raw_info->fd, &dwHi);
            if (dwLo == 0xffffffff) {
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_IMG_OPEN);
                tsk_error_set_errstr("raw_open file: %" PRIttocTSK
                    " GetFileSize: %d", image, (int) GetLastError());
                return NULL;
            }
            img_info->size = dwLo | ((TSK_OFF_T) dwHi << 32);
        }
        else {
            DISK_GEOMETRY pdg;
            DWORD junk;

            if (FALSE == DeviceIoControl(raw_info->fd,  // device to be queried
                    IOCTL_DISK_GET_DRIVE_GEOMETRY,      // operation to perform
                    NULL, 0, &pdg, sizeof(pdg), &junk,
                    (LPOVERLAPPED) NULL)) {
                tsk_error_reset();
                tsk_error_set_errno(TSK_ERR_IMG_OPEN);
                tsk_error_set_errstr("raw_open file: %" PRIttocTSK
                    " DeviceIoControl: %d", image, (int) GetLastError());
                return NULL;
            }

            img_info->size =
                pdg.Cylinders.QuadPart *
                (TSK_OFF_T) pdg.TracksPerCylinder *
                (TSK_OFF_T) pdg.SectorsPerTrack *
                (TSK_OFF_T) pdg.BytesPerSector;
        }
    }
#else
    if ((raw_info->fd = open(image, O_RDONLY | O_BINARY)) < 0) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_IMG_OPEN);
        tsk_error_set_errstr("raw_open file: %" PRIttocTSK " msg: %s",
            image, strerror(errno));
        return NULL;
    }

#if defined(__APPLE__)
    /* OS X doesn't support SEEK_END on char devices */
    if ((stat_buf.st_mode & S_IFMT) != S_IFCHR) {
        img_info->size = lseek(raw_info->fd, 0, SEEK_END);
        lseek(raw_info->fd, 0, SEEK_SET);
    }

    if (img_info->size == 0) {
        int blkSize;
        long long blkCnt;

        if (ioctl(raw_info->fd, DKIOCGETBLOCKSIZE, &blkSize) >= 0) {
            if (ioctl(raw_info->fd, DKIOCGETBLOCKCOUNT, &blkCnt) >= 0) {
                img_info->size = blkCnt * (long long) blkSize;
            }
        }
    }
#else
    /* We don't use the stat output because it doesn't work on raw
     * devices and such */
    img_info->size = lseek(raw_info->fd, 0, SEEK_END);
    lseek(raw_info->fd, 0, SEEK_SET);
#endif

#endif
    raw_info->seek_pos = 0;

    return img_info;
}
示例#8
0
/**
 * Open the set of disk images as a set of split raw images
 *
 * @param num_img Number of images in set
 * @param images List of disk image paths (in sorted order)
 * @param next Pointer to next image type abstraction (can be NULL)
 *
 * @return NULL on error
 */
TSK_IMG_INFO *
split_open(int num_img, const TSK_TCHAR ** images, TSK_IMG_INFO * next)
{
    IMG_SPLIT_INFO *split_info;
    TSK_IMG_INFO *img_info;
    int i;

    if (next != NULL) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_IMG_LAYERS;
        snprintf(tsk_errstr, TSK_ERRSTR_L, "split must be lowest layer");
        return NULL;
    }

    if ((split_info =
            (IMG_SPLIT_INFO *) tsk_malloc(sizeof(IMG_SPLIT_INFO))) == NULL)
        return NULL;

    memset((void *) split_info, 0, sizeof(IMG_SPLIT_INFO));

    img_info = (TSK_IMG_INFO *) split_info;

    img_info->itype = TSK_IMG_INFO_TYPE_RAW_SPLIT;
    img_info->read_random = split_read_random;
    img_info->get_size = split_get_size;
    img_info->close = split_close;
    img_info->imgstat = split_imgstat;
    img_info->next = NULL;

    /* Open the files */
    split_info->cptr = (int *) tsk_malloc(num_img * sizeof(int));
    if (split_info->cptr == NULL) {
        free(split_info);
        return NULL;
    }

    memset((void *) &split_info->cache, 0,
        SPLIT_CACHE * sizeof(IMG_SPLIT_CACHE));
    split_info->next_slot = 0;

    split_info->max_off = (OFF_T *) tsk_malloc(num_img * sizeof(OFF_T));
    if (split_info->max_off == NULL) {
        free(split_info->cptr);
        free(split_info);
        return NULL;
    }
    img_info->size = 0;

    split_info->num_img = num_img;
    split_info->images = images;

    /* Get size info for each file - we do not open each one because that
     * could cause us to run out of file decsriptors when we only need a few.
     * The descriptors are opened as needed
     */
    for (i = 0; i < num_img; i++) {
        struct STAT_STR sb;

        split_info->cptr[i] = -1;
        if (TSTAT(images[i], &sb) < 0) {
            tsk_error_reset();
            tsk_errno = TSK_ERR_IMG_STAT;
            snprintf(tsk_errstr, TSK_ERRSTR_L,
                "split_open - %" PRIttocTSK " - %s", images[i],
                strerror(errno));
            free(split_info->max_off);
            free(split_info->cptr);
            free(split_info);
            return NULL;
        }
        else if ((sb.st_mode & S_IFMT) == S_IFDIR) {
            if (tsk_verbose)
                tsk_fprintf(stderr,
                    "split_open: image %" PRIttocTSK " is a directory\n",
                    images[i]);

            tsk_error_reset();
            tsk_errno = TSK_ERR_IMG_MAGIC;
            snprintf(tsk_errstr, TSK_ERRSTR_L,
                "split_open: Image is a directory");
            return NULL;
        }

        /* Add the size of this image to the total and save the current max */
        img_info->size += sb.st_size;
        split_info->max_off[i] = img_info->size;

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "split_open: %d  size: %" PRIuOFF "  max offset: %"
                PRIuOFF "  Name: %" PRIttocTSK "\n", i, sb.st_size,
                split_info->max_off[i], images[i]);
    }

    return img_info;
}
示例#9
0
int main(int argc, char **argv1)
{
    TSK_TCHAR **argv;
    extern int OPTIND;
    int ch;
    struct STAT_STR stat_buf;
    TSK_TCHAR *pipeline_config = NULL;
    TSK_TCHAR *framework_config = NULL;

#ifdef TSK_WIN32
    // On Windows, get the wide arguments (mingw doesn't support wmain)
    argv = CommandLineToArgvW(GetCommandLineW(), &argc);
    if (argv == NULL) {
        fprintf(stderr, "Error getting wide arguments\n");
        exit(1);
    }
#else
    argv = (TSK_TCHAR **) argv1;
#endif

    while ((ch =
        GETOPT(argc, argv, _TSK_T("c:p:vV"))) > 0) {
            switch (ch) {
        case _TSK_T('?'):
        default:
            TFPRINTF(stderr, _TSK_T("Invalid argument: %s\n"),
                argv[OPTIND]);
            usage();
        case _TSK_T('c'):
            framework_config = OPTARG;
            break;
        case _TSK_T('p'):
            pipeline_config = OPTARG;
            break;
        case _TSK_T('v'):
            tsk_verbose++;
            break;
        case _TSK_T('V'):
            tsk_version_print(stdout);
            exit(0);
            }
    }

    /* We need at least one more argument */
    if (OPTIND == argc) {
        tsk_fprintf(stderr, "Missing image name\n");
        usage();
    }
    TSK_TCHAR *imagePath = argv[OPTIND];

    // Load the framework config if they specified it
    Poco::AutoPtr<Poco::Util::XMLConfiguration> pXMLConfig;
    if (framework_config) {
        // @@@ Not Unix-friendly
        try {
            pXMLConfig = new Poco::Util::XMLConfiguration(TskUtilities::toUTF8(framework_config));
        }
        catch (std::exception& e) {
            fprintf(stderr, "Error opening framework config file (%s)\n", e.what());
            return 1;
        }
        // Initialize properties based on the config file.
        TskSystemPropertiesImpl *systemProperties = new TskSystemPropertiesImpl();    
        systemProperties->initialize(*pXMLConfig);
        TskServices::Instance().setSystemProperties(*systemProperties);
    }

    // make up an output folder to store the database and such in
    TSK_TCHAR outDirPath[1024];
    TSNPRINTF(outDirPath, 1024, _TSK_T("%s_tsk_out"), imagePath);
    if (TSTAT(outDirPath, &stat_buf) == 0) {
        fprintf(stderr, "Output directory already exists (%"PRIttocTSK")\n", outDirPath);
        return 1;
    }

    if (makeDir(outDirPath)) {
        return 1;
    }

    // @@@ Not UNIX-friendly
    TSK_SYS_PROP_SET(TskSystemPropertiesImpl::OUT_DIR, outDirPath);

    // Create and register our SQLite ImgDB class   
    std::auto_ptr<TskImgDB> pImgDB(NULL);
    pImgDB = std::auto_ptr<TskImgDB>(new TskImgDBSqlite(outDirPath));
    if (pImgDB->initialize() != 0) {
        fprintf(stderr, "Error initializing SQLite database\n");
        tsk_error_print(stderr);
        return 1;
    }

    // @@@ Call pImgDB->addToolInfo() as needed to set version info...

    TskServices::Instance().setImgDB(*pImgDB);

    // Create a Blackboard and register it with the framework.
    TskServices::Instance().setBlackboard(TskDBBlackboard::instance());

    // @@@ Not UNIX-friendly
    if (pipeline_config != NULL) 
        TSK_SYS_PROP_SET(TskSystemPropertiesImpl::PIPELINE_CONFIG, pipeline_config);

    // Create an ImageFile and register it with the framework.
    TskImageFileTsk imageFileTsk;
    if (imageFileTsk.open(imagePath) != 0) {
        fprintf(stderr, "Error opening image: %"PRIttocTSK"\n", imagePath);
        tsk_error_print(stderr);
        return 1;
    }
    TskServices::Instance().setImageFile(imageFileTsk);

    // Let's get the pipelines setup to make sure there are no errors.
    TskPipelineManager pipelineMgr;
    TskPipeline *filePipeline;
    try {
        filePipeline = pipelineMgr.createPipeline(TskPipelineManager::FILE_ANALYSIS_PIPELINE);
    }
    catch (TskException &e ) {
        fprintf(stderr, "Error creating file analysis pipeline\n");
        std::cerr << e.message() << endl;
        filePipeline = NULL;
    }

    TskPipeline *reportPipeline;
    try {
        reportPipeline = pipelineMgr.createPipeline(TskPipelineManager::REPORTING_PIPELINE);
    }
    catch (TskException &e ) {
        fprintf(stderr, "Error creating reporting pipeline\n");
        std::cerr << e.message() << endl;
        reportPipeline = NULL;
    }

    // now we analyze the data.
    // Extract
    if (imageFileTsk.extractFiles() != 0) {
        fprintf(stderr, "Error adding file system info to database\n");
        tsk_error_print(stderr);
        return 1;
    }

    //Run pipeline on all files
    // @@@ this needs to cycle over the files to analyze, 10 is just here for testing 
    if (filePipeline) {
        for (int i = 0; i < 10; i++) {
            try {
                filePipeline->run(i);
            }
            catch (...) {
                // error message has been logged already.
            }
        }
    }

    if (reportPipeline) {
        try {
            reportPipeline->run();
        }
        catch (...) {
            fprintf(stderr, "Error running reporting pipeline\n");
            return 1;
        }
    }

    fprintf(stderr, "image analysis complete\n");
    return 0;
}