現代IT 產品通常必須處理各種文件格式。雖然確保與開放文件格式的兼容性很容易,但讓您的軟件處理專有或封閉文件格式卻很棘手。
主要的挑戰是沒有一種通用的解決方案來反轉專有文件格式。在每種情況下,您都必鬚根據手頭的數據採取不同的行動。
在本文中,我們探討了專有文件格式是什麼以及為什麼您可能需要對一種文件格式進行逆向工程。我們還分享了我們處理封閉格式文件的經驗,並展示了一些從中恢復數據的方法。本文對於希望通過支持封閉文件格式來增強產品互操作性的開發領導者很有用。
以專有格式反轉文件的方式和原因文件格式具有用於結構化和存儲數據的特定編碼方案。如果沒有特定的軟件或硬件,專有文件格式通常無法解碼和解釋。數據通常由專有軟件以專有格式讀取和保存。
專有格式通常被設計為保密的,這意味著數據編碼格式的規範不公開發布或僅在保密協議下披露。有時,創建者(個人開發者或組織)會發布編碼詳細信息,但會通過許可證限制格式的使用。因此,專有格式被認為是封閉格式,與公開格式形成對比,開放格式可供所有人免費使用。
封閉文件格式的著名示例是WMA 和CDR。一些流行的文件格式,如XLS 和DOC,過去是封閉的和未記錄的,但現在是開放的。
為什麼需要對專有文件格式進行逆向工程?
軟件開發人員通常需要對專有文件格式進行逆向工程以提高軟件互操作性。
處理封閉文件格式的法律立場因各國與軟件專利相關的法律而異。但是,為提高互操作性而對文件格式進行逆向工程通常是合法的。此外,您可能需要對計算機取證的封閉文件格式進行逆向工程。
沒有通用的方法來對每次都有效的封閉文件格式進行逆向工程。每個案例都是獨立的。在本文中,我們探討了針對不同情況恢復專有文件格式的三個示例:
確定專有文件格式的3 種方法
讓我們詳細探討每個場景,從我們可以避免逆向工程的場景開始。
如何根據文件簽名確定專有文件格式使用任何文件格式都從發現格式的名稱並找到可以使用它的解析器開始。有時,此過程可能很簡單,您只需在Google 中鍵入file extension parser 即可找到相關的解析器。
但是,文件擴展名有時與文件的實際格式不匹配。例如,計算機遊戲通常將其資源文件擴展名指定為DAT,儘管它們內部可以是ZIP 文件。此外,一些基於Matroska容器的視頻格式使用自定義編解碼器來傳輸視頻,因此它們具有非標准文件擴展名。
要確定文件格式,您可以使用專門的工具,例如:
file(1) — 在Linux 中確定文件類型的工具
Binwalk — 用於分析、逆向工程和提取固件映像的工具
FACT 提取器——提取最常見容器格式的工具
然後,您需要檢查文件是否已存檔和加密。一種方法是使用Hex Workshop 中的Data Visualizer功能。
如果文件可能被歸檔,請嘗試使用7-Zip打開它。令人驚訝的是,這個文件歸檔器可以通過掃描文件的開頭來識別格式。即使文件在ZIP 數據之前有一些自定義標頭,7-Zip 仍然可以識別它。
另一個有用的工具是Offzip,它允許您以二進制代碼搜索zlib 流並將它們提取為文件。
所有這些工具都提供了識別已知文件格式並避免在沒有實際需要的情況下進行逆向工程的機會。但是如果您找不到文件格式,您可以嘗試使用文件的簽名來搜索它。要發現文件的簽名,請在十六進制編輯器中打開文件。
文件簽名,也稱為幻數,是文件開頭的唯一字節序列,用於標識其格式。通常,文件簽名是指文件的前二到八個字節。獲得文件簽名後,在Google 和GitHub 上搜索幻數,使用在網站或代碼中如何描述這些數字的不同變體。
假設您的文件簽名以以下字節開頭:41 50 52 34 65 76 65 72。以下是您應該嘗試的搜索請求的幾個示例:
41 50 52 34 65 76 65 72 簽名
41 50 52 34 65 76 65 72 魔法
41 50 52 34 簽名
41 50 52 34 魔法
41505234(因為簽名也可以是DWORD)
0x410x500x520x340x650x760x650x72 簽名
0x41505234
0x34525041(如果是小端)
您還可以使用美國信息交換標準代碼(ASCII)。在我們的例子中,我們對文件簽名的搜索查詢看起來像“APR4ever”。
這種方法可以幫助您識別這種文件格式類似於什麼,甚至可以找到一個現成的解析器。您還可以找到這種格式的其他文件,並分析它們的創建者和解析方式。
如何使用可執行文件對數據格式進行逆向工程如果您在Google 上徹底搜索文件簽名後仍未找到任何內容,則可能意味著您的文件格式確實很少見。在這種情況下,您可以使用可以解析此特定格式的可執行文件開始對您的專有文件格式進行逆向工程。但是如何找到這個可執行文件呢?
有兩種選擇:方案一:通過目標文件的簽名查找可執行文件。掃描與您計劃進行逆向工程的文件一起使用的整個程序目錄,搜索二進制形式的簽名。按文件內容啟動搜索以查找與目標文件匹配的簽名。查找目標文件以使用專用工具(如Effective File Search或Total Commander for Windows)或命令行工具(如分別在Linux 和macOS 上的grep或Binwalk)開頭的字節。
如果找到匹配的簽名,則將可執行文件加載到交互式反彙編程序(IDA) 中,搜索檢查文件簽名的位置,然後開始逆向執行進一步解析數據的代碼。
如果一個文件沒有簽名或者你在按文件內容搜索時沒有找到任何東西,你可以在運行時分析這個文件。
選項2:在運行時分析目標文件。啟動Process Monitor,為文件操作設置過濾器,並嘗試捕捉專有文件打開的時刻。然後,查看進程監視器中的相關行以查找文件的CreateFile 操作或第一個ReadFile。查看此事件的堆棧,了解哪個可執行文件試圖調用ReadFile(),更重要的是,代碼中的地址是什麼。將您的文件上傳到IDA 並查看解析如何運行,就像簽名搜索一樣。
通常,用於解析的代碼位於靠近閱讀開始的地方。在這種情況下,查看所有ReadFile 操作,查看讀取了多少字節,並查看這些字節在文件中的位置。
但是,有些文件可以用更複雜的方式開發。例如,開發人員可以使用流類甚至自定義類來訪問基於具有虛擬函數和多線程的類層次結構的文件,而不是使用簡單的函數來讀取文件。
在這種情況下,當您找到ReadFile函數時,您將找不到任何接近它的解析代碼。您將看到的只是一個從某個虛函數調用的ReadFile,讀取的數據將存儲在緩衝區中。
在這種情況下,您必須:
恢復閱讀器的類
找到使用讀取器從緩衝區接收數據的類
了解該類如何與讀者同步
只有這樣你才能找到解析文件中數據的類。
但是,有時您可能需要從既沒有簽名也沒有可執行文件的文件中恢復數據。讓我們探討一下在這種情況下可以做什麼。
如何在沒有可執行文件的情況下對數據格式進行逆向工程在我們開始探索如何從沒有可執行文件的專有文件格式恢復數據的示例之前,讓我們簡要概述一下信息如何存儲在文件中的一般邏輯。
了解所有文件都具有結構化數據這一點很重要。沒有人以允許隨機放置對象的方式創建文件格式。
每種文件格式都有一定的邏輯。而這個邏輯通常與文件的用途有關。例如,文件系統映像的文件必須具有特定的結構才能存儲元數據,例如大小、名稱和其他屬性。圖像文件必須能夠存儲有關圖像大小、顏色數量和其他圖像元數據的信息。
開發人員在他們創建的文件中組織信息存儲的選項通常有限。邏輯的選擇通常基於開發人員的知識和經驗。沒有必要使這樣的任務過於復雜並嘗試提出原創想法,尤其是在創建專有文件格式時。
現在讓我們探討如何使用真實示例對專有數據文件格式進行逆向工程。這裡我們有一個封閉格式的隨機固件文件。我們無法根據其簽名在Internet 上找到任何信息,並且它沒有可以幫助我們識別格式的獨特擴展名。
截圖1. 文件夾中的一個固件文件
顯然數據在最大的文件中:swfl_00005684.bin.001_032_079。但我們也可以看到swfl_00005684.xml.001_032_079 文件,這對於揭示如何從目標文件中解析數據很有用。
第一條規則是不要忽視元數據。
在這種情況下,我們會在要恢復的文件附近看到一個XML 文件。打開swfl_00005684.xml.001_032_079 文件後,我們會發現BIN 文件部分的描述:
在此示例中,SOURCE-START-ADDRESS指向BIN 文件中偏移的片段的開頭。並且SOURCE-END-ADDRESS是這個片段的結尾。
從swfl_00005684.bin.001_032_079 文件中提取數據片段後,如XML 文件中所述,我們得到三個文件。其中一個是數字簽名,另外兩個是另一種具有HAR#$%@ 簽名的專有格式。
我們發現這兩個文件是存檔。第一條線索是Data Visualizer 向我們展示了這些文件在開頭有一些文本,然後是高熵數據。
屏幕截圖2. 高熵數據在數據可視化工具中的外觀
第二條線索是這個文件在十六進制編輯器中的樣子:
屏幕截圖3. HAR 文件的開頭在十六進制編輯器中的樣子
它看起來像一個包含存檔文件名稱的表格。然而,挑戰在於找到一種方法來解析這些數據,以便我們可以將zlib 流與其元數據連接起來。
由於我們知道它是有關存檔文件的信息,因此我們將此數據粘貼到記事本中以查看哪些數據正在更改,哪些沒有。這是我們最終得到的:
屏幕截圖4. HAR 文件頭中的數據在記事本中的外觀
因此,存檔中保存的文件元數據很可能包含創建/更新日期、屬性以及壓縮和解壓縮文件的大小等信息。
關於存檔中不同文件的創建/更新日期的信息會略有不同,因為文件元數據通常以Unix 時間格式顯示。這就是為什麼我們可以看到這個數據大部分是重複的。
我們可以學習使用此文件的第二條規則是了解常見數據類型在十六進制編輯器中的外觀。對於常見的數據類型,我們指的是Unix Time、Dos Time、Float、Double 等。
很明顯,如果元數據包含目錄描述(而不是文件),則不會提及大小。
在目錄之後,我們有一個條目,如下面的屏幕截圖所示。由於它是一個文件描述符,因此該條目的大小字段中填充了值。
屏幕截圖5. 我們在目錄後得到的條目
出於好奇,我們使用Offzip 掃描工具來驗證我們的猜測,結果如下:
截圖6. Offzip 工具掃描HAR 文件後的結果
讓我們看看HAR 文件末尾偏移量0x335 處的數據:
屏幕截圖7. HAR 文件末尾偏移量0x335 處的數據
它是偏移量為0x335 的zlib 流,長度為0x99 字節。
這些是我們已經在元數據中看到的相同數字。所以我們可以得出結論,這個HAR文件只包含/tmp/manifest/usr/share/swe/00005684/00f15000.manifest文件,其餘都是目錄。
因此,我們僅使用文件本身的數據提取了一個未知格式的文件,因為我們了解我們希望在那裡找到的內容。
結論了解如何對專有文件格式進行逆向工程可以幫助您確保您的軟件適用於各種文件格式。
但逆向工程一個封閉的文件格式是具有挑戰性的。它不僅需要逆向工程方面的專業技能,還需要對許多其他主題的深入了解。例如,必須注意存儲在您需要進行逆向工程的文件附近的其他文件,並了解十六進制編輯器中不同數據類型的外觀。
Recommended Comments