Exemple #1
0
TSK_WALK_RET_ENUM part_act(
        TSK_VS_INFO* pVsInfo,
        const TSK_VS_PART_INFO* pPartInfo,
        void* pData)
{
    TSK_FS_INFO* lFsInfo = NULL;
    OS_FH_TYPE lOut = (OS_FH_TYPE)pData;
    unsigned long long lCnt = 0;
    char lBuf[32768] = { 0 };
    unsigned long long lOffsetBlock = 0;

    /* open file system */
    if ((lFsInfo = tsk_fs_open_vol(
            pPartInfo, /* partition to open */
            TSK_FS_TYPE_DETECT /* auto-detect mode on */
            )) != NULL)
    {
        /* known file-system */

        /* iterate over unallocated blocks of fs */
        tsk_fs_block_walk(
                lFsInfo, /* file-system info */
                0, /* start */
                lFsInfo->block_count - 1, /* end */
                TSK_FS_BLOCK_WALK_FLAG_UNALLOC, /* only unallocated blocks */
                block_act, /* callback */
                pData /* file-handle */
                );
        /* close fs */
        tsk_fs_close(lFsInfo);
    }
    else
    {
        /* unknown file-system */

        /* iterate through all blocks of this volume regardless of their state */
        for (lCnt = 0; lCnt < pPartInfo->len; lCnt++)
        {
            lOffsetBlock = (pPartInfo->start + lCnt) * pPartInfo->vs->block_size;

            LOGGING_DEBUG(
                    "Block in unknown partition (Len: %lu blocks). " 
                    "Size: %u, Absolute address (Bytes): %lld\n",
                    pPartInfo->len,
                    pPartInfo->vs->block_size,
                    lOffsetBlock);

            /* use the following function so that forensic images are supported */
            /* HINT: this is not the case with fopen/fseek/fread/fclose functions */
            tsk_vs_part_read_block(
                    pPartInfo,
                    lCnt, /* start address (blocks) relative to start of volume */
                    lBuf, /* buffer to store data in */
                    pPartInfo->vs->block_size /* amount of data to read */
                    );
            data_act(lBuf,
                    pPartInfo->vs->block_size, 
                    lOffsetBlock,
                    lOut);
        }
    }

    return TSK_WALK_CONT;
}
int
main(int argc, char **argv1)
{
    TSK_VS_INFO *vs;
    TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT;
    TSK_VS_TYPE_ENUM vstype = TSK_VS_TYPE_DETECT;
    int ch;
    TSK_OFF_T imgaddr = 0;
    TSK_IMG_INFO *img;
    TSK_PNUM_T pnum;
    TSK_DADDR_T addr;
    const TSK_VS_PART_INFO *vs_part;
    char *buf;
    TSK_TCHAR **argv;
    unsigned int ssize = 0;
    TSK_TCHAR *cp;

#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


    progname = argv[0];

    while ((ch = GETOPT(argc, argv, _TSK_T("b:i:o:t:vV"))) > 0) {
        switch (ch) {
        case _TSK_T('b'):
            ssize = (unsigned int) TSTRTOUL(OPTARG, &cp, 0);
            if (*cp || *cp == *OPTARG || ssize < 1) {
                TFPRINTF(stderr,
                    _TSK_T
                    ("invalid argument: sector size must be positive: %s\n"),
                    OPTARG);
                usage();
            }
            break;
        case _TSK_T('i'):
            if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) {
                tsk_img_type_print(stderr);
                exit(1);
            }
            imgtype = tsk_img_type_toid(OPTARG);
            if (imgtype == TSK_IMG_TYPE_UNSUPP) {
                TFPRINTF(stderr, _TSK_T("Unsupported image type: %s\n"),
                    OPTARG);
                usage();
            }
            break;

        case _TSK_T('o'):
            if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) {
                tsk_error_print(stderr);
                exit(1);
            }
            break;
        case _TSK_T('t'):
            if (TSTRCMP(OPTARG, _TSK_T("list")) == 0) {
                tsk_vs_type_print(stderr);
                exit(1);
            }
            vstype = tsk_vs_type_toid(OPTARG);
            if (vstype == TSK_VS_TYPE_UNSUPP) {
                TFPRINTF(stderr,
                    _TSK_T("Unsupported volume system type: %s\n"),
                    OPTARG);
                usage();
            }
            break;
        case 'v':
            tsk_verbose++;
            break;
        case 'V':
            tsk_version_print(stdout);
            exit(0);
        case '?':
        default:
            tsk_fprintf(stderr, "Unknown argument\n");
            usage();
        }
    }

    /* We need at least two more arguments */
    if (OPTIND + 1 >= argc) {
        tsk_fprintf(stderr,
            "Missing image name and/or partition number\n");
        usage();
    }

    /* open the image */
    if ((img =
            tsk_img_open(argc - OPTIND - 1, &argv[OPTIND],
                imgtype, ssize)) == NULL) {
        tsk_error_print(stderr);
        exit(1);
    }
    if ((imgaddr * img->sector_size) >= img->size) {
        tsk_fprintf(stderr,
            "Sector offset supplied is larger than disk image (maximum: %"
            PRIu64 ")\n", img->size / img->sector_size);
        exit(1);
    }

    if (tsk_parse_pnum(argv[argc - 1], &pnum)) {
        tsk_error_print(stderr);
        exit(1);
    }

    /* process the partition tables */
    if ((vs = tsk_vs_open(img, imgaddr * img->sector_size, vstype)) == NULL) {
        tsk_error_print(stderr);
        if (tsk_error_get_errno() == TSK_ERR_VS_UNSUPTYPE)
            tsk_vs_type_print(stderr);

        exit(1);
    }

    if (pnum >= vs->part_count) {
        tsk_fprintf(stderr,
            "Partition address is too large (maximum: %"
            PRIuPNUM ")\n", vs->part_count);
        exit(1);
    }

    vs_part = tsk_vs_part_get(vs, pnum);
    if (vs_part == NULL) {
        tsk_fprintf(stderr, "Error looking up partition\n");
        exit(1);
    }

    buf = (char *) malloc(vs->block_size);
    if (buf == NULL) {
        tsk_error_print(stderr);
        exit(1);
    }

#ifdef TSK_WIN32
    char strerror_buffer[1024];
    if (-1 == _setmode(_fileno(stdout), _O_BINARY)) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_WRITE);
        tsk_error_set_errstr(
            "mmcat: error setting stdout to binary: %s",
            strerror_s(strerror_buffer, 1024, errno));
        return 1;
    }
#endif


    for (addr = 0; addr < vs_part->len; addr++) {
        ssize_t retval;
        retval =
            tsk_vs_part_read_block(vs_part, addr, buf, vs->block_size);
        if (retval == -1) {
            tsk_error_print(stderr);
            exit(1);
        }

        if ((size_t) retval != fwrite(buf, 1, retval, stdout)) {
            tsk_fprintf(stderr, "Error writing data to stdout\n");
            exit(1);
        }
    }

    tsk_vs_close(vs);
    tsk_img_close(img);
    exit(0);
}