⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imager.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		 */		if(((direction==1) && (last_read_short==false)) ||		   ((direction==-1) && (valid_reverse_data==true))){		    write_data(buf,data_offset,bytes_to_read);		    bad_sectors_read += sectors_to_read; // I'm giving up on them...		    hash_invalid = true;		}				if(++consecutive_read_error_regions<retry_count){ //		    /* Just skip to the next area */		    int sectors_to_bump = readsectors / 2;		    if(sectors_to_bump==0) sectors_to_bump = 1;	// need to bump by a positive amount		    		    /* Is there room left? */		    if(low_water_mark + sectors_to_bump > high_water_mark){			break;		// no more room.		    }		    		    if(direction == 1){			low_water_mark += sectors_to_bump;	// give a little bump		    }		    else {			high_water_mark -= sectors_to_bump;		    }		}		else {		    /* Retry count in this directory exceeded. Either reverse		     * direction or give up...		     */		    if(direction ==  1){			consecutive_read_errors = 0; // reset count			consecutive_read_error_regions = 0;			direction = -1;			continue;		    }		    if(direction == -1){			/* That's it. Give up */			break;		    }		    errx(1,"imager: Unknown direction: %d\n",direction);		}	    }	}	if(error_mask==1){	    /* Stop reading at the first error and write the incomplete buffer */	    if(bytes_read>0){		write_data(buf,data_offset,bytes_read);	    }	    break;	}    }    imaging = false;    free(buf); buf = 0;				// no longer valid    free(badflag); badflag = 0;}/* Returns 0 if okay, -1 if failure. */int imager::set_input_fd(int ifd){    in = ifd;    /* Make sure infile is actually a device, and not a file */    struct stat so;    if(fstat(ifd,&so)){	perror("fstat");	return -1;    }    int mode = so.st_mode & S_IFMT;    struct af_figure_media_buf afb;    memset(&afb,0,sizeof(afb));    /* Now figure out how many input blocks we have */    if(mode==S_IFBLK || mode==S_IFCHR){	if (af_figure_media(in,&afb)){	    return -1;	}	sector_size = afb.sector_size;	total_sectors = afb.total_sectors;	maxreadblocks = afb.max_read_blocks;	return 0;    }    if(mode==S_IFREG){			// regular file	if(allow_regular==false){	    fprintf(stderr,"input is a regular file.\n");	    fprintf(stderr,"Use afconvert or aimage -E to convert regular files to AFF.\n");	    return -1;	}	/* Just got with the file size... */	sector_size  = 512;		// default	total_sectors= so.st_size / sector_size;	maxreadblocks = 0;	return 0;    }    /* Okay. We don't know how big it will be, so just get what we can... */    sector_size   = 512;		// it's a good guess    total_sectors = 0;			// we don't know    maxreadblocks = 0;			// no limit    return 0;}int imager::set_input(const char *name){    /* Set the input given a "name"     *      * First, try to open the input file.     * If the name specified by the user can be opened, use it.     * If the name cannot be opened work, see if it is a operating system     * specific filename such as "ide0" or "ata0", in which the     * operating system-specific code will attempt to attach the     * device.     */    /* Check for '-' which is stdin */    if(strcmp(name,"-")==0){	strcpy(infile,name);		// make a local copy	return set_input_fd(0);			// file descriptor 0 is stdin    }    /* Check for 'listen:%d' which means listen for a TCP connection */    int port;    if(sscanf(name,"listen:%d",&port)==1){	if(socket_listen(port)) return -1;	// sets infile	sector_size = 512;		// no rationale for picking anything else	return 0;    }    /* The name must be a file. See if we can open it... */    int ifd = open(name,O_RDONLY);    if(ifd>0){	strcpy(infile,name);		// make a local copy	return set_input_fd(ifd);    }    /* Attempt to open infile failed; check for a special     * device name...     */    ifd = open_dev(name);    if(ifd>0){	return set_input_fd(ifd);    }    /* If we haven't been able to open the something by this point, give up. */    perror(name);    return -1;}void imager::hash_setup(){    /* Set up the MD5 & SHA1 machinery */    MD5_Init(&md5);    SHA1_Init(&sha);}/* start_recover_scan(): * Do a recover scan... * Try to read all of the pages that are not in the image */void imager::start_recover_scan(){    if(total_sectors==0){	err(1,"total_sectors not set. Cannot proceed with recover_scan");    }    if(af->image_sectorsize==0){	err(1,"af->image_sectorsize not set. Cannot proceed with recover_scan");    }    if(af->image_pagesize==0){	err(1,"af->image_pagesize not set. Cannot proceed with recover_scan");    }    int64 sectors_per_page = af->image_pagesize / af->image_sectorsize;    int64 num_pages = (total_sectors+sectors_per_page-1) / sectors_per_page;    int *pages = (int *)calloc(sizeof(int *),num_pages);    printf("There are %qd pages... Checking to see which are in image...\n");    /* Now figure out which pages we have.     * This only works with true AFF files, because we go directly to the TOC cache.     */    for(int64 i=0;i<num_pages;i++){	char segname[AF_MAX_NAME_LEN];	snprintf(segname,sizeof(segname),AF_PAGE,i);	if(af_toc(af,segname)){	    printf("Page %qd is in the image...\r",i);	    pages[i]=1; // note that we have this page	}    }    /* Print the missing pages: */    int missing_pages = 0;    printf("Missing pages:\n");    for(int64 i=0;i<num_pages;i++){	if(pages[i]==0){	    printf("%qd ",i);	    missing_pages++;	}    }    printf("\n");    printf("Total missing pages: %d\n",missing_pages);    /* Now randomly try to get each of the missing pages */#ifdef HAVE_SRANDOMDEV    srandomdev();#endif    while(missing_pages>0){	int random_page = random() % num_pages;	while(pages[random_page]!=0) random_page = (++random_page) % num_pages;	printf("*** try for page %d\n",random_page);	uint64 start_sector = random_page * sectors_per_page;	uint64 end_sector   = start_sector + sectors_per_page;	image_loop(start_sector,end_sector,1,opt_readsectors,1);	pages[random_page] = 1;		// did that page	missing_pages--;    }    free(pages);    exit(0);}/* start_imaging2(): * Actually run the imaging */void imager::start_imaging2(){    retry_count = opt_retry_count;    /* See if the skipping makes sense */    if(!opt_skip_sectors){	if(opt_skip % sector_size != 0){	    fprintf(stderr,		    "Skipping must be an integral multiple of sector size "		    "(%d bytes)\n",sector_size);	    imaging_failed = true;	    return;	}	opt_skip /= sector_size;	// get the actuall offset    }    int starting_direction = 1;    if(opt_reverse) starting_direction = -1;    /****************************************************************     *** Start imaging     ****************************************************************/    signal(SIGINT,sig_intr);	// set the signal handler    hash_setup();		// get ready...    image_loop(opt_skip,	       total_sectors,starting_direction,	       opt_readsectors,opt_error_mode); // start the process    signal(SIGINT,0);		// unset the handler    /****************************************************************     *** Finished imaging     ****************************************************************/    /* Calculate the final MD5 and SHA1 */    MD5_Final(final_md5,&md5);    SHA1_Final(final_sha1,&sha);}/* Start the imaging. * If files are specified, opens them. * then does the imaging. * Then closes the files. */int imager::start_imaging(){    output_ident = new class ident(fname_aff[0] ? fname_aff : fname_raw);    /* If the user is imaging to an AFF file,     * open it and try to ident the drive.     * Drive ident is not done if writing to a raw file, because     * there is no place to store the ident information. This will be changed     * when we can write an XML log.     */    if(af){	af->tag = (void *)this;			// remember me!	/* If the segment size hasn't been set, then set it */	if(opt_append){	    /* Make sure that the AFF file is for this drive, and set it up */	}	else {	    ident();			// ident the drive if possible	    af_update_seg(af,AF_ACQUISITION_COMMAND_LINE,0,command_line,strlen(command_line));	    af_update_seg(af,AF_ACQUISITION_DEVICE,0,infile,strlen(infile));	    af_set_sectorsize(af,sector_size);	    af_set_pagesize(af,opt_pagesize);	// sets current page size	    if(opt_maxsize){		if(af_set_maxsize(af,opt_maxsize)){		    exit(-1);		}	    }	    if(total_sectors>0){		af_update_segq(af,AF_DEVICE_SECTORS,(int64)total_sectors);	    }	    if(opt_no_ifconfig==0){		char *macs = ident::mac_addresses();		if(macs){		    af_update_seg(af,AF_ACQUISITION_MACADDR,0,macs,strlen(macs));		    free(macs);		}	    }	    if(opt_no_dmesg==0){		char *dmesg = ident::dmesg();		if(dmesg && strlen(dmesg)){		    af_update_seg(af,AF_ACQUISITION_DMESG,0,dmesg,strlen(dmesg));		    free(dmesg);		}	    }	    if(af_get_seg(af,AF_IMAGE_GID,0,0,0)!=0){		unsigned char bit128[16];		RAND_pseudo_bytes(bit128,sizeof(bit128));		af_update_seg(af,AF_IMAGE_GID,0,bit128,sizeof(bit128));	    }	}	af_set_callback(af,segwrite_callback);	char timeseg[65536];	size_t datalen = sizeof(timeseg);	memset(timeseg,0,sizeof(timeseg));	af_get_seg(af,AF_ACQUISITION_DATE,0, (unsigned char *)timeseg,&datalen);	time_t t = time(0);	char timebuf[64];	strftime(timebuf,sizeof(timebuf),"%Y-%m-%d %H:%M:%S\n",localtime(&t));	strlcat(timeseg,timebuf,sizeof(timeseg));	af_update_seg(af,AF_ACQUISITION_DATE,0,timeseg,strlen(timeseg));    }    /* Here is where the imaging takes place.     * Do it unless ifd==FD_IDENT, which is the fictitious FD.     */    if(logfile){	fprintf(logfile,"aimage infile=%s ",infile);	if(fname_raw[0]) fprintf(logfile,"outfile_raw=%s ",fname_raw);	if(fname_aff[0]) fprintf(logfile,"outfile_aff=%s ",fname_aff);	fprintf(logfile,"\n");    }    if(in!=FD_IDENT){	imaging_timer.start();	if(opt_recover_scan){	    start_recover_scan();	}	else{	    start_imaging2();	}	imaging_timer.stop();    }    /* AFF Cleanup... */    if(af){	if(hash_invalid==false){	    if(af_update_seg(af,AF_MD5,0,final_md5,16)){		if(errno!=ENOTSUP) perror("Could not update AF_MD5");	    }	    if(af_update_seg(af,AF_SHA1,0,final_sha1,20)){		if(errno!=ENOTSUP) perror("Could not update AF_SHA1");	    }	}	else {	    af_del_seg(af,AF_MD5);	// because it is not valid	    af_del_seg(af,AF_SHA1);	}	if(af_update_segq(af,AF_BADSECTORS, (int64)bad_sectors_read)){	    if(errno!=ENOTSUP) perror("Could not update AF_BADSECTORS");	}	if(af_update_segq(af,AF_BLANKSECTORS, (int64)total_blank_sectors)){	    if(errno!=ENOTSUP) perror("Could not update AF_BLANKSECTORS");	}	unsigned long elapsed_seconds = (unsigned long)imaging_timer.elapsed_seconds();	if(af_update_seg(af,AF_ACQUISITION_SECONDS,elapsed_seconds,0,0)){	    if(errno!=ENOTSUP) perror("Could not update AF_ACQUISITION_SECONDS");	}    }    return 0;}/* Listen for a local socket connection and return the * file descriptor... */int imager::socket_listen(int port){    struct sockaddr_in local;    struct sockaddr_in remote;    socklen_t rsize = sizeof(remote);    int sock = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);    /* Open a listening socket ... */    memset(&local,0,sizeof(local));    memset(&remote,0,sizeof(remote));#ifdef HAVE_SOCKADDR_SIN_LEN    local.sin_len = sizeof(sockaddr_in);#endif    local.sin_family = AF_INET;    local.sin_port   = htons(port);	// listen on requested port.    if(bind(sock,(sockaddr *)&local,sizeof(local))) err(1,"bind");    if(listen(sock,0)) err(1,"listen");		// listen, and only accept one    printf("Listening for connection on port %d...\n",port);    in = accept(sock,(sockaddr *)&remote,&rsize);    if(in<0){	perror("accept");	in = 0;	return -1;    }    strcpy(infile,inet_ntoa(remote.sin_addr));    printf("Connection accepted from %s\n",infile);    return 0;}/* final_report(): * Let's make the user feel good... */void imager::final_report(){    bold("****************************** IMAGING REPORT ******************************");    putchar('\n');    printf("Input: "); bold(infile); putchar('\n');    if(device_model[0]){	printf("  Model: ");	bold(device_model);    }    if(serial_number[0]){	printf("  S/N: ");	bold(serial_number);    }    putchar('\n');    if(fname_aff[0]){	printf("  AFF Output file: ");	bold(fname_aff);    }    if(fname_raw[0]){	printf("   Raw Output file: ");	bold(fname_raw);    }    putchar('\n');        char buf[64];    printf("  Bytes read: %s\n", af_commas(buf,total_bytes_read));    printf("  Bytes written: %s\n", af_commas(buf,callback_bytes_written));    char print_buf[256];    printf("\n");    if(hash_invalid==false){	printf("raw image md5:  %s\n",	       af_hexbuf(print_buf,sizeof(print_buf),final_md5,16,opt_hexbuf));		printf("raw image sha1: %s\n",	       af_hexbuf(print_buf,sizeof(print_buf),final_sha1,20,opt_hexbuf));    }    if(imaging_failed){	printf("\nTHIS DRIVE COULD NOT BE IMAGED DUE TO A HARDWARE FAILURE.\n");    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -