Experimental fast ADX encryption cracker by furrybob at 1:43 PM EDT on May 29, 2017
I was recently asked by @bnmm about guessing keys for encrypted ADX files. Sadly, I knew nothing about ADX encryption at the time. Yesterday I remembered bnmm's comment, and decided to have a go at it, and here's the result.
Link Usage: VGAudioTools.exe CrackAdx <path to files>
Unlike GuessAdx, this operates on a folder of encrypted ADX files, with the goal of finding keys as quickly as possible, usually within 1-3 seconds.
Once a valid key is found, it will be used to decrypt, decode, and reencode all the ADX files in the folder, and the re-encoded file will be compared to the original. The closer to the original the re-encoded file is, the more likely the found key is correct.
I only implemented type 8 encryption cracking. I'll probably add type 9 soon.
@bnmm I haven't looked at that Japanese ADX cracker yet. I might take a look now that I've made one myself.
Instead of reimplementing some stuff in a separate program, I used my library, VGAudio, for reading, decoding, and encoding the audio. Just a note in case anyone wonders why the .exe is so large.
Whoops. I hadn't pushed the commits. Here's the code.
I take advantage of the fact that the scale of the first non-empty frame in the file is usually 1 or 2, so I try those first. Combined with the fact that the key's shared between dozens of files, you're pretty much guaranteed to find the key within couple seconds. They're practically giving away the seed value, and from there, the search space is small enough that brute forcing is no problem at all.
Neat stuff, we could also crosscheck old keys with it (though I tried God Hand and seemed it couldn't decide which key was best from 3).
What makes interesting the japanese decoder though, is that it supports (I believe -- I just checked the code) the original key format expected by the encoder/decoder. Ie.- seed/mult/add isn't really a key, but the result of deriving the original 16b key (let's call it keyphrase for a moment).
Type 8 and 9 derive seed/mult/add differently, but interestingly keyphrases seem shared between ADX and HCA (also 16b).
I think I could add this key format (for science) once I check the validity. It would be nice to key cracker would find these original keyphrases too. Maybe they can be re-derived from seed/mult/add too?
I researched type 9 encryption today, and I'm wondering what in the world the developers were thinking when they "improved" the encryption. It's no better than it was before, and quickly crackable. There are still only 0x2000^3, or 2^39, possible keys. The upper 3 bits of each part of the LCG values have no effect on the encryption.
@bnnm The official encoder uses what they call a "keycode" for the encryption key. This can be anything from 0 to u64_max.
Amusingly, those 2^64 possible keycodes only contain 2^39 unique keys for the purpose of ADX encryption. That means that about only 3/100,000,000 of the possible keyspace is used. To be fair, the upper ~21 bits of the keycode have no effect on the LCG values, which would result in 1/16 of the keyspace being unique.
Anyway, the conversion between the formats looks like this. Is that what's in the Japanese decoder? I still haven't looked at it.
Unfortunately, I haven't found any readily available type-9-encrypted ADX files except for some Sonic Runners SFX. The keycode for Sonic Runners is 19910623, or seed:0x0000 mult:0x1fbd inc:0x18b1
I think it's a lookup table of primes. guessadx uses this too but does a Sieve of Eratosthenes at runtime (see the readme for some discussion of that), and probably uses 3x as many as it needs to since this table only has the 0x400 first from 0x4000.
Those files for Gunhound aren't encrypted. I've pushed code that cracks type 9 ADX files. I realized today that the search space is 8x smaller than I thought, so cracking type 9 might be faster than cracking type 8 ATM.
Does anybody have any software that creates type-8 encrypted ADX files? The old adxencd only does version 3 ADX, and CriAtomEncoder only does type 9 encryption. There's some "adxfed.dll" for ADX encoding and decoding, but searching for it gets no results.
Edit: I spoke too soon. Found something by searching for adxtools
So Type 8 encryption is pretty much worthless now.
Using a stock i7-6700K to crack type 8 encryption using one file:
Worst case time when the first frame is not empty: ~450ms. Worst case time when the first frame is empty: ~5000ms. This is the time it takes to check every single possible (I'm pretty sure) key.
Average time when the first frame is not empty: ~10-100ms depending on the first frame's scale. Average time when the first frame is empty: ~10-400ms depending on the first frame's scale.
I reverse engineered the type 8 encryption from that ADXTools thing I downloaded. The seed, multiplier, and increment all have to come from a set of 1024 primes. That information allowed the search time to get so low, and I wouldn't be surprised if there are still ways to bring that time even lower.