mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-16 11:33:20 +01:00
Fix search for ADX encryption type-9 key
This commit is contained in:
parent
27419d1a43
commit
a1ab700764
108
src/meta/adx.c
108
src/meta/adx.c
@ -548,6 +548,8 @@ static int find_key(STREAMFILE *file, uint8_t type, uint16_t *xor_start, uint16_
|
|||||||
{
|
{
|
||||||
/* try to guess key */
|
/* try to guess key */
|
||||||
#define MAX_FRAMES (INT_MAX/0x8000)
|
#define MAX_FRAMES (INT_MAX/0x8000)
|
||||||
|
struct { uint16_t start, mult, add; } *keys = NULL;
|
||||||
|
int keycount = 0, keymask = 0;
|
||||||
int scales_to_do;
|
int scales_to_do;
|
||||||
int key_id;
|
int key_id;
|
||||||
|
|
||||||
@ -582,82 +584,52 @@ static int find_key(STREAMFILE *file, uint8_t type, uint16_t *xor_start, uint16_
|
|||||||
|
|
||||||
if (type == 8)
|
if (type == 8)
|
||||||
{
|
{
|
||||||
/* guess each of the keys */
|
keys = &keys_8;
|
||||||
for (key_id=0;key_id<keys_8_count;key_id++) {
|
keycount = keys_8_count;
|
||||||
/* test pre-scales */
|
keymask = 0x6000;
|
||||||
uint16_t xor = keys_8[key_id].start;
|
|
||||||
uint16_t mult = keys_8[key_id].mult;
|
|
||||||
uint16_t add = keys_8[key_id].add;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0;i<bruteframe &&
|
|
||||||
((prescales[i]&0x6000)==(xor&0x6000) ||
|
|
||||||
prescales[i]==0);
|
|
||||||
i++) {
|
|
||||||
xor = xor * mult + add;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == bruteframe)
|
|
||||||
{
|
|
||||||
/* test */
|
|
||||||
for (i=0;i<scales_to_do &&
|
|
||||||
(scales[i]&0x6000)==(xor&0x6000);i++) {
|
|
||||||
xor = xor * mult + add;
|
|
||||||
}
|
|
||||||
if (i == scales_to_do)
|
|
||||||
{
|
|
||||||
*xor_start = keys_8[key_id].start;
|
|
||||||
*xor_mult = keys_8[key_id].mult;
|
|
||||||
*xor_add = keys_8[key_id].add;
|
|
||||||
|
|
||||||
rc = 1;
|
|
||||||
goto find_key_cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (type == 9)
|
else if (type == 9)
|
||||||
{
|
{
|
||||||
/* smarter XOR as seen in PSO2, can't do an exact match so we
|
/* smarter XOR as seen in PSO2. The scale is technically 13 bits,
|
||||||
* have to search for the lowest */
|
* but the maximum value assigned by the encoder is 0x1000.
|
||||||
long best_score = MAX_FRAMES * 0x1fff;
|
* This is written to the ADX file as 0xFFF, leaving the high bit
|
||||||
|
* empty, which is used to validate a key */
|
||||||
|
keys = &keys_9;
|
||||||
|
keycount = keys_9_count;
|
||||||
|
keymask = 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
/* guess each of the keys */
|
/* guess each of the keys */
|
||||||
for (key_id=0;key_id<keys_9_count;key_id++) {
|
for (key_id=0;key_id<keycount;key_id++) {
|
||||||
/* run past pre-scales */
|
/* test pre-scales */
|
||||||
uint16_t xor = keys_9[key_id].start;
|
uint16_t xor = keys[key_id].start;
|
||||||
uint16_t mult = keys_9[key_id].mult;
|
uint16_t mult = keys[key_id].mult;
|
||||||
uint16_t add = keys_9[key_id].add;
|
uint16_t add = keys[key_id].add;
|
||||||
int i;
|
int i;
|
||||||
long total_score = 0;
|
|
||||||
|
|
||||||
for (i=0;i<bruteframe;i++) {
|
for (i=0;i<bruteframe &&
|
||||||
xor = xor * mult + add;
|
((prescales[i]&keymask)==(xor&keymask) ||
|
||||||
}
|
prescales[i]==0);
|
||||||
|
i++) {
|
||||||
if (i == bruteframe)
|
xor = xor * mult + add;
|
||||||
{
|
|
||||||
/* test */
|
|
||||||
for (i=0;i<scales_to_do && total_score < best_score;i++) {
|
|
||||||
xor = xor * mult + add;
|
|
||||||
total_score += (scales[i]^xor)&0x1fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (total_score < best_score)
|
|
||||||
{
|
|
||||||
*xor_start = keys_9[key_id].start;
|
|
||||||
*xor_mult = keys_9[key_id].mult;
|
|
||||||
*xor_add = keys_9[key_id].add;
|
|
||||||
|
|
||||||
best_score = total_score;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* arbitrarily decide if we have won? */
|
if (i == bruteframe)
|
||||||
if (best_score < scales_to_do * 0x1000)
|
|
||||||
{
|
{
|
||||||
rc = 1;
|
/* test */
|
||||||
|
for (i=0;i<scales_to_do &&
|
||||||
|
(scales[i]&keymask)==(xor&keymask);i++) {
|
||||||
|
xor = xor * mult + add;
|
||||||
|
}
|
||||||
|
if (i == scales_to_do)
|
||||||
|
{
|
||||||
|
*xor_start = keys[key_id].start;
|
||||||
|
*xor_mult = keys[key_id].mult;
|
||||||
|
*xor_add = keys[key_id].add;
|
||||||
|
|
||||||
|
rc = 1;
|
||||||
|
goto find_key_cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user