分享
 
 
 

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

王朝system·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

利用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;

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有