mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-19 00:04:04 +01:00
commit
6a35dcb342
@ -27,6 +27,12 @@ sfx01.wav #h22050
|
||||
field.bfstm #C3,4
|
||||
```
|
||||
|
||||
**bgm01.flac #I 10.0 .txtp**
|
||||
```
|
||||
# (empty)
|
||||
# this is a "mini-txtp" that sets loop start to 10 seconds
|
||||
# notice it has the original filename + extension, then commands, then .txtp
|
||||
```
|
||||
|
||||
## TXTP MODES
|
||||
TXTP can join and play together multiple songs in various ways by setting a file list and mode:
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifdef HCA_BRUTEFORCE
|
||||
static void bruteforce_hca_key(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey);
|
||||
#endif
|
||||
static void find_hca_key(hca_codec_data* hca_data, uint64_t* p_keycode, uint16_t subkey);
|
||||
static int find_hca_key(hca_codec_data* hca_data, uint64_t* p_keycode, uint16_t subkey);
|
||||
|
||||
|
||||
/* CRI HCA - streamed audio from CRI ADX2/Atom middleware */
|
||||
@ -60,7 +60,9 @@ VGMSTREAM* init_vgmstream_hca_subkey(STREAMFILE* sf, uint16_t subkey) {
|
||||
}
|
||||
#ifdef HCA_BRUTEFORCE
|
||||
else if (1) {
|
||||
bruteforce_hca_key(sf, hca_data, &keycode, subkey);
|
||||
int ok = find_hca_key(hca_data, &keycode, subkey);
|
||||
if (!ok)
|
||||
bruteforce_hca_key(sf, hca_data, &keycode, subkey);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
@ -156,7 +158,7 @@ static inline void test_key(hca_codec_data* hca_data, uint64_t key, uint16_t sub
|
||||
}
|
||||
|
||||
/* try to find the decryption key from a list. */
|
||||
static void find_hca_key(hca_codec_data* hca_data, uint64_t* p_keycode, uint16_t subkey) {
|
||||
static int find_hca_key(hca_codec_data* hca_data, uint64_t* p_keycode, uint16_t subkey) {
|
||||
const size_t keys_length = sizeof(hcakey_list) / sizeof(hcakey_info);
|
||||
int best_score = -1;
|
||||
int i;
|
||||
@ -191,6 +193,7 @@ done:
|
||||
VGM_ASSERT(best_score > 1, "HCA: best key=%08x%08x (score=%i)\n",
|
||||
(uint32_t)((*p_keycode >> 32) & 0xFFFFFFFF), (uint32_t)(*p_keycode & 0xFFFFFFFF), best_score);
|
||||
vgm_asserti(best_score < 0, "HCA: decryption key not found\n");
|
||||
return best_score > 0;
|
||||
}
|
||||
|
||||
#ifdef HCA_BRUTEFORCE
|
||||
@ -213,16 +216,17 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
||||
uint8_t* buf = NULL;
|
||||
int best_score = 0xFFFFFF, cur_score;
|
||||
off_t keys_size, bytes;
|
||||
int pos;
|
||||
int pos, step;
|
||||
uint64_t old_key = 0;
|
||||
uint64_t key = 0;
|
||||
uint64_t best_key = 0;
|
||||
|
||||
|
||||
/* load whole file in memory for performance (exes with keys shouldn't be too big) */
|
||||
sf_keys = open_streamfile_by_filename(sf, "keys.bin");
|
||||
if (!sf_keys) return;
|
||||
|
||||
VGM_LOG("HCA: test keys.bin (type %i)\n", type);
|
||||
VGM_LOG("HCA BF: test keys.bin (type %i)\n", type);
|
||||
*p_keycode = 0;
|
||||
|
||||
keys_size = get_streamfile_size(sf_keys);
|
||||
@ -233,24 +237,37 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
||||
bytes = read_streamfile(buf, 0, keys_size, sf_keys);
|
||||
if (bytes != keys_size) goto done;
|
||||
|
||||
VGM_LOG("HCA: start\n");
|
||||
VGM_LOG("HCA BF: start .bin\n");
|
||||
|
||||
switch(type) {
|
||||
case HBF_TYPE_64LE_1:
|
||||
case HBF_TYPE_64BE_1:
|
||||
case HBF_TYPE_32LE_1:
|
||||
case HBF_TYPE_32BE_1: step = 0x01; break;
|
||||
case HBF_TYPE_64LE_4:
|
||||
case HBF_TYPE_64BE_4:
|
||||
case HBF_TYPE_32LE_4:
|
||||
case HBF_TYPE_32BE_4: step = 0x04; break;
|
||||
default: goto done;
|
||||
}
|
||||
|
||||
pos = 0;
|
||||
while (pos < keys_size - 4) {
|
||||
while (pos < keys_size - 8) {
|
||||
VGM_ASSERT(pos % 0x1000000 == 0, "HCA: pos %x...\n", pos);
|
||||
|
||||
/* keys are usually u64le but other orders may exist */
|
||||
switch(type) {
|
||||
case HBF_TYPE_64LE_1: key = get_u64le(buf + pos); pos += 0x01; break;
|
||||
case HBF_TYPE_64BE_1: key = get_u64be(buf + pos); pos += 0x01; break;
|
||||
case HBF_TYPE_32LE_1: key = get_u32le(buf + pos); pos += 0x01; break;
|
||||
case HBF_TYPE_32BE_1: key = get_u32be(buf + pos); pos += 0x01; break;
|
||||
case HBF_TYPE_64LE_4: key = get_u64le(buf + pos); pos += 0x04; break;
|
||||
case HBF_TYPE_64BE_4: key = get_u64be(buf + pos); pos += 0x04; break;
|
||||
case HBF_TYPE_32LE_4: key = get_u32le(buf + pos); pos += 0x04; break;
|
||||
case HBF_TYPE_32BE_4: key = get_u32be(buf + pos); pos += 0x04; break;
|
||||
default: key = 0; pos = keys_size; break;
|
||||
case HBF_TYPE_64LE_1: key = get_u64le(buf + pos); break;
|
||||
case HBF_TYPE_64BE_1: key = get_u64be(buf + pos); break;
|
||||
case HBF_TYPE_32LE_1: key = get_u32le(buf + pos); break;
|
||||
case HBF_TYPE_32BE_1: key = get_u32be(buf + pos); break;
|
||||
case HBF_TYPE_64LE_4: key = get_u64le(buf + pos); break;
|
||||
case HBF_TYPE_64BE_4: key = get_u64be(buf + pos); break;
|
||||
case HBF_TYPE_32LE_4: key = get_u32le(buf + pos); break;
|
||||
case HBF_TYPE_32BE_4: key = get_u32be(buf + pos); break;
|
||||
default: goto done;
|
||||
}
|
||||
pos += step;
|
||||
|
||||
if (key == 0 || key == old_key)
|
||||
continue;
|
||||
@ -259,27 +276,30 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
||||
cur_score = 0;
|
||||
test_key(hca_data, key, subkey, &cur_score, p_keycode);
|
||||
if (cur_score == 1) {
|
||||
best_key = key;
|
||||
best_score = cur_score;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (cur_score > 0 && cur_score <= 500) {
|
||||
VGM_LOG("HCA: possible key=%08x%08x (score=%i) at %x\n",
|
||||
(uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), cur_score, pos-0x04);
|
||||
if (best_score > cur_score)
|
||||
VGM_LOG("HCA BF: possible key=%08x%08x (score=%i) at offset %x\n",
|
||||
(uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), cur_score, pos - step);
|
||||
if (best_score > cur_score) {
|
||||
best_key = key;
|
||||
best_score = cur_score;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (best_score < 0 || best_score > 10000) {
|
||||
*p_keycode = 0;
|
||||
VGM_LOG("HCA: good key not found\n");
|
||||
VGM_LOG("HCA BF: no good key found\n");
|
||||
}
|
||||
else {
|
||||
/* print key as p_keycode includes subkey */
|
||||
VGM_LOG("HCA: best key=%08x%08x (score=%i)\n",
|
||||
(uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), best_score);
|
||||
/* print best_key as p_keycode includes subkey */
|
||||
VGM_LOG("HCA BF: best key=%08x%08x (score=%i)\n",
|
||||
(uint32_t)((best_key >> 32) & 0xFFFFFFFF), (uint32_t)(best_key & 0xFFFFFFFF), best_score);
|
||||
}
|
||||
|
||||
close_streamfile(sf_keys);
|
||||
@ -319,7 +339,7 @@ static void bruteforce_hca_key_txt(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
||||
sf_keys = open_streamfile_by_filename(sf, "keys.txt");
|
||||
if (!sf_keys) return;
|
||||
|
||||
VGM_LOG("HCA: test keys.txt\n");
|
||||
VGM_LOG("HCA BF: test keys.txt\n");
|
||||
*p_keycode = 0;
|
||||
|
||||
keys_size = get_streamfile_size(sf_keys);
|
||||
@ -330,7 +350,7 @@ static void bruteforce_hca_key_txt(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
||||
bytes = read_streamfile(buf, 0, keys_size, sf_keys);
|
||||
if (bytes != keys_size) goto done;
|
||||
|
||||
VGM_LOG("HCA: start\n");
|
||||
VGM_LOG("HCA BF: start .txt\n");
|
||||
|
||||
pos = 0;
|
||||
while (pos < keys_size) {
|
||||
@ -356,18 +376,18 @@ static void bruteforce_hca_key_txt(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
||||
goto done;
|
||||
|
||||
if (cur_score > 0 && cur_score <= 500) {
|
||||
VGM_LOG("HCA: possible key=%08x%08x (score=%i) at %x\n",
|
||||
(uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), cur_score, pos-0x04);
|
||||
VGM_LOG("HCA BF: possible key=%08x%08x (score=%i) at %x\n",
|
||||
(uint32_t)((key >> 32) & 0xFFFFFFFF), (uint32_t)(key & 0xFFFFFFFF), cur_score, pos - bytes_read);
|
||||
if (best_score > cur_score)
|
||||
best_score = cur_score;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
VGM_LOG("HCA: done %i keys.txt\n", i);
|
||||
VGM_ASSERT(best_score > 0, "HCA: best key=%08x%08x (score=%i)\n",
|
||||
VGM_LOG("HCA BF: done %i keys.txt\n", i);
|
||||
VGM_ASSERT(best_score > 0, "HCA BF: best key=%08x%08x (score=%i)\n",
|
||||
(uint32_t)((*p_keycode >> 32) & 0xFFFFFFFF), (uint32_t)(*p_keycode & 0xFFFFFFFF), best_score);
|
||||
VGM_ASSERT(best_score < 0, "HCA: key not found\n");
|
||||
VGM_ASSERT(best_score < 0, "HCA BF: no good key found\n");
|
||||
if (best_score < 0 || best_score > 10000)
|
||||
*p_keycode = 0;
|
||||
|
||||
|
@ -781,7 +781,33 @@ static const hcakey_info hcakey_list[] = {
|
||||
{53346933792338754}, // 00BD86C0EE8C7342
|
||||
|
||||
// THE iDOLM@STER Starlit Season (PS4/PC)
|
||||
{7865357762459531720}, // 6d275d3666c2f9c8
|
||||
{0x1e03b570b6145d1d}, // BGM
|
||||
{0x1da915aaa181a461}, // SE
|
||||
{0x1c82b6ab7487a5ec}, // Voice
|
||||
{0x6d275d3666c2f9c8}, // Sng001
|
||||
{0x0f53815df3044e6d}, // Sng002
|
||||
{0x158778e2e2fab347}, // Sng003
|
||||
{0x16b75e8b5247d46b}, // Sng004
|
||||
{0x157df8a6047048fc}, // Sng005
|
||||
{0x184d358b50b658d0}, // Sng006
|
||||
{0x157fb75af4ddd983}, // Sng007
|
||||
{0x404ba38c3e470827}, // Sng008
|
||||
{0x01d0b788a3b60d48}, // Sng009
|
||||
{0x021718d55d0960c9}, // Sng010
|
||||
{0x0021c5993d2b901c}, // Sng011
|
||||
{0x08237bcb9b711087}, // Sng012
|
||||
{0x01af60402e1228a5}, // Sng013
|
||||
{0x4eec18ab73a1a634}, // Sng014
|
||||
{0x1855099898b11ad9}, // Sng015
|
||||
{0x57ef8f2ea5d54db5}, // Sng016
|
||||
{0x17cc6975d67e2a1f}, // Sng017
|
||||
{0x0a5d0fc8cc5c4502}, // Sng018
|
||||
{0x198ea1a17416050b}, // Sng019
|
||||
{0x2aa3b8abad207a1e}, // Sng020
|
||||
{0x33d98a3a9f9bfdef}, // Sng026
|
||||
{0x2284fd5ca82c78f4}, // Sng027
|
||||
{0x178a76b6436d20f0}, // Sng028
|
||||
{0x3ff99f2fed65a1ed}, // Sng030
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user