Add support for T6 server zones which are unsigned and unencrypted

This commit is contained in:
Jan 2019-09-27 15:31:33 +02:00
parent d662e5dcfa
commit f9b7fa57c8
2 changed files with 29 additions and 10 deletions

View File

@ -23,6 +23,7 @@
const std::string ZoneLoaderFactoryT6::MAGIC_SIGNED_TREYARCH = "TAff0100"; const std::string ZoneLoaderFactoryT6::MAGIC_SIGNED_TREYARCH = "TAff0100";
const std::string ZoneLoaderFactoryT6::MAGIC_SIGNED_ASSET_BUILDER = "ABff0100"; const std::string ZoneLoaderFactoryT6::MAGIC_SIGNED_ASSET_BUILDER = "ABff0100";
const std::string ZoneLoaderFactoryT6::MAGIC_UNSIGNED = "TAffu100"; const std::string ZoneLoaderFactoryT6::MAGIC_UNSIGNED = "TAffu100";
const std::string ZoneLoaderFactoryT6::MAGIC_UNSIGNED_SERVER = "TAsvu100";
const int ZoneLoaderFactoryT6::VERSION = 147; const int ZoneLoaderFactoryT6::VERSION = 147;
const int ZoneLoaderFactoryT6::STREAM_COUNT = 4; const int ZoneLoaderFactoryT6::STREAM_COUNT = 4;
@ -83,7 +84,7 @@ const uint8_t ZoneLoaderFactoryT6::RSA_PUBLIC_KEY_TREYARCH[]
class ZoneLoaderFactoryT6::ZoneLoaderFactoryT6Impl class ZoneLoaderFactoryT6::ZoneLoaderFactoryT6Impl
{ {
static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial) static bool CanLoad(ZoneHeader& header, bool* isSecure, bool* isOfficial, bool* isEncrypted)
{ {
assert(isSecure != nullptr); assert(isSecure != nullptr);
assert(isOfficial != nullptr); assert(isOfficial != nullptr);
@ -97,6 +98,7 @@ class ZoneLoaderFactoryT6::ZoneLoaderFactoryT6Impl
{ {
*isSecure = true; *isSecure = true;
*isOfficial = true; *isOfficial = true;
*isEncrypted = true;
return true; return true;
} }
@ -104,6 +106,7 @@ class ZoneLoaderFactoryT6::ZoneLoaderFactoryT6Impl
{ {
*isSecure = true; *isSecure = true;
*isOfficial = false; *isOfficial = false;
*isEncrypted = true;
return true; return true;
} }
@ -111,6 +114,15 @@ class ZoneLoaderFactoryT6::ZoneLoaderFactoryT6Impl
{ {
*isSecure = false; *isSecure = false;
*isOfficial = true; *isOfficial = true;
*isEncrypted = true;
return true;
}
if(!memcmp(header.m_magic, MAGIC_UNSIGNED_SERVER.c_str(), 8))
{
*isSecure = false;
*isOfficial = true;
*isEncrypted = false;
return true; return true;
} }
@ -174,20 +186,25 @@ class ZoneLoaderFactoryT6::ZoneLoaderFactoryT6Impl
return signatureLoadStep; return signatureLoadStep;
} }
static ISignatureDataProvider* AddXChunkProcessor(ZoneLoader* zoneLoader, std::string& fileName) static ISignatureDataProvider* AddXChunkProcessor(bool isEncrypted, ZoneLoader* zoneLoader, std::string& fileName)
{ {
ISignatureDataProvider* result = nullptr;
auto* xChunkProcessor = new ProcessorXChunks(STREAM_COUNT, XCHUNK_SIZE); auto* xChunkProcessor = new ProcessorXChunks(STREAM_COUNT, XCHUNK_SIZE);
// First decrypt the chunks with Salsa20 if(isEncrypted)
{
// If zone is encrypted, the decryption is applied before the decompression. T6 Zones always use Salsa20.
auto* chunkProcessorSalsa20 = new ChunkProcessorSalsa20(STREAM_COUNT, fileName, SALSA20_KEY_TREYARCH, sizeof(SALSA20_KEY_TREYARCH)); auto* chunkProcessorSalsa20 = new ChunkProcessorSalsa20(STREAM_COUNT, fileName, SALSA20_KEY_TREYARCH, sizeof(SALSA20_KEY_TREYARCH));
xChunkProcessor->AddChunkProcessor(chunkProcessorSalsa20); xChunkProcessor->AddChunkProcessor(chunkProcessorSalsa20);
result = chunkProcessorSalsa20;
}
// Then decompress the chunks using zlib // Decompress the chunks using zlib
xChunkProcessor->AddChunkProcessor(new ChunkProcessorInflate()); xChunkProcessor->AddChunkProcessor(new ChunkProcessorInflate());
zoneLoader->AddLoadingStep(new StepAddProcessor(xChunkProcessor)); zoneLoader->AddLoadingStep(new StepAddProcessor(xChunkProcessor));
// The signed data of the zone is the final hash blocks provided by the Salsa20 IV adaption algorithm // If there is encryption, the signed data of the zone is the final hash blocks provided by the Salsa20 IV adaption algorithm
return chunkProcessorSalsa20; return result;
} }
public: public:
@ -195,9 +212,10 @@ public:
{ {
bool isSecure; bool isSecure;
bool isOfficial; bool isOfficial;
bool isEncrypted;
// Check if this file is a supported T6 zone. // Check if this file is a supported T6 zone.
if(!CanLoad(header, &isSecure, &isOfficial)) if(!CanLoad(header, &isSecure, &isOfficial, &isEncrypted))
return nullptr; return nullptr;
// Create new zone // Create new zone
@ -215,7 +233,7 @@ public:
ISignatureProvider* signatureProvider = AddAuthHeaderSteps(isSecure, zoneLoader, fileName); ISignatureProvider* signatureProvider = AddAuthHeaderSteps(isSecure, zoneLoader, fileName);
// Setup loading XChunks from the zone from this point on. // Setup loading XChunks from the zone from this point on.
ISignatureDataProvider* signatureDataProvider = AddXChunkProcessor(zoneLoader, fileName); ISignatureDataProvider* signatureDataProvider = AddXChunkProcessor(isEncrypted, zoneLoader, fileName);
// Start of the XFile struct // Start of the XFile struct
zoneLoader->AddLoadingStep(new StepSkipBytes(8)); // Skip size and externalSize fields since they are not interesting for us zoneLoader->AddLoadingStep(new StepSkipBytes(8)); // Skip size and externalSize fields since they are not interesting for us

View File

@ -8,6 +8,7 @@ class ZoneLoaderFactoryT6 final : public IZoneLoaderFactory
static const std::string MAGIC_SIGNED_TREYARCH; static const std::string MAGIC_SIGNED_TREYARCH;
static const std::string MAGIC_SIGNED_ASSET_BUILDER; static const std::string MAGIC_SIGNED_ASSET_BUILDER;
static const std::string MAGIC_UNSIGNED; static const std::string MAGIC_UNSIGNED;
static const std::string MAGIC_UNSIGNED_SERVER;
static const int VERSION; static const int VERSION;
static const int STREAM_COUNT; static const int STREAM_COUNT;