mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 08:20:54 +01:00
SCD Ogg Vorbis with obfuscated header triad (FFXIII-2)
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@970 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
968b6afdf1
commit
d8e13f6d29
@ -97,6 +97,10 @@ typedef struct {
|
||||
int32_t loop_end;
|
||||
meta_t meta_type;
|
||||
layout_t layout_type;
|
||||
|
||||
// XOR setup with a single byte (SCD)
|
||||
unsigned char scd_xor;
|
||||
off_t scd_xor_len;
|
||||
} vgm_vorbis_info_t;
|
||||
|
||||
VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const char * filename, ov_callbacks *callbacks, off_t other_header_bytes, const vgm_vorbis_info_t *vgm_inf);
|
||||
|
@ -80,6 +80,32 @@ static size_t read_func_kovs(void *ptr, size_t size, size_t nmemb, void * dataso
|
||||
return items_read;
|
||||
}
|
||||
|
||||
static size_t read_func_scd(void *ptr, size_t size, size_t nmemb, void * datasource)
|
||||
{
|
||||
ogg_vorbis_streamfile * const ov_streamfile = datasource;
|
||||
size_t items_read;
|
||||
|
||||
size_t bytes_read;
|
||||
|
||||
bytes_read = read_streamfile(ptr, ov_streamfile->offset + ov_streamfile->other_header_bytes, size * nmemb,
|
||||
ov_streamfile->streamfile);
|
||||
|
||||
items_read = bytes_read / size;
|
||||
|
||||
/* first bytes are xor'd with a constant byte */
|
||||
if (ov_streamfile->offset < ov_streamfile->scd_xor_len) {
|
||||
int num_crypt = ov_streamfile->scd_xor_len-ov_streamfile->offset;
|
||||
int i;
|
||||
|
||||
if (num_crypt > bytes_read) num_crypt=bytes_read;
|
||||
for (i=0;i<num_crypt;i++)
|
||||
((uint8_t*)ptr)[i] ^= ov_streamfile->scd_xor;
|
||||
}
|
||||
|
||||
ov_streamfile->offset += items_read * size;
|
||||
|
||||
return items_read;
|
||||
}
|
||||
static int seek_func(void *datasource, ogg_int64_t offset, int whence) {
|
||||
ogg_vorbis_streamfile * const ov_streamfile = datasource;
|
||||
ogg_int64_t base_offset;
|
||||
@ -130,7 +156,8 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||
int um3_ogg = 0;
|
||||
int kovs_ogg = 0;
|
||||
|
||||
vgm_vorbis_info_t inf = {0,0,0,0,0,0,0,0};
|
||||
vgm_vorbis_info_t inf;
|
||||
memset(&inf, 0, sizeof(inf));
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
@ -214,12 +241,17 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||
int32_t loop_end = vgm_inf->loop_end;
|
||||
|
||||
ov_callbacks default_callbacks;
|
||||
default_callbacks.read_func = read_func;
|
||||
default_callbacks.seek_func = seek_func;
|
||||
default_callbacks.close_func = close_func;
|
||||
default_callbacks.tell_func = tell_func;
|
||||
|
||||
if (!callbacks_p) {
|
||||
default_callbacks.read_func = read_func;
|
||||
default_callbacks.seek_func = seek_func;
|
||||
default_callbacks.close_func = close_func;
|
||||
default_callbacks.tell_func = tell_func;
|
||||
|
||||
if (vgm_inf->scd_xor != 0) {
|
||||
default_callbacks.read_func = read_func_scd;
|
||||
}
|
||||
|
||||
callbacks_p = &default_callbacks;
|
||||
}
|
||||
|
||||
@ -227,11 +259,14 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||
temp_streamfile.offset = 0;
|
||||
temp_streamfile.size = get_streamfile_size(temp_streamfile.streamfile);
|
||||
temp_streamfile.other_header_bytes = other_header_bytes;
|
||||
temp_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||
temp_streamfile.scd_xor_len = vgm_inf->scd_xor_len;
|
||||
|
||||
/* can we open this as a proper ogg vorbis file? */
|
||||
memset(&temp_ovf, 0, sizeof(temp_ovf));
|
||||
if (ov_test_callbacks(&temp_streamfile, &temp_ovf, NULL,
|
||||
0, *callbacks_p)) goto fail;
|
||||
|
||||
/* we have to close this as it has the init_vgmstream meta-reading
|
||||
STREAMFILE */
|
||||
ov_clear(&temp_ovf);
|
||||
@ -246,6 +281,8 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||
data->ov_streamfile.offset = 0;
|
||||
data->ov_streamfile.size = get_streamfile_size(data->ov_streamfile.streamfile);
|
||||
data->ov_streamfile.other_header_bytes = other_header_bytes;
|
||||
data->ov_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||
data->ov_streamfile.scd_xor_len = vgm_inf->scd_xor_len;
|
||||
|
||||
/* open the ogg vorbis file for real */
|
||||
if (ov_open_callbacks(&data->ov_streamfile, &data->ogg_vorbis_file, NULL,
|
||||
|
@ -64,6 +64,10 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
if (codec_id == 0x6)
|
||||
{
|
||||
vgm_vorbis_info_t inf;
|
||||
uint32_t seek_table_size = read_32bit(meta_offset+0x30, streamFile);
|
||||
uint32_t vorb_header_size = read_32bit(meta_offset+0x34, streamFile);
|
||||
|
||||
memset(&inf, 0, sizeof(inf));
|
||||
inf.loop_start = loop_start;
|
||||
inf.loop_end = loop_end;
|
||||
inf.loop_flag = loop_flag;
|
||||
@ -72,7 +76,39 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
inf.layout_type = layout_ogg_vorbis;
|
||||
inf.meta_type = meta_SQEX_SCD;
|
||||
|
||||
return init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf);
|
||||
VGMSTREAM * result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf);
|
||||
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// try skipping seek table
|
||||
{
|
||||
if (0x20 + seek_table_size + vorb_header_size != read_32bit(meta_offset+0x18, streamFile)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
start_offset = meta_offset + 0x40 + seek_table_size;
|
||||
result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// try deobfuscating header (assume skipping seek table)
|
||||
{
|
||||
unsigned char xor_byte = read_8bit(meta_offset+0x22, streamFile);
|
||||
|
||||
if (xor_byte == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inf.scd_xor = xor_byte;
|
||||
inf.scd_xor_len = vorb_header_size;
|
||||
|
||||
VGMSTREAM * result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -659,6 +659,10 @@ typedef struct {
|
||||
ogg_int64_t offset;
|
||||
ogg_int64_t size;
|
||||
ogg_int64_t other_header_bytes;
|
||||
|
||||
// XOR setup with a single byte (SCD)
|
||||
unsigned char scd_xor;
|
||||
ogg_int64_t scd_xor_len;
|
||||
} ogg_vorbis_streamfile;
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
Reference in New Issue
Block a user