int parse_fixed_program_record(unsigned char **pp, struct fixed_program_record * prog, int varsize) { unsigned char * p = *pp; int data_len; u8 offset; memset(prog, 0, sizeof prog); prog->flags = rtv_to_u32(&p); prog->event_time = rtv_to_u32(&p); prog->tmsid = rtv_to_u32(&p); prog->minutes = rtv_to_u16(&p); prog->genre1 = *p++; prog->genre2 = *p++; prog->genre3 = *p++; prog->genre4 = *p++; prog->record_len = rtv_to_u16(&p); prog->title_len = *p++; prog->episode_len = *p++; prog->description_len = *p++; prog->actor_len = *p++; prog->guest_len = *p++; prog->suzuki_len = *p++; prog->producer_len = *p++; prog->director_len = *p++; if (varsize) data_len = prog->record_len - 28; else data_len = sizeof(prog->datablock); memcpy(prog->datablock, p, data_len); p += data_len; *pp = p; p = prog->datablock; if (prog->flags & 0x0040) parse_parts(&p, &prog->parts); if (prog->flags & 0x0020) parse_movie(&p, &prog->movie); offset = p - prog->datablock; prog->title_offset = offset; offset += prog->title_len; prog->episode_offset = offset; offset += prog->episode_len; prog->description_offset = offset; offset += prog->description_len; prog->actor_offset = offset; offset += prog->actor_len; prog->guest_offset = offset; offset += prog->guest_len; prog->suzuki_offset = offset; offset += prog->suzuki_len; prog->producer_offset = offset; offset += prog->producer_len; prog->director_offset = offset; offset += prog->director_len; expect(prog->record_len == 0 || ((offset + 28 + 3) & 0xfffc) == prog->record_len); return 0; }
int parse_cg2_channel(unsigned char **pp, struct cg2_channel * chan) { unsigned char * p = *pp; memset(chan, 0, sizeof *chan); chan->mod_time = rtv_to_u32(&p); chan->tmsid = rtv_to_u32(&p); chan->data_len = rtv_to_u32(&p); *pp = p; return 0; }
int parse_program(unsigned char **pp, struct program * prog) { unsigned char * p = *pp; memset(prog, 0, sizeof prog); prog->struct_size = rtv_to_u32(&p); prog->unknown1 = rtv_to_u32(&p); prog->isvalid = rtv_to_u32(&p); prog->tuning = rtv_to_u32(&p); parse_fixed_program_record(&p, &prog->fixed_program_record, 0); if (prog->struct_size) { expect(prog->struct_size == 272); expect(prog->unknown1 == 1); expect(prog->isvalid == 1); } *pp = p; return 0; }
static int dump_programset_file(FILE * fp) { unsigned char header[256]; unsigned char buffer[256]; unsigned char * bigbuf; unsigned char * p; struct fixed_program_record r; u32 tms_id; u32 length; int i = 0; while (fread(buffer, 8, 1, fp)) { p = buffer; tms_id = rtv_to_u32(&p); length = rtv_to_u32(&p); bigbuf = malloc(length); expect(bigbuf != NULL); dump_group_start("Programset Channel"); dump_u32 ("TMS ID", tms_id); dump_u32 ("Length", length); fread(bigbuf, length, 1, fp); for (p = bigbuf, parse_fixed_program_record(&p, &r, 1); p < bigbuf + length; parse_fixed_program_record(&p, &r, 1)) { sprintf(header, "FPR #%d", i); dump_group_start(header); dump_fixed_program_record(&r); dump_group_end(); i++; } dump_group_end (); free(bigbuf); } return 0; }
int main(int argc, char ** argv) { unsigned char buf[32768]; unsigned char * p; size_t words_in_buf; size_t cur_word; u64 buf_start = 0; u64 value; u64 video_start = 0, gop = 0, audio_start = 0; int recno = 0; (void)argc; (void)argv; write_header(); while ((words_in_buf = fread(buf, 4, sizeof(buf)/4, stdin)) > 0) { p = buf; for (cur_word = 0; cur_word < words_in_buf; cur_word++) { value = rtv_to_u32(&p); if (value == VIDEO_START && !gop) { video_start = buf_start + cur_word * 4; } if (value == GOP_START) { gop = buf_start + cur_word * 4; } if (value == AUDIO_START && gop) { audio_start = buf_start + cur_word * 4; report(recno++, video_start, audio_start); video_start = gop = audio_start = 0; } } buf_start += sizeof(buf); } return 0; }
int rtv_decrypt(const char * cyphertext, u32 cyphertext_len, char * plainbuf, u32 plainbuf_len, u32 * p_time, u32 * p_plain_len, int checksum_num) { unsigned char key_buf[4]; unsigned char sanity_buf[4]; unsigned char time_buf[4]; unsigned char csum_buf[16]; unsigned char * p; u32 key; u32 sanity; #if VERBOSE_OBFUSC unsigned char obfusc_buf[4]; u32 obfusc; #endif if (plainbuf_len < cyphertext_len - 32) return -1; /* unshuffle the key and unxor it */ key_buf[0] = cyphertext[2]; key_buf[1] = cyphertext[4]; key_buf[2] = cyphertext[1]; key_buf[3] = cyphertext[7]; p = key_buf; key = rtv_to_u32(&p) ^ 0xcb0baf47; #if VERBOSE_OBFUSC obfusc_buf[0] = cyphertext[0]; obfusc_buf[1] = cyphertext[3]; obfusc_buf[2] = cyphertext[5]; obfusc_buf[3] = cyphertext[6]; p = key_buf; obfusc = rtv_to_u32(&p); //fprintf(stderr, "Key: %ld (0x%lx)\n", (unsigned long)key, (unsigned long)key); //fprintf(stderr, "Obfusc: %ld (0x%lx)\n", (unsigned long)obfusc, (unsigned long)obfusc); #endif /* check the sanity field */ memcpy(sanity_buf, cyphertext + 24, 4); key = cryptblock(key, sanity_buf, 4); p = sanity_buf; sanity = rtv_to_u32(&p); if (sanity != 0x42ffdfa9) return -1; /* decrypt the time field */ memcpy(time_buf, cyphertext + 28, 4); key = cryptblock(key, time_buf, 4); /* decrypt the actual text */ memcpy(plainbuf, cyphertext + 32, cyphertext_len - 32); cryptblock(key, plainbuf, cyphertext_len - 32); /* check the checksum */ checksum(csum_buf, cyphertext + 24, cyphertext_len - 24, checksum_num); if (memcmp(csum_buf, cyphertext + 8, 16) != 0) return -2; if (p_plain_len) { *p_plain_len = cyphertext_len - 32; } if (p_time) { p = time_buf; *p_time = rtv_to_u32(&p); #if VERBOSE_OBFUSC // fprintf(stderr, "Time: %ld (0x%lx)\n", (unsigned long)*p_time, (unsigned long)*p_time); #endif } return 0; }