经过前面的学习,也许大家会觉得我们离编一个病毒还很远。其实不然,这一篇我们就结合API函数,来一起完成一个简单的任务。
这个任务是什么呢?下面我来实现介绍一下,任务如下:
编一个程序,完成两个功能(用两个选项来选择)。
选项一:安装程序。
具体要求:
1、将程序自身复制到C盘根目录下,并命名为"virus.exe",并使之具有系统、只读、隐藏属性。
2、修改注册表,使"virus.exe"开机自动运行。
4、修改注册表,使所有隐藏文件均不可见。
选项二:卸载程序。
具体要求:
1、恢复注册表,取消"virus.exe"开机自动运行。
2、恢复注册表,使隐藏文件可见。
3、删除C盘根目录下的程序。
怎么样?这样的一个简单任务,大家还有兴趣吧?当然,我们现在所做的一切都是能简单则简单,所以大家不要问我为什么最后的程序会被杀毒软件拦截之类的问题哈~这个不属于现在讨论的话题。
这是一个简单的任务,可是,对于一个对API函数、对注册表不那么熟悉的人来说,也需要一点时间来消化,所以我们尽量详细些讲。但是API函数,我会越来越粗略地讲了。因为MSDN上有,大家可以自己查到,而且这个东西本来也是用的时候在查的,讲的太详细也只是浪费时间。好吧,现在我们就开始从头完成这样一个任务吧~
首先,这个任务有几个不同的功能需要实现,所以,很常规的,我们会将它们用不同的函数来实现。这样我就可以思路更清晰地来解决这些问题了。
一、复制。
看过前面的教程,我想大家不会觉得复制这样一个文件有什么困难吧?值得提一下的是,也许有人会突然转不过弯,我们如何得到程序自身的路径及文件名呢?大家还记得,main函数的其中一种写法吗?那就是int main(int argc, char *argv[])。这样大家就应该知道了吧?程序自身的文件名其实操作系统会告诉程序自己的,那就是argv[0]指向的字符串。不信大家可以编个程序试试,代码如下:
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("此程序的路径及名字:%s/n",argv[0]);
system("pause");
return 0;
}
这里就不多说了,我只把复制函数的代码贴出来,大家应该都能明白:
int selfcopy(const char *from,const char *to)
{
//用于复制的函数
FILE *f_from,*f_to;
if((f_from=fopen(from,"rb"))==NULL)
{
printf("目标文件不能读取!/n");
return -1;
}
if((f_to=fopen(to,"wb"))==NULL)
{
printf("不能写入磁盘,请确定你有足够的权限,且磁盘未满!/n");
return -1;
}
unsigned int count=0;
char tmp[512];
while(!feof(f_from))
{
count=fread(tmp,1,512,f_from); //计划读入一个扇区
fwrite(tmp,1,count,f_to); //写入实际读入的字符数
}
fclose(f_to);
fclose(f_from);
return 0;
}
二、修改文件属性。
你有过中病毒的经验吗?如果有的话,你就会很容易明白我们修改文件属性的原因。这其实是一种简单的自我保护方式。说它简单一方面是因为它很容易实现,另一方面是因为单单修改文件属性很难真正起到保护作用。
那么这个简单的功能如何实现呢?我们需要一个API函数,那就是:
BOOL SetFileAttributes(LPCTSTR lpFileName,DWORD dwFileAttributes)
第一个参数为字符串指针,指向文件的全路径文件名;第二个参数使用宏,设置文件的属性。常用的宏以及函数的具体用法,大家可以查看MSDN,注意要选Platform SDK下的函数看。
这里还需说明的是,我们在使用API函数的时候,需要使用一个可能大家不太熟悉的头文件,那就是<windows.h>,这里面定义了绝大多数API函数的原型,使用起来非常方便。
好了,那么具体我们如何修改设置一个文件的属性呢?我们如何将文件设置为“只读、系统、隐藏”呢?代码如下:
int hidefile(const char *filename)
{
return(!SetFileAttributes(filename,FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM));
}
这里其实直接调用API函数而不另写一个函数也可以,不过为了清晰思路,我们还是单独将它模块化好了。
同样的道理,如果我们需要将文件恢复到正常的属性怎么办呢?只需这样:
int displayfile(const char *filename)
{
return(!SetFileAttributes(filename,FILE_ATTRIBUTE_NORMAL));
}
这个简单吧?哈哈,这就是API的魅力!