你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:杂志经典 / 编程语言
操作系统以外的硬盘空间(上)
 

  要:本文介绍如何利用视窗系统(WINDOWS)所不能管理的硬盘空间来达到特殊的数据保护要求,和如何编写MBR程序来完成特殊的系统服务

关键词:主引导记录(MBR),引导记录(DBR),CHS寻址,分区表

 

一、引言

一谈到数据保护,大家就会想到用加密、磁盘阵列(数据备份系统)、硬盘保护卡等方法进行数据保护。不错,这些方法都很好,但对于普通个人用户来说是不实际的。而本文探讨另外一些可行的系统数据保护方法。

什么数据需要保护呢?一些你不想被别人知道的数据,如你的银行密码;一些你不想被别人盗取的数据,如你的论文;一些容易被破坏的数据,如公共机房的电脑中系统文件。

二、DOS/WINDOWS9X不能管理的硬盘空间

现今,个人微机机的高速发展使得视窗操作系统无处不在。存储技术的发展也使得硬盘的容量不断增大。但视窗系统不能完全利用所有的硬盘空间,我不是说视窗系统不能支持这些大容量的硬盘,而是视窗系统无法利用这些硬盘空间----这就是所谓的隐含扇区。

硬盘上有几块的空间是视窗系统所不能读写的。众所周知,使用硬盘之前一定要分区,硬盘的0磁头0柱面1扇区保存了第一张分区表(主分区表),分区表所在的磁道(0磁头0柱面的第一个磁道63个扇区),和其他逻辑驱动器的分区表(分区链表)所在的磁道。而且一般硬盘用LBA模式管理硬盘空间,硬盘最后的两个柱面DOS/WIDOWS系统也没有使用。例如:2.1G的硬盘使用LBA模式有1023柱面、64个磁头/柱面和63个扇区/磁道,共1023柱面X64磁头/柱面X63扇区/磁道X512字节/扇区,若2014MB;而视窗系统的分区程序分出来的最后一个扇区的位置(也就是操作系统所管辖的硬盘空间)是255柱面,253磁头,63扇区(柱面和磁头是通过换算出来的逻辑数据),共(254柱面X255磁头/柱面+1柱面X253 磁头/柱面)X63扇区/磁道X512字节/扇区,若2000MB。很明显有14MB的空间没有用上,这是因为不同的硬盘寻址模式的转换而造成的部分空间不能使用(丢失)

系统的INT 13H API允许程序读写这些视窗系统不能管理的空间,这些没用上的额外空间就可以用来保存一些秘密的信息,例如:某些软件的加密数据就保存在硬盘的0磁道。这些额外的空间上没有FAT,簇等概念,要读写这些空间,只有通过CHS寻址定位扇区,用13号中断进行扇区读写。当然,这需要有一定的编程能力和对硬盘有一定的了解!

三、MBR(MASTER BOOT RECORD)扇区

这些额外空间中最有魅力的是MBR扇区,这个扇区位于硬盘的0磁头0柱面1扇区。MBR扇区是系统启动时自检后INT 19H首先读取MBR扇区的512Bytes内容到内存07C00,然后把控制权交给MBR扇区。它的魅力就在与此,这时操作系统还没有加载,反而操作系统还需要MBR程序来引导,所以MBR扇区又叫主引导扇区,相对于视窗系统的引导记录叫DBRDOS BOOT RECORD)。一些主引导扇区的病毒就利用了MBR扇区的特点,操作系统还没引导就执行了病毒代码,进行破坏!

这是一把双刃的剑,利用好了它同样能为大家提供优质的服务。最常见的例子就是多操作系统的引导。MBR扇区虽然只有512BYTES,这对于引导程序来说是足够的。但它所在的0磁道的其他扇区没有用上,视窗系统的分区表形成一个链表,有多少个逻辑驱动器就会有多少个分区表,也就是有相应多的磁道没有使用。在视窗系统下,不能对这些磁道直接读写。只有用程序读出分区链表,得到分区情况和这些磁道的地址,再用INT 13加以利用。例如,编写一个增强的主引导记录(MBR),但程序大小超过512Bytes,可以把程序的二进制代码分成多个512Bytes,分别存在0磁道上,但首先执行的代码必须放在MBR扇区里,而且要保留好主分区表(共64BYTES)和MAGIC ID2Bytes);MBR执行时,MBR把程序的其他部分从0磁道读到内存里再执行。理论上,主引导程序只受隐含磁道的多少限制,一个磁道时31.5KBYTES,主引导程序和分区表必须保证不被破坏(防止某些软件运用隐含磁道,而破坏主引导记录),所以程序必须高效、精练和短小,最好用汇编语言编写。

还有一点,主引导程序必须保存在隐含扇区里,这是视窗系统的文件管理子系统所不能做到的。所以,必须用一个安装程序把主引导程序的程序代码和数据(MBR)当作安装程序的数据通过INT 13H的写扇区操作把MBR写到0磁道0扇区扇区里。这样的操作有一定的危险,因为原来的主引导记录和主分区表会被破坏,所以千万要备份原来的MBR和主分区表,并完全复制主分区表到新的主引导记录里。

四、利用硬盘额外空间

刚才提到,用INT 13H 可以把数据写到硬盘的隐含磁道里。同样,也可以把数据读出来。怎样才能把一些想要藏起来的数据好好的藏起来?

其实,13号中断对硬盘的访问是以扇区为单位的,而扇区又以字节为最小的单位。事实上所有的数据都可以当作字节流看待,忽略其实际的数据结构,运用INT 13H02H号读扇区子功能和03H号写扇区子功能,就可以轻易的从硬盘读写数据。至于13号中断的用法,很多汇编的书上都有介绍,这不是本文探讨的内容!

有一个问题,怎么知道硬盘上哪些地方操作系统没有用上?前面已介绍了视窗系统没有使用硬盘的大概哪一处,现在介绍怎么通过计算来得知具体的位置。先来介绍一些硬盘存储结构的知识。

一个硬盘设计时就有定好了硬件参数,有多少个物理磁头,物理柱面,每磁道有多少个扇区,BUFFER有多大等,必须清楚现今的硬盘是一个三维的立体结构(CHS--CYLINDERHEADSECTOR)。硬盘在出厂时就已经进行低级格式化,每一个扇区都标明了寻找地址,标记了坏扇区,并给出实际容量。这时的硬盘就象一张有小格的纸,操作系统的分区程序把硬盘划分为多个区域,再用高级格式化程序格式化每个区域以便于文件系统进行文件存储。前面提及,硬盘分区表也保存再隐含磁道里,而分区表是一个链表结构,得知每所有的隐含磁道的位置。现在简要介绍一下分区表的结构:

硬盘分区表(Hard Disk Partition Table)是记录硬盘分区信息的数据。一般情况下,硬盘的0磁头0柱面1扇区(即MBR-Master Boot Record 扇区)保存了硬盘第一张分区表(主分区表),分区表位于该扇区位移1BEH处,连续40H个字节。一张分区表最多可以容纳四个分区表项,每个表项占用10H个字节,一个分区表项代表一个分区的使用情况。分区表项的数据结构适合INT 13H的数据格式。

分区表项的结构是这样的:第0字节80H是活动分区的标志,非活动分区为00H;第123字节表示分区的起始位置,第4字节为是操作系统标志,不同操作系统使用不同的标记;第567字节表示终止位置,第891011字节表示以当前分区为基准相对于本分区首扇区相对号,第12131415字节指出分区占用扇区总数。起始地址和终止地址是用CHS的寻址方式,地址用3个字节表示,分区起始(结束)的柱面及扇区数据合用前两个字节,第一字节的低6位为分区起始扇区值,最大为63(扇区由1开始计数),高字节的高2位与低字节的8位共10位为分区起始柱面值,最大值为1023(第三字节是磁头号,最大值为255柱面和磁头由0开始计数)。视窗系统的分区链表结构,主分区表项是活动分区,扩展分区表项表示扩展分区的信息,扩展分区里有可划分逻辑分区(逻辑驱动器);扩展分区表项的第123字节指示第一个逻辑分区的分区表的位置;如果存在第二个逻辑分区,这个分区表的第二个表项的第123字节又指示下一个逻辑分区表的位置,如果没有这个表项为0值。这就形成了链表的结构。

在缺省的情况下,视窗系统的分区程序把每一张分区表保存在隐含磁道的首扇区,但一个磁道有63个扇区,就是说还有62个扇区共31KB没使用。至于怎样利用这些空间就要看需要了。通过读取分区链表,得到操作系统使用硬盘的情况,对比一下BIOS(基本输入输出系统)检测到的有关硬盘的信息(保存在CMOS数据中),就可以知道操作系统到底有多少空间没有用上(主要是硬盘最后一个柱面的部分扇区)。可以通过调用INT 13H08H号子功能返回硬盘的最大柱面号。前面的计算额外硬盘空间的例子,就知道视窗系统有好几MB的空间不用!越大的硬盘额外硬盘空间就越大!

把一些秘密的敏感的数据保存在这些视窗系统遗弃的空间里,别人无法通过操作系统读取,至于放在哪里,以什么形式存放,只有你和你的程序知道,有一定的保密效用!

五、示范实例

有很多的文章介绍一些使用这些硬盘特殊空间的思想。例如,利用硬盘额外空间存放个人的机密文件,CMOS数据或个人软件的加密数据;写一个新的能把某一分区保护起来INT 13H服务程序保存在隐含磁道里,用一个特殊的MBR把新的INT 13H服务程序驻留内存,达到硬盘软保护卡的功能。

现在以一个CMOS数据自我保护的MBR程序的编写为例子,具体说明数据怎么保存在隐含扇区里和增强主引导记录的程序编写。CMOS数据的保护有多种方法,有人用VXD技术对CMOS数据进行写保护;有人用文件保存CMOS数据,在自动批处理文件中用程序把CMOS数据文件中的数据回写CMOS中,这同样达到保护的功效。

本文的例子的CMOS数据保护的原理是:首先,通过端口70H71HCMOS数据读取出来;然后,用INT 13H03H子功能把CMOS数据写到一个隐含扇区中,例如:0柱面0磁头29扇区;再编写相应的MBR,在每次引导时把隐含扇区中的CMOS数据写回CMOS。这样也达到CMOS数据的保护功能!

这里涉及到CMOS数据的读写方法和MBR程序的编程技巧。不同公司出品的BIOS,它们的CMOS数据格式有所不同,但都时先把CMOS地址(一个CMOS地址读写一个字节的数据)送端口70H,再用端口71H读写这个CMOS地址的数据。AWARD公司出品的BIOS10H字节保存一些动态的CMOS数据如时间,后70H字节保存一些硬件信息和用户配置设置,只须把后面70H个字节的比较固定的CMOS数据保存起来。

MBR--主引导记录,系统自检后由19号中断服务程序把MBR扇区中的数据,也就是MBR程序读到内存地址07C00H中,然后把控制权交给MBR。本文的MBR程序按以下流程完成CMOS数据回写和读取操作系统引导(DBR)记录到内存,并把控制权交给DBR进行操作系统引导。

1.         MBR从内存07C00H搬移到内存00600H,共512Bytes

2.         跳到从内存00600H00700H中的MBR搬移代码后的位置继续执行,把保留CMOS数据隐含扇区读到内存00800H

3.         设置CMOS的地址端口(70H)和读写端口(71H),把内存00800中的70HCMOS数据回写CMOS中;

4.         依次读取主分区表的四个分区表项的的内容,判断是否为可引导分区,如果是转5,否则打印“Invalid partition table.”信息并进入死循环;如果四个分区表项都无效则进入Rom Basic

5.         保存可引导分区表项的起始扇区地址,多次读取引导扇区(DBR)到内存07C00H,如果读取DBR成功并通过MACIC ID(魔数AA55)判断是否为引导记录,如果是控制权转移到07C00H,继续进行操作系统的引导,否则打印“Missing operating system.”信息并进入死循环;如果读取DBR不成功,打印“Error loading operating system.”信息并进入死循环;

(文后附汇编源程序并有编译方法和程序说明)

有了MBR,怎么把它写到MBR扇区里面呢?先把文后的程序编译成EXE文件,再用DEBUG把程序的代码和数据提取到一个文件里(方法程序中附有)。你可以用程序把这个512BYTES的文件读到内存字节数组中,再把数组用INT 13H写到0柱面0磁头1扇区中。又可以用程序把MBR文件的二进制数据转化成你所用编程语言可以接受的数据表示形式加到你的安装程序中,把这些数据写到硬盘中。安装程序用C语言或汇编语言写都可以,但MBR程序一定要用汇编语言写!文后也附有一个安装程序(CMBOOTLD.ASM)和数据转化程序(BINTODAT.C)。

同样,还可以想出更多更实用的想法来,如,加密分区表,设密码授权访问硬盘,用两个同样大小的分区模拟备份系统等。模拟备份系统在公共机房中快速恢复系统是比较实用的。利用现在大硬盘的优势,分出两个同样大小的分区AB,在其中A分区中安装操作系统和应用软件,并编写一个管理程序把A分区的内容完整复制到B分区上,并隐藏B分区;写一个主引导记录,每次引导时可以用热键管理选择把B分区的内容恢复(复制)到A分区或正常启动。MBR能实现的功能还有很多,你可以充分发挥你的想象力去设计这样的MBR

六、结束语  

由上面的文字看来,充分使用硬盘的空间似乎很简单,但这需要对硬盘有比较深的了解,能自如运用C/C++或汇编语言。总的来说,有扎实的功底一切会更好。现在存储技术的高速发展,硬盘的容量和速度大大的提高,是否有需要象文中所述的那样想尽办法利用硬盘空间?其实答案是,你是否有一些特别的需要,而本文所述的方法能确切的解决你的问题!希望本文能给大家一些帮助。

参考文献

〈〈硬盘保护技术手册〉〉  人民邮电出版社  1996年三月版

〈〈计算机组织与设计:硬件/软件接口〉〉机械工业出版社

 

[:]

1.       主引导记录源程序

; **********************************************************************

; * cmosboot.asm HardDisk Cmos data self reload boot Program           *

; *====================================================================*

; * tasm cmosboot                                                      *

; * tlink cmosboot                                                     *

; * exe2bin cmosboot                                                   *

; * debug cmosboot.exe                                                 *

; * -n cmosboot.bin                                                    *

; * -rcx                                                               *

; * :200                                                               *

; * -w cs:0                                                            * 

; * -q                                                                 * 

; * bintodat cmosboot.bin cmosboot.doc                                 *

; * bintocat cmosboot.bin cmosboot.cat                                 *

; *                                                                    * 

; **********************************************************************

 

; **********************************************************************

; * Designer:Howard                                                    *

; * Creat date:08/13/2000                                              *

; * Original place:Wuhan                                               *

; * Modification date:09/13/2000                                       *

; * Now version: 1.0                                                   *

; **********************************************************************

 

; **********************************************************************

; *                     Modification History                           *

; *====================================================================*

; * Version 1.0  1.This program is a Master Boot Record.               *

; *  09/13/2000  2.It can reload cmos data to the cmos when boot the   *

; *                the machine from Hard Disk every time               *

; *              3.The cmos data haved backuped to the Hard Disk       *

; *                0 cylinder,0 head,29 sector.                        *

; *              4.Before install this MBR to the Hard Disk,The cmos   *

; *                data must be haved Backuped to the Hard Disk        *

; *              5.The cmos data is only 20 bytes,it is from cmos      *

; *                data address 10h to 2Fh.                            *

; **********************************************************************        

PartLoad    equ    600h         ;

TableBegin  equ    7beh         ;partition table address in the memory

BootLoc     equ    7c00h        ;dos boot sector loaded to the address

IDAddr      equ    7dfeh        ;dos boot sector ended flag(55aah)

           .MODEL  tiny

       .CODE  

       org     0

Head:

start:

         cli                    ;disable the interrupt (if=0)

     xor   ax,ax            ;ax=0

     mov   ss,ax            ;ss=ax

     mov   sp,7c00h         ;sp=7c00h

     mov   si,sp            ;si=sp

     push  ax              

     pop   es               ;es=0

     push  ax

         pop   ds               ;ds=0

     sti                    ;enable the interrupt  (if=1)

     cld                    ;disable the direction (df=0)

     mov   di,PartLoad      ;di=600h

     mov   cx,100h          ;cx=100h (512 bytes=256 words)

     repne movsw            ;move the Master Boot Record from 0:7c00 to 0:600

     db    0eah             ;0eah is far jump code,that is jmp far ptr contiune

     dw    offset Continue+600h,0000h ;jump to 0:continue+600h

 

; ************************************************************************

; * The continue code is read the cmos backup data from hard disk sector.*

; * And rewrite the data to cmos.                                        *

; ************************************************************************

 

continue:

         mov   ax,0201h        ;ah=02h,al=01h

         mov   bx,0800h        ;bx=800h,cmos data read to 0:800h

         mov   cx,001dh        ;ch=00h,cl=1dh (the No.29 sector)

         mov   dx,0080h        ;dh=00h (the No.0 head),dl=80h (Hard Disk)

         int   13h

         mov   ax,0010h        ;al=10h cmos unit address

         mov   cx,0020h        ;write 20h bytes cmos data to cmos

         cld                   ;disable the direction df=0

writecmosdata:

         out   70h,al          ;set the cmos data address

         push  ax              ;the address backup to stack

         mov   al,[bx]         ;al=[bx]

         out   71h,al          ;write a byte data the address

         pop   ax             

         inc   al              ;the next address

         inc   bx              ;the next byte data

         loop  writecmosdata   ;loop

         std                   ;enable the direction df=1

@next1:

         mov   si,TableBegin   ;si=Partition table begin address

     mov   bl,4            ;4 sets partition data

FindBoot:

         cmp   byte ptr [si],80h ;Boot partition?

     je    SaveRec           ;if yes then jump to SaveRec

     cmp   byte ptr [si],0   ;=0?

     jne   Invalid           ;Invalid partition

     add   si,10h            ;the next partition

     dec   bl                ;bl-1

     jnz   FindBoot          ;continue findboot

     int   18h               ;jump to rom basic

SaveRec:

         mov   dx,[si]

     mov   cx,[si+2]         ;let Boot partition first sector to cx

     mov   bp,si             ;bp=si

 

; ********************************

; * Checked the next partition   *

; ********************************

                                 

FindNext:

         add   si,10h

     dec   bl

     jz    SetRead           ;jump to setread

     cmp   byte ptr [si],0

     je    FindNext

Invalid:

         mov   si,offset ErrMsg1+600h   ;Errmsg address to si

PrintMsg:

         call  PrintStr                 ;print the msg

DeadLock:

         jmp   short DeadLock           ;Dead lock

SetRead:

         mov   di,5                     ;set reading dos boot sector 5 times

 

; *******************************************************************

; * read the dos boot sector in order to boot the operating system  *

; *******************************************************************

ReadBoot:

         mov   bx,BootLoc          ;the dos boot sector read to 0:7c00

     mov   ax,201h             ;ah=02h,al=01h

     push  di                  ;di pushed to stack(backup the reading times)

     int   13h

     pop   di                 

     jnc   GoBoot              ;if reading ok then boot the OS

     xor   ax,ax               ;ax=00h

     int   13h                 ;reset the driver

     dec   di                  ;di-1

     jnz   ReadBoot            ;continue read boot sector

     mov   si,offset ErrMsg2+600h  ;get errmsg2 address to si

     jmp   short PrintMsg          ;print the msg

GoBoot:

         mov   si,offset ErrMsg3+600h  ;get errmsg3 address to si

     mov   di,IDAddr               ;di=boot sector last two bytes

     cmp   word ptr [di],0AA55h    ;is a boot sector

     jne   PrintMsg                ;if not boot sector then print errmsg

     mov   si,bp                   ;si point to bootable partition

     db    0EAh,00h,7Ch,00h,00h    ;jump to 0:7c00h

 

  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089