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

📄 aimage_os.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
字号:
#include "config.h"#include "afflib.h"#include "afflib_i.h"#include "aimage.h"#include "imager.h"/* ident_update_seg: * If af!=NULL, then update segname to contain the string str. * Otherwise just print it (for debugging) */void ident_update_seg(AFFILE *af,char *segname,char *str,int is_number){    if(af){	if(is_number){	    af_update_seg(af,segname,atoi(str),0,0);	}	else{	    af_update_seg(af,segname,0,str,strlen(str));	}    }    else{	printf("%s: %s\n",segname,str);    }}/* checkline: * Looks for a name in a line in a buf and, if found, * make a copy of the text, put a copy of the next into the * AFFILE... */void checkline(char *name,char *segname, char *buf,char *copy,AFFILE *af,int is_number){    while(buf[0] && isspace(buf[0])) buf++; // advance buf to end of spaces    char *pos = strstr(buf,name);    if(pos==0) return;    /* The string was found */    char *cc = pos + strlen(name);		// skip past to the end of the string    while(*cc && isspace(*cc)) cc++;	// scan to end of spaces    char *dd = index(cc,'\n');		// can we find a \n?    if(dd) *dd = '\000';		// yes; clear it    ident_update_seg(af,segname,cc,is_number);    if(copy) strcpy(copy,cc);		// make a copy}/* FreeBSD-specific ident routines */#ifdef __FreeBSD__#include <sys/param.h>#include <sys/mount.h>int freebsd_get_ata_params(const char *infile,int *controller,int *channel){  int adnum;  if(sscanf(infile,"/dev/ad%d",&adnum)==1){      if(controller) *controller = adnum / 2;      if(channel)    *channel    = adnum % 2;      return 0;  }  return(-1);}/* fix_freebsd_sn: * FreeBSD 6.0 release returns ^_ as the serial number of some USB devices. * If that is the case here, scan the output of sysctl -a to find the * device and put in the S/N. This can fail if there is more than * one USB device with the same S/N. */#include <regex.h>static void fix_freebsd_sn(AFFILE *af,char *serial_number,int sn_len,char *device_model){    char word1[1024];    char buf[1024];    /* Get the first word of the model number */    strlcpy(word1,device_model,sizeof(word1));    char *cc = index(word1,' ' );    if(cc) *cc = '\000';    sprintf(buf,"sysctl -a dev.umass");    FILE *f = popen(buf,"r");    int in_section = 0;    while(!feof(f)){	if(fgets(buf,sizeof(buf),f)){	    /* See if this is the new section */	    if(strstr(buf,"dev.umass.") && strstr(buf,"desc:")){		if(strstr(buf,word1)){		    in_section = 1;		}		else {		    in_section = 0;		}	    }	    if(in_section){		regex_t r_sn;		if(regcomp(&r_sn,"sernum=\"([^\"]*)\"",REG_EXTENDED|REG_ICASE)) err(1,"regcomp");		regmatch_t pm[2];		memset(pm,0,sizeof(pm));		if(regexec(&r_sn,buf,2,pm,REG_NOTBOL)==0){		    char b2[1024];		    memset(b2,0,sizeof(b2));		    strncpy(b2,buf+pm[1].rm_so,pm[1].rm_eo-pm[1].rm_so);		    strlcpy(serial_number,b2,sn_len);		    ident_update_seg(af,AF_DEVICE_SN,serial_number,0);		}		regfree(&r_sn);	    }	}    }    pclose(f);}#define IDENT_DEFINED/* ident for freebsd */void imager::ident(){    int controller = 0;    int channel    = 0;    /* Check for a SCSI drive.     * This needs to be cleaned up; right now it assumes SCSI bus 2.     */    int da_dev = -1;    if(sscanf(infile,"/dev/da%d",&da_dev)==1){	char checkbuf[64];	char want[64];	char buf[256];	/* Now do the devlist to figure out which device this is... */	scsi_bus = -1;			// for now	snprintf(want,sizeof(want),"da%d",da_dev);	sprintf(checkbuf,"camcontrol devlist");	FILE *f = popen(checkbuf,"r");	while(!feof(f)){	    if(fgets(buf,sizeof(buf),f)){		if(strstr(buf,want)){	// this is the correct line		    char *cc = strstr(buf,"at scbus");		    if(cc){			if(sscanf(cc,				  "at scbus%d target %d lun %d (pass%d,da%d)",				  &scsi_bus,&scsi_tid,&scsi_lun,				  &scsi_pass,&da_dev)==5){			    break;		// found it!			}			if(sscanf(cc,				  "at scbus%d target %d lun %d (da%d,pass%d)",				  &scsi_bus,&scsi_tid,&scsi_lun,				  &da_dev,&scsi_pass)==5){			    break;		// found it!			}		    }		}	    }	}	pclose(f);	if(scsi_bus==-1) err(1,"can't find SCSI device for %s",infile);	/* Now we need to inquiry */	sprintf(checkbuf,"camcontrol inquiry %d:%d",scsi_bus,scsi_tid);	f = popen(checkbuf,"r");	char capbuf[65536];	capbuf[0] = 0;      	while(!feof(f)){	    if(fgets(buf,sizeof(buf),f)){		strlcat(capbuf,buf,sizeof(capbuf));		char *cc = index(buf,'>'); // see if it should be terminated		if(cc) *cc = 0;		sprintf(checkbuf,"pass%d: <",scsi_pass);		checkline(checkbuf,AF_DEVICE_MODEL,buf,device_model,af,0);		sprintf(checkbuf,"pass%d: Serial Number ",scsi_pass);		checkline(checkbuf,AF_DEVICE_SN,buf,serial_number,af,0);	    }	}	pclose(f);	if(serial_number[0]=='\037' && serial_number[1]=='\000'){	    fix_freebsd_sn(af,serial_number,sizeof(serial_number),device_model);	}	ident_update_seg(af,AF_DEVICE_CAPABILITIES,capbuf,0);	return;    }				         /* Check for an IDE drive */    if(strncmp(infile,"/dev/ad",7)==0 &&       freebsd_get_ata_params(infile,&controller,&channel)==0){	char capbuf[65536];	char buf[256];#if __FreeBSD_version > 600000	/* Syntax of command was changed in FreeBSD 6.0 */	sprintf(buf,"atacontrol cap ad%d",controller*2+channel);#else	sprintf(buf,"atacontrol cap ata%d %d",controller,channel);#endif	capbuf[0] = 0;	FILE *f = popen(buf,"r");	while(!feof(f)){	    if(fgets(buf,sizeof(buf),f)){		buf[sizeof(buf)-1] = 0;	// make sure it is null-terminated		strlcat(capbuf,buf,sizeof(capbuf));		checkline("device model",AF_DEVICE_MODEL,buf,device_model,af,0);		checkline("serial number",AF_DEVICE_SN,buf,serial_number,af,0);		checkline("firmware revision",AF_DEVICE_FIRMWARE,buf,firmware_revision,af,0);		checkline("cylinders",AF_CYLINDERS,buf,0,af,1);		checkline("heads",AF_HEADS,buf,0,af,1);		checkline("sectors/track",AF_SECTORS_PER_TRACK,buf,0,af,1);	    }	}	pclose(f);	ident_update_seg(af,AF_DEVICE_CAPABILITIES,capbuf,0);	return;    }}/* FreeBSD ata attach commands */#define MAKE_ATA_ATTACH_COMMANDS_DEFINEDvoid make_ata_attach_commands(char *attach,char *detach,char *master,char *slave,int dev){    sprintf(attach,"atacontrol attach ata%d",dev);    sprintf(detach,"atacontrol detach ata%d",dev);    sprintf(master,"/dev/ad%d",dev*2);    sprintf(slave,"/dev/ad%d",dev*2+1);}/* FreeBSD scsi attach commands. Actually does it and returns 0 if successful, * as well as the device. */#define SCSI_ATTACH_DEFINEDint  scsi_attach(char *fname,int fname_len,		 class imager *im) // returns 0 if successful & sets fname{    char buf[256];    char looking[64];    sprintf(buf,"camcontrol rescan %d",im->scsi_bus);    system(buf);    sprintf(looking,"scbus%d",im->scsi_bus);	// what I'm looking for    /* Now, see if there is a device on this scsi bus */    FILE *f = popen("camcontrol devlist","r");    if(!f) err(1,"camcontrol devlist");    while(!feof(f)){	memset(buf,0,sizeof(buf));	if(fgets(buf,sizeof(buf),f)){	    char *cc = strstr(buf,looking);	    if(cc){		int da_num;		/* Get the target and lun.		 * Notice that FreeBSD is inconsistent in the way that this		 * is reported.		 */		if(sscanf(cc+strlen(looking)+1,			  "target %d lun %d (pass%d,da%d)",			  &im->scsi_tid,&im->scsi_lun,&im->scsi_pass,&da_num)==4){		    snprintf(fname,fname_len,"/dev/da%d",da_num);		    return 0;		}		if(sscanf(cc+strlen(looking)+1,			  "target %d lun %d (da%d,pass%d)",			  &im->scsi_tid,&im->scsi_lun,&da_num,&im->scsi_pass)==4){		    snprintf(fname,fname_len,"/dev/da%d",da_num);		    return 0;		}		err(1,"could not parse: '%s'",buf);	    }	}    }    pclose(f);    fprintf(stderr,"No SCSI device found:\n");    fprintf(stderr,"# camcontrol rescan all\n");    system("camcontrol rescan all");    return -1;				// failure	}#endif#ifdef linux#include <dirent.h>static void getfile(const char *dirname,const char *filename,char *copy,		    int copysize,		    AFFILE *af,char *segname){    char path[MAXPATHLEN];    char buf[1024];    /* Build the pathname we are supposed to get */    memset(buf,0,sizeof(buf));    strlcpy(path,dirname,sizeof(path));    strlcat(path,filename,sizeof(path));    FILE *f = fopen(path,"r");    if(f){	if(fgets(buf,sizeof(buf),f)){	    char *cc = rindex(buf,'\n');	    if(cc) *cc = '\000';	// remove trailing \n	    ident_update_seg(af,segname,buf,0);	    if(copy) strlcat(copy,buf,copysize);		}	fclose(f);    }}#define IDENT_DEFINEDvoid imager::ident(){    /* Is this a regular file? If so, just return */    struct stat so;    if(stat(infile,&so)==0){	if(so.st_mode & S_IFMT) return;    }    /* Check to see if infile is a USB device. If so, print things about it.     * If the Linux /sys file system is installed, then /sys/bus/scsi/devices/.../block     * are symlinks to the actual devices.     * These have the same name as the /dev/<name>, minus the partition.     */     if(strncmp(infile,"/dev/",5)==0){	char *cc;	char sdname[MAXPATHLEN];	memset(sdname,0,sizeof(sdname));	strcpy(sdname,infile+5);	/* If a partition name was provided, eliminate it */	for(cc=sdname;*cc;cc++){	    if(isdigit(*cc)){		*cc = '\000';		break;	    }	}	/* Look to see if this is a USB device*/	DIR *dir = opendir("/sys/bus/scsi/devices/");	struct dirent *dp;	while((dp = readdir(dir))!=0){	    if(dp->d_name[0]=='.') continue; // skip the dot names	    char dirname[MAXPATHLEN];	    strlcpy(dirname,"/sys/bus/scsi/devices/",sizeof(dirname));	    strlcat(dirname,dp->d_name,sizeof(dirname));	    char devname[MAXPATHLEN];	    strlcpy(devname,dirname,sizeof(devname));	    strlcat(devname,"/",sizeof(devname));	    strlcat(devname,"/block",sizeof(devname));	    /* If this is a link, then stat it */	    char path[MAXPATHLEN];	    memset(path,0,sizeof(path));	    if(readlink(devname,path,sizeof(path))>0){		cc = rindex(path,'/');	// find the end of the link		if(cc && strcmp(cc+1,sdname)==0){		    /* Found it!		     * Now, it turns out that dirname is also a symbolic link.		     * Use it to find the directory where the USB information is stored.		     */		    char usbdir[MAXPATHLEN];		    strlcpy(usbdir,dirname,sizeof(usbdir));		    strlcat(usbdir,"/../../../../",sizeof(usbdir));		    device_model[0] = 0;		    serial_number[0] = 0;		    getfile(usbdir,"manufacturer",device_model,sizeof(device_model),			    af,AF_DEVICE_MANUFACTURER);		    strlcat(device_model," ",sizeof(device_model));		    getfile(usbdir,"product",device_model,sizeof(device_model),			    af,AF_DEVICE_MODEL);		    getfile(usbdir,"serial",serial_number,sizeof(serial_number),			    af,AF_DEVICE_SN);		    //getfile(usbdir,"version",0,0,af,AF_DEVICE_FIRMWARE);		    return;		// we have successfully identified the device		}	    }	}	/* Fall back to a regular hard drive */	if(access(infile,R_OK)==0){	    char capbuf[65536];	    char buf[256];	    if(af_hasmeta(infile)) return;	// something is wrong here	    snprintf(buf,sizeof(buf),"hdparm -I %s",infile);	    capbuf[0] = 0;	    FILE *f = popen(buf,"r");	    while(!feof(f)){		if(fgets(buf,sizeof(buf),f)){		    buf[sizeof(buf)-1] = 0;	// make sure it is null-terminated		    strlcat(capbuf,buf,sizeof(capbuf));	// append to the buffer		    		    /* Now check for each of the lines */		    checkline("Model Number:",AF_DEVICE_MODEL,buf,device_model,af,0);		    checkline("Serial Number:",AF_DEVICE_SN,buf,serial_number,af,0);		    checkline("Firmware Revision:",AF_DEVICE_FIRMWARE,			      buf,firmware_revision,af,0);		    checkline("cylinders",AF_CYLINDERS,buf,0,af,1);		    checkline("heads",AF_HEADS,buf,0,af,1);		    checkline("sectors/track",AF_SECTORS_PER_TRACK,buf,0,af,1);		}	    }	    pclose(f);	    ident_update_seg(af,AF_DEVICE_CAPABILITIES,capbuf,0);	}    }    return;				// can't figure it out}/* * Here are some parameters you may find interesting: *       hdparm -R 0x1700 0 0 /dev/hda   (to remove /dev/hda) *       ide2: BM-DMA at 0xb800-0xb807, BIOS settings: hde:DMA, hdf:pio * Unfortunately, I can't get Linux ATA attach to work. Can you? * Note: "These mknod calls should be eliminated. If this is not possible, * a secure sub-directory should be created to hold them, and * umask() should be called to control access." --- VSecurity */#define MAKE_ATA_ATTACH_COMMANDS_DEFINEDvoid make_ata_attach_commands(char *attach,char *detach,char *master,char *slave,int dev){#if 0    system("/sbin/mknod /tmp/hda c  3 0");    system("/sbin/mknod /tmp/hdb c  3 64");    system("/sbin/mknod /tmp/hdc c 22 0");    system("/sbin/mknod /tmp/hdd c 22 64");    sprintf(attach,"hdparm -R %d",dev);    sprintf(detach,"hdparm -U %d",dev);    sprintf(master,"/dev/ad%d",dev*2);    sprintf(slave,"/dev/ad%d",dev*2+1);#endif}/* Linux scsi attach commands *//* I can't figure out how to do this. */void make_scsi_attach_commands(char *cmd_attach,char *cmd_detach, int scsi_bus){    cmd_attach[0] = 0;    cmd_detach[0] = 0;}#define SCSI_ATTACH_DEFINEDint  scsi_attach(char *fname,int fname_len,class imager *) // returns 0 if successful & sets fname{    return -1;				// can't do it}#endif/**************************************************************** *** MacOS ****************************************************************/#ifdef __APPLE__int get_block(FILE *f,char *buf,int buflen){    /* Get a block from FILE f, where a block is defined as lines until a \n\n */    memset(buf,0,buflen);    buflen--;				// so we won't lose the last \n    int consecutive_newlines = 0;    int lns = 0;    while(!feof(f)){	if(!fgets(buf,buflen,f)) break;	if(buf[0]=='\n'){	    return 1;			// blank line	}	consecutive_newlines = 0;	int bytes = strlen(buf);	// number of bytes that was read	buf += bytes;	buflen -= bytes;	lns++;    }    return lns>0;}#define IDENT_DEFINEDvoid imager::ident(){    if(strncmp(infile,"/dev/",5)==0){	char *name = infile+5;	char buf[65536];	char looking[65536];	snprintf(looking,sizeof(looking),"BSD Name: %s",name);	FILE *f = popen("system_profiler SPUSBDataType","r");	while(get_block(f,buf,sizeof(buf))){	    if(strstr(buf,looking)){	// did I find the block I'm looking for?		checkline("Serial Number:",AF_DEVICE_SN,buf,serial_number,af,0);		checkline("Manufacturer:",AF_DEVICE_MANUFACTURER,buf,device_model,af,0);	    }	}	pclose(f);    }    }#endif/* If we do not have an ident, make it a stub... */#ifndef IDENT_DEFINEDvoid imager::ident(){    return;}#endif#ifndef MAKE_ATA_ATTACH_COMMANDS_DEFINED/* We do not have these defined either... */void make_ata_attach_commands(char *attach,char *detach,char *master,char *slave,int dev){    attach[0] = 0;    detach[0] = 0;    master[0] = 0;    slave[0]  = 0;}#endif#ifndef SCSI_ATTACH_DEFINEDint  scsi_attach(char *fname,int fname_len,class imager *) // returns 0 if successful & sets fname{    return -1;				// can't do it}#endif

⌨️ 快捷键说明

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