From 9751176b8c96ae1507cb2f65a14478dc49175800 Mon Sep 17 00:00:00 2001 From: apple1417 Date: Mon, 18 Jul 2022 20:51:29 +1200 Subject: [PATCH] validate that serial database version has enough bits to encrypt --- BL3Tools/GameData/Items/Borderlands3Serial.cs | 63 ++++++++++++------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/BL3Tools/GameData/Items/Borderlands3Serial.cs b/BL3Tools/GameData/Items/Borderlands3Serial.cs index 282581b..c544dce 100644 --- a/BL3Tools/GameData/Items/Borderlands3Serial.cs +++ b/BL3Tools/GameData/Items/Borderlands3Serial.cs @@ -36,6 +36,7 @@ namespace BL3Tools.GameData.Items { // - BL3(AwAAAACxlIC1y1QBE0QesjkdMfnY444QAAAAAACADAg=) // - BL3(AwAAAAA4jIA5lMPiFgAAAA==) :: Customization // - BL3(AwAAAAChWIC5UhEHFgAAAA==) :: Customization + // - BL3(AwAAAAB8zICZyMsgAo7jAYk0GZPSKXTprJyAEAAAAAAAAAAA) :: EM-P5 at database version 25 - add an anoint to force it to upgrade /// /// A class representing a Borderlands 3 Serial Item @@ -139,7 +140,7 @@ public byte[] EncryptSerialToBytes(uint seed = 0) { // Encrypt the data BogoEncrypt(seed, buffer, 0, buffer.Length); - + // Slap the serial version & seed onto the start buffer = Helpers.ConcatArrays(header, buffer); @@ -172,7 +173,7 @@ public static Borderlands3Serial DecryptSerial(byte[] serial) { IOWrapper serialIO = new IOWrapper(serial, Endian.Big, 1); uint originalSeed = serialIO.ReadUInt32(); - + // Copy the decrypted serial into a new buffer int decryptedSize = (int)(serial.Length - serialIO.Position); byte[] decrypted = new byte[decryptedSize]; @@ -182,7 +183,7 @@ public static Borderlands3Serial DecryptSerial(byte[] serial) { BogoDecrypt(originalSeed, decrypted, 0, decryptedSize); IOWrapper decryptedSerialIO = new IOWrapper(decrypted, Endian.Big, 0); - + // Read in the original checksum ushort originalChecksum = decryptedSerialIO.ReadUInt16(); @@ -192,7 +193,7 @@ public static Borderlands3Serial DecryptSerial(byte[] serial) { byte[] checksumBuffer = Helpers.ConcatArrays(new byte[] { serial[0], // Serial Version - serial[1], serial[2], serial[3], serial[4], // Seed + serial[1], serial[2], serial[3], serial[4], // Seed 0xFF, 0xFF // When calculating, the preset checksum is 0xFF }, remaining); // Append the remaining (unencrypted) data @@ -239,11 +240,11 @@ public static Borderlands3Serial DecryptSerial(byte[] serial) { // Both Anointments & Mayhem mode are currently stored in InventoryGenericPartData genericParts = EatBitArrayForCategory(reader, "InventoryGenericPartData", SerialDatabaseVersion, 4); - + // Some other stuff is apparently probably in here, no idea what or why (: int additionalCount = reader.ReadInt32(8); additionalData = new List(); - for (int i = 0; i < additionalCount; i++) + for (int i = 0; i < additionalCount; i++) additionalData.Add(reader.ReadInt32(8)); try { @@ -268,7 +269,7 @@ public static Borderlands3Serial DecryptSerial(byte[] serial) { var nameParts = parts.Select(x => (string)x.Clone()).ToList(); nameParts.Add(balance); string userFriendlyName = InventoryNameDatabase.GetNameForParts(nameParts); - + // This means we've got some sort of item that we don't know entirely have info on... if (string.IsNullOrEmpty(userFriendlyName)) userFriendlyName = shortBalance; @@ -340,28 +341,48 @@ private static string EatBitsForCategory(BitReader reader, string category, int return partValue; } + public void ValidateSerialDatabaseVersion(string category, string part) { + int bits = InventorySerialDatabase.GetBitsToEat(category, SerialDatabaseVersion); + int index = InventorySerialDatabase.GetIndexByPart(category, part); + + if (index > 0 && (ulong)index > BitWriter.MaxValueForBitCount[bits]) { + SerialDatabaseVersion = (int)InventorySerialDatabase.MaximumVersion; + } + } + public void ValidateFields() { - string fullName = InventorySerialDatabase.GetBalanceFromShortName(this.Balance); - if (fullName != null) - this.Balance = fullName; + string fullName = InventorySerialDatabase.GetBalanceFromShortName(Balance); + if (fullName != null) { + Balance = fullName; + } + ValidateSerialDatabaseVersion("InventoryBalanceData", Balance); string invData = InventorySerialDatabase.GetInventoryDatas(false).FirstOrDefault(x => x.EndsWith(InventoryData)); - if (!string.IsNullOrEmpty(invData)) - this.InventoryData = invData; - + if (!string.IsNullOrEmpty(invData)) { + InventoryData = invData; + } + ValidateSerialDatabaseVersion("InventoryData", InventoryData); + string manu = InventorySerialDatabase.GetManufacturers(false).FirstOrDefault(x => x.EndsWith(Manufacturer)); - if (!string.IsNullOrEmpty(manu)) - this.Manufacturer = manu; - this.InventoryKey = InventoryKeyDB.GetKeyForBalance(Balance); + if (!string.IsNullOrEmpty(manu)) { + Manufacturer = manu; + } + ValidateSerialDatabaseVersion("ManufacturerData", Manufacturer); - if(InventoryKey != null) { + this.InventoryKey = InventoryKeyDB.GetKeyForBalance(Balance); + if (InventoryKey != null) { var validParts = InventorySerialDatabase.GetPartsForInvKey(InventoryKey); - this.Parts.RemoveAll(x => !validParts.Contains(x)); - - var validGenerics = InventorySerialDatabase.GetPartsForInvKey("InventoryGenericPartData"); - this.GenericParts.RemoveAll(x => !GenericParts.Contains(x)); + Parts.RemoveAll(x => !validParts.Contains(x)); + foreach (var part in Parts) { + ValidateSerialDatabaseVersion(InventoryKey, part); + } } + var validGenerics = InventorySerialDatabase.GetPartsForInvKey("InventoryGenericPartData"); + GenericParts.RemoveAll(x => !validGenerics.Contains(x)); + foreach (var part in GenericParts) { + ValidateSerialDatabaseVersion("InventoryGenericPartData", part); + } } // Credits to Rick/Gibbed for the BogoEncrypt functions from their BL2 save editor: