程序如下:/*程序功能:根据病毒库查找病毒*/
#include<conio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdio.h>
#include<dir.h>
#include<dos.h>
#include<alloc.h>
#include<io.h>
FILE*fp;
Unsigned char d[2];/*用来存放临时读取的字节*/
unsigned char dat[100][256]; /*用来存放病毒特征码*/
unsigned char string[100][256];/*用来存放病毒提示信息*/
int vl;
/*特征码查找函数*/
int find(unsigned char *dat1,unsigned char *hex)
{
//获得字符串的长度
unsigned long len=strlen((char*)dat1);
unsigned long num=0,hnum=0,i;
for (i=0;i<len;i++)
{
if(dat1[i]!=hex[hnum])
{
/*遇到一个“?”号,则向前推进2个字符*/
if(dat1[i]=='?')
{
i++;
hnum+=2;
continue;
}
/*遇到一个“%”号,则向前推进32个字符*/
if(dat1[i]=='%')
{
i++;
for(num=0;num<32;num++)
{
if(dat1[i+1]==hex[hnum+num])
{
/*递归匹配字串*/
if(find(&dat1[i+1],&hex[hnum+num])==1
return 1;
}
}
}
return 0;
}
hnum++;
}
return 1;
}
/*在指定的文件中查找病毒*/
int findvirus(char*filename)
{
FILE *fh;
unsigned int rnum=1;
unsigned char *buf;
unsigned char *hex;
unsigned char x1,x2,vn[100];
unsigned long rsize=500,i,j,flen;
int v;
/*把字符串vn全部置0*/
strset((char*)vn,'0');
/*为匹配字符串分配空间,如果内存不足,则显示提示信息后,返回*/
if((hex=(unsigned char*)malloc(1000))==NULL)
{
puts("内存不足,请关闭一些程序以释放内存。");
return 1;
}
/*为缓冲区分配空间,如果内存不足,则显示提示信息后,返回*/
if((buf=(unsigned char*)malloc(500))==NULL)
{
puts("内存不足,请关闭一些程序以释放内存。");
return 1;
}
/*打开文件*/
fh=fopen(filename,"rb++");
/*获得文件长度*/
flen=filelength(fileno(fh));
/*rsize为每次读文件的字节数,初始值为500。如果文件长度少于等于500,则只需读一次就够了*/
if(flen<=rsize)
{
rsize=flen;
rnum=0;
}
for(j=0;j<=rnum;j++)
{
if(j==1)
fseek(fh,-rsize,SEEK_END);
else
fseek(fh,0,SEEK_SET);
/*开始读文件*/
fread(buf,rsize,1,fh);
/*关闭文件*/
fclose(fh);
/*把所读字节转换成十六进制形式表示,例如,把“A(65)”转换成4和1,从而形成41,以与文本特征码对应*/
for(i=0;I<rsize;i++)
{
x1=buf[i]/16;
x2=buf[i]-x1*16;
hex[2*i]=x1<10?x1+0x30:x1-10+0X41;
hex[2*i+1]=x2<10?x2+0x30:x2-10+0X41;
}
/*把所读信息与病毒库信息逐个比较,看是否匹配*/
for(v=0;v<=v1;v++)
{
for(i=0;i<rsize;i++)
{
if(hex[2*i]==dat[v][0]&&hex[2*i+1]==dat[v][1])
/*调用特征码查找函数*/
if(find(dat[v],&hex[2*i])==1)
{
if(vn[v]=='0')
{
vn[v]='1';
puts(" ");
/*显示找到病毒提示信息*/
puts(string[v]);
}
}
}
}
}
/*释放内存*/
free(buf);
free(hex);
return 0;
}
/*列出当前目录的文件*/
void findfile()
{
int p,x,y,hav,len;
struct ffblk dirment,fname;
char path[256];
/*获得当前路径*/
getcwd(path,256);
/*开始列文件*/
hav=findfirst("*.*",&fname,FA_RDONLY||FA_HIDDEN||FA_SYSTEM);
while(!hav)
{
/*x是屏幕的X坐标*/
x=wherex();
/*获得路径字符串长度*/
len=strlen(path);
/*清屏幕*/
clreol();
/*如果路径长度等于3,说明是根目录*/
if(len!=3)
printf("Scaning%s\\%s",path,fname.ff_name);
else
printf("Scaning%s%s",path,fname.ff_name);
/*如果是EXE文件或COM文件,则调用查病毒的函数*/
if((strstr(fname.ff_name,".EXE")!=NULL)||(strstr(fname.ff_name,".COM")!=NULL))
{
findvirus(fname.ff_name);
}
/*y是屏幕的Y坐标*/
y=wherey();
gotoxy(x,y);
/*查找下一个文件*/
hav=findnext(&fname);
}
/*查目录里的子目录,直到所有子目录查完*/
p=findfirst("*.*",&dirment,0x3f);
if(!p&&dirment.ff_name[0]=='.')
{
p=findnext(&dirment);
p=findnext(&dirment);
}
/*如果子目录非空*/
while(!p)
{
if((dirment.ff_attrib&0x10)==FA_DIREC)
{
chdir(dirment.ff_name);
/*递归调用自身*/
findfile();
chdir("..");
}
p=findnext(&dirment);
}
}
/*主函数*/
main(int argc,char**argv)
{
/*取当前盘符*/
char curdrive=getdisk();
char curpath[256],drive;
unsiged long n,dnum;
int end=0;/*病毒特征码和提示信息读取完毕的标志*/
FILE *fp;
union REGS regs;
/*检查程序运行参数是否正确,如果不正确,则显示用法后退出*/
if(argc<2)
{
printf("Usage: %s Drive",argv[0]);
exit(0);
}
/*调用33号中断的2号功能*/
regs.x.ax=2;
int86(0x33,®s,®s);
/*以只读方式打开病毒库文件*/
fp=fopen("virus.dat","r");
/*无法打开,则显示提示信息后退出*/
if(fp==NULL)
{
puts("无法打开病毒特征库,请检查特征库文件是否在当前目录下。");
exit(0);
}
/*把文件指针移到文件开头的第一个字节*/
fseek(fp,1,0);
/*假设病毒库中有1000条病毒信息,每循环一次,读取一条*/
for(v1=0;v1<1000;v1++)
{
/*下面循环读取病毒特征码,假设每条病毒特征码不超过256个字符*/
for(dnum=0,n=0;dnum<256;dnum++)
{
/*一次读一个字节*/
fread(d,1,1,fp);
/*如果所读的字节为“"”,说明已经读完,该病毒特征码没有256个字符,则增加结束符后,退出内循环*/
if(d[0]=='"')
{
dat[v1][n]=='\0';
break;
}
/*如果所读字节为空格,则继续读下一个字节*/
if(d[0]=='')
continue;
/*既非“"”,又非空格,则把读出的字符放到数组dat相应的单元里*/
dat[v1][n]==d[0];
n++;
}
/*下面循环读取病毒特征码后面的提示信息,假设每条提示信息不超过256个字符*/
for(dnum=0,n=0;dnum<256;dnum++)
{
/*如果所读的字节为NULL,说明整个库已经读完,则增加结束符,结束标志置位后,退出内循环*/
if(fread(d,1,1,fp)==NULL)
{
string[v1][0]='\0';
end=1;/*结束标志置位*/
break;
}
/*如果所读的字节为“"”,则说明已经读完,该条提示信息没有256个字符,则增加结束符后,退出内循环*/
if(d[0]=='"')
{
string[v1][n]='\0';
break;
}
/*如果所读字节是不可显示字符,则继续读取下一个字节*/
if(d[0]<0x20)
continue;
/*既不是“"”,也不是空白,又是可显示字符,则把所读字节放入string数组的相应单元里*/
string[v1][n]=d[0];
n++;
}
/*把dat数组字符串转换为大写*/
strupr((char*)dat[v1]);
/*如果结束标志已置位,则全部读完,没有1000条信息,直接跳出大循环*/
if(end==1)
break;
}
/*获得系统当前目录,保存到curpath中*/
getcwd(curpath,256);
/*把磁盘盘符转换为数字*/
drive=toupper(argv[1][0]-'A';
/*设置系统当前盘为参数指定的盘*/
setdisk(drive);
/*设置系统当前目录为根目录*/
chdir("\\");
/*设置系统当前目录为参数指定的目录*/
chdir(argv[1]);
/*调用查找病毒的函数*/
findfile();
/*恢复原来的当前盘*/
setdisk(curdrive);
/*恢复原来的当前目录*/
chdir(curpath);
/*关闭文件*/
fclose(fp);
/*清屏幕*/
clreol();
}