作業系統以外的硬碟空間-利用DOS/WINDOWS9X的隱含扇區保護資料 (轉)

worldblog發表於2007-12-10
作業系統以外的硬碟空間-利用DOS/WINDOWS9X的隱含扇區保護資料 (轉)[@more@]

 利用DOS/9X的隱含扇區保護資料

摘要:本文介紹如何利用視窗(WINDOWS)所不能管理的空間來達到特殊的資料保護要求,和如何編寫MBR來完成特殊的系統服務
關鍵詞:主開機記錄(MBR),引導記錄(R),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 允許程式讀寫這些視窗系統不能管理的空間,這些沒用上的額外空間就可以用來儲存一些秘密的資訊,例如:某些的加密資料就儲存在硬碟的0磁軌。這些額外的空間上沒有,簇等概念,要讀寫這些空間,只有透過CHS定址定位扇區,用13號中斷進行扇區讀寫。當然,這需要有一定的能力和對硬碟有一定的瞭解!
三、MBR(MASTER BOOT RECORD)扇區
 這些額外空間中最有魅力的是MBR扇區,這個扇區位於硬碟的0磁頭0柱面1扇區。MBR扇區是系統啟動時自檢後INT 19H首先讀取MBR扇區的512Bytes內容到0:7C00,然後把控制權交給MBR扇區。它的魅力就在與此,這時作業系統還沒有載入,反而作業系統還需要MBR程式來引導,所以MBR扇區又叫主引導扇區,相對於視窗系統的引導記錄叫DBR(DBOOT 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沒使用。至於怎樣利用這些空間就要看需要了。透過讀取分割槽連結串列,得到作業系統使用硬碟的情況,對比一下(基本輸入輸出系統)檢測到的有關硬碟的資訊(儲存在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檔案,再用DE把程式的程式碼和資料提取到一個檔案裡(方法程式中附有)。你可以用程式把這個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 s)
  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
  l  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
  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
#include
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,"ntdb  ");
 for(i=0;i {
  tmp=fgetc(fp1);
  if(tmp<0xa0)
  fprintf(fp2,"%02Xh,",tmp);
  else
  fprintf(fp2,"%03Xh,",tmp);
  if((i+1)%12==0)fprintf(fp2,"ntdb  ");
 }
 printf("nProcess O.K.");
 return 0;
}

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-990878/,如需轉載,請註明出處,否則將追究法律責任。

相關文章