/** * Process the data as a volume system to find the partitions * and volumes. * File system analysis will be performed on each partition. * * @param img Image file information structure for data to analyze * @param start Byte offset to start analyzing from. * * @return 1 on error and 0 on success */ static uint8_t proc_vs(TSK_IMG_INFO * img_info, TSK_OFF_T start) { TSK_VS_INFO *vs_info; // USE mm_walk to get the volumes if ((vs_info = tsk_vs_open(img_info, 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 (proc_fs(img_info, start)) { return 1; } } else { fprintf(stderr, "Volume system open, examining each\n"); /* Walk the allocated volumes (skip metadata and unallocated volumes) */ if (tsk_vs_part_walk(vs_info, 0, vs_info->part_count - 1, (TSK_VS_PART_FLAG_ENUM) (TSK_VS_PART_FLAG_ALLOC), vs_act, NULL)) { tsk_vs_close(vs_info); return 1; } tsk_vs_close(vs_info); } return 0; }
/* * Open the volume system at the given offset * @return the created TSK_VS_INFO pointer * @param env pointer to java environment this was called from * @param obj the java object this was called from * @param a_img_info the pointer to the parent img object * @param vsOffset the offset of the volume system in bytes */ JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVsNat (JNIEnv * env, jclass obj, jlong a_img_info, jlong vsOffset) { TSK_IMG_INFO *img_info = castImgInfo(env, a_img_info); TSK_VS_INFO *vs_info; vs_info = tsk_vs_open(img_info, vsOffset, TSK_VS_TYPE_DETECT); if (vs_info == NULL) { throwTskError(env, tsk_error_get()); } return (jlong) vs_info; }
// Find all the harddisk address corresponding to target file // // \param img_path path of target image // \param file_path the target filename // // Return NULL if error, otherwise a UT_array of (start, end) tuple will returned, where start and end are the harddisk byte addrsesses UT_array* tsk_find_haddr_by_filename(const char* img_path, const char* file_path) { TSK_IMG_TYPE_ENUM img_type ; TSK_IMG_INFO *img; TSK_VS_INFO *vs; find_file_data data; UT_array* ret = NULL; img_type = tsk_img_type_toid(QCOW_IMG_TYPE); //XXX([email protected]):need error handling. img = tsk_img_open_sing(img_path, img_type, 0); if(img == NULL) { printf("Image Open Failed!!\n"); return NULL; } vs = tsk_vs_open(img, 0, TSK_VS_TYPE_DETECT); if(vs==NULL) { printf("Volume Open Failed!!\n"); tsk_img_close(img); return NULL; } data.file_found = 0; data.full_path = file_path; utarray_new(data.offsets_in_disk, &ut_tsk_daddr_tuple_icd); tsk_vs_part_walk( vs, // the volume system 0, // start from first partiton vs->part_count - 1, // walk to last partiton TSK_VS_PART_FLAG_ALLOC, // traverse all allocated partiton find_file_in_partiton, // action for each partition &data // argument for action ); if (data.file_found) { ret = data.offsets_in_disk; } else { tsk_vs_close(vs); tsk_img_close(img); return NULL; } tsk_vs_close(vs); tsk_img_close(img); return ret; }
Image::Image(TSK_IMG_INFO* img, const vector< string >& files, bool close): Img(img), Files(files), ShouldClose(close) { TSK_VS_INFO* vs = tsk_vs_open(img, 0, TSK_VS_TYPE_DETECT); if (vs) { VS.reset(new VolumeSystem(vs)); } TSK_FS_INFO* fs = tsk_fs_open_img(img, 0, TSK_FS_TYPE_DETECT); if (fs) { Fs.reset(new Filesystem(fs)); } }
/** * Process the data as a volume system to find the partitions * and volumes. * File system analysis will be performed on each partition. * * @param img Image file information structure for data to analyze * @param start Byte offset to start analyzing from. * * @return 1 on error and 0 on success */ static uint8_t proc_vs(TSK_IMG_INFO * img_info, TSK_OFF_T start) { TSK_VS_INFO *vs_info; // Open the volume system if ((vs_info = tsk_vs_open(img_info, 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 (proc_fs(img_info, start)) { return 1; } } else { fprintf(stderr, "Volume system open, examining each\n"); // cycle through the partitions for (TSK_PNUM_T i = 0; i < vs_info->part_count; i++) { const TSK_VS_PART_INFO *vs_part; if ((vs_part = tsk_vs_part_get(vs_info, i)) == NULL) { fprintf(stderr, "Error getting volume %" PRIuPNUM "\n", i); continue; } // ignore the metadata partitions if (vs_part->flags & TSK_VS_PART_FLAG_META) continue; // could do something with unallocated volumes else if (vs_part->flags & TSK_VS_PART_FLAG_UNALLOC) { } else { if (proc_fs(img_info, vs_part->start * vs_info->block_size)) { // We could do more fancy error checking here to see the cause // of the error or consider the allocation status of the volume... tsk_error_reset(); } } } tsk_vs_close(vs_info); } return 0; }
Image::Image(TSK_IMG_INFO* img, const std::vector< std::string >& files, bool close): Img(img), Files(files), ShouldClose(close) { // std::cerr << "opening volumeSystem, sector size = " << Img->sector_size << ", desc = " << desc() << std::endl; TSK_VS_INFO* vs = tsk_vs_open(img, 0, TSK_VS_TYPE_DETECT); if (vs) { VS.reset(new VolumeSystem(vs)); } else { // std::cerr << "opening fileSystem" << std::endl; TSK_FS_INFO* fs = tsk_fs_open_img(img, 0, TSK_FS_TYPE_DETECT); if (fs) { Fs.reset(new Filesystem(fs)); } } }
/** * Starts in a specified byte offset of the opened disk images and looks for a * volume system or file system. Will call processFile() on each file * that is found. * @param a_start Byte offset to start analyzing from. * @param a_vtype Volume system type to analyze * @return 1 on error, 0 on success */ uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype) { if (!m_img_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_AUTO_NOTOPEN); tsk_error_set_errstr("findFilesInVs\n"); 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, a_vtype)) == NULL) { char msg[1024]; snprintf(msg, 1024, "Unable to open volume system at offset %" PRIuOFF " (%s)", a_start, tsk_error_get()); if (tsk_verbose) fprintf(stderr, "%s\n", msg); handleNotification(msg); /* There was no volume system, but there could be a file system */ tsk_error_reset(); if (findFilesInFs(a_start)) { return 1; } } else { TSK_FILTER_ENUM retval = filterVs(vs_info); if (retval == TSK_FILTER_STOP) return TSK_STOP; else if (retval == TSK_FILTER_SKIP) return TSK_OK; /* 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; }
/** * Starts in a specified byte offset of the opened disk images and looks for a * volume system or file system. Will call processFile() on each file * that is found. * @param a_start Byte offset to start analyzing from. * @param a_vtype Volume system type to analyze * @return 1 if an error occured (messages will have been registered) and 0 on success */ uint8_t TskAuto::findFilesInVs(TSK_OFF_T a_start, TSK_VS_TYPE_ENUM a_vtype) { if (!m_img_info) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_AUTO_NOTOPEN); tsk_error_set_errstr("findFilesInVs -- img_info"); registerError(); 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, a_vtype)) == NULL) { /* we're going to ignore this error to avoid confusion if the * fs_open passes. */ tsk_error_reset(); if(tsk_verbose) fprintf(stderr, "findFilesInVs: Error opening volume system, trying as a file system\n"); /* There was no volume system, but there could be a file system * Errors will have been registered */ findFilesInFs(a_start); } // process the volume system else { TSK_FILTER_ENUM retval = filterVs(vs_info); if ((retval == TSK_FILTER_STOP) || (retval == TSK_FILTER_SKIP)|| (m_stopAllProcessing)) return m_errors.empty() ? 0 : 1; /* 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)) { registerError(); tsk_vs_close(vs_info); return 1; } tsk_vs_close(vs_info); } return m_errors.empty() ? 0 : 1; }
int main(int argc, char* argv1[]) { TSK_VS_INFO* lVsInfo = NULL; TSK_OFF_T lCnt = 0; char lBuf[32768] = { 0 }; unsigned lCntRead = 0; TSK_IMG_INFO* lImgInfo = OS_FH_INVALID; OS_FH_TYPE lOut = OS_FH_INVALID; const TSK_TCHAR *const *argv; #ifdef TSK_WIN32 argv = CommandLineToArgvW(GetCommandLineW(), &argc); #else argv = (const TSK_TCHAR *const *) argv1; #endif lOut = OS_FOPEN_WRITE(argv[2]); if (lOut == OS_FH_INVALID) { LOGGING_ERROR("Could not open export image in write mode. \n") exit(1); } lImgInfo = tsk_img_open( 1, /* number of images */ (argv + 1), /* path to images */ TSK_IMG_TYPE_DETECT, /* disk image type */ 0); /* size of device sector in bytes */ if (lImgInfo != NULL) { TSK_OFF_T lSizeSectors = lImgInfo->size / lImgInfo->sector_size + \ (lImgInfo->size % lImgInfo->sector_size ? 1 : 0); LOGGING_INFO("Image size (Bytes): %lu, Image size (sectors): %lu\n", lImgInfo->size, lSizeSectors); lVsInfo = tsk_vs_open(lImgInfo, 0, TSK_VS_TYPE_DETECT); if (lVsInfo != NULL) { if (tsk_vs_part_walk(lVsInfo, 0, /* start */ lVsInfo->part_count - 1, /* end */ TSK_VS_PART_FLAG_ALL, /* all partitions */ part_act, /* callback */ (void*) lOut /* data passed to the callback */ ) != 0) { fprintf(stderr, "Problem when walking partitions. \n"); } } else { LOGGING_DEBUG("Volume system cannot be opened.\n"); for (lCnt = 0; lCnt < lSizeSectors; lCnt++) { lCntRead = lCnt == lSizeSectors - 1 ? lImgInfo->size % lImgInfo->sector_size : lImgInfo->sector_size; LOGGING_DEBUG("Reading %u bytes\n", lCntRead); tsk_img_read( lImgInfo, /* handler */ lCnt * lImgInfo->sector_size, /* start address */ lBuf, /* buffer to store data in */ lCntRead /* amount of data to read */ ); data_act(lBuf, lCntRead, lCnt * lImgInfo->sector_size, lOut); } } } else { LOGGING_ERROR("Problem opening the image. \n"); tsk_error_print(stderr); exit(1); } if (lOut != OS_FH_INVALID) { OS_FCLOSE(lOut); } return EXIT_SUCCESS; }
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_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 one more argument */ if (OPTIND >= argc) { tsk_fprintf(stderr, "Missing image name\n"); usage(); } /* open the image */ if ((img = tsk_img_open(argc - OPTIND, &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); } /* 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); } print_stats(vs); tsk_vs_close(vs); tsk_img_close(img); exit(0); }
void tsk_get_file(const char* imgname,uint64_t haddr_img_offset, const char* file_path, const char* destination, uint64_t start_offset, int read_file_len ) { TSK_IMG_INFO *img; TSK_VS_INFO *vs; TSK_FS_INFO *fs; uint8_t id_used = 0, type_used = 0; TSK_DADDR_T partition_offset = 0; TSK_DADDR_T block_img_offset = 0; TSK_DADDR_T part_byte_offset = 0; TSK_DADDR_T part_block_offset = 0; MBA_IFIND_DATA_DATA* ifind_data; TSK_IMG_TYPE_ENUM imgtype; MBA_FFIND_DATA* ffind_data; TSK_FS_FILE *file; FILE* writeHive; char *temp; //open image imgtype = tsk_img_type_toid(QCOW_IMG_TYPE); img = tsk_img_open_sing(imgname, imgtype, 0); if(img == NULL) { printf("Image Open Failed!!\n"); return; } if(haddr_img_offset >= img->size) { printf("Request haddr is larger than image size\n"); return; } //open volume vs = tsk_vs_open(img, 0 , TSK_VS_TYPE_DETECT); if(vs==NULL) { printf("Volume Open Failed!!\n"); return; } //calculate block address block_img_offset = haddr_img_offset/img->sector_size; //search the partition contain the target block partition_offset = search_partition(vs, block_img_offset); if(partition_offset == 0) { printf("Cannot found partition contains the target haddr\n"); return; } //open the partition's file system fs = tsk_fs_open_img(img, partition_offset * img->sector_size, TSK_FS_TYPE_DETECT); if(fs==NULL) { printf("Cannot open file system\n"); return; } //calculate offset to the current partition part_byte_offset = haddr_img_offset - (partition_offset * img->sector_size); part_block_offset = part_byte_offset/fs->block_size; file = tsk_fs_file_open( fs, NULL, file_path); if ( OPEN_FAIL(file) ) printf("open file fail\n\n"); temp = calloc( read_file_len, sizeof(char)); int size = tsk_fs_file_read( file, start_offset, temp, read_file_len, TSK_FS_FILE_READ_FLAG_NONE ); tsk_fs_file_close(file); writeHive = fopen( destination, "w" ); if ( writeHive == NULL ) printf("Open fail"); else { fwrite( temp, size, sizeof(char), writeHive ); fclose(writeHive); } // else free(temp); //find the inode of this block ifind_data = fs_ifind_data(fs, (TSK_FS_IFIND_FLAG_ENUM) 0, part_block_offset); if(ifind_data == NULL) { return; } if(ifind_data->found!=1) { printf("Inode not found\n"); return; } //Find the inode's filename //Note: Do Not Know what to fill in variable type_used and id_used ffind_data = fs_ffind(fs, 0, ifind_data->curinode, ifind_data->curtype , type_used, ifind_data->curid , id_used, (TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC)); if(ffind_data==NULL){ printf("Cannot found fdata associate with inode\n"); return; } free(ifind_data); return; }
// Find the filename of the specified harddisk byte offset // // \param imgname path of target image // \param haddr_img_offset the target harddisk byte address // // Return NULL if error, otherwise a UT_array of filename UT_array* tsk_get_filename_by_haddr(const char* imgname, uint64_t haddr_img_offset) { TSK_IMG_INFO *img; TSK_VS_INFO *vs; TSK_FS_INFO *fs; uint8_t id_used = 0, type_used = 0; TSK_DADDR_T partition_offset = 0; TSK_DADDR_T block_img_offset = 0; TSK_DADDR_T part_byte_offset = 0; TSK_DADDR_T part_block_offset = 0; MBA_IFIND_DATA_DATA* ifind_data; TSK_IMG_TYPE_ENUM imgtype; MBA_FFIND_DATA* ffind_data; UT_array* ret = NULL; //open image imgtype = tsk_img_type_toid(QCOW_IMG_TYPE); img = tsk_img_open_sing(imgname, imgtype, 0); if(img == NULL) { printf("Image Open Failed!!\n"); return NULL; } if(haddr_img_offset >= img->size) { printf("Request haddr is larger than image size\n"); tsk_img_close(img); return NULL; } //open volume vs = tsk_vs_open(img, 0 , TSK_VS_TYPE_DETECT); if(vs==NULL) { printf("Volume Open Failed!!\n"); tsk_img_close(img); return NULL; } //calculate block address block_img_offset = haddr_img_offset/img->sector_size; //search the partition contain the target block partition_offset = search_partition(vs, block_img_offset); if(partition_offset == 0) { tsk_img_close(img); tsk_vs_close(vs); return NULL; } //open the partition's file system fs = tsk_fs_open_img(img, partition_offset * img->sector_size, TSK_FS_TYPE_DETECT); if(fs==NULL) { printf("Cannot open file system\n"); tsk_img_close(img); tsk_vs_close(vs); return NULL; } //calculate offset to the current partition part_byte_offset = haddr_img_offset - (partition_offset * img->sector_size); part_block_offset = part_byte_offset/fs->block_size; //find the inode of this block ifind_data = fs_ifind_data(fs, (TSK_FS_IFIND_FLAG_ENUM) 0, part_block_offset); if(ifind_data == NULL) { tsk_img_close(img); tsk_vs_close(vs); return NULL; } if(ifind_data->found!=1) { tsk_img_close(img); tsk_vs_close(vs); return NULL; } //Find the inode's filename //Note: Do Not Know what to fill in variable type_used and id_used ffind_data = fs_ffind(fs, 0, ifind_data->curinode, ifind_data->curtype , type_used, ifind_data->curid , id_used, (TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC)); if(ffind_data==NULL){ printf("Cannot found fdata associate with inode\n"); tsk_img_close(img); tsk_vs_close(vs); return NULL; } //free data //reserve return data first ret = ffind_data->filenames; free(ifind_data); free(ffind_data); tsk_vs_close(vs); tsk_img_close(img); return ret; }
int main(int argc, char **argv1) { TSK_VS_INFO *vs; int ch; TSK_OFF_T imgaddr = 0; int flags = 0; TSK_IMG_INFO *img; TSK_IMG_TYPE_ENUM imgtype = TSK_IMG_TYPE_DETECT; TSK_VS_TYPE_ENUM vstype = TSK_VS_TYPE_DETECT; uint8_t hide_meta = 0; 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("aAb:Bi:mMo:rt:vV"))) > 0) { switch (ch) { case _TSK_T('a'): flags |= TSK_VS_PART_FLAG_ALLOC; break; case _TSK_T('A'): flags |= TSK_VS_PART_FLAG_UNALLOC; break; case _TSK_T('B'): print_bytes = 1; break; 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('m'): flags |= (TSK_VS_PART_FLAG_META); break; case _TSK_T('M'): // we'll set this after all flags have been set hide_meta = 1; break; case _TSK_T('o'): if ((imgaddr = tsk_parse_offset(OPTARG)) == -1) { tsk_error_print(stderr); exit(1); } break; case _TSK_T('r'): recurse = 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 _TSK_T('v'): tsk_verbose++; break; case _TSK_T('V'): tsk_version_print(stdout); exit(0); case _TSK_T('?'): default: tsk_fprintf(stderr, "Unknown argument\n"); usage(); } } // if they want to hide metadata volumes, set that now if (hide_meta) { if (flags == 0) flags = (TSK_VS_PART_FLAG_ALLOC | TSK_VS_PART_FLAG_UNALLOC); else flags &= ~TSK_VS_PART_FLAG_META; } else if (flags == 0) { flags = TSK_VS_PART_FLAG_ALL; } /* We need at least one more argument */ if (OPTIND >= argc) { tsk_fprintf(stderr, "Missing image name\n"); usage(); } /* open the image */ img = tsk_img_open(argc - OPTIND, &argv[OPTIND], imgtype, ssize); if (img == 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); } /* process the partition tables */ vs = tsk_vs_open(img, imgaddr * img->sector_size, vstype); if (vs == NULL) { tsk_error_print(stderr); if (tsk_error_get_errno() == TSK_ERR_VS_UNSUPTYPE) tsk_vs_type_print(stderr); tsk_img_close(img); exit(1); } print_header(vs); if (tsk_vs_part_walk(vs, 0, vs->part_count - 1, (TSK_VS_PART_FLAG_ENUM) flags, part_act, NULL)) { tsk_error_print(stderr); tsk_vs_close(vs); tsk_img_close(img); exit(1); } tsk_vs_close(vs); if ((recurse) && (vs->vstype == TSK_VS_TYPE_DOS)) { int i; /* disable recursing incase we hit another DOS partition * future versions may support more layers */ recurse = 0; for (i = 0; i < recurse_cnt; i++) { vs = tsk_vs_open(img, recurse_list[i], TSK_VS_TYPE_DETECT); if (vs != NULL) { tsk_printf("\n\n"); print_header(vs); if (tsk_vs_part_walk(vs, 0, vs->part_count - 1, (TSK_VS_PART_FLAG_ENUM) flags, part_act, NULL)) { tsk_error_reset(); } tsk_vs_close(vs); } else { /* Ignore error in this case and reset */ tsk_error_reset(); } } } tsk_img_close(img); exit(0); }
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); }