Fix ciph-1 HCA and add errors [DQ Monsters: Super Light (Mobile)]

This commit is contained in:
bnnm 2018-10-13 13:02:40 +02:00
parent 7b0e18171d
commit 0c53449df1

View File

@ -26,7 +26,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <memory.h> #include <memory.h>
#define HCA_MASK 0x7F7F7F7F /* chunk obfuscation when the HCA is encrypted (ciph type > 0) */ #define HCA_MASK 0x7F7F7F7F /* chunk obfuscation when the HCA is encrypted with key */
#define HCA_SUBFRAMES_PER_FRAME 8 #define HCA_SUBFRAMES_PER_FRAME 8
#define HCA_SAMPLES_PER_SUBFRAME 128 #define HCA_SAMPLES_PER_SUBFRAME 128
#define HCA_SAMPLES_PER_FRAME (HCA_SUBFRAMES_PER_FRAME*HCA_SAMPLES_PER_SUBFRAME) #define HCA_SAMPLES_PER_FRAME (HCA_SUBFRAMES_PER_FRAME*HCA_SAMPLES_PER_SUBFRAME)
@ -34,6 +34,13 @@
#define HCA_MAX_CHANNELS 16 /* internal max? in practice only 8 can be encoded */ #define HCA_MAX_CHANNELS 16 /* internal max? in practice only 8 can be encoded */
#define HCA_ERROR_PARAMS -1
#define HCA_ERROR_HEADER -2
#define HCA_ERROR_CHECKSUM -3
#define HCA_ERROR_SYNC -4
#define HCA_ERROR_UNPACK -5
#define HCA_ERROR_BITREADER -6
//-------------------------------------------------- //--------------------------------------------------
// Decoder config/state // Decoder config/state
//-------------------------------------------------- //--------------------------------------------------
@ -239,7 +246,7 @@ int clHCA_isOurFile(const void *data, unsigned int size) {
unsigned int header_size = 0; unsigned int header_size = 0;
if (!data || size < 0x08) if (!data || size < 0x08)
return -1; return HCA_ERROR_PARAMS;
bitreader_init(&br, data, 8); bitreader_init(&br, data, 8);
if ((bitreader_peek(&br, 32) & HCA_MASK) == 0x48434100) {/*'HCA\0'*/ if ((bitreader_peek(&br, 32) & HCA_MASK) == 0x48434100) {/*'HCA\0'*/
@ -248,13 +255,13 @@ int clHCA_isOurFile(const void *data, unsigned int size) {
} }
if (header_size == 0) if (header_size == 0)
return -1; return HCA_ERROR_HEADER;
return header_size; return header_size;
} }
int clHCA_getInfo(clHCA *hca, clHCA_stInfo *info) { int clHCA_getInfo(clHCA *hca, clHCA_stInfo *info) {
if (!hca || !info || !hca->is_valid) if (!hca || !info || !hca->is_valid)
return -1; return HCA_ERROR_PARAMS;
info->version = hca->version; info->version = hca->version;
info->headerSize = hca->header_size; info->headerSize = hca->header_size;
@ -424,7 +431,7 @@ static int ath_init(unsigned char *ath_curve, int type, unsigned int sample_rate
ath_init1(ath_curve, sample_rate); ath_init1(ath_curve, sample_rate);
break; break;
default: default:
return -1; return HCA_ERROR_HEADER;
} }
return 0; return 0;
} }
@ -455,7 +462,7 @@ static void cipher_init1(unsigned char *cipher_table) {
const int add = 11; const int add = 11;
unsigned int i, v = 0; unsigned int i, v = 0;
/* keyless encryption (unused?) */ /* keyless encryption (rare) */
for (i = 1; i < 256 - 1; i++) { for (i = 1; i < 256 - 1; i++) {
v = (v * mul + add) & 0xFF; v = (v * mul + add) & 0xFF;
if (v == 0 || v == 0xFF) if (v == 0 || v == 0xFF)
@ -542,7 +549,7 @@ static void cipher_init56(unsigned char *cipher_table, unsigned long long keycod
} }
static int cipher_init(unsigned char *cipher_table, int type, unsigned long long keycode) { static int cipher_init(unsigned char *cipher_table, int type, unsigned long long keycode) {
if (!(keycode)) if (type == 56 && !(keycode))
type = 0; type = 0;
switch (type) { switch (type) {
@ -556,7 +563,7 @@ static int cipher_init(unsigned char *cipher_table, int type, unsigned long long
cipher_init56(cipher_table, keycode); cipher_init56(cipher_table, keycode);
break; break;
default: default:
return -1; return HCA_ERROR_HEADER;
} }
return 0; return 0;
} }
@ -570,14 +577,15 @@ static unsigned int header_ceil2(unsigned int a, unsigned int b) {
int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) { int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
clData br; clData br;
int res;
if (!hca || !data ) if (!hca || !data)
return -1; return HCA_ERROR_PARAMS;
hca->is_valid = 0; hca->is_valid = 0;
if (size < 0x08) if (size < 0x08)
return -1; return HCA_ERROR_PARAMS;
bitreader_init(&br, data, size); bitreader_init(&br, data, size);
@ -594,18 +602,18 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
hca->version != 0x0102 && hca->version != 0x0102 &&
hca->version != 0x0103 && hca->version != 0x0103 &&
hca->version != 0x0200) hca->version != 0x0200)
return -1; return HCA_ERROR_HEADER;
#endif #endif
if (size < hca->header_size) if (size < hca->header_size)
return -1; return HCA_ERROR_PARAMS;
if (crc16_checksum(data,hca->header_size)) if (crc16_checksum(data,hca->header_size))
return -1; return HCA_ERROR_CHECKSUM;
size -= 0x08; size -= 0x08;
} }
else { else {
return -1; return HCA_ERROR_HEADER;
} }
/* format info */ /* format info */
@ -618,18 +626,18 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
hca->encoder_padding = bitreader_read(&br, 16); hca->encoder_padding = bitreader_read(&br, 16);
if (!(hca->channels >= 1 && hca->channels <= HCA_MAX_CHANNELS)) if (!(hca->channels >= 1 && hca->channels <= HCA_MAX_CHANNELS))
return -1; return HCA_ERROR_HEADER;
if (hca->frame_count == 0) if (hca->frame_count == 0)
return -1; return HCA_ERROR_HEADER;
if (!(hca->sample_rate >= 1 && hca->sample_rate <= 0x7FFFFF)) /* encoder max seems 48000 */ if (!(hca->sample_rate >= 1 && hca->sample_rate <= 0x7FFFFF)) /* encoder max seems 48000 */
return -1; return HCA_ERROR_HEADER;
size -= 0x10; size -= 0x10;
} }
else { else {
return -1; return HCA_ERROR_HEADER;
} }
/* compression (v2.0) or decode (v1.x) info */ /* compression (v2.0) or decode (v1.x) info */
@ -668,7 +676,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
size -= 0x0c; size -= 0x0c;
} }
else { else {
return -1; return HCA_ERROR_HEADER;
} }
/* VBR (variable bit rate) info */ /* VBR (variable bit rate) info */
@ -678,7 +686,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
hca->vbr_noise_Level = bitreader_read(&br, 16); hca->vbr_noise_Level = bitreader_read(&br, 16);
if (!(hca->frame_size == 0 && hca->vbr_max_frame_size > 8 && hca->vbr_max_frame_size <= 0x1FF)) if (!(hca->frame_size == 0 && hca->vbr_max_frame_size > 8 && hca->vbr_max_frame_size <= 0x1FF))
return -1; return HCA_ERROR_HEADER;
size -= 0x08; size -= 0x08;
} }
@ -710,7 +718,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
if (!(hca->loop_start_frame >= 0 && hca->loop_start_frame <= hca->loop_end_frame if (!(hca->loop_start_frame >= 0 && hca->loop_start_frame <= hca->loop_end_frame
&& hca->loop_end_frame < hca->frame_count)) && hca->loop_end_frame < hca->frame_count))
return -1; return HCA_ERROR_HEADER;
size -= 0x10; size -= 0x10;
} }
@ -729,7 +737,7 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
hca->ciph_type = bitreader_read(&br, 16); hca->ciph_type = bitreader_read(&br, 16);
if (!(hca->ciph_type == 0 || hca->ciph_type == 1 || hca->ciph_type == 56)) if (!(hca->ciph_type == 0 || hca->ciph_type == 1 || hca->ciph_type == 56))
return -1; return HCA_ERROR_HEADER;
size -= 0x06; size -= 0x06;
} }
@ -760,11 +768,11 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
hca->comment_len = bitreader_read(&br, 8); hca->comment_len = bitreader_read(&br, 8);
if (hca->comment_len > size) if (hca->comment_len > size)
return -1; return HCA_ERROR_HEADER;
temp = realloc(hca->comment, hca->comment_len + 1); temp = realloc(hca->comment, hca->comment_len + 1);
if (!temp) if (!temp)
return -1; return HCA_ERROR_HEADER;
hca->comment = temp; hca->comment = temp;
for (i = 0; i < hca->comment_len; ++i) for (i = 0; i < hca->comment_len; ++i)
hca->comment[i] = bitreader_read(&br, 8); hca->comment[i] = bitreader_read(&br, 8);
@ -782,17 +790,17 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
size -= (size - 0x02); /* fills up to header_size, sans checksum */ size -= (size - 0x02); /* fills up to header_size, sans checksum */
} }
/* should be fully read, but allow data buffer may be bigger than header_size */ /* should be fully read, but allow as data buffer may be bigger than header_size */
//if (size != 0x02) //if (size != 0x02)
// return -1; // return HCA_ERROR_HEADER;
/* extra validations */ /* extra validations */
if (!(hca->frame_size >= 0x08 && hca->frame_size <= 0xFFFF)) /* actual max seems 0x155*channels */ if (!(hca->frame_size >= 0x08 && hca->frame_size <= 0xFFFF)) /* actual max seems 0x155*channels */
return -1; /* theoretically can be 0 if VBR (not seen) */ return HCA_ERROR_HEADER; /* theoretically can be 0 if VBR (not seen) */
if (!(hca->min_resolution == 1 && hca->max_resolution == 15)) if (!(hca->min_resolution == 1 && hca->max_resolution == 15))
return -1; return HCA_ERROR_HEADER;
/* inits state */ /* inits state */
@ -803,10 +811,12 @@ int clHCA_DecodeHeader(clHCA *hca, void *data, unsigned int size) {
hca->total_band_count - hca->base_band_count - hca->stereo_band_count, hca->total_band_count - hca->base_band_count - hca->stereo_band_count,
hca->bands_per_hfr_group); hca->bands_per_hfr_group);
if (ath_init(hca->ath_curve, hca->ath_type, hca->sample_rate) < 0) res = ath_init(hca->ath_curve, hca->ath_type, hca->sample_rate);
return -1; if (res < 0)
if (cipher_init(hca->cipher_table, hca->ciph_type, hca->keycode) < 0) return res;
return -1; res = cipher_init(hca->cipher_table, hca->ciph_type, hca->keycode);
if (res < 0)
return res;
/* init channels */ /* init channels */
@ -1002,19 +1012,19 @@ int clHCA_DecodeBlock(clHCA *hca, void *data, unsigned int size) {
unsigned int subframe, ch; unsigned int subframe, ch;
if (!data || !hca || !hca->is_valid) if (!data || !hca || !hca->is_valid)
return -1; return HCA_ERROR_PARAMS;
if (size < hca->frame_size) if (size < hca->frame_size)
return -1; return HCA_ERROR_PARAMS;
bitreader_init(&br, data, hca->frame_size); bitreader_init(&br, data, hca->frame_size);
/* test sync (not encrypted) */ /* test sync (not encrypted) */
sync = bitreader_read(&br, 16); sync = bitreader_read(&br, 16);
if (sync != 0xFFFF) if (sync != 0xFFFF)
return -1; return HCA_ERROR_SYNC;
if (crc16_checksum(data, hca->frame_size)) if (crc16_checksum(data, hca->frame_size))
return -1; return HCA_ERROR_CHECKSUM;
cipher_decrypt(hca->cipher_table, data, hca->frame_size); cipher_decrypt(hca->cipher_table, data, hca->frame_size);
@ -1029,7 +1039,7 @@ int clHCA_DecodeBlock(clHCA *hca, void *data, unsigned int size) {
int unpack = decode1_unpack_channel(&hca->channel[ch], &br, int unpack = decode1_unpack_channel(&hca->channel[ch], &br,
hca->hfr_group_count, packed_noise_level, hca->ath_curve); hca->hfr_group_count, packed_noise_level, hca->ath_curve);
if (unpack < 0) if (unpack < 0)
return -1; return unpack;
} }
} }
@ -1060,9 +1070,8 @@ int clHCA_DecodeBlock(clHCA *hca, void *data, unsigned int size) {
} }
/* should read all frame sans checksum at most */ /* should read all frame sans checksum at most */
if (br.bit > br.size - 16) { if (br.bit > br.size - 16)
return -1; return HCA_ERROR_BITREADER;
}
return 0; return 0;
} }
@ -1132,7 +1141,7 @@ static int decode1_unpack_channel(stChannel *ch, clData *br,
/* may happen with bad keycodes, scalefactors must be 6b indexes */ /* may happen with bad keycodes, scalefactors must be 6b indexes */
int scalefactor_test = (int)scalefactor_prev + ((int)delta - (int)extra_delta); int scalefactor_test = (int)scalefactor_prev + ((int)delta - (int)extra_delta);
if (scalefactor_test < 0 || scalefactor_test > 64) { if (scalefactor_test < 0 || scalefactor_test > 64) {
return -1; return HCA_ERROR_UNPACK;
} }
scalefactor_prev += delta - extra_delta; scalefactor_prev += delta - extra_delta;
@ -1160,7 +1169,7 @@ static int decode1_unpack_channel(stChannel *ch, clData *br,
} }
/* 15 may be an invalid value? */ /* 15 may be an invalid value? */
//else { //else {
// return -1; // return HCA_ERROR_INSENSITY;
//} //}
} }
else { else {