一、引言
公用机房的防破坏问题一直就是令管理员头疼的问题,也是保障机房有效完成上机任务的关键问题。最彻底的解决办法是买硬盘保护卡,可是每块上百元的价格又令人望而却步。现有一些软件和文章也提供了解决办法,但有如下一些缺点:
1、要占有大量的硬盘空间。
2、恢复的时间太长。
3、有些防护不彻底,dos和windows方式不能兼顾。
4、无法防止使用者从A驱启动,恶意破坏。
征对以上的一些不足,我们自己编写了一个软件,来模仿硬盘写保护卡的功能,他可以对硬盘的C分区进行写保护,还可防止学生从A盘启动来恶意破坏硬盘,彻底封杀了学生的破坏之道。经我们机房80台装有Pwin98系统的计算机试用,再也没有因学生的破坏而重装系统,而且有一定的防病毒的能力。
二、硬盘的写保护
在dos时代,操作系统对磁盘的访问最终都是通过BIOS中断的 int 13h来实现的。在PWIN9X操作系统中,我们经过实验,发现他并没有通过int 13h,而是通过自己的32位的保护模式下的磁盘驱动程序来访问磁盘,这给我们要实现dos和pwin9X下的统一保护带来了难题。经过实验,我们发现Pwin9X一样可采用16位的磁盘驱动程序,即int 13h。只需在系统属性->性能->文件系统->疑难解答中禁用32位的保护模式下的磁盘驱动程序即可。
虽然,这样使pwin9x的磁盘操作工作在16位方式下,磁盘访问性能有所降低,但是,这为我们的磁盘写保护带来了方便,使得在pwin9x下也可实现磁盘的写保护。
使用int 13h访问磁盘扇区,读使用02h或0ah号功能,写使用03h或0bh号功能,他们的入口参数是:
AH=功能号
AL=要访问的扇区数
DL=驱动器号(第一硬盘为80h)
DH=磁头号
CL=低6位是起始扇区号,高2位是拄面号的高2位
CH=10位拄面号的低8位
由于int 13h采用10位二进制位来表示拄面号,所以他的拄面号不能超过1023。在硬盘“LBA”工作方式下,他最大可访问为8.4G的空间,因此,本文的实现方法只对C分区容量小于8.4G的硬盘适用。
要对硬盘写保护,我们采用拦截int 13h的读和写功能的办法,使系统对int 13h的读写请求先进入自编的程序,如果为写C盘,则返回,如果不是写C盘,则进入真正的int 13h。要使拦截工作最为彻底,我们通过换主引导记录的办法,使计算机最先执行我们的程序。从而驻留自编的程序,然后才进入正常的启动过程。具体流程如下:
(1)计算机加电启动,执行BIOS程序。
(2)执行我们的保护系统,保护系统完成修改中断向量表和使新的int 13h程序驻留内存的工作。然后加载旧的主引导记录,转向旧的主引导记录执行。
(3)旧的主引导记录执行,机器正常引导操作系统。
新的int 13h的处理流程如下:
(1)是对硬盘操作吗?不是则转(6)。
(2)是03h或0bh功能吗?不是则转(6)。
(3)判断是否读0柱0头1扇区,如是,则扇区号加1,指向真正的分区表并转(6)。
(4)计算请求拄面号,如果大于C盘的末拄面号,则转(6)。
(5)中断返回,什么也不做。
(6)转旧的int 13h。
三、防止从A驱启动
硬盘进行了写保护,可是对稍有操作知识的使用者都会从A盘启动,然后为所欲为。你把CMOS设置为不许A盘启动,可是使CMOS口令失效的方法已成了公开的"秘密"。所以,只有使计算机无法从A盘启动,才能保证C盘的有效保护。经过实验,在dos和pwin9x系统下,将分区表的主DOS分区表置为"ff",并将扩展分区的起始扇区指向主引导扇区,就可使dos系统无法从A盘启动,这也许是dos设计有问题,不过,事实就是如此,我们可以加以利用。
四、实现过程
1、编写自己的主引导记录程序
在debug下输入:
-a100
26E4:0100 CLI
26E4:0101 XOR AX,AX ;初始化段寄存器,指向0000:7c00
26E4:0103 MOV SS,AX
26E4:0105 MOV SP,7C00
26E4:0108 MOV SI,SP
26E4:010A PUSH AX
26E4:010B POP ES
26E4:010C PUSH AX
26E4:010D POP DS
26E4:010E STI
26E4:010F CLD
26E4:0110 MOV DI,0600 ;将0000:7c00开始的100h个字移到0000:0600处
26E4:0113 MOV CX,0100
26E4:0116 REPNZ
26E4:0117 MOVSW
26E4:0118 JMP 0000:061D ;转向新的代码位置接着执行
26E4:011D PUSH AX
26E4:011E PUSH ES
26E4:011F PUSH BX
26E4:0120 PUSH CX
26E4:0121 PUSH SI
26E4:0122 MOV CX,0017 ;显示“Load WDM Protected System!"的信息
26E4:0125 MOV SI,019E
26E4:0128 ADD SI,0500
26E4:012C MOV AH,0E
26E4:012E MOV AL,[SI]
26E4:0130 INT 10
26E4:0132 INC SI
26E4:0133 LOOP 012E
26E4:0135 XOR AX,AX ;修改常规内存容量使之减小1K,来存放驻留程序
26E4:0137 MOV ES,AX
26E4:0139 MOV DS,AX
26E4:013B MOV AX,[0413]
26E4:013E SUB AX,0001
26E4:0141 MOV [0413],AX
26E4:0144 MOV CL,06 ;计算驻留程序的存放首地址,放在ES中
26E4:0146 SHL AX,CL
26E4:0148 MOV ES,AX
26E4:014A PUSH ES
26E4:014B MOV AX,0201 ;读出新的int 13h代码,放在ES;0000处,
26E4:014E MOV BX,0000
26E4:0151 MOV CX,0003 ;新的int 13h代码,安装在0面0柱3扇区,由安装程序写入
26E4:0154 MOV DX,0080
26E4:0157 INT 13
26E4:0159 CLD
26E4:015A XOR AX,AX ;将原来的int 13h向量保存在ES:01FC开始处
26E4:015C MOV DS,AX
26E4:015E MOV DI,01FC
26E4:0161 MOV SI,004C
26E4:0164 MOV CX,0002
26E4:0167 REPNZ
26E4:0168 MOVSW
26E4:0169 MOV AX,0301 ;将带有原来的int 13h向量的新的int 13h代码保存到磁盘
26E4:016C MOV BX,0000
26E4:016F MOV CX,0003
26E4:0172 MOV DX,0080
26E4:0175 INT 13
26E4:0177 XOR AX,AX ;读出原来的主引导记录到0000:7C00处,
26E4:0179 MOV ES,AX
26E4:017B MOV DS,AX ;原来的主引导记录被安装程序移到了0面0柱2扇区
26E4:017D MOV AX,0201
26E4:0180 MOV BX,7C00
26E4:0183 MOV CX,0002
26E4:0186 MOV DX,0080
26E4:0189 INT 13
26E4:018B XOR AX,AX ;修改int 13h的中断向量表,使它指向新的int 13h代码
26E4:018D MOV [004C],AX
26E4:0190 POP AX ;弹出刚才压入的es到ax,即新的int 13h的段地址
26E4:0191 MOV [004E],AX
26E4:0194 POP SI
26E4:0195 POP CX
26E4:0196 POP BX
26E4:0197 POP ES
26E4:0198 POP AX
26E4:0199 JMP 0000:7C00 ;跳向旧的主引导记录执行,进入正常引导。
26E4:019E DB 4C ;以下全是数据,是刚才显示的“Load WDM Protected System!"信息
26E4:019F DB 6F ;的ascii码
26E4:01A0 DB 61
26E4:01A1 DB 64
26E4:01A2 DB 20,57,44
26E4:01A5 DB 4D
26E4:01A6 DB 20,50,72
26E4:01A9 DB 6F
26E4:01AA DB 63
26E4:01AB DB 74,65
26E4:01AD DB 64
26E4:01AE DB 20,53,79
26E4:01B1 DB 74,65
26E4:01B3 DB 6D
26E4:01B4 DB 21,0E,8E,46
-rbx ;设置写入代码的大小
bx 00
:00
-rcx
cx 00
:b5 ;写入b5h个字节
-nmymbr.dat ;文件名为mymbr.dat
-w100 ;从100h开始写入
这样得到的mymbr.dat就是新的主引导记录。
2、编写新的int 13h的代码
在dubug下输入:
-a100
26E4:0100 PUSHF
26E4:0101 CMP DL,80 ;判断是否对硬盘操作
26E4:0104 JNZ 0129 ;不是则转移
26E4:0106 CMP AH,03 ;是否是写操作
26E4:0109 JZ 0110
26E4:010B CMP AH,0B
26E4:010E JNZ 0129 ;不是则转移
26E4:0110 PUSH AX ;若是对硬盘写,则判断是否是对C分区写
26E4:0111 PUSH CX
26E4:0112 PUSH BX
26E4:0113 XOR AX,AX ;计算出写的柱面号
26E4:0115 MOV AH,CL
26E4:0117 MOV CL,06
26E4:0119 SHR AH,CL
26E4:011B MOV AL,CH
26E4:011D MOV BX,0105 ;将实际C分区的末柱面号放入BX中,实际C分区的末柱面号
;由安装程序根据实际情况填入,这里可用任意值代替
26E4:0120 CMP AX,BX ;比较操作的拄面号是否大于C分区的末柱面号
26E4:0122 POP BX
26E4:0123 POP CX
26E4:0124 POP AX
26E4:0125 JA 0129 ;大于,可以操作,转移
26E4:0127 POPF ;不大于,写保护,什么也不做,中断返回。
26E4:0128 IRET
26E4:0129 CMP AX,0201 ;判断是否是读主引导扇区,如是,则将0面0柱2扇区中
26E4:012C JNZ 013D ;真正的主引导扇区读出。
26E4:012E CMP CX,0001
26E4:0132 JNZ 013D
26E4:0134 CMP DX,0080
26E4:0138 JNZ 013D
26E4:013A MOV CX,0002 ;是读主引导扇区,则将扇区号置为2,使之读出真正的主引导扇区
26E4:013D POPF ;转向真正的int 13h去完成非保护的磁盘操作
26E4:013E CS:
26E4:013F JMP FAR [01FC] ;真正的int 13h入口点放在cs:[01fc]处
-rcx ;将43h个字节的代码写入int13.dat中
cx 00
:43
-rbx
:00
-nint13.dat
-w100
这样得到int13.dat文件就是新的int 13h代码。
|