程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> KV300技術分析(有關硬盤鎖)

KV300技術分析(有關硬盤鎖)

編輯:關於C++

注:此程序有一定的風險性。老妖也沒有試過。希望大家考慮清楚了再行事。

要不是親自試一下,你一定不會相信,運行下面的程序,你的機器將不能從軟盤啟動,更不能從硬盤啟動。而這個程序僅僅修改了你的硬盤的擴展DOS分區的首隱藏扇區。

code segment
assume cs:code,ds:code
org 100h
begin:
xor ax,ax
mov dl,80h
int 13h ;復位硬盤
mov ax,201h
mov bx,200h
mov cx,1
mov dx,80h
int 13h ;讀主引導扇區到200H
mov cx,ds:[3d0h]
mov [3ceh],0
mov bx,210h
mov ax,301h
int 13h ;寫擴展分區首隱藏扇區
int 19h ;快啟動
code ends
end begin

程序很短,你可以在DEBUG中輸入並運行。在編譯成.com 之後,運行之前請保存好硬盤的擴展DOS分區的首隱藏扇區的內容,以備將來恢復時用。

筆者是在編制一個硬盤加鎖程序時,因計算有誤而偶然發現這一點的。僅僅因為修改硬盤一個隱藏扇區,造成機器從軟硬盤都不能啟動,從未見資料提及。作者當時很驚訝。

為了解決問題,筆者按復位鍵,進入CMOS設置,將硬盤設置為未安裝,則可以從軟盤啟動,但是,使用INT13h仍不能讀寫硬盤,因此無法將被破壞的扇區復原。

筆者估計是引導過程中,讀取硬盤分區表時形成循環的緣故。理由有兩點:

1、因為僅僅修改硬盤一個扇區,造成了如此現象,而該扇區僅記錄了硬盤分區表的一些信息;

2、啟動過程中,不管從軟盤啟動還是從硬盤啟動,最終的現象都是硬盤燈第亮。因此,換用不支持硬盤分區的低版本DOS系統盤也許能夠啟動,使用2.0版的系統盤,果然可以在CMOS設置為硬盤正常安裝的情況下啟動機器,啟動後雖仍不能進入硬盤,但可以用INT13h讀寫硬盤。在DEBUG中用正常的內容覆蓋硬盤的擴展DOS分區的首隱藏扇,重新啟動機器,成功。

為什麼從軟、硬盤啟動都會造成讀硬盤分區的死循環呢?筆者為此對硬盤分區表及DOS引導過程進行了分析,提出幾點粗淺看法,供參考。

大家知道,硬盤分區表位於主引導扇區的1BEh與1FDh處,占64個字節,共4個分區項。

每個表項對應一個邏輯分區,每個表項占16個字節,其含義見表。

=====================================

偏移量  含 義

=====================================

0    引導標志(80h表示活動分區,00h表示非活動分區,其他值非法)

1    本分區的起始磁頭號

2-3   本分區的起始扇區號和起始柱號

4    分區類型(1-DOS,12位FAT;2-XENIX;4-DOS,16位FAT,小於32M;

5-擴展DOS;6-DOS,16位FAT,大於32M;0DBh-並發DOS.

5    本分區的結束磁頭號

6-7   本分區的結束扇區號和結束柱號

8-B   本分區的相對扇區號

C-F   本分區的扇區數

=====================================

各邏輯分區首隱藏扇區與主引導扇區類似,在偏移1BEh到1DDh處,記錄兩個分區表項第一表項對應於本分區,第二表項則對應於下一分區,各字節含義同上。這樣,各邏輯分區通過首隱藏扇區的分區信息表串起來形成了DOS硬盤分區的所謂鏈式結構,使得DOS能夠管理多個邏輯分區。DOS引導時,不管是從軟盤啟動還是從硬盤啟動,都將搜索這條鏈,以便為各邏輯盤建立磁盤基數表。

值得注意的是分區類型(偏移04h)中的擴展DOS分區是相對來說的,D盤相對於C是擴展DOS分區,但相對本身來說不是擴展的,因此在主引導扇區對應於D盤的分區表項中該字節為5,在D盤首隱藏扇區此處應為1、4或6。相應地,某表項若04h字節為5,則01-03h三字節就記錄所對應分區的首隱藏扇區的物理地址,若04h字節為1、4或6(此時該表項必為第一表項),則01-03h字節記錄所對應分區的DOS引導扇區。DOS搜索鏈表建立磁盤基數表的過程是這樣的:首先檢查分區類型,若為1、4或6,則從01h-03h取分區dos引導扇區地址,根據引導扇區和分區表信息建立該分區的磁盤基數表,然後轉向下一表項(如果有的話);若為5,則從01h-03h取該分區首隱藏扇區地址,並轉向該扇區,判斷該扇區分區表,准備建立下一分區的磁盤基數表;若04h為其他值則跳過,而調試程序運行後,04h字節被誤置為5。引導時,DOS據此認為該表項指向下一個DOS擴展分區,於是從01h-03字節取“下一個”分區的起始物理地址,讀取下一個分區的首隱藏扇區,而此處又被誤置為D盤的首隱藏扇區的地址,於是機器就陷於讀取D盤首隱藏扇區的死循環中。

雖然發生如此情況的可能性微乎其微,但一但出現,造成的危害不可低估,因為低版本的DOS已極度難找到,即使找到也需要對硬盤分區表了解較深,才能挽救。作為一個完善的操作系統,應該在任何情況下都是無懈可擊的,而且僅需加幾條指令就可避免如此後果,這不能不說是設計者的一個失誤。更高版本的DOS是否注意到了這一點呢?筆者為此曾用dos3.30,5.0,6.20在多種型號的機器上試驗,均出現上述現象。

雖然這是一個失誤,但我們可以利用它做一些有益的事。比如:很多硬盤加鎖軟件,雖然可以做到從軟盤啟動不能使用硬盤,但無法避免對硬盤了解較深的人通過修復主引導扇區進入硬盤,因此,要達到完全鎖住硬盤,必須做到從軟盤不能啟動機器。DOS的這個失誤為此提供了可能。筆者利用此點編寫了一個硬盤主引導程序,使得機器只能從硬盤啟動,並且必須輸入正確的口令;從軟盤啟動則死機。

首先,《失誤》文中所述DOS對邏輯分區的管理機制基本上正確的,DOS的這種鏈表式數據結構,可以說到處可見,在設備管理中、在內存管理中、在文件管理中,可謂比比皆是,而且嚴格地講,不僅DOS如此,其他操作系統亦如此。文中所述方法會造成死機,這是事實,但進而就說這是DOS的一個失誤,可就不應該了。原因很簡單:在DOS的這些鏈表式結構中,不管改變了哪一個,都可能引起死機。比如:改變了內存鏈(即MCB鏈),使之不符合DOS的要求,則馬上就會死機。能因此就說這是DOS的失誤嗎?顯然是不合適的。作為用戶,要求DOS能在任何情況下,都能正常運行,是可

以理解的,但這也是不可能的。事實上,任何一種操作系統,進而言之,任何一種軟件,都不可能做到。那麼,從開發的角度,或者說從程序設計的角度,用戶要設計一個較低級(指管理上)一點的程序,使其能和DOS一起工作,甚至控制DOS的工作,可能就要牽扯到對這些鏈表的操作,怎麼辦呢?一句話,必須適應DOS!(不可能讓操作系統去適應您)比如想自己去管理內存,就必須符合DOS的管理方式,使DOS認為是合理的,否則DOS就死了。再比如想接管DOS的磁盤管理,也必須如此,否則,雖然DOS不至於馬上就死,但會造成磁盤的混亂和數據的丟失。

其次,《失誤》文中認為這是加密的一個好方法,實際上也不然。應該說《失誤》文中談到的種種現象都確實是存在的,即:硬盤、軟盤啟動結果都是死機,硬盤燈常亮。但並不是沒有辦法解決。這裡應該先明確一點, DOS為各邏輯盤建立磁盤基數表(即建立設備管理鏈表)的過程是由IO.SYS(或IBMIO.COM)文件來完成的,明白了這一點,我們就可以在IO.SYS取得控制權之前,先行一步,即:對軟盤的DOS引導扇區--0面0道1扇區直接編程,就可以排除《失誤》文中所述的情況(不熟悉DOS引導過程的讀者,可參考有關專著,這裡不作敘述)。

有一個最簡單的解決辦法就是把硬盤的主引導扇區改為無效。然後就可以用軟盤啟動了,也可以用一些磁盤維護工具(或者直接用INT13H),來對硬盤工作了。比如:

恢復主引導扇區和被破壞了的“擴展分區首隱藏扇區”。具體操作如下。

首先用另一台計算機,找一張格式化好的軟盤,插入A驅或B驅。按如下輸入:

C:\DEBUG
-a 100
mov ax,0301
mov bx,0200
mov cx,0001
mov dx,0000
;如果您的軟盤在B驅,這裡應改為:mov dx,0001
int 13
int 3
-a 200
mov ax,0301
mov bx,0200
mov cx,0001
mov dx,0080
int 13
int 3
-g=100

執行完後,將軟盤從驅動器中取出,此時這張盤就成了"開鎖的鑰匙",將其插入“病”計算機的A驅,打開電源,啟動“病”計算機,顯然這張盤並不是系統盤,不能真正啟動“病”計算機,但待這張盤“啟動”完後(硬盤燈亮了一下,顯示器上無任何顯示),再插入真正的系統盤,關機,再重新啟動,就可以了。

當然,明白了這一道理後,可能會有更好的方法,以上就算是拋磚引玉吧。

注意:不要修改CMOS。軟錯誤當然軟解決,千萬不能將CMOS設置硬盤為未安.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved