private AdxKeyConfidence GetReencodeConfidence(CriAdxKey key, string filename) { CriAdxFormat adx; using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read)) { var reader = new AdxReader { EncryptionKey = key }; adx = (CriAdxFormat)reader.ReadFormat(stream); } Pcm16Format pcm = adx.ToPcm16(); CriAdxFormat adx2 = new CriAdxFormat().EncodeFromPcm16(pcm); var confidence = new AdxKeyConfidence(); int toCompareFull = adx.Channels[0].Audio.Length; int toCompareShort = Math.Min(adx.FrameSize * 100, toCompareFull); for (int i = 0; i < adx.ChannelCount; i++) { confidence.TotalBytesFull += toCompareFull; confidence.TotalBytesShort += toCompareShort; confidence.IdenticalBytesFull += Common.DiffArrays(adx.Channels[i].Audio, adx2.Channels[i].Audio, toCompareFull); confidence.IdenticalBytesShort += Common.DiffArrays(adx.Channels[i].Audio, adx2.Channels[i].Audio, toCompareShort); } return(confidence); }
public bool KeyIsValid(CriAdxKey key, ushort[] scales) { int xor = key.Seed; foreach (ushort scale in scales) { if (((scale ^ xor) & ValidationMask) != 0 && scale != 0) { return(false); } xor = (xor * key.Mult + key.Inc) & XorMask; } return(true); }
public void AddKey(CriAdxKey key) { if (!TriedKeys.TryAdd(key, 0)) { return; } Progress?.LogMessage($"Trying key {PrintKey(key)}"); if (Files.Any(stream => !KeyIsValid(key, stream.Scales))) { Progress?.LogMessage($"Key {PrintKey(key)} is invalid"); return; } string[] keyStrings = KeyStrings?[key].ToArray(); Progress?.LogMessage($"Key {PrintKey(key)} could be valid. Calculating confidence..."); var confidences = Files.AsParallel().Select(file => GetReencodeConfidence(key, file.Filename)).ToList(); double confidenceSmall = 1 - (double)confidences.Sum(x => x.IdenticalBytesShort) / confidences.Sum(x => x.TotalBytesShort); double confidenceFull = 1 - (double)confidences.Sum(x => x.IdenticalBytesFull) / confidences.Sum(x => x.TotalBytesFull); var sb = new StringBuilder(); sb.Append('-', 40).AppendLine(); sb.AppendLine(PrintKey(key)); sb.AppendLine($"Confidence Short - {confidenceSmall:P3} Full - {confidenceFull:P3}"); if (EncryptionType == 9) { sb.AppendLine($"Key code: {key.KeyCode}"); } if (keyStrings != null && keyStrings.Any()) { sb.AppendLine($"Possible key strings: {string.Join(", ", keyStrings)}"); } sb.Append('-', 40); Keys.Add(key); Progress?.LogMessage(sb.ToString()); string PrintKey(CriAdxKey k) => $"Seed - {k.Seed:x4} Multiplier - {k.Mult:x4} Increment - {k.Inc:x4}"; }
public void TryScale(AdxFile adx, int index) { int seed = (adx.Scales[adx.StartFrame] ^ index) & MaxSeed - 1; if (adx.StartFrame == 0 && !PossibleSeeds.Contains(seed)) { return; } foreach (int mult in PossibleMultipliers) { foreach (int inc in PossibleIncrements) { int xor = seed; bool match = true; for (int i = adx.StartFrame; i < adx.Scales.Length; i++) { ushort scale = adx.Scales[i]; if (((scale ^ xor) & ValidationMask) != 0 && scale != 0) { match = false; break; } xor = (xor * mult + inc) & XorMask; } if (match) { CriAdxKey key = FindStartingKey(seed, mult, inc, adx.StartFrame); if (key != null) { AddKey(key); } } } } }