2017 年 3 月

第 32 卷,第 3 期

本文章是由機器翻譯。

Visual Studio - 使用 Visual Studio 對原始程式碼檔案進行雜湊,以確保檔案完整性

Mike Lai | 2017 年 3 月

人們可讀取的程式碼,電腦可讀取的程式碼轉換介紹所有已編譯的軟體語言的軟體保證的一項挑戰︰ 使用者如何有信心,他的電腦上執行的軟體程式所建立的開發人員所建立的相同來源的程式碼檔案? 這並不一定確定性 」 — 即使在開放原始碼軟體的情況下都由主題專家,檢閱原始程式碼檔案。軟體保證的重要部分是信任檢閱過的原始程式碼檔案是可執行檔都已內建的相同來源的程式碼檔案。 

在編譯和連結處理序中,一組特定的程式語言 (C#、 c + +、 OBJECTIVE-C、 Java 等) 撰寫的原始程式碼檔會轉換成針對特定架構的電腦上執行的二進位可執行檔 (x86、 x64、 ARM,例如)。但這種轉換可能不具決定性。很可能兩組不同的原始程式檔導致兩位元相同的可執行檔。某些情況下,這是刻意設計的。含有更多或較少空格或文字註解內的原始程式碼檔應該不會影響編譯器發出的二進位程式碼。相反地,它,也可以在單一組原始程式碼檔導致不同的可執行檔,從不同的編譯程序。在任一情況下,問題是其中一個確定性 」 — 確定了解您擁有的檔案是您所需。

若要解決此問題,最好在編譯期間使用 Visual Studio 編譯器雜湊的原始程式碼檔。從編譯器檢查的原始程式檔從產生的雜湊值的雜湊值相符,驗證可執行程式碼確實來自特定來源的程式碼檔案。很顯然,這是很好的使用者 (並,事實上,好處更進一步的其他編譯器廠商也會遵循類似的方法)。本文說明新的 Visual Studio 參數選擇雜湊演算法,其中這類的雜湊可能派上用場的案例,以及如何使用 Visual Studio 來產生來源的程式碼的雜湊。

在編譯期間產生強式雜湊

程式資料庫 (PDB) 檔案是不同的資料檔案儲存用來偵錯二進位可執行檔的資訊。Microsoft 最近剛更新其各種編譯器檔案雜湊作業 (例如 PDB 檔案中內嵌來源的雜湊) 若要使用強式密碼編譯演算法。   

原生程式碼編譯器原生 C/c + + 編譯器的 Visual Studio 2015,cl.exe,隨附於選擇不同的雜湊演算法雜湊的原始程式碼檔的編譯器的新參數︰ /ZH: {MD5 |SHA_256}。預設值為 MD5,已知為更容易衝突發生,但是會保留預設值,因為其雜湊值是產生運算成本較低。使用新的參數,編譯器會實作 sha-256 選項,也就是密碼編譯方面比 MD5 更強。

如果的原始程式碼檔案的 sha-256 雜湊比對二進位可執行檔,它是特定的相同原始程式檔都會編譯到可執行檔,讓有信心二進位可執行檔中的任何專案關係人的 PDB 檔案中儲存的 sha-256 雜湊。實際上,統稱為二進位可執行檔的 PDB 檔案中所儲存的 sha-256 雜湊值的集合成為二進位可執行檔中,「 生日憑證 」 中的識別項 」 提供 birth 「 二進位可執行檔的編譯器會登錄這些識別項。  

使用偵錯介面存取 SDK (bit.ly/2gBqKDo),很容易建立簡單的工具,偵錯資訊傾印工具,例如 cvdump.exe (,與其原始程式碼,現在已可在bit.ly/2hAUhyy)。您可以使用的 cvdump.exe-sf 切換 MD5 或 SHA 256 雜湊,以檢視 (使用其完整路徑名稱中的本機組建電腦) 的模組清單,在 [命令] 視窗中所示**[圖 1**。

使用雜湊 cvdump.exe 檢視模組
[圖 1 cvdump.exe 檢視模組使用雜湊

若要檢視同一個 PDB 檔使用舊版的 cvdump.exe,我看到文字 」 0x3 」 而不是 「 SHA_256 」。0x3 值是 SHA_256 和更新的 cvdump.exe 的列舉值才知道如何解譯它。它是相同的偵錯介面存取 sdk idiasourcefile:: Get_checksumtype 方法所傳回的列舉值。

Managed 程式碼編譯器根據預設,Visual Studio 2015 managed 程式碼 C# 編譯器,csc.exe,會使用 sha-1 密碼編譯演算法來計算來源檔案總和檢查碼雜湊在 PDB 檔案中儲存的值。不過,csc.exe 現在支援新的選用"/ checksumalgorithm"參數來指定 sha-256 演算法。若要切換 sha-256 演算法,請編譯所有 C# 中的檔案目前的目錄,並將偵錯資訊,包括來源檔案清單和 sha-256 雜湊值 PDB 檔案中使用此選項︰

csc /checksumalgorithm:SHA256 /debug+ *.cs

.NET 編譯器平台 ("Roslyn") 開放原始碼專案的一部分,csc.exe 位於github.com/dotnet/roslyn。您可以找到支援 sha-256 來源檔偵錯的總和檢查碼演算法命令列選取器在檔案中bit.ly/2hd3rF3

Visual Studio 2015 csc.exe 就會只相容的 Microsoft.NET Framework 4 或更高的可執行檔。其他用來建置可執行檔,在第 4 版之前的 Visual Studio 2015 的.NET Framework 編譯器並不支援 /checksumalgorithm 參數。

Managed 程式碼 PDB 檔案將資料儲存方式不同於原生程式碼 PDB 檔案。如果不使用偵錯介面存取 SDK,Microsoft DiaSymReader interop 介面和公用程式可用來讀取 PDB 檔的 managed 程式碼。Microsoft DiaSymReader 是從 NuGet 套件形式提供bit.ly/2hrLZJb。   

Roslyn 專案包含一個稱為 pdb2xml.exe,您會發現在其來源的公用程式bit.ly/2h2h596。此公用程式會以 XML 格式顯示 PDB 的內容。例如,在區段**[圖 2**一直是用來編譯 managed 程式碼可執行的程式碼檔案會顯示 C# 原始程式檔的清單。  

以 XML 格式顯示 Managed 程式碼 PDB
[圖 2 顯示 Managed 程式碼 PDB 以 XML 格式

「 8829d00f-11b8-4213-878b-770e8597ac16 」 中的 GUID checkSumAlgorithmId 欄位指出總和檢查碼欄位的值是 [名稱] 欄位中參考之檔案的 sha-256 雜湊值。此 GUID 可攜式的 PDB 格式規格 v0.1 中定義 (bit.ly/2hVYfEX)。  

Sha-256 編譯器支援

下列 Visual Studio 2015 編譯器支援 sha-256 雜湊的原始程式檔的選項︰      

  • cl.exe /ZH:SHA_256
  • ml.exe /ZH:SHA_256
  • ml64.exe /ZH:SHA_256
  • armasm.exe-gh: SHA_256
  • armasm64.exe-gh: SHA_256
  • csc.exe /checksumalgorithm:SHA256

這些編譯器可從 Visual Studio 2015 的 「 開發人員 VS2015 命令提示字元 」 命令視窗。

沒有 Windows 平台為目標的編譯器通常不使用 PDB 檔案來儲存其偵錯資訊。這些編譯器通常會產生兩個可執行檔同時執行一個 unstripped 編譯期間和其他移除 (bit.ly/2hIfvx6)。完整偵錯資訊會儲存在 unstripped 可執行檔,而等量的執行檔未包含任何偵錯的詳細的資訊。Unstripped 可執行檔可能適合儲存 sha-256 雜湊的可執行檔已處理的原始程式檔。我們計劃要連接的這些其他編譯器的建立者,以找出這方法最適合其編譯器,讓使用這些編譯器,例如 Office android、 ios、 Office 或 Office for Mac 的非 windows 軟體可取得相似的效益,以 Windows 為基礎的軟體。

使用案例情節   

現在讓我們看看一些案例來源檔案的雜湊值可以是很有用。       

擷取編製索引的可攜式執行檔 (PE) 的二進位檔案的原始程式檔Ssindex.cmd 指令碼(bit.ly/2haI0D6) 是內建到原始檔控制,以及儲存 PDB 檔案中的每個檔案的版本資訊 (索引) 的原始程式檔檢查清單的公用程式。如果 PDB 檔會有此版本控制資訊,您可以使用 srctool 公用程式 (bit.ly/2hs3WXY) 使用其-h 選項來顯示資訊。因為索引的原始程式檔也有其內嵌於 PDB 檔的雜湊值,用來擷取,過程中驗證的原始程式檔的真實性的雜湊值 3195907 的知識庫文件中所述 (bit.ly/2hs8q0u),「 」 如何來擷取編製索引原始程式檔可移植的可執行檔二進位。 」 具體來說,如果雜湊值不相符,可能有哪裡發生錯誤時產生的 PE/PDB 配對或原始檔控制系統中。這可能會保證進一步調查。相反地,如果雜湊值相符,則擷取索引的來源檔案用來編譯 PE/PDB 組的強式指示。        

比對雜湊值所產生的來源檔案的靜態分析器現階段而言,很常實作階段建議由 Microsoft 安全性開發生命週期 (SDL) 的方式,使用自動工具來評估軟體的品質 (bit.ly/29qEfVd)。具體來說,來源檔案的靜態分析器來掃描目標原始程式檔,以評估的軟體品質的許多不同層面。這些靜態分析器通常會產生對應的即時結果時掃描的目標原始程式碼檔。靜態分析程式掃描個別原始程式檔,它會呈現的絕佳機會,也要產生強式雜湊 (sha-256) 針對每個掃描的原始程式碼檔。事實上,靜態分析結果交換格式 (SARIF),建議在開放原始碼專案中bit.ly/2ibkbwz,提供特定的位置,以產生掃描的目標原始程式碼檔和其 sha-256 雜湊值的靜態分析器的靜態分析結果中。 

PE 檔案,我們假設以下是可用︰

  1. 清單對應之 PDB 檔中,由編譯器產生編譯的來源檔案雜湊。
  2. 列出從對應的靜態分析結果時所產生的靜態分析程式掃描的來源檔案雜湊。

在此案例中,您可以檢閱並確認是否有符合的兩個檔案的雜湊清單。如果是的話,原始程式檔已經針對某些品質評估掃描的靜態分析器,您不需要重新掃描原始程式檔。以前,如果沒有使用檔案雜湊清單,您可能必須重新掃描只是要先確定靜態分析並未適當評估。  

更快速例行性檢查軟體更新或 Hotfix 開發程序中在您要發行的軟體更新來修正找到來源檔案的靜態分析器所發行的產品品質問題的情況下,靜態分析師應該報告沒有暫止更新的來源檔案中將該品質問題。最小值,此報表會確認更新有效處理原始品質問題。換句話說,它會驗證軟體更新的預定的用途。如有需要,您或安全性檢閱人員可以採取下列步驟,以進行快速的驗證︰ 

  1. 確認原始的靜態分析器報表識別的品質問題。
  2. 確認原始的靜態分析器報表包括包含品質問題的來源檔案的雜湊值。
  3. 符合原始的靜態分析器報表發行的產品版本的原始程式檔的雜湊值中的檔案雜湊值。
  4. 取得更新的靜態分析器報表所產生的原始程式檔,使用相同的靜態分析器更新的掃描。
  5. 確認先前找到的品質問題不存在的靜態分析器報告更新。
  6. 符合更新的靜態分析報表中的更新來源檔案的雜湊值的檔案雜湊值。

在這些驗證步驟,您不需要存取原始發行的產品或更新的實際原始程式碼檔。 

建構來源的程式碼差異之間兩個版本的軟體檢閱一組完整的原始程式碼花費的時間。不過,在某些情況下,有原始程式碼中,變更原始程式碼的完整檢閱並非必須。如此一來,可能會要求您只會針對來源的程式碼差異。此要求是當然沒有合理的基礎,自上次檢閱未變更的任何部分重複分析合理的。      

過去,而不需要的原始程式檔的強式密碼編譯雜湊值,它很難建構與任何有效位數的差異子集。即使您已提供差異子集,主題專家可能已有不怎麼能夠精確地建立差異部分。但這不會再大小寫。原始程式檔的強式密碼編譯雜湊值,您可以使用下列步驟來建立差異子集︰

  1. 取得集區,集區 X,例如雜湊值的所有來源的原始產品版本的程式碼檔案。
  2. 檔案目錄,目錄的完整副本比方說,其中包含來源的程式碼登記建構差異子集的後續產品版本。
  3. 比方說,準備最終檔案資料夾目的地,Dir B 來保存只有差異檔案子集。
  4. 排序中的所有檔案在 Dir a:
  5.         a.如果檔案的雜湊值符合在集區 X 的雜湊值,不執行任何動作,並移至下一個檔案。
  6.         b.如果檔案的雜湊值不符合集區 X 中的雜湊值,將檔案複製到 Dir B 移到下一個檔案之前。
  7. 驗證 Dir B 中的所有檔案都必須符合對應之來源檔案的後續產品版本的雜湊值的雜湊值。  
  8. 對 Dir B 的內容的後續產品版本的差異來源檔案的子集。     

產生雜湊

現在讓我們看看如何進行檔案雜湊與 Visual Studio 編譯器。若要這樣做,我將使用的"Hello,World"應用程式建立範例中的線上 Visual Studio 文件 (bit.ly/2haPupF) 至︰

  1. 顯示輸出 PDB 檔中您可以在何處編譯的原始程式檔的雜湊值
  2. 使用 certutil 工具 (bit.ly/2hIrnPR) 來計算要比對的 PDB 檔案中找到的來源檔案雜湊值。       

若要開始,我會建立新的 Win32HelloWorld 應用程式專案的 Visual Studio 2015\Projects 資料夾中。在此 Win32HelloWorld 專案中,沒有所示的只有一個 c + + 來源 file—Win32HelloWorld.cpp—as [圖 3

Win32HelloWorld.cpp
[圖 3 Win32HelloWorld.cpp

如您所見,Win32HelloWorld.cpp 包含 main 函式,會顯示"Hello"文字。

我的 Win32HelloWorld 專案的組建之後,我得到的 Visual Studio 2015\Projects\W32HelloWorld\x64\Debug 資料夾中的 W32HelloWorld.exe 和 W32HelloWorld.pdb 檔案。

Cvdump 工具,搭配 W32HelloWorld.pdb 檔案中,針對其-sf 選項中所示的輸出顯示 Win32HelloWorld.cpp 檔案和 MD5 雜湊值**[圖 4**。

Cvdump 輸出顯示 Win32HelloWorld.cpp 和 MD5 雜湊值
[圖 4 Cvdump 輸出顯示 Win32HelloWorld.cpp 和 MD5 雜湊值

雜湊值,所以 MD5 MD5 是預設演算法對於 Visual Studio 2015 編譯器,cl.exe。若要切換的原始程式檔雜湊 sha-256 的演算法,我需要提供給 cl.exe 的 /ZH:SHA_256 選項。我這樣可以新增 「 / ZH:SHA_256 」 的其他選項中方塊的 Win32HelloWorld 專案屬性頁面中所示**[圖 5**。

切換雜湊 sha-256 演算法的原始程式檔
[圖 5 切換來源檔案的 sha-256 雜湊演算法

重建之後在 Visual Studio 中,我可以有新的 W32HelloWorld.exe 和 W32HelloWorld.pdb PE/PDB 組 Visual Studio 2015\Projects\W32HelloWorld\x64\Debug 資料夾中。現在,使用 cvdump 工具,以新的 W32HelloWorld.pdb 檔案對其-sf 選項會顯示 Win32HelloWorld.cpp 檔案以及其 sha-256 雜湊值在輸出中,如所示**[圖 6**。

Cvdump 顯示 Win32HelloWorld.cpp 和其 sha-256 雜湊值
[圖 6 Cvdump 顯示 Win32HelloWorld.cpp 和其 sha-256 雜湊值

現在,我可以回到 W32HelloWorld.cpp 檔案資料夾中,Visual Studio 2015\Projects\W32HelloWorld\W32HelloWorld 以查看其 sha-256 雜湊值。使用 certutil 工具以 Win32HelloWorld.cpp 檔案對其-hashfile 動詞 sha-256,取得所顯示的 sha-256 雜湊值**[圖 7**。

取得使用 Certutil sha-256 雜湊值
[圖 7 取得 sha-256 雜湊 Certutil 值

很明顯地,它符合 W32HelloWorld.pdb 檔中記錄的 SHA 256 值。這強烈表示 Win32HelloWorld.cpp 檔案已確實使用編譯 W32HelloWorld.exe 應用程式,如預期般。

如需處理原生程式碼與受管理的相關公用工具的詳細資訊,程式碼 PE/PDB 檔案組,請參閱知識庫文章 3195907,< 如何來擷取索引來源檔案的可攜式可執行檔二進位檔案 > (bit.ly/2hs8q0u)。

總結

我希望本文已說明更強的連結,原始程式檔和編譯,它們在 PE 檔之間的一些潛在的好處。您可以建立更強的連結讓編譯器雜湊的原始程式碼檔使用最強的雜湊演算法可在編譯期間 — sha-256。由編譯器產生的原始程式碼檔的實際的雜湊值實際上會變成用來編譯可執行檔的原始程式碼檔的唯一識別碼。

一旦您了解這些唯一的識別項的值,您可以使用它們在不同的軟體開發生命週期配置追蹤、 處理和控制的原始程式碼檔具有強式的連結到特定的可執行檔,因而產生較高的使用者可執行檔中的信賴等級。


Mike Lai剛輸入他 20 年的 Microsoft 工作。 他是 Microsoft 的功能和其許多產品的工程方面提供各種機會感激。他想要在高可信度電腦運算感謝他目前的管理,讓他的想法變成成熟且逐漸將納入到發行的產品,其沒有耐性以及其參與資訊和通訊技術的安全性標準組織的支援。

感謝下列 Microsoft 技術專家來檢閱這份文件︰ Scott 欄位、 Mike Grimm 控告 Hotelling,Ariel Netz Richard Ward 和 Roy Williams