對虛幻引擎 4 項目的 AES 密鑰進行逆向工程

這篇文章是針對使用 4.21 製作的虛幻引擎 4 遊戲的 Windows 版本而設計的。這可能適用於以前的版本,甚至可能適用於引擎的未來版本。你的旅費可能會改變。

免責聲明

注意:我不會幫助您找到特定標題的密鑰。所以不要問。這篇文章旨在分享一些關於您通常如何做這樣的事情的知識,並且僅用於教育目的。

本指南僅適用於您的個人項目。不要從商業項目中竊取受版權保護的材料,這是非法的。修改商業遊戲以進行重新分發是非法的。

網上有很多人定期爲已發佈的遊戲執行此操作,但我還沒有找到任何人解釋如何實際實現它。我希望嘗試阻止這種神聖的知識,並向在線其他人和任何其他遊戲開發者公開這是如何完成的,以便我們可以瞭解這些事情是如何實現的,甚至可能在未來改進遊戲數據加密!

在本教程中,我使用加密的 pak 索引構建了自己的測試遊戲。我強烈建議您構建自己的加密虛幻引擎遊戲來測試這一點作爲練習。我這次測試的關鍵是:

pzq1+cZGipLozoSKnxO/vLeOunJWRFSBPUC+bZiLIsQ=

另外值得注意的是,這只是我解決問題的方法。我不知道其他人是如何實現這一點的(我不知道該問誰,並且在谷歌上找不到任何東西),但我懷疑其他人正在做類似的事情(如果不是完全相同的話)。那麼,我們去狩獵吧!

我們正在做什麼

一些遊戲對其數據文件進行加密,以避免人們看到源資產。這通常是通過加密密鑰來完成的。在某些時候,遊戲必須在內存中擁有該密鑰才能執行解密過程。我們的目標是在此時停止遊戲並從內存中讀取密鑰,以便我們自己使用它。

所需工具

確定虛幻引擎版本

您想檢查製作遊戲的虛幻版本

找到目標遊戲的安裝目錄並瀏覽到:

[GameName]/Binaries/Win64/

您將在此目錄中看到一個名爲 [GameName]-Win64-Shipping.exe 的 exe。右鍵單擊它並選擇“屬性”。

轉到“詳細信息”面板並檢查文件版本。這將告訴您構建遊戲所用的虛幻版本。我構建的這個測試遊戲是在 4.21.2 中創建的。如果您可以獲得理想的確切版本,最新的 4.21 就可以了,但可能所有 4.21.x 版本對此都足夠相似。

我們需要鑰匙嗎?

首先,請檢查您是否確實需要密鑰。找到目標遊戲的安裝目錄並瀏覽到:

[GameName]/Content/Paks/

該目錄下應該有一個pak文件。這包含了遊戲的主要內容。某些遊戲可能包含多個 pak 文件。您需要弄清楚哪個文件包含主要的遊戲資源,其他文件可能是 DLC 或 mod。

虛幻引擎附帶了一個名爲 UnrealPak.exe 的工具。您可以在以下位置找到此內容:

[Unreal Engine Install]/Engine/Binaries/Win64/UnrealPak.exe

您可以使用它對我們上面找到的 pak 文件運行命令。

例如,我們可以測試該文件,看看是否可以打開它,傳入 pak 文件的完整路徑:

[Unreal Engine Install]/Engine/Binaries/Win64/UnrealPak.exe -Test [PAK FILE PATH]

如果您收到如下錯誤消息:

斷言失敗:Key.IsValid()

那我們就出發吧!我們需要提供一個有效的密鑰,所以讓我們去尋找它。如果您收到不同的錯誤,則可能有不同的(或額外的)問題需要解決,並且可能不會從這篇博客文章中獲得太多運氣。

如果您獲得了一長串資產名稱,那麼恭喜您!您的 pak 文件未加密。您現在還擁有提取文件的正確工具,請嘗試使用“-Extract”功能而不是“-Test”。

進行設置

啓動虛幻引擎並使用與構建目標遊戲相同的版本創建一個新的代碼項目。重要的是,您使用的引擎版本與用於構建的版本相匹配,以便我們將閱讀的代碼與遊戲相匹配。

創建項目後,在 Visual Studio 中打開解決方案。這將允許您瀏覽虛幻引擎的源代碼。我們想要找到引擎從哪裏獲取解密密鑰。

在 4.21 中,使用函數“FPakPlatformFile::GetPakEncryptionKey”獲取解密密鑰。這在 IPlatformFilePak.cpp 的 DecryptData() 函數中調用。

使用您最喜歡的源代碼軟件(我正在使用 VisualAssist - 如果您想一直生氣,Intellisense 就可以),查找如何調用此函數。我們正在尋找將在 Shipping exe 中的字符串,以用作我們在實際遊戲 EXE 中查找的地標。

這裏 VisualAssist 告訴我有幾個函數調用了我們的 DecryptData 函數。但我們主要感興趣的是 LoadIndex。這是 pak 文件中包含資產列表的部分。它首先由引擎加載,並且通常是唯一實際加密的部分。

通常只有索引被加密,因爲所有這些加密/解密需要很長時間才能完成,並且開發人員不希望顯着增加所有遊戲資產的加載時間。僅加密索引仍然會使文件在沒有密鑰的情況下毫無用處,但使解密時間可以忽略不計。

現在我們來看看 LoadIndex 函數。我們可以看到函數頂部有一個致命錯誤。這對我們很有用,因爲致命錯誤不會從發佈版本中刪除。正常的日誌行通常會從運輸版本中刪除,因爲它們是不需要的,只會減慢遊戲速度,但致命錯誤會出現在最終的遊戲中,所以我們現在有一些可以查找的文本。

我們現在要開始調試目標遊戲並查找“pak 文件中損壞的索引偏移量”。細繩。

附加到遊戲

大多數遊戲都有某種啓動器或第三方集成,會阻止您直接啓動遊戲。爲了避免這種情況,我們將使用一個名爲 GFlags 的工具。GFlags 允許我們在任何 EXE 啓動後立即將調試器附加到該 EXE。

找到您安裝的 GFlags 並運行它。默認情況下它會在這裏:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe

導航到圖像文件選項卡。

您要在此處輸入遊戲 EXE 的名稱。這是名稱中帶有“-Win64-Shipping”的一個。例如,我的遊戲“RealGame”名爲“RealGame-Win64-Shipping.exe”。這應該只是文件名和擴展名,而不是完整路徑。

按 T​​AB 刷新 UI 並轉到“調試器”。勾選此框並輸入 x64dbg 中 x64dbg.exe 的完整路徑名。這應該位於 x64dbg\release\x64 或下載中的類似位置。

單擊“應用”並啓動目標遊戲。您應該獲得 x64dbg 而不是遊戲。恭喜!我們現在“連接”並實時調試遊戲。

找出我們的錯誤

因此,之前我們識別了字符串“pak 文件中的索引偏移量已損壞”。就在我們的 DecryptData 函數之前被擊中。

在主窗口中右鍵單擊並導航至“搜索 -> 所有模塊 -> 字符串引用”

下一個窗口底部有一個進度條。最好等它完成後再繼續!完成後,輸入“pak 文件中的索引偏移已損壞”。進入搜索:底部的框。

成功!我們有一些點擊。它們位於相同的粗略內存區域中,因此看起來實際上是相同的代碼塊。雙擊其中一個即可跳轉到 EXE 的該區域進行查看。

此過程的一個重要部分是大致瞭解這裏發生的情況。這是 EXE 的低級代碼。需要注意的重要事項:

  • 以 j 開頭的命令 - 這些命令通常會“跳轉”到其他地方
  • “call” - 將跳轉到特定模塊中的函數

在上面的屏幕截圖中,我們可以看到 x64dbg 非常有幫助,並向我們展示了窗口左側的跳轉。我們可以看到,如果條件爲真,以“jge”開頭的行將跳過我們的錯誤消息(jge 表示“如果大於等於則跳轉”)。因爲這直接跳過了我們的錯誤消息,所以看起來我們處於正確的位置。這些行與我們之前看到的代碼完全對應:

這就是現在謎題的主要部分。我們將逐步調試這個遊戲,遵循 EXE 的結構並將其與 UE4 進行比較,以找出我們所處的位置。一旦我們進入 DecryptData 函數,我們就可以查找內存值並獲取密鑰。

單擊窗口一側的小氣泡將設置斷點。您需要在我們找到的代碼的該區域內設置一個斷點,然後單擊“運行”按鈕,直到到達斷點爲止。

注意:默認情況下,x64dbg 在許多不同的事件上都會中斷。我在“選項”->“設置”->“中斷:”下關閉所有這些。這將節省繼續越過許多斷點的麻煩。

讓我們更詳細地看一下 LoadIndex 函數。

我們這裏分爲三個主要部分。

  1. 數組初始化
  2. 可選的索引解密
  3. SHA檢查

第一個塊相當簡單,在 x64dbg 中看起來相對簡單。

我們的解密步驟將在一個相當小的跳轉內,並在某處調用模塊函數。這應該很容易發現。

SHA 哈希有一堆內存設置、一個巨大的分支和一個 for 循環(當你處於如此低的級別時,這只是一個複雜的跳轉)。

讓我們再看看我們的 x64dbg。

看起來我們有一個小跳躍,另一個小跳躍,然後是一堆複雜的跳躍。

兩次跳是怎麼回事?最後一節明明是SHA哈希開始的,但是前面只有一個if語句?

上面我們調用了“AddUninitialized”。這就是所謂的“內聯函數”。當它被調用時,它的執行基本上被注入到調用它的地方,而不是在內存中跳轉。

正如我們所看到的,這個函數有自己的 if 語句。因此,如果它內聯到調用函數中,它將在那裏添加這個分支。這解釋了我們看到的第一個分支。因此,我們可以假設第二個小分支是進行加密的分支。您可以看到我已經在模塊函數調用處添加了一個斷點,因爲這是我要開始調試的地方。

調試

現在我們已連接,正在調試,並且位於正確的位置。確保我們在模塊調用處得到了斷點,並且我們已經運行了應用程序直到遇到它。

現在我們要運行“Step Into”(F7)。這將跳轉到我們當前正在執行的功能,然後立即再次停止遊戲。這將帶我們到達 DecryptData 函數在 EXE 中的位置。

現在讓我們再次檢查我們的代碼。

我們有一個關鍵變量初始化,然後獲取它,然後解密數據。check() 應該在 Shipping 版本之外進行編譯,因此我們可以忽略這一點。

因爲變量初始化可能相當複雜,所以讓我們從 EXE 代碼的底部開始並進行備份。

在頂部我們有多個“push”命令。這些通常指示函數的狀態。

在底部我們有一個“ret”命令。這通常是函數結束(返回)。

向上工作,有一些模塊調用,我認爲這些是最終的 DecryptData 函數調用。C++ 調用的 DecryptData 函數非常小,並且調用 DecryptData 的不同變體,因此編譯器可能會自行將其內聯到此處以進行優化。編譯器做了很多優化,這將使最終的 EXE 看起來與原始的 C++ 不同,準備好通過大量的猜測和預感來解決這個問題,這通常是錯誤的,導致您回溯並重新開始。

現在的目標是逐步瞭解並開始查看我們的記憶。上面我添加了一個斷點,我認爲我們正在獲取解密密鑰。所以我繼續運行,直到達到那個點,然後我點擊“Step Over”(F8)調試按鈕來完整運行模塊功能(我不關心它如何獲取密鑰,我只是想讓它獲取它)。

一旦我們跨過去,請注意 x64dbg 右側的部分(我已經截取了上面跨過那一刻的屏幕截圖)。這向我們展示了我們的寄存器(如果您不知道那是什麼,請繼續操作,我們會沒事的)。以紅色突出顯示的內容在最後一個調試步驟中發生了變化。右鍵單擊每個並選擇“Follow in Dump”,然後查看 x64dbg 底部的“Dump 1”窗口,看看裏面有什麼。

在這裏,我的 RCX 寄存器有我想象中的遊戲的正確密鑰。即“A73AB5F9C6468A92E8CE848A9F13BFBCB78EBA72564454813D40BE6D988B22C4”。

這是十六進制格式的,您需要將其轉換爲 Base64 以用於 Unreal。我剛剛在 Google 上搜索了“Hex 到 Base64 編碼器”,發現了很多相關網站。

繁榮!這是我們的 AES 密鑰。

如何使用

UnrealPak.exe 接受“crypto.json”參數。您需要在某處創建此文件並添加以下內容:

{
  "$types": {
    "UnrealBuildTool.EncryptionAndSigning+CryptoSettings, UnrealBuildTool, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null": "1",
    "UnrealBuildTool.EncryptionAndSigning+EncryptionKey, UnrealBuildTool, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null": "2"
  },
  "$type": "1",
  "EncryptionKey": {
    "$type": "2",
    "Name": null,
    "Guid": null,
    "Key": "pzq1+cZGipLozoSKnxO/vLeOunJWRFSBPUC+bZiLIsQ="
  },
  "SigningKey": null,
  "bEnablePakSigning": false,
  "bEnablePakIndexEncryption": true,
  "bEnablePakIniEncryption": true,
  "bEnablePakUAssetEncryption": false,
  "bEnablePakFullAssetEncryption": false,
  "bDataCryptoRequired": true,
  "SecondaryEncryptionKeys": []
}

在這裏您可以看到密鑰以及有關如何使用它的一些設置。我的測試遊戲對索引和ini 文件(配置文件)進行了加密。如果您運氣不好並且開發人員已加密了他們的所有文件,您將需要使用這些。

像以前一樣測試您的 pak 文件,但添加 -cryptokeys= 選項

[Unreal Engine Install]/Engine/Binaries/Win64/UnrealPak.exe -Test [PAK FILE PATH] -cryptokeys=[LOCATION OF crypto.json]

我建議 UModel 對結果數據進行實際處理。http://www.gildor.org/en/projects/umodel

祝你好運!

對虛幻引擎 4 項目的 AES 密鑰進行逆向工程

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章