李寧
摘 要:MS SQL SERVER的數據庫恢復的案件實例和恢復還原的方法和原理。筆者在2011年曾經協助我院自偵部門辦理過一件貪污案件,在案件中涉及恢復一個MS SQL SERVER的數據庫。在經過常規的數據恢復方法無法正常恢復的情況下,經專家指點使用數據庫逆向還原的方法恢復了數據。
關鍵詞:MS SQL SERVER 數據庫;恢復;還原
一、恢復數據的過程
筆者拿到證據硬盤后首先對硬盤做了鏡像拷貝,保證證據硬盤沒有收到污染和破壞。其次,使用常用數據恢復軟件對鏡像硬盤進行掃描,試圖恢復數據庫的MDF文件或者備份文件。但是掃描結果是多個備份文件已經被刪除,并在硬盤上找不到任何刪除的數據庫的文件名和存儲位置信息。顯然常規方法行不通,筆者經過多方查找資料和聯系專家,經專家指點找到一種恢復數據庫的方法即利用數據庫MDF文件的數據硬盤頁式存儲結構信息,逆向還原MDF 文件。實際做法如下:
1、首先定義數據頁特征:MDF文件的數據頁大小為8K,應該符合以下幾個條件:第0字節為1, 0x40字節至0x60字節全為0。當數據庫只有一個mdf文件時,屬于該mdf文件的頁0x24字節為1, 0x25字節為0, 頁號記錄在0x20 處,從0開始。
2、建立一個日志文件1.log,對鏡像硬盤進行遍歷. 然后讀取每一個扇區,檢查是否符合數據頁要求。如符合,輸出0x20處,長度為4的頁id, 同時輸出當前扇區號到1.log文件。到這樣就能夠得到一個記錄了格式符合SQL數據頁的位置和頁號的日志。
3、對1.log中,上下兩行頁號的差等于扇區的差除以16(數據頁大小為16個扇區)的話, 可以認為這兩個數據頁連續。這樣,當遇到數據頁不連續時,可以將上一頁作為一個文件碎片的結束,而不連續的那個頁作為下一個文件碎片的開始。記錄下每一個碎片的開始扇區, 結束扇區,開始數據頁號,結束數據頁號, 以及包含頁數量。將這些信息記錄在2.log文件中。
4、第0號頁中包含了數據庫文件的總頁數, 其位置在0xAF到0xB2中。根據這個長度創建一個空文件1.mdf。
5、如果鏡像硬盤中只包含一個數據庫,2.log中的數據可以直接使用,將記錄的對應扇區中的數據頁拷貝到1.mdf中。如果包含多個數據庫,可以手工調整,例如只保留其中物理位置比較接近,較完整,且能夠逆向還原整個數據庫。
二、逆向還原數據庫的原理
(一)數據庫文件數據頁結構分析
SQL Server的MDF文件是頁式存儲格式。文件被劃分成若干數據頁。數據頁是包含所有非文本或圖像的數據的結構。就像使用SQL Server中的其他類型的頁面一樣,數據頁面具有8KB(或8192字節)的固定大小。它們由三個主要部分組成:頁面標題、數據行和行偏移量數組,在每個數據頁中,頁面標題占用了前96個字節(剩下的8096字節用于數據和行偏移量)數據頁的頁號pageID是從0開始, 順序排列。
(二)文件RAW恢復方法
通過對整個磁盤按扇區逐一掃描,找出文件頭和文件腳信息的這種恢復技術叫做RAW文件恢復。RAW文件恢復方式可恢復一些特定類型的文件,也經常用于恢復SQL Server 數據庫 .MDF文件。
RAW文件恢復程序按以下工作步驟;
在硬盤上按扇區同步搜索一種或多種文件類型的文件頭。如果找到任何一個文件頭,則保存這些數據到一個文件,同時檢查下面4個條件,關閉和保存該文件。
1、找到該文件的文件頭;
2、找到相同文件類型的另一個文件頭;
3、找到另一個文件類型的一個文件頭;
4、當找不到文件腳或其他此類文件頭時,計算文件長度(某些類型的文件,其長度保存在文件前部或按預先設定的文件長度的最大值)。
(三)基于數據庫文件頁式存儲格式的恢復方法
利用數據庫文件的頁式存儲格式重建.mdf文件,首先確定要恢復的數據庫文件在硬盤上的第0頁的位置,即查找pageType = 0F的頁。在第0頁可獲取文件的總頁數,根據總頁數創建一個與要重建的文件等長度的空文件(文件的內容全為0)。遍歷整個硬盤,根據頁號pageID提取數據頁,將數據頁寫入已經創建好的空文件的對應位置。寫入所有的頁數據或硬盤遍歷完畢后,文件的重建即可完成。設新創建的空文件為 F,
則 F =(n=總頁數)
Fi 為新建空文件的第i頁,用 Si 表示在硬盤上查找到的pageID = i的數據頁,
令 Fi = Si ,文件F 將被重建成數據庫文件。
但在實際恢復過程中將會遇到以下兩種情況:
1、Si = { },即Si 不存在;
2、Si 不唯一;
(四)數據庫文件的低層恢復
重建的數據庫文件可能不能直接使用,主要原因是由于數據庫文件有缺頁。如果有缺頁Si在文件的用戶表的位置上,可以通過修改 Si-1 和 Si+1 的 nextPage 和 prePage修復,即 Si-1 的 nextPage = i+1, Si+1 的prePage = i-1, 當然這是有損修復。
如果重建的數據庫文件缺頁太多或缺頁在文件的系統表的位置上,數據庫文件就不可能被數據庫直接使用,因此必須通過直接提取用戶表的數據。SQL Server 主要有4張系統表記錄了數據文件的頭信息、系統表信息和用戶表信息,它們是 sysobjects、sysindexes、syscolumns 和systypes, 通過這4張表記錄的信息再結合數據頁的objID 就能將指定的用戶表的數據完整的或部分的提取出來,轉換成文本文件格式或其他數據格式。endprint