bool MmlsTable::nextSubEntity() { //Save the original mActivePartitionIndex, we may need it if there is no next one. TSK_PNUM_T oldIndex=mActivePartitionIndex; //Search the next partition within this table. while (mActivePartitionIndex < (mVsHandle->part_count -1)) { mActivePartitionIndex++; const TSK_VS_PART_INFO *partition=tsk_vs_part_get(mVsHandle,mActivePartitionIndex); int8_t tableno=partition->table_num; if (tableno > 0 ) { //Partition tables are bound to their own table level what leaves them unconnected //to the level one below. We thus decrement the table number of extended tables //by one to fix the tree. std::string description= partition->desc; size_t i = description.find("(#"); if ( (i != std::string::npos ) && ((i+2) < description.length()) ) { int table_num = atoi(description.substr(i + 2, description.length() - 2).c_str()); tableno = table_num -1; } } if (tableno == mTableNum) { return true; } } //We didn't find the next one, lets restore the old value. mActivePartitionIndex=oldIndex; return false; };
VolumeSystem::VolumeSystem(TSK_VS_INFO* volInfo): VolInfo(volInfo) { for (unsigned int i = 0; i < VolInfo->part_count; ++i) { std::shared_ptr<Volume> p(new Volume(tsk_vs_part_get(VolInfo, i))); Volumes.push_back(p); WeakVols.push_back(std::weak_ptr<Volume>(p)); } }
/* * Open volume with the given id from the given volume system * @return the created TSK_VS_PART_INFO pointer * @param env pointer to java environment this was called from * @param obj the java object this was called from * @param a_vs_info the pointer to the parent vs object * @param vol_id the id of the volume to get */ JNIEXPORT jlong JNICALL Java_org_sleuthkit_datamodel_SleuthkitJNI_openVolNat(JNIEnv * env, jclass obj, jlong a_vs_info, jlong vol_id) { TSK_VS_INFO *vs_info = castVsInfo(env, a_vs_info); const TSK_VS_PART_INFO *vol_part_info; vol_part_info = tsk_vs_part_get(vs_info, (TSK_PNUM_T) vol_id); if (vol_part_info == NULL) { throwTskError(env, tsk_error_get()); } return (jlong) vol_part_info; }
/** * 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; }
// should warn user when there is more than one partition available // with a readable filesystem. Right now, this simply returns // the last one found. VALUE open_fs_from_volume(VALUE self, VALUE vs_obj, VALUE opts) { struct tsk4r_vs * rb_volumesystem; struct tsk4r_fs_wrapper * my_pointer; Data_Get_Struct(vs_obj, struct tsk4r_vs, rb_volumesystem); Data_Get_Struct(self, struct tsk4r_fs_wrapper, my_pointer); VALUE fs_type_flag = rb_hash_aref(opts, rb_symname_p("type_flag")); TSK_FS_TYPE_ENUM * type_flag_num = get_fs_flag(fs_type_flag); TSK_PNUM_T c = 0; while (c < rb_volumesystem->volume->part_count) { const TSK_VS_PART_INFO * partition = tsk_vs_part_get(rb_volumesystem->volume, c); my_pointer->filesystem = tsk_fs_open_vol(partition, (TSK_FS_TYPE_ENUM)type_flag_num); if (my_pointer->filesystem != NULL) { break; } c++; } return self; }
void MmlsTable::getCurrentSubEntity(TreeGraphNode ** subent) { if (*subent) { throw ocfa::misc::OcfaException("MmlsTopNode::getCurrentSubEntity called with subent not cleared"); } const TSK_VS_PART_INFO *partition=tsk_vs_part_get(mVsHandle,mActivePartitionIndex); off_t start = partition->start * mVsHandle->block_size; off_t length = partition->len * mVsHandle->block_size; std::string description= partition->desc ; bool allocated=(partition->flags & TSK_VS_PART_FLAG_ALLOC); bool meta=(partition->flags & TSK_VS_PART_FLAG_META); //Avoid copying out extended partitions not marked as meta data partitions by setting the meta flag. //FIXME (THIS IS A NASTY HACK!) size_t i = description.find("Extended"); if (i != std::string::npos ) { meta=true; } i = description.find("(#"); if ( (i != std::string::npos ) && ((i+2) < description.length()) ) { //A child node can be an other extended table. int table_num = atoi(description.substr(i + 2, description.length() - 2).c_str()); *subent=new MmlsTable(mCarvpathTop,mVsHandle,table_num,description,start,length,mActivePartitionIndex); } else { //Or a leave node. if (mCarvpathTop) { //Represented either by a carvpath based node interface. *subent=new CarvPathPartition(mCarvpathTop,start,length,description,allocated,meta,mActivePartitionIndex); } else { //Or a stream based node interface. *subent=new StreamPartition(mImageHandle,start,length,description,allocated,meta,mActivePartitionIndex); } } return; };
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); }