操作系统以外的硬盘空间-利用DOS/WINDOWS9X的隐含扇区保护数据

类别:编程语言 点击:0 评论:0 推荐:

 利用DOS/WINDOWS9X的隐含扇区保护数据

摘要:本文介绍如何利用视窗系统(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内容到内存0:7C00,然后把控制权交给MBR扇区。它的魅力就在与此,这时操作系统还没有加载,反而操作系统还需要MBR程序来引导,所以MBR扇区又叫主引导扇区,相对于视窗系统的引导记录叫DBR(DOS BOOT RECORD)。一些主引导扇区的病毒就利用了MBR扇区的特点,操作系统还没引导就执行了病毒代码,进行破坏!
这是一把双刃的剑,利用好了它同样能为大家提供优质的服务。最常见的例子就是多操作系统的引导。MBR扇区虽然只有512BYTES,这对于引导程序来说是足够的。但它所在的0磁道的其他扇区没有用上,视窗系统的分区表形成一个链表,有多少个逻辑驱动器就会有多少个分区表,也就是有相应多的磁道没有使用。在视窗系统下,不能对这些磁道直接读写。只有用程序读出分区链表,得到分区情况和这些磁道的地址,再用INT 13加以利用。例如,编写一个增强的主引导记录(MBR),但程序大小超过512Bytes,可以把程序的二进制代码分成多个512Bytes,分别存在0磁道上,但首先执行的代码必须放在MBR扇区里,而且要保留好主分区表(共64BYTES)和MAGIC ID(2Bytes);MBR执行时,MBR把程序的其他部分从0磁道读到内存里再执行。理论上,主引导程序只受隐含磁道的多少限制,一个磁道时31.5KBYTES,主引导程序和分区表必须保证不被破坏(防止某些软件运用隐含磁道,而破坏主引导记录),所以程序必须高效、精练和短小,最好用汇编语言编写。
还有一点,主引导程序必须保存在隐含扇区里,这是视窗系统的文件管理子系统所不能做到的。所以,必须用一个安装程序把主引导程序的程序代码和数据(MBR)当作安装程序的数据通过INT 13H的写扇区操作把MBR写到0磁道0扇区扇区里。这样的操作有一定的危险,因为原来的主引导记录和主分区表会被破坏,所以千万要备份原来的MBR和主分区表,并完全复制主分区表到新的主引导记录里。
四、利用硬盘额外空间
  干才提到,用INT 13H 可以把数据写到硬盘的隐含磁道里。同样,也可以把数据读出来。怎样才能把一些想要藏起来的数据好好的藏起来?
其实,13号中断对硬盘的访问是以扇区为单位的,而扇区又以字节为最小的单位。事实上所有的数据都可以当作字节流看待,忽略其实际的数据结构,运用INT 13H的02H号读扇区子功能和03H号写扇区子功能,就可以轻易的从硬盘读写数据。至于13号中断的用法,很多汇编的书上都有介绍,这不是本文探讨的内容!
有一个问题,怎么知道硬盘上哪些地方操作系统没有用上?前面已介绍了视窗系统没有使用硬盘的大概哪一处,现在介绍怎么通过计算来得知具体的位置。先来介绍一些硬盘存储结构的知识。
一个硬盘设计时就有定好了硬件参数,有多少个物理磁头,物理柱面,每磁道有多少个扇区,BUFFER有多大等,必须清楚现今的硬盘是一个三维的立体结构(CHS--CYLINDER,HEAD,SECTOR)。硬盘在出厂时就已经进行低级格式化,每一个扇区都标明了寻找地址,标记了坏扇区,并给出实际容量。这时的硬盘就象一张有小格的纸,操作系统的分区程序把硬盘划分为多个区域,再用高级格式化程序格式化每个区域以便于文件系统进行文件存储。前面提及,硬盘分区表也保存再隐含磁道里,而分区表是一个链表结构,得知每所有的隐含磁道的位置。现在简要介绍一下分区表的结构:
硬盘分区表(Hard Disk Partition Table)是记录硬盘分区信息的数据。一般情况下,硬盘的0磁头0柱面1扇区(即MBR-Master Boot Record 扇区)保存了硬盘第一张分区表(主分区表),分区表位于该扇区位移1BEH处,连续40H个字节。一张分区表最多可以容纳四个分区表项,每个表项占用10H个字节,一个分区表项代表一个分区的使用情况。分区表项的数据结构适合INT 13H的数据格式。
分区表项的结构是这样的:第0字节80H是活动分区的标志,非活动分区为00H;第1,2,3字节表示分区的起始位置,第4字节为是操作系统标志,不同操作系统使用不同的标记;第5,6,7字节表示终止位置,第8,9,10,11字节表示以当前分区为基准相对于本分区首扇区相对号,第12,13,14,15字节指出分区占用扇区总数。起始地址和终止地址是用CHS的寻址方式,地址用3个字节表示,分区起始(结束)的柱面及扇区数据合用前两个字节,第一字节的低6位为分区起始扇区值,最大为63(扇区由1开始计数),高字节的高2位与低字节的8位共10位为分区起始柱面值,最大值为1023(第三字节是磁头号,最大值为255柱面和磁头由0开始计数)。视窗系统的分区链表结构,主分区表项是活动分区,扩展分区表项表示扩展分区的信息,扩展分区里有可划分逻辑分区(逻辑驱动器);扩展分区表项的第1、2、3字节指示第一个逻辑分区的分区表的位置;如果存在第二个逻辑分区,这个分区表的第二个表项的第1、2、3字节又指示下一个逻辑分区表的位置,如果没有这个表项为0值。这就形成了链表的结构。
在缺省的情况下,视窗系统的分区程序把每一张分区表保存在隐含磁道的首扇区,但一个磁道有63个扇区,就是说还有62个扇区共31KB没使用。至于怎样利用这些空间就要看需要了。通过读取分区链表,得到操作系统使用硬盘的情况,对比一下BIOS(基本输入输出系统)检测到的有关硬盘的信息(保存在CMOS数据中),就可以知道操作系统到底有多少空间没有用上(主要是硬盘最后一个柱面的部分扇区)。可以通过调用INT 13H的08H号子功能返回硬盘的最大柱面号。前面的计算额外硬盘空间的例子,就知道视窗系统有好几MB的空间不用!越大的硬盘额外硬盘空间就越大!
把一些秘密的敏感的数据保存在这些视窗系统遗弃的空间里,别人无法通过操作系统读取,至于放在哪里,以什么形式存放,只有你和你的程序知道,有一定的保密效用!
五、示范实例
 有很多的文章介绍一些使用这些硬盘特殊空间的思想。例如,利用硬盘额外空间存放个人的机密文件,CMOS数据或个人软件的加密数据;写一个新的能把某一分区保护起来INT 13H服务程序保存在隐含磁道里,用一个特殊的MBR把新的INT 13H服务程序驻留内存,达到硬盘软保护卡的功能。
现在以一个CMOS数据自我保护的MBR程序的编写为例子,具体说明数据怎么保存在隐含扇区里和增强主引导记录的程序编写。CMOS数据的保护有多种方法,有人用VXD技术对CMOS数据进行写保护;有人用文件保存CMOS数据,在自动批处理文件中用程序把CMOS数据文件中的数据回写CMOS中,这同样达到保护的功效。
本文的例子的CMOS数据保护的原理是:首先,通过端口70H和71H把CMOS数据读取出来;然后,用INT 13H的03H子功能把CMOS数据写到一个隐含扇区中,例如:0柱面0磁头29扇区;再编写相应的MBR,在每次引导时把隐含扇区中的CMOS数据写回CMOS。这样也达到CMOS数据的保护功能!
这里涉及到CMOS数据的读写方法和MBR程序的编程技巧。不同公司出品的BIOS,它们的CMOS数据格式有所不同,但都时先把CMOS地址(一个CMOS地址读写一个字节的数据)送端口70H,再用端口71H读写这个CMOS地址的数据。AWARD公司出品的BIOS头10H字节保存一些动态的CMOS数据如时间,后70H字节保存一些硬件信息和用户配置设置,只须把后面70H个字节的比较固定的CMOS数据保存起来。
MBR--主引导记录,系统自检后由19号中断服务程序把MBR扇区中的数据,也就是MBR程序读到内存地址0:7C00H中,然后把控制权交给MBR。本文的MBR程序按以下流程完成CMOS数据回写和读取操作系统引导(DBR)记录到内存,并把控制权交给DBR进行操作系统引导。
1. 把MBR从内存0:7C00H搬移到内存0:0600H,共512Bytes;
2. 跳到从内存0:0600H到0:0700H中的MBR搬移代码后的位置继续执行,把保留CMOS数据隐含扇区读到内存0:0800H;
3. 设置CMOS的地址端口(70H)和读写端口(71H),把内存0:0800中的70H个CMOS数据回写CMOS中;
4. 依次读取主分区表的四个分区表项的的内容,判断是否为可引导分区,如果是转5,否则打印“Invalid partition table.”信息并进入死循环;如果四个分区表项都无效则进入Rom Basic;
5. 保存可引导分区表项的起始扇区地址,多次读取引导扇区(DBR)到内存0:7C00H,如果读取DBR成功并通过MACIC ID(魔数AA55)判断是否为引导记录,如果是控制权转移到0:7C00H,继续进行操作系统的引导,否则打印“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)。
同样,还可以想出更多更实用的想法来,如,加密分区表,设密码授权访问硬盘,用两个同样大小的分区模拟备份系统等。模拟备份系统在公共机房中快速恢复系统是比较实用的。利用现在大硬盘的优势,分出两个同样大小的分区A、B,在其中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

; **********************
; * Error message      *
; **********************
ErrMsg1  db    'Invalid partition table.',0
ErrMsg2  db    'Error loading operating system.',0
ErrMsg3  db    'Missing operating system.',0

PrintStr:
         lodsb              ;read a byte from [si]
  cmp   al,0         ;al=0?
  je    @exit        ;if yes the jump to @exit
  push  si           ;push si to stack
  mov   bx,7         ;
  mov   ah,0Eh       ;display the char
  int   10h
  pop   si         
  jmp   short PrintStr  ;print the next char
@exit:
         retn                 
Tail:                          ;the Master Boot Record tail
FillNum  equ   1BEh-(Tail-Head)  ;count the fill number
         db    FillNum dup (0)  

; *******************************************************************
; * The Parttition table data                                       *
; * Notise: You must change the next parttition table data to your  *
; *         own Hard Disk parttition table data.                    *
; *******************************************************************
parttable   db  80h,01h,01h,00h,06h,3Fh,7Fh,96h,3Fh,00h
     db  00h,00h,01h,0Ah,19h,00h,00h,00h,41h,97h,0Fh,3Fh
     db  0FFh,0FDh,40h,0Ah,19h,00h,00h,0E6h,25h,00h,00h,00h
     db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
     db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
     db  00h,00h,00h,00h,00h,00h
MagicID        dw   0AA55h
         end start
 
2. 主引导记录的安装程序
; *********************************************************************
; * Program:The Cmboot.exe MBR Sector loader.And read the cmos data   *
; *         and saved it to the harddisk hidden sector.               *
; *===================================================================*
; * tasm Cmbootld1.asm                                                *
; * tlink Cmbootld                                                    *
; *===================================================================*
; * Designer:Howard                                                   *
; * Creat Date:08/29/2000                                             *
; * Original place:Wuhan                                              *
; * Modification date:08/29/2000                                      *
; * Now Version:1.0                                                   *
; *===================================================================*
; *                Modification History                               *
; *-------------------------------------------------------------------*
; * Version:1.0   1.Backup the old mbr to a file.                     *
; * 08/29/2000    2.Load the backup mbr file and saved it to the mbr  *
; *                 sector(cylinder:0,head:0,sector:1).               *
; *               3.Saved the cmos data to hard disk hidden sector.   *
; *               4.Load the cmoscheckedmbr the mbr sector.           *
; *               5.Reboot the computer.                              *
; *-------------------------------------------------------------------*
; *08/30/2000    6.Modify the psp and _data segment mistake.         *
; *-------------------------------------------------------------------*
; * 09/01/2000    7.Modify some bug,and optimize some instructions.   *
; *-------------------------------------------------------------------*
; * 09/07/2000    8.Modify the parameter error,ignore the space bet-  *
; *                 ween the program name and parameter.              *
; *               9.Modify the file creating problem,add zero to the  *
; *                 end of filename string.                           *
; *********************************************************************
; * problem: 1.The _data and psp segment address is still a problem.  *
; * 09/01/2000   Use a debug information.Maybe the buffer offset address*
; *            is not correct,or the data segment is too large.       *
; *            I haved used two mem unit to save the psp and _data    *
; *            segment address.Do not use the stack to save psp and   *
; *            data segment address.                                  *
; *          2.The file "creat/open/read/write" operating is still    *
; *            a problem.                                             *
; *-------------------------------------------------------------------*
; * bugs:      1.Int 13h ah=02/03h es:bx point to the buffer,but      *
; * modifying    program executing,es=psp segment address,it must     *
; * 09/01/2000     be make it equarl the real buffer segment address.   *
; *            2.Push and pop operating must be make sure the         *
; *              operands is correct.                                 *
; * 09/07/2000   3.The program can not creat a new file.error writing   *
; *              device AUX.                                          *             
; *********************************************************************

;      dosseg
      .model small
      .486
      .stack  200h
      .data
;以下数据(SECTOR)是通过编译CMOSBOOT.ASM后用DEBUG得到CMOSBOOT.bin和并用BINTODAT.EXE转换CMOSBOOT.BIN得出来的
 sector db  0FAh,33h,0C0h,8Eh,0D0h,0BCh,00h,7Ch,8Bh,0F4h,50h,07h
 db  50h,1Fh,0FBh,0FCh,0BFh,00h,06h,0B9h,00h,01h,0F2h,0A5h
 db  0EAh,1Dh,06h,00h,00h,0B8h,01h,02h,0BBh,00h,08h,0B9h
 db  1Dh,00h,0BAh,80h,00h,0CDh,13h,0B8h,10h,00h,0B9h,70h
 db  00h,0FCh,0E6h,70h,50h,8Ah,07h,0E6h,71h,58h,0FEh,0C0h
 db  43h,0E2h,0F3h,0FDh,0BEh,0BEh,07h,0B3h,04h,80h,3Ch,80h
 db  74h,0Eh,80h,3Ch,00h,75h,1Ch,83h,0C6h,10h,0FEh,0CBh
 db  75h,0EFh,0CDh,18h,8Bh,14h,8Bh,4Ch,02h,8Bh,0EEh,83h
 db  0C6h,10h,0FEh,0CBh,74h,0Dh,80h,3Ch,00h,74h,0F4h,0BEh
 db  0A1h,06h,0E8h,83h,00h,0EBh,0FEh,0BFh,05h,00h,0BBh,00h
 db  7Ch,0B8h,01h,02h,57h,0CDh,13h,5Fh,73h,0Ch,33h,0C0h
 db  0CDh,13h,4Fh,75h,0EDh,0BEh,0BAh,06h,0EBh,0E0h,0BEh,0DAh
 db  06h,0BFh,0FEh,7Dh,81h,3Dh,55h,0AAh,75h,0D4h,8Bh,0F5h
 db  0EAh,00h,7Ch,00h,00h,49h,6Eh,76h,61h,6Ch,69h,64h
 db  20h,70h,61h,72h,74h,69h,74h,69h,6Fh,6Eh,20h,74h
 db  61h,62h,6Ch,65h,2Eh,00h,45h,72h,72h,6Fh,72h,20h
 db  6Ch,6Fh,61h,64h,69h,6Eh,67h,20h,6Fh,70h,65h,72h
 db  61h,74h,69h,6Eh,67h,20h,73h,79h,73h,74h,65h,6Dh
 db  2Eh,00h,4Dh,69h,73h,73h,69h,6Eh,67h,20h,6Fh,70h
 db  65h,72h,61h,74h,69h,6Eh,67h,20h,73h,79h,73h,74h
 db  65h,6Dh,2Eh,00h,0ACh,3Ch,00h,74h,0Bh,56h,0BBh,07h
 db  00h,0B4h,0Eh,0CDh,10h,5Eh,0EBh,0F0h,0C3h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,80h,01h,01h,00h,06h,3Fh,7Fh,96h,3Fh,00h
 db  00h,00h,01h,0Ah,19h,00h,00h,00h,41h,97h,0Fh,3Fh
 db  0FFh,0FDh,40h,0Ah,19h,00h,00h,0E6h,25h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h
 db  00h,00h,00h,00h,00h,00h,55h,0AAh
      
       res    dw 0072h,0040h
       dat    dw 0000h,0ffffh
       buffer db 512 dup(0)
       filename db 'hdpt.dat',0
       parameter db 2 dup(?)
       copyright db 0dh,0ah,'JiangBiFang,I love you!','$'
       helpmsg db 0dh,0ah,'1.cmbootld /c'
               db 0dh,0ah,'  Saved the cmos data to hard disk hidden sector.'
        db 0dh,0ah,'2.cmbootld /w'
        db 0dh,0ah,'  Load the old mbr data from a file and saved it to mbr sector.'
               db 0dh,0ah,'3.cmbootld /s'
        db 0dh,0ah,'  Saved the mbr sector to a file.'
        db 0dh,0ah,'4.cmbootld /l'
        db 0dh,0ah,'  Load the cmoschecked mbr sector to hard disk.'
        db 0dh,0ah,'5.cmbootld /r'
        db 0dh,0ah,'  Reboot the computer.'
        db 0dh,0ah,'6.cmbootld /?'
        db 0dh,0ah,'  Print the help message.','$'
       noparamsg db 0dh,0ah,'Please use cmbootld /? for help.','$'            
;       debug     db 0dh,0ah,'Debug message.','$'
       hdbkokmsg db 0dh,0ah,'Harddisk mbr back ok.','$'
       hdreaderrmsg db 0dh,0ah,'Harddisk reading error!','$'
       hdwriteerrmsg db 0dh,0ah,'Harddisk writing error!','$'
       filecreaterrmsg db 0dh,0ah,'File creating error!','$'
       fileopenerrmsg db 0dh,0ah,'File opening error!','$'
       filewriteerrmsg db 0dh,0ah,'File writing error!','$'
       filewriteokmsg  db 0dh,0ah,'File writing OK!','$'
       filereaderrmsg  db 0dh,0ah,'File reading error!','$'
       mbrwriteokmsg   db 0dh,0ah,'The cmoschecked mbr loading ok!','$'
       cmossavedtohdokmsg db 0dh,0ah,'The cmos data haved to harddisk.','$'
       mbrbkokmsg  db 0dh,0ah,'The old mbr haved backup to the file hdpt.dat.','$'
       cmoscheckedmbrldokmsg db 0dh,0ah,'The cmoscheckedmbr haved installed ok!','$'
       wrongparamsg db 0dh,0ah,'The wrong parameter:"','$'      
       .code
start:      
main proc far
          assume cs:_text,ds:_data,es:_data,ss:stack
         mov  cs:pspseg,ds
;         push ds
  xor  ax,ax
  mov  ax,_data
  mov  cs:dataseg1,ax
  mov  ds,ax           ;ds=_data
 
  mov  es,ax           ;int 13h es:bx point to buffer,es=seg _data
  lea  dx,copyright
  call disp1 
;        push ds
;  pop  cx              ;cx=_data
;        pop  ds       ;ds=psg
  mov  ds,cs:pspseg              ;ds=psp
  cld
  mov  si,81h
  lodsb
;  push ds
;        mov  ds,cx                     ;ds=_data seg
  mov  ds,cs:dataseg1            ;ds=_data
  cmp  al,0dh
         jz   nopara
  cmp  al,' '
  jz   judgespace
;         pop  ds                ;ds=psp
continue: 
         push si
  dec  si
         mov  ds,cs:pspseg
  lodsb
;  push ds
;        mov  ds,cx                       ;ds=_data
  mov  ds,cs:dataseg1              ;ds=_data
         lea  bx,parameter
  cmp  al,'/'
  jz   scanparaloop
 ; lea  bx,parameter
;        push ds 
         jmp  error


scanparaloop:
         mov  [bx],al
;  pop  ds                  ;ds=psp
         mov  ds,cs:pspseg
  lodsb
;  push ds
;        mov  ds,cx                        ;ds=_data
  mov  ds,cs:dataseg1               ;ds=_data
  cmp  al,0dh
  jz   choise
  inc  bx
  jnb  scanparaloop        ;instruction loop can not use rigister cx,
 
judgespace:
         mov  ds,cs:pspseg
         lodsb
;        call debug         ;set break point 
  cmp  al,0dh
  je   nopara
  cmp  al,' '
  je   judgespace
  jne  continue   
nopara:
         lea  dx,noparamsg
  jmp  disp
;         call disp
;         call rettodos

help:
         lea  dx,helpmsg
  jmp  disp
;  call disp
;  call rettodos

choise:
;         push cx
;         mov  ds,dataseg1
         lea  si,parameter
  mov  al,[si+1]
  cmp  al,'s'
  jz   savembr
  cmp  al,'S'
  jz   savembr
  cmp  al,'w'
  jz   writembr
  cmp  al,'W'
  jz   writembr
  cmp  al,'c'
  jz   savedcmosdatatohd
  cmp  al,'C'
  jz   savedcmosdatatohd
  cmp  al,'r'
  jz   reboot
  cmp  al,'R'
  jz   reboot
  cmp  al,'l'
  jz   cmoscheckedmbrld
  cmp  al,'L'
  jz   cmoscheckedmbrld
  cmp  al,'?'
  jz   help
  jmp  error

savembr:
;    -----  Debug instrution ------
;         mov  ds,cs:dataseg1
;         lea  dx,debug
;  call disp1
;  mov  ah,07h
;  int  21h
;  cli
;    ------------------------------ 
;         sub  ax,ax
;        pop  ds             ;ds=_data
;        push ds
;        pop  es             ;es=_data
         mov  ax,0201h
;  mov  bx,offset buffer
         lea  bx,buffer      ;es:bx=_data:buffer ,es=seg _data
  mov  cx,0001h
  mov  dx,0080h
  int  13h     
;  push bx
  jb   harddiskreaderr
;  mov  ax,_data
;  mov  ds,ax
;  push bx  
         xor  bx,bx
  mov  dx,offset filename
  mov  cx,0
  mov  ah,3ch
  int  21h
  jc   filecreaterr
  mov  bx,ax
  mov  dx,offset buffer
;  pop  dx
         mov  cx,200h
  mov  ah,40h
  int  21h
  jc   filewriteerr
  mov  ah,3eh
  int  21h
  jmp  filewriteok
 
filecreaterr:
         lea  dx,filecreaterrmsg
  jmp  disp
;  call disp
;  call rettodos
filewriteerr:
         lea  dx,filewriteerrmsg
;  call disp
;  call rettodos
         jmp  disp
harddiskreaderr:
         lea  dx,hdreaderrmsg
  jmp  disp
 
;  call disp
;  call rettodos
filewriteok:
         lea  dx,filewriteokmsg
  jmp  disp
;  call disp
;  call rettodos

writembr:
;        pop  ds    ;ds=_data
;        push ds   
;        pop  es    ;es=_data
         lea  dx,filename
  mov  ax,3d00h
  mov  cx,0
  int  21h
  jc   fileopenerr
  mov  bx,ax
  mov  cx,200h
  lea  dx,buffer
  push dx
  mov  ah,3fh
  int  21h
  jc   filereaderr
  mov  ah,3eh
  int  21h
  pop  bx
  mov  ax,0301h
  mov  cx,0001h
  mov  dx,0080h
  int  13h
  jb   hdwriteerr
  jnb  mbrwriteok
;  jmp  reboot
filereaderr:
         lea  dx,filereaderrmsg
  jmp  disp
;  call disp
;  call rettodos
fileopenerr:
         lea  dx,fileopenerrmsg
  jmp  disp
;  call disp
;  call rettodos
hdwriteerr:
         lea  dx,hdwriteerrmsg
  jmp  disp
;  call disp
;  call rettodos
hdreaderr:
         lea  dx,hdreaderrmsg
  jmp  disp
;  call disp
;  call rettodos
mbrwriteok:
         lea  dx,mbrwriteokmsg
  call disp1
;  jmp  reboot
  call rettodos
savedcmosdatatohd:
;         mov  ds,cs:[dataseg1]       ;pop ds    ;ds=_data seg
;  push ds
;  pop  es      ;es=_data
         mov  bx,offset buffer
  cld
  xor  cx,cx
  push cx
  pop  ax
  mov  cx,70h
  mov  al,10h
  push bx              ;mistake goes here,it must be push
  cld
cmosdatareadloop:
         out  70h,al
  push ax
  in   al,71h
  mov  ds:[bx],al
  pop  ax
  inc  bx
  inc  al
  loop cmosdatareadloop
  std
  pop  bx      ;lea bx,buffer
  mov  ax,0301h
;  mov  bx,offset buffer
         mov  cx,1ch         ;modify the number
  mov  dx,0080h
  int  13h
  jb   hdwriteerr
;  jb   cmossavetohdok

cmossavetohdok:
         lea  dx,cmossavedtohdokmsg
  jmp  disp
;  call disp
;  call rettodos

cmoscheckedmbrld:
         mov  ax,0201h
  mov  bx,offset buffer
  mov  cx,0001h
  mov  dx,0080h
  int  13h
  jb   hdreaderr
  cld
  mov  si,offset buffer+01beh
  mov  di,offset sector+01beh
  mov  cx,40h
  repne movsb
;  std
  mov  ax,0301h
  mov  bx,offset buffer
  mov  cx,19
  mov  dx,0080h
  int  13h
  jb   hdwriteerr
  lea  dx,mbrbkokmsg
  call disp1
  mov  ax,0301h
  mov  bx,offset sector
  mov  cx,0001h
  mov  dx,0080h
  int  13h  
  jb   hdwriteerr
  lea  dx,cmoscheckedmbrldokmsg
  call disp1
;  jmp  reboot
  jmp  rettodos
error:
;        pop  ds               ;ds=_data
         lea  dx,wrongparamsg
  call disp1
  mov  ax,0200h
;         mov  si,81h
;  inc  si
;         pop  ds           ;ds=psp
         mov  ds,cs:pspseg
;         mov  si,81h
         pop  si
  dec  si
prnwrongparameter:
;        mov  dl,ds:[si]
;        cmp  dl,0dh
;        jz   retdos
;        mov  ah,02h
;        int  21h
;        inc  si
;        loop prnwrongparameter
  lodsb
  cmp  al,0dh
  jz   retdos
  mov  dl,al
;  mov  ah,02h
  int  21h
;  inc  si
  loop prnwrongparameter
;  call disp
retdos:
         mov  dl,'"'
  int  21h
  mov  dl,'!'
  int  21h
  jmp rettodos
reboot:
;         lea  bx,res
  mov  word ptr [bx],1234h
         lea  bx,dat
  call dword ptr [bx]
disp:
         mov  ah,09h
  int  21h
rettodos: 
  mov  ah,4ch
  int  21h
main endp
disp1 proc near
         mov  ah,09h
  int  21h
  ret
disp1 endp
;rettodos proc near
 ;        mov  ah,4ch
;  int  21h
;rettodos endp
 dataseg1 dw ?      
 pspseg dw ?
end start

3. 数据转换程序
/* 把二进制文件转换成汇编语言的数据文件格式 */
/* bintodat *.bin *.out */


#include <stdio.h>
#include <stdlib.h>
long filesize(FILE *stream)
{
 long curpos,length;
 curpos=ftell(stream);
 fseek(stream,0L,SEEK_END);
 length=ftell(stream);
 fseek(stream,curpos,SEEK_SET);
 return length;
}
int main(int argc,char * *argv)
{
 FILE *fp1,*fp2;
 long fsize;
 unsigned i;
 unsigned char tmp;
 if(argc<2)
 {
  printf("Usage:BINTODAT [input] [output]");
  exit(1);
 }
 fp1=fopen(argv[1],"rb");
  if(fp1==NULL)
  {printf("Open file %s error ",argv[1]);
   exit(0);
  }
 fp2=fopen(argv[2],"wt");
 fsize=filesize(fp1);
 fprintf(fp2,"\n\tdb  ");
 for(i=0;i<fsize;i++)
 {
  tmp=fgetc(fp1);
  if(tmp<0xa0)
   fprintf(fp2,"%02Xh,",tmp);
  else
   fprintf(fp2,"%03Xh,",tmp);
  if((i+1)%12==0)fprintf(fp2,"\n\tdb  ");
 }
 printf("\nProcess O.K.");
 return 0;
}

 

本文地址:http://com.8s8s.com/it/it29965.htm