From 85c015f7ff9637d51f211334ed0d69b88aecf2b0 Mon Sep 17 00:00:00 2001 From: Christian Engelhardt Date: Sun, 21 Jul 2024 22:52:11 +0200 Subject: [PATCH] fix(Steam): meta file enrcyption --- libNOM.io/PlatformSteam.cs | 14 +++++++------- libNOM.io/libNOM.io.csproj | 2 +- libNOM.test/Steam.cs | 22 ++++++++++++++++++++++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/libNOM.io/PlatformSteam.cs b/libNOM.io/PlatformSteam.cs index 51d35b7..ffe57b2 100644 --- a/libNOM.io/PlatformSteam.cs +++ b/libNOM.io/PlatformSteam.cs @@ -220,15 +220,15 @@ 91. EMPTY ( 20) // META_FORMAT_4 } if (container.IsSave) { - // Extended metadata since Waypoint 4.00. - UpdateContainerWithWaypointMetaInformation(container, disk); + // Extended metadata since Waypoint 4.00. + UpdateContainerWithWaypointMetaInformation(container, disk); // Extended metadata including a new META_FORMAT since Worlds 5.00. UpdateContainerWithWorldsMetaInformation(container, disk, decompressed); - // GameVersion with BaseVersion only is not 100% accurate but good enough to calculate SaveVersion. - container.SaveVersion = Meta.SaveVersion.Calculate(container, Meta.GameVersion.Get(container.Extra.BaseVersion)); - } + // GameVersion with BaseVersion only is not 100% accurate but good enough to calculate SaveVersion. + container.SaveVersion = Meta.SaveVersion.Calculate(container, Meta.GameVersion.Get(container.Extra.BaseVersion)); + } } // Size is save to write always. @@ -299,7 +299,7 @@ protected override Span DecryptMeta(Container container, Span meta) uint i1 = (current >> 3) ^ (result[valueIndex] << 4); uint i2 = (current * 4) ^ (result[valueIndex] >> 5); - uint i3 = (result[valueIndex] ^ key[keyIndex]); + uint i3 = (result[valueIndex] ^ key[keyIndex]); // [(0 & 3) ^ keyIndex] as in j3 to be precise (0 would be the last executed index) but (0 & 3) is always zero and therefore does not matter uint i4 = (current ^ hash); result[0] -= (i1 + i2) ^ (i3 + i4); @@ -441,7 +441,7 @@ protected override ReadOnlySpan EncryptMeta(Container container, ReadOnlyS uint i1 = (value[0] >> 3) ^ (current << 4); uint i2 = (value[0] * 4) ^ (current >> 5); - uint i3 = (current ^ key[keyIndex ^ 1]); + uint i3 = (current ^ key[(lastIndex & 3) ^ keyIndex]); uint i4 = (value[0] ^ hash); value[lastIndex] += (i1 + i2) ^ (i3 + i4); current = value[lastIndex]; diff --git a/libNOM.io/libNOM.io.csproj b/libNOM.io/libNOM.io.csproj index edc6e28..6ad6061 100644 --- a/libNOM.io/libNOM.io.csproj +++ b/libNOM.io/libNOM.io.csproj @@ -58,7 +58,7 @@ - 0.10.0-beta.8 + 0.10.0-beta.9 cengelha Provides reading and writing save files from the game No Man's Sky for all possible platforms as well as related actions. Copyright (c) Christian Engelhardt 2021 diff --git a/libNOM.test/Steam.cs b/libNOM.test/Steam.cs index 244367a..5d7df29 100644 --- a/libNOM.test/Steam.cs +++ b/libNOM.test/Steam.cs @@ -147,6 +147,28 @@ private static void AssertCommonMeta(IContainer container, uint[] metaA, uint[] Assert.IsTrue(metaA.Skip(20).SequenceEqual(metaB.Skip(20))); } } + else if (metaA.Length == META_LENGTH_TOTAL_WORLDS) + { + AssertAllAreEqual(META_FORMAT_4, metaA[1], metaB[1]); + + if (container.IsAccount) + { + AssertAllNotZero(metaA.Skip(2).Take(4), metaB.Skip(2).Take(4)); + AssertAllNotZero(metaA.Skip(6).Take(8), metaB.Skip(6).Take(8)); + AssertAllZero(metaA.Skip(14), metaB.Skip(14)); + } + else + { + AssertAllZero(metaA.Skip(2).Take(12), metaB.Skip(2).Take(12)); + AssertAllNotZero(metaA.Skip(14).Take(2), metaB.Skip(14).Take(2)); + AssertAllZero(metaA[16], metaB[16]); + Assert.IsTrue(metaA.Skip(20).Take(69).SequenceEqual(metaB.Skip(20).Take(69))); + AssertAllNotZero(metaA[89], metaB[89]); + AssertAllAreEqual(META_FORMAT_4, metaA[90], metaB[90]); + AssertAllZero(metaA.Skip(91), metaB.Skip(91)); + + } + } else throw new AssertFailedException(); }