Fix Devkit XEX Decryption

Devkit key is all zeros, unlike the all-precious retail key.
This commit is contained in:
Julia Nelz 2025-03-04 04:19:16 -08:00 committed by Caroline Joy Bell
parent b8edc34d75
commit 1e9993b65e
2 changed files with 21 additions and 2 deletions

View File

@ -126,7 +126,8 @@ Image Xex2LoadImage(const uint8_t* data, size_t dataSize)
{
auto* header = reinterpret_cast<const Xex2Header*>(data);
auto* security = reinterpret_cast<const Xex2SecurityInfo*>(data + header->securityOffset);
const auto* fileFormatInfo = reinterpret_cast<const Xex2OptFileFormatInfo*>(getOptHeaderPtr(data, XEX_HEADER_FILE_FORMAT_INFO));
const auto* fileFormatInfo = static_cast<const Xex2OptFileFormatInfo*>(getOptHeaderPtr(data, XEX_HEADER_FILE_FORMAT_INFO));
const auto* execInfo = static_cast<const Xex2OptExecutionInfo*>(getOptHeaderPtr(data, XEX_HEADER_EXECUTION_INFO));
Image image{};
std::unique_ptr<uint8_t[]> result{};
@ -147,7 +148,11 @@ Image Xex2LoadImage(const uint8_t* data, size_t dataSize)
uint8_t decryptedKey[KeySize];
memcpy(decryptedKey, security->aesKey, KeySize);
AES_init_ctx_iv(&aesContext, Xex2RetailKey, AESBlankIV);
if (!execInfo || !execInfo->titleId) {
AES_init_ctx_iv(&aesContext, Xex2DevkitKey, AESBlankIV);
} else {
AES_init_ctx_iv(&aesContext, Xex2RetailKey, AESBlankIV);
}
AES_CBC_decrypt_buffer(&aesContext, decryptedKey, KeySize);
decryptedData = std::make_unique<uint8_t[]>(dataSize - header->headerSize);

View File

@ -3,6 +3,7 @@
#include "xbox.h"
inline constexpr uint8_t Xex2RetailKey[16] = { 0x20, 0xB1, 0x85, 0xA5, 0x9D, 0x28, 0xFD, 0xC3, 0x40, 0x58, 0x3F, 0xBB, 0x08, 0x96, 0xBF, 0x91 };
inline constexpr uint8_t Xex2DevkitKey[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
inline constexpr uint8_t AESBlankIV[16] = {};
enum Xex2ModuleFlags
@ -186,6 +187,19 @@ struct Xex2OptFileFormatInfo
be<uint16_t> compressionType;
};
struct Xex2OptExecutionInfo
{
be<uint32_t> mediaId;
be<uint32_t> version;
be<uint32_t> versionBase;
be<uint32_t> titleId;
uint8_t platform;
uint8_t executableTable;
uint8_t discNumber;
uint8_t discTotal;
be<uint32_t> savedGameId;
};
struct Xex2ImportHeader
{
be<uint32_t> sizeOfHeader;