Code: Select all
/* check SNGW (Capcom's MT Framework PC games), may be encrypted */
if (is_sngw) {
if (read_32bitBE(0x00,streamFile) != 0x4f676753) { /* "OggS" */
ovmi.xor_value = read_32bitBE(0x00,streamFile);
ovmi.decryption_callback = sngw_ogg_decryption_callback;
}
ovmi.meta_type = meta_OGG_SNGW;
}
Code: Select all
static void sngw_ogg_decryption_callback(void *ptr, size_t size, size_t nmemb, void *datasource) {
size_t bytes_read = size*nmemb;
ogg_vorbis_streamfile * const ov_streamfile = datasource;
int i;
char *header_id = "OggS";
uint8_t key[4];
put_32bitBE(key, ov_streamfile->xor_value);
/* bytes are xor'd with key and nibble-swapped, first "OggS" is changed */
for (i = 0; i < bytes_read; i++) {
if (ov_streamfile->offset+i < 0x04) {
((uint8_t*)ptr)[i] = (uint8_t)header_id[(ov_streamfile->offset + i) % 4];
}
else {
uint8_t val = ((uint8_t*)ptr)[i] ^ key[(ov_streamfile->offset + i) % 4];
((uint8_t*)ptr)[i] = ((val << 4) & 0xf0) | ((val >> 4) & 0x0f);
}
}
}